diff --git a/newgrf_station.c b/newgrf_station.c index 6a930ba619..18a1386024 100644 --- a/newgrf_station.c +++ b/newgrf_station.c @@ -164,6 +164,23 @@ const StationSpec *GetCustomStationSpec(StationClassID sclass, uint station) } +const StationSpec *GetCustomStationSpecByGrf(uint32 grfid, byte localidx) +{ + StationClassID i; + uint j; + + for (i = STAT_CLASS_DFLT; i < STAT_CLASS_MAX; i++) { + for (j = 0; j < station_classes[i].stations; j++) { + const StationSpec *statspec = station_classes[i].spec[j]; + if (statspec == NULL) continue; + if (statspec->grfid == grfid && statspec->localidx == localidx) return statspec; + } + } + + return NULL; +} + + /* Evaluate a tile's position within a station, and return the result a bitstuffed format. * if not centred: .TNLcCpP, if centred: .TNL..CP * T = Tile layout number (GetStationGfx), N = Number of platforms, L = Length of platforms diff --git a/newgrf_station.h b/newgrf_station.h index 50b4dc6ea7..bea4535a3a 100644 --- a/newgrf_station.h +++ b/newgrf_station.h @@ -94,6 +94,7 @@ uint GetNumCustomStations(StationClassID sclass); void SetCustomStationSpec(StationSpec *statspec); const StationSpec *GetCustomStationSpec(StationClassID sclass, uint station); +const StationSpec *GetCustomStationSpecByGrf(uint32 grfid, byte localidx); /* Get sprite offset for a given custom station and station structure (may be * NULL - that means we are in a build dialog). The station structure is used diff --git a/openttd.c b/openttd.c index 8d8fed663e..fab4ba049c 100644 --- a/openttd.c +++ b/openttd.c @@ -1426,5 +1426,7 @@ bool AfterLoadGame(void) FOR_ALL_PLAYERS(p) p->avail_railtypes = GetPlayerRailtypes(p->index); + if (!CheckSavegameVersion(27)) AfterLoadStations(); + return true; } diff --git a/saveload.c b/saveload.c index 0087db17e5..fcbbd25a82 100644 --- a/saveload.c +++ b/saveload.c @@ -30,7 +30,7 @@ #include "variables.h" #include -const uint16 SAVEGAME_VERSION = 26; +const uint16 SAVEGAME_VERSION = 27; uint16 _sl_version; /// the major savegame version identifier byte _sl_minor_version; /// the minor savegame version, DO NOT USE! diff --git a/station.h b/station.h index 09a6a80c5a..5f2a36dad4 100644 --- a/station.h +++ b/station.h @@ -194,6 +194,7 @@ static inline uint16 GetRoadStopPoolSize(void) VARDEF bool _station_sort_dirty[MAX_PLAYERS]; VARDEF bool _global_station_sort_dirty; +void AfterLoadStations(void); void GetProductionAroundTiles(AcceptedCargo produced, TileIndex tile, int w, int h, int rad); void GetAcceptanceAroundTiles(AcceptedCargo accepts, TileIndex tile, int w, int h, int rad); uint GetStationPlatforms(const Station *st, TileIndex tile); diff --git a/station_cmd.c b/station_cmd.c index 0d4160242a..b748a90213 100644 --- a/station_cmd.c +++ b/station_cmd.c @@ -2821,6 +2821,22 @@ void InitializeStations(void) } +void AfterLoadStations(void) +{ + Station *st; + uint i; + + /* Update the speclists of all stations to point to the currently loaded custom stations. */ + FOR_ALL_STATIONS(st) { + for (i = 0; i < st->num_specs; i++) { + if (st->speclist[i].grfid == 0) continue; + + st->speclist[i].spec = GetCustomStationSpecByGrf(st->speclist[i].grfid, st->speclist[i].localidx); + } + } +} + + const TileTypeProcs _tile_type_station_procs = { DrawTile_Station, /* draw_tile_proc */ GetSlopeZ_Station, /* get_slope_z_proc */ @@ -2906,6 +2922,7 @@ static const SaveLoad _station_desc[] = { /* Used by newstations for graphic variations */ SLE_CONDVAR(Station,random_bits, SLE_UINT16, 27, SL_MAX_VERSION), SLE_CONDVAR(Station,waiting_triggers, SLE_UINT8, 27, SL_MAX_VERSION), + SLE_CONDVAR(Station,num_specs, SLE_UINT8, 27, SL_MAX_VERSION), // reserve extra space in savegame here. (currently 32 bytes) SLE_CONDNULL(32, 2, SL_MAX_VERSION), @@ -2927,10 +2944,17 @@ static const SaveLoad _goods_desc[] = { SLE_END() }; +static const SaveLoad _station_speclist_desc[] = { + SLE_CONDVAR(StationSpecList, grfid, SLE_UINT32, 27, SL_MAX_VERSION), + SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8, 27, SL_MAX_VERSION), + + SLE_END() +}; + static void SaveLoad_STNS(Station *st) { - int i; + uint i; SlObject(st, _station_desc); for (i = 0; i != NUM_CARGO; i++) { @@ -2941,6 +2965,12 @@ static void SaveLoad_STNS(Station *st) st->goods[i].enroute_from = INVALID_STATION; } } + + if (st->num_specs != 0) { + /* Allocate speclist memory when loading a game */ + if (st->speclist == NULL) st->speclist = calloc(st->num_specs, sizeof(*st->speclist)); + for (i = 0; i < st->num_specs; i++) SlObject(&st->speclist[i], _station_speclist_desc); + } } static void Save_STNS(void)