diff options
author | Patric Stout <truebrain@openttd.org> | 2021-06-06 16:03:56 +0200 |
---|---|---|
committer | Patric Stout <github@truebrain.nl> | 2021-06-14 21:58:05 +0200 |
commit | 4e4720f2178c9e0faf7233e55bec71e6ae19f9ad (patch) | |
tree | af474483110fca7fd7c617e052d1d381991e1179 /src/saveload | |
parent | 4600d289b5d12389137d36e57bfda09c26ed6caf (diff) | |
download | openttd-4e4720f2178c9e0faf7233e55bec71e6ae19f9ad.tar.xz |
Codechange: remove the special station/vehicle code from SaveLoad
With the new SLEG_STRUCT it is much easier to embed a struct
in a struct, where the sub-struct has limitations on when it is
being used.
This makes both the code easier to read (less magic) and avoids
the SaveLoad needing to know all these things about Stations
and Vehicles.
Diffstat (limited to 'src/saveload')
-rw-r--r-- | src/saveload/saveload.cpp | 21 | ||||
-rw-r--r-- | src/saveload/saveload.h | 21 | ||||
-rw-r--r-- | src/saveload/saveload_internal.h | 1 | ||||
-rw-r--r-- | src/saveload/station_sl.cpp | 176 | ||||
-rw-r--r-- | src/saveload/vehicle_sl.cpp | 420 |
5 files changed, 380 insertions, 259 deletions
diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 6be86a7ac..cb28fb6d2 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -1447,9 +1447,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld) default: NOT_REACHED(); } break; - case SL_WRITEBYTE: return 1; // a byte is logically of size 1 - case SL_VEH_INCLUDE: return SlCalcObjLength(object, GetVehicleDescription(VEH_END)); - case SL_ST_INCLUDE: return SlCalcObjLength(object, GetBaseStationDescription()); + case SL_SAVEBYTE: return 1; // a byte is logically of size 1 case SL_STRUCT: case SL_STRUCTLIST: { if (!SlIsObjectValidInSavegame(sld)) break; @@ -1555,10 +1553,10 @@ static bool SlObjectMember(void *object, const SaveLoad &sld) break; } - /* SL_WRITEBYTE writes a value to the savegame to identify the type of an object. + /* SL_SAVEBYTE writes a value to the savegame to identify the type of an object. * When loading, the value is read explicitly with SlReadByte() to determine which * object description to use. */ - case SL_WRITEBYTE: { + case SL_SAVEBYTE: { void *ptr = GetVariableAddress(object, sld); switch (_sl.action) { @@ -1572,19 +1570,6 @@ static bool SlObjectMember(void *object, const SaveLoad &sld) break; } - /* SL_VEH_INCLUDE loads common code for vehicles */ - case SL_VEH_INCLUDE: { - void *ptr = GetVariableAddress(object, sld); - SlObject(ptr, GetVehicleDescription(VEH_END)); - break; - } - - case SL_ST_INCLUDE: { - void *ptr = GetVariableAddress(object, sld); - SlObject(ptr, GetBaseStationDescription()); - break; - } - case SL_STRUCT: case SL_STRUCTLIST: if (!SlIsObjectValidInSavegame(sld)) return false; diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index ff0982569..7b0127709 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -570,10 +570,7 @@ enum SaveLoadType : byte { SL_STDSTR = 6, ///< Save/load a \c std::string. SL_STRUCT = 7, ///< Save/load a struct. SL_STRUCTLIST = 8, ///< Save/load a list of structs. - /* non-normal save-load types */ - SL_WRITEBYTE = 9, - SL_VEH_INCLUDE = 10, - SL_ST_INCLUDE = 11, + SL_SAVEBYTE = 9, ///< Save (but not load) a byte. }; typedef void *SaveLoadAddrProc(void *base, size_t extra); @@ -740,11 +737,17 @@ struct SaveLoad { */ #define SLE_CONDNULL(length, from, to) {SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL, length, from, to, 0, nullptr, 0, nullptr} -/** Translate values ingame to different values in the savegame and vv. */ -#define SLE_WRITEBYTE(base, variable) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, SL_MIN_VERSION, SL_MAX_VERSION, 0) - -#define SLE_VEH_INCLUDE() {SL_VEH_INCLUDE, 0, 0, SL_MIN_VERSION, SL_MAX_VERSION, 0, [] (void *b, size_t) { return b; }, 0, nullptr} -#define SLE_ST_INCLUDE() {SL_ST_INCLUDE, 0, 0, SL_MIN_VERSION, SL_MAX_VERSION, 0, [] (void *b, size_t) { return b; }, 0, nullptr} +/** + * Only write byte during saving; never read it during loading. + * When using SLE_SAVEBYTE you will have to read this byte before the table + * this is in is read. This also means SLE_SAVEBYTE can only be used at the + * top of a chunk. + * This is intended to be used to indicate what type of entry this is in a + * list of entries. + * @param base Name of the class or struct containing the variable. + * @param variable Name of the variable in the class or struct referenced by \a base. + */ +#define SLE_SAVEBYTE(base, variable) SLE_GENERAL(SL_SAVEBYTE, base, variable, 0, 0, SL_MIN_VERSION, SL_MAX_VERSION, 0) /** * Storage of global simple variables, references (pointers), and arrays. diff --git a/src/saveload/saveload_internal.h b/src/saveload/saveload_internal.h index 920be0417..a7fc54d7d 100644 --- a/src/saveload/saveload_internal.h +++ b/src/saveload/saveload_internal.h @@ -23,7 +23,6 @@ void ResetOldNames(); void ResetOldWaypoints(); void MoveBuoysToWaypoints(); void MoveWaypointsToBaseStations(); -SaveLoadTable GetBaseStationDescription(); void AfterLoadVehicles(bool part_of_load); void FixupTrainLengths(); diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 92fa2bafd..9c07834e4 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -374,89 +374,125 @@ static void Ptrs_STNS() } } +static OldPersistentStorage _old_st_persistent_storage; -static const SaveLoad _base_station_desc[] = { - SLE_VAR(BaseStation, xy, SLE_UINT32), - SLE_REF(BaseStation, town, REF_TOWN), - SLE_VAR(BaseStation, string_id, SLE_STRINGID), - SLE_SSTR(BaseStation, name, SLE_STR | SLF_ALLOW_CONTROL), - SLE_VAR(BaseStation, delete_ctr, SLE_UINT8), - SLE_VAR(BaseStation, owner, SLE_UINT8), - SLE_VAR(BaseStation, facilities, SLE_UINT8), - SLE_VAR(BaseStation, build_date, SLE_INT32), +/** + * SaveLoad handler for the BaseStation, which all other stations / waypoints + * make use of. + */ +class SlStationBase : public DefaultSaveLoadHandler<SlStationBase, BaseStation> { +public: + inline static const SaveLoad description[] = { + SLE_VAR(BaseStation, xy, SLE_UINT32), + SLE_REF(BaseStation, town, REF_TOWN), + SLE_VAR(BaseStation, string_id, SLE_STRINGID), + SLE_SSTR(BaseStation, name, SLE_STR | SLF_ALLOW_CONTROL), + SLE_VAR(BaseStation, delete_ctr, SLE_UINT8), + SLE_VAR(BaseStation, owner, SLE_UINT8), + SLE_VAR(BaseStation, facilities, SLE_UINT8), + SLE_VAR(BaseStation, build_date, SLE_INT32), + + /* Used by newstations for graphic variations */ + SLE_VAR(BaseStation, random_bits, SLE_UINT16), + SLE_VAR(BaseStation, waiting_triggers, SLE_UINT8), + SLE_VAR(BaseStation, num_specs, SLE_UINT8), + }; - /* Used by newstations for graphic variations */ - SLE_VAR(BaseStation, random_bits, SLE_UINT16), - SLE_VAR(BaseStation, waiting_triggers, SLE_UINT8), - SLE_VAR(BaseStation, num_specs, SLE_UINT8), + void GenericSaveLoad(BaseStation *bst) const + { + SlObject(bst, this->GetDescription()); + } + + void Save(BaseStation *bst) const override { this->GenericSaveLoad(bst); } + void Load(BaseStation *bst) const override { this->GenericSaveLoad(bst); } + void FixPointers(BaseStation *bst) const override { this->GenericSaveLoad(bst); } }; -static OldPersistentStorage _old_st_persistent_storage; +/** + * SaveLoad handler for a normal station (read: not a waypoint). + */ +class SlStationNormal : public DefaultSaveLoadHandler<SlStationNormal, BaseStation> { +public: + inline static const SaveLoad description[] = { + SLEG_STRUCT(SlStationBase), + SLE_VAR(Station, train_station.tile, SLE_UINT32), + SLE_VAR(Station, train_station.w, SLE_FILE_U8 | SLE_VAR_U16), + SLE_VAR(Station, train_station.h, SLE_FILE_U8 | SLE_VAR_U16), + + SLE_REF(Station, bus_stops, REF_ROADSTOPS), + SLE_REF(Station, truck_stops, REF_ROADSTOPS), + SLE_CONDNULL(4, SL_MIN_VERSION, SLV_MULTITILE_DOCKS), + SLE_CONDVAR(Station, ship_station.tile, SLE_UINT32, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), + SLE_CONDVAR(Station, ship_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), + SLE_CONDVAR(Station, ship_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), + SLE_CONDVAR(Station, docking_station.tile, SLE_UINT32, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), + SLE_CONDVAR(Station, docking_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), + SLE_CONDVAR(Station, docking_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), + SLE_VAR(Station, airport.tile, SLE_UINT32), + SLE_CONDVAR(Station, airport.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_140, SL_MAX_VERSION), + SLE_CONDVAR(Station, airport.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_140, SL_MAX_VERSION), + SLE_VAR(Station, airport.type, SLE_UINT8), + SLE_CONDVAR(Station, airport.layout, SLE_UINT8, SLV_145, SL_MAX_VERSION), + SLE_VAR(Station, airport.flags, SLE_UINT64), + SLE_CONDVAR(Station, airport.rotation, SLE_UINT8, SLV_145, SL_MAX_VERSION), + SLEG_CONDARR(_old_st_persistent_storage.storage, SLE_UINT32, 16, SLV_145, SLV_161), + SLE_CONDREF(Station, airport.psa, REF_STORAGE, SLV_161, SL_MAX_VERSION), + + SLE_VAR(Station, indtype, SLE_UINT8), + + SLE_VAR(Station, time_since_load, SLE_UINT8), + SLE_VAR(Station, time_since_unload, SLE_UINT8), + SLE_VAR(Station, last_vehicle_type, SLE_UINT8), + SLE_VAR(Station, had_vehicle_of_type, SLE_UINT8), + SLE_REFLIST(Station, loading_vehicles, REF_VEHICLE), + SLE_CONDVAR(Station, always_accepted, SLE_FILE_U32 | SLE_VAR_U64, SLV_127, SLV_EXTEND_CARGOTYPES), + SLE_CONDVAR(Station, always_accepted, SLE_UINT64, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION), + }; -static const SaveLoad _station_desc[] = { - SLE_WRITEBYTE(Station, facilities), - SLE_ST_INCLUDE(), - - SLE_VAR(Station, train_station.tile, SLE_UINT32), - SLE_VAR(Station, train_station.w, SLE_FILE_U8 | SLE_VAR_U16), - SLE_VAR(Station, train_station.h, SLE_FILE_U8 | SLE_VAR_U16), - - SLE_REF(Station, bus_stops, REF_ROADSTOPS), - SLE_REF(Station, truck_stops, REF_ROADSTOPS), - SLE_CONDNULL(4, SL_MIN_VERSION, SLV_MULTITILE_DOCKS), - SLE_CONDVAR(Station, ship_station.tile, SLE_UINT32, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), - SLE_CONDVAR(Station, ship_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), - SLE_CONDVAR(Station, ship_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), - SLE_CONDVAR(Station, docking_station.tile, SLE_UINT32, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), - SLE_CONDVAR(Station, docking_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), - SLE_CONDVAR(Station, docking_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), - SLE_VAR(Station, airport.tile, SLE_UINT32), - SLE_CONDVAR(Station, airport.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_140, SL_MAX_VERSION), - SLE_CONDVAR(Station, airport.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_140, SL_MAX_VERSION), - SLE_VAR(Station, airport.type, SLE_UINT8), - SLE_CONDVAR(Station, airport.layout, SLE_UINT8, SLV_145, SL_MAX_VERSION), - SLE_VAR(Station, airport.flags, SLE_UINT64), - SLE_CONDVAR(Station, airport.rotation, SLE_UINT8, SLV_145, SL_MAX_VERSION), - SLEG_CONDARR(_old_st_persistent_storage.storage, SLE_UINT32, 16, SLV_145, SLV_161), - SLE_CONDREF(Station, airport.psa, REF_STORAGE, SLV_161, SL_MAX_VERSION), - - SLE_VAR(Station, indtype, SLE_UINT8), - - SLE_VAR(Station, time_since_load, SLE_UINT8), - SLE_VAR(Station, time_since_unload, SLE_UINT8), - SLE_VAR(Station, last_vehicle_type, SLE_UINT8), - SLE_VAR(Station, had_vehicle_of_type, SLE_UINT8), - SLE_REFLIST(Station, loading_vehicles, REF_VEHICLE), - SLE_CONDVAR(Station, always_accepted, SLE_FILE_U32 | SLE_VAR_U64, SLV_127, SLV_EXTEND_CARGOTYPES), - SLE_CONDVAR(Station, always_accepted, SLE_UINT64, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION), + void GenericSaveLoad(BaseStation *bst) const + { + if ((bst->facilities & FACIL_WAYPOINT) != 0) return; + SlObject(bst, this->GetDescription()); + } + + void Save(BaseStation *bst) const override { this->GenericSaveLoad(bst); } + void Load(BaseStation *bst) const override { this->GenericSaveLoad(bst); } + void FixPointers(BaseStation *bst) const override { this->GenericSaveLoad(bst); } }; -static const SaveLoad _waypoint_desc[] = { - SLE_WRITEBYTE(Waypoint, facilities), - SLE_ST_INCLUDE(), +class SlStationWaypoint : public DefaultSaveLoadHandler<SlStationWaypoint, BaseStation> { +public: + inline static const SaveLoad description[] = { + SLEG_STRUCT(SlStationBase), + SLE_VAR(Waypoint, town_cn, SLE_UINT16), + + SLE_CONDVAR(Waypoint, train_station.tile, SLE_UINT32, SLV_124, SL_MAX_VERSION), + SLE_CONDVAR(Waypoint, train_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_124, SL_MAX_VERSION), + SLE_CONDVAR(Waypoint, train_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_124, SL_MAX_VERSION), + }; - SLE_VAR(Waypoint, town_cn, SLE_UINT16), + void GenericSaveLoad(BaseStation *bst) const + { + if ((bst->facilities & FACIL_WAYPOINT) == 0) return; + SlObject(bst, this->GetDescription()); + } - SLE_CONDVAR(Waypoint, train_station.tile, SLE_UINT32, SLV_124, SL_MAX_VERSION), - SLE_CONDVAR(Waypoint, train_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_124, SL_MAX_VERSION), - SLE_CONDVAR(Waypoint, train_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_124, SL_MAX_VERSION), + void Save(BaseStation *bst) const override { this->GenericSaveLoad(bst); } + void Load(BaseStation *bst) const override { this->GenericSaveLoad(bst); } + void FixPointers(BaseStation *bst) const override { this->GenericSaveLoad(bst); } }; -/** - * Get the base station description to be used for SL_ST_INCLUDE - * @return the base station description. - */ -SaveLoadTable GetBaseStationDescription() -{ - return _base_station_desc; -} +static const SaveLoad _station_desc[] = { + SLE_SAVEBYTE(BaseStation, facilities), + SLEG_STRUCT(SlStationNormal), + SLEG_STRUCT(SlStationWaypoint), +}; static void RealSave_STNN(BaseStation *bst) { - bool waypoint = (bst->facilities & FACIL_WAYPOINT) != 0; - SlObject(bst, waypoint ? SaveLoadTable(_waypoint_desc) : SaveLoadTable(_station_desc)); + SlObject(bst, _station_desc); - if (!waypoint) { + if ((bst->facilities & FACIL_WAYPOINT) == 0) { Station *st = Station::From(bst); for (CargoID i = 0; i < NUM_CARGO; i++) { _num_dests = (uint32)st->goods[i].cargo.Packets()->MapSize(); @@ -509,7 +545,7 @@ static void Load_STNN() bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0; BaseStation *bst = waypoint ? (BaseStation *)new (index) Waypoint() : new (index) Station(); - SlObject(bst, waypoint ? SaveLoadTable(_waypoint_desc) : SaveLoadTable(_station_desc)); + SlObject(bst, _station_desc); if (!waypoint) { Station *st = Station::From(bst); @@ -583,7 +619,7 @@ static void Ptrs_STNN() } for (Waypoint *wp : Waypoint::Iterate()) { - SlObject(wp, _waypoint_desc); + SlObject(wp, _station_desc); } } diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 260973050..ffa020677 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -573,150 +573,169 @@ static uint16 _cargo_paid_for; static Money _cargo_feeder_share; static uint32 _cargo_loaded_at_xy; -/** - * Make it possible to make the saveload tables "friends" of other classes. - * @param vt the vehicle type. Can be VEH_END for the common vehicle description data - * @return the saveload description - */ -SaveLoadTable GetVehicleDescription(VehicleType vt) -{ - /** Save and load of vehicles */ - static const SaveLoad _common_veh_desc[] = { - SLE_VAR(Vehicle, subtype, SLE_UINT8), - - SLE_REF(Vehicle, next, REF_VEHICLE_OLD), - SLE_CONDVAR(Vehicle, name, SLE_NAME, SL_MIN_VERSION, SLV_84), +class SlVehicleCommon : public DefaultSaveLoadHandler<SlVehicleCommon, Vehicle> { +public: +#if defined(_MSC_VER) && (_MSC_VER == 1915 || _MSC_VER == 1916) + /* This table access private members of other classes; they have this + * class as friend. For MSVC CL 19.15 and 19.16 this doesn't work for + * "inline static const", so we are forced to wrap the table in a + * function. CL 19.16 is the latest for VS2017. */ + inline static const SaveLoad description[] = {{}}; + SaveLoadTable GetDescription() const override { +#else + inline +#endif + static const SaveLoad description[] = { + SLE_VAR(Vehicle, subtype, SLE_UINT8), + + SLE_REF(Vehicle, next, REF_VEHICLE_OLD), + SLE_CONDVAR(Vehicle, name, SLE_NAME, SL_MIN_VERSION, SLV_84), SLE_CONDSSTR(Vehicle, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, unitnumber, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_8), - SLE_CONDVAR(Vehicle, unitnumber, SLE_UINT16, SLV_8, SL_MAX_VERSION), - SLE_VAR(Vehicle, owner, SLE_UINT8), - SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), - SLE_CONDVAR(Vehicle, tile, SLE_UINT32, SLV_6, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), - SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, SLV_6, SL_MAX_VERSION), - - SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), - SLE_CONDVAR(Vehicle, x_pos, SLE_UINT32, SLV_6, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), - SLE_CONDVAR(Vehicle, y_pos, SLE_UINT32, SLV_6, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, z_pos, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_164), - SLE_CONDVAR(Vehicle, z_pos, SLE_INT32, SLV_164, SL_MAX_VERSION), - SLE_VAR(Vehicle, direction, SLE_UINT8), + SLE_CONDVAR(Vehicle, unitnumber, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_8), + SLE_CONDVAR(Vehicle, unitnumber, SLE_UINT16, SLV_8, SL_MAX_VERSION), + SLE_VAR(Vehicle, owner, SLE_UINT8), + SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), + SLE_CONDVAR(Vehicle, tile, SLE_UINT32, SLV_6, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), + SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, SLV_6, SL_MAX_VERSION), + + SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), + SLE_CONDVAR(Vehicle, x_pos, SLE_UINT32, SLV_6, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), + SLE_CONDVAR(Vehicle, y_pos, SLE_UINT32, SLV_6, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, z_pos, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_164), + SLE_CONDVAR(Vehicle, z_pos, SLE_INT32, SLV_164, SL_MAX_VERSION), + SLE_VAR(Vehicle, direction, SLE_UINT8), SLE_CONDNULL(2, SL_MIN_VERSION, SLV_58), - SLE_VAR(Vehicle, spritenum, SLE_UINT8), + SLE_VAR(Vehicle, spritenum, SLE_UINT8), SLE_CONDNULL(5, SL_MIN_VERSION, SLV_58), - SLE_VAR(Vehicle, engine_type, SLE_UINT16), + SLE_VAR(Vehicle, engine_type, SLE_UINT16), SLE_CONDNULL(2, SL_MIN_VERSION, SLV_152), - SLE_VAR(Vehicle, cur_speed, SLE_UINT16), - SLE_VAR(Vehicle, subspeed, SLE_UINT8), - SLE_VAR(Vehicle, acceleration, SLE_UINT8), - SLE_CONDVAR(Vehicle, motion_counter, SLE_UINT32, SLV_VEH_MOTION_COUNTER, SL_MAX_VERSION), - SLE_VAR(Vehicle, progress, SLE_UINT8), - - SLE_VAR(Vehicle, vehstatus, SLE_UINT8), - SLE_CONDVAR(Vehicle, last_station_visited, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5), - SLE_CONDVAR(Vehicle, last_station_visited, SLE_UINT16, SLV_5, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, last_loading_station, SLE_UINT16, SLV_182, SL_MAX_VERSION), - - SLE_VAR(Vehicle, cargo_type, SLE_UINT8), - SLE_CONDVAR(Vehicle, cargo_subtype, SLE_UINT8, SLV_35, SL_MAX_VERSION), + SLE_VAR(Vehicle, cur_speed, SLE_UINT16), + SLE_VAR(Vehicle, subspeed, SLE_UINT8), + SLE_VAR(Vehicle, acceleration, SLE_UINT8), + SLE_CONDVAR(Vehicle, motion_counter, SLE_UINT32, SLV_VEH_MOTION_COUNTER, SL_MAX_VERSION), + SLE_VAR(Vehicle, progress, SLE_UINT8), + + SLE_VAR(Vehicle, vehstatus, SLE_UINT8), + SLE_CONDVAR(Vehicle, last_station_visited, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5), + SLE_CONDVAR(Vehicle, last_station_visited, SLE_UINT16, SLV_5, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, last_loading_station, SLE_UINT16, SLV_182, SL_MAX_VERSION), + + SLE_VAR(Vehicle, cargo_type, SLE_UINT8), + SLE_CONDVAR(Vehicle, cargo_subtype, SLE_UINT8, SLV_35, SL_MAX_VERSION), SLEG_CONDVAR( _cargo_days, SLE_UINT8, SL_MIN_VERSION, SLV_68), SLEG_CONDVAR( _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_7), SLEG_CONDVAR( _cargo_source, SLE_UINT16, SLV_7, SLV_68), SLEG_CONDVAR( _cargo_source_xy, SLE_UINT32, SLV_44, SLV_68), - SLE_VAR(Vehicle, cargo_cap, SLE_UINT16), - SLE_CONDVAR(Vehicle, refit_cap, SLE_UINT16, SLV_182, SL_MAX_VERSION), + SLE_VAR(Vehicle, cargo_cap, SLE_UINT16), + SLE_CONDVAR(Vehicle, refit_cap, SLE_UINT16, SLV_182, SL_MAX_VERSION), SLEG_CONDVAR( _cargo_count, SLE_UINT16, SL_MIN_VERSION, SLV_68), SLE_CONDREFLIST(Vehicle, cargo.packets, REF_CARGO_PACKET, SLV_68, SL_MAX_VERSION), - SLE_CONDARR(Vehicle, cargo.action_counts, SLE_UINT, VehicleCargoList::NUM_MOVE_TO_ACTION, SLV_181, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, cargo_age_counter, SLE_UINT16, SLV_162, SL_MAX_VERSION), + SLE_CONDARR(Vehicle, cargo.action_counts, SLE_UINT, VehicleCargoList::NUM_MOVE_TO_ACTION, SLV_181, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, cargo_age_counter, SLE_UINT16, SLV_162, SL_MAX_VERSION), - SLE_VAR(Vehicle, day_counter, SLE_UINT8), - SLE_VAR(Vehicle, tick_counter, SLE_UINT8), - SLE_CONDVAR(Vehicle, running_ticks, SLE_UINT8, SLV_88, SL_MAX_VERSION), + SLE_VAR(Vehicle, day_counter, SLE_UINT8), + SLE_VAR(Vehicle, tick_counter, SLE_UINT8), + SLE_CONDVAR(Vehicle, running_ticks, SLE_UINT8, SLV_88, SL_MAX_VERSION), - SLE_VAR(Vehicle, cur_implicit_order_index, SLE_UINT8), - SLE_CONDVAR(Vehicle, cur_real_order_index, SLE_UINT8, SLV_158, SL_MAX_VERSION), + SLE_VAR(Vehicle, cur_implicit_order_index, SLE_UINT8), + SLE_CONDVAR(Vehicle, cur_real_order_index, SLE_UINT8, SLV_158, SL_MAX_VERSION), /* num_orders is now part of OrderList and is not saved but counted */ SLE_CONDNULL(1, SL_MIN_VERSION, SLV_105), /* This next line is for version 4 and prior compatibility.. it temporarily reads - type and flags (which were both 4 bits) into type. Later on this is - converted correctly */ - SLE_CONDVAR(Vehicle, current_order.type, SLE_UINT8, SL_MIN_VERSION, SLV_5), - SLE_CONDVAR(Vehicle, current_order.dest, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5), + type and flags (which were both 4 bits) into type. Later on this is + converted correctly */ + SLE_CONDVAR(Vehicle, current_order.type, SLE_UINT8, SL_MIN_VERSION, SLV_5), + SLE_CONDVAR(Vehicle, current_order.dest, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5), /* Orders for version 5 and on */ - SLE_CONDVAR(Vehicle, current_order.type, SLE_UINT8, SLV_5, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, current_order.flags, SLE_UINT8, SLV_5, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, current_order.dest, SLE_UINT16, SLV_5, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, current_order.type, SLE_UINT8, SLV_5, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, current_order.flags, SLE_UINT8, SLV_5, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, current_order.dest, SLE_UINT16, SLV_5, SL_MAX_VERSION), /* Refit in current order */ - SLE_CONDVAR(Vehicle, current_order.refit_cargo, SLE_UINT8, SLV_36, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, current_order.refit_cargo, SLE_UINT8, SLV_36, SL_MAX_VERSION), SLE_CONDNULL(1, SLV_36, SLV_182), // refit_subtype /* Timetable in current order */ - SLE_CONDVAR(Vehicle, current_order.wait_time, SLE_UINT16, SLV_67, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, current_order.travel_time, SLE_UINT16, SLV_67, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, current_order.max_speed, SLE_UINT16, SLV_174, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, timetable_start, SLE_INT32, SLV_129, SL_MAX_VERSION), - - SLE_CONDREF(Vehicle, orders, REF_ORDER, SL_MIN_VERSION, SLV_105), - SLE_CONDREF(Vehicle, orders, REF_ORDERLIST, SLV_105, SL_MAX_VERSION), - - SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), - SLE_CONDVAR(Vehicle, age, SLE_INT32, SLV_31, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, max_age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), - SLE_CONDVAR(Vehicle, max_age, SLE_INT32, SLV_31, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, date_of_last_service, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), - SLE_CONDVAR(Vehicle, date_of_last_service, SLE_INT32, SLV_31, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, service_interval, SLE_UINT16, SL_MIN_VERSION, SLV_31), - SLE_CONDVAR(Vehicle, service_interval, SLE_FILE_U32 | SLE_VAR_U16, SLV_31, SLV_180), - SLE_CONDVAR(Vehicle, service_interval, SLE_UINT16, SLV_180, SL_MAX_VERSION), - SLE_VAR(Vehicle, reliability, SLE_UINT16), - SLE_VAR(Vehicle, reliability_spd_dec, SLE_UINT16), - SLE_VAR(Vehicle, breakdown_ctr, SLE_UINT8), - SLE_VAR(Vehicle, breakdown_delay, SLE_UINT8), - SLE_VAR(Vehicle, breakdowns_since_last_service, SLE_UINT8), - SLE_VAR(Vehicle, breakdown_chance, SLE_UINT8), - SLE_CONDVAR(Vehicle, build_year, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), - SLE_CONDVAR(Vehicle, build_year, SLE_INT32, SLV_31, SL_MAX_VERSION), - - SLE_VAR(Vehicle, load_unload_ticks, SLE_UINT16), + SLE_CONDVAR(Vehicle, current_order.wait_time, SLE_UINT16, SLV_67, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, current_order.travel_time, SLE_UINT16, SLV_67, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, current_order.max_speed, SLE_UINT16, SLV_174, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, timetable_start, SLE_INT32, SLV_129, SL_MAX_VERSION), + + SLE_CONDREF(Vehicle, orders, REF_ORDER, SL_MIN_VERSION, SLV_105), + SLE_CONDREF(Vehicle, orders, REF_ORDERLIST, SLV_105, SL_MAX_VERSION), + + SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), + SLE_CONDVAR(Vehicle, age, SLE_INT32, SLV_31, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, max_age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), + SLE_CONDVAR(Vehicle, max_age, SLE_INT32, SLV_31, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, date_of_last_service, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), + SLE_CONDVAR(Vehicle, date_of_last_service, SLE_INT32, SLV_31, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, service_interval, SLE_UINT16, SL_MIN_VERSION, SLV_31), + SLE_CONDVAR(Vehicle, service_interval, SLE_FILE_U32 | SLE_VAR_U16, SLV_31, SLV_180), + SLE_CONDVAR(Vehicle, service_interval, SLE_UINT16, SLV_180, SL_MAX_VERSION), + SLE_VAR(Vehicle, reliability, SLE_UINT16), + SLE_VAR(Vehicle, reliability_spd_dec, SLE_UINT16), + SLE_VAR(Vehicle, breakdown_ctr, SLE_UINT8), + SLE_VAR(Vehicle, breakdown_delay, SLE_UINT8), + SLE_VAR(Vehicle, breakdowns_since_last_service, SLE_UINT8), + SLE_VAR(Vehicle, breakdown_chance, SLE_UINT8), + SLE_CONDVAR(Vehicle, build_year, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), + SLE_CONDVAR(Vehicle, build_year, SLE_INT32, SLV_31, SL_MAX_VERSION), + + SLE_VAR(Vehicle, load_unload_ticks, SLE_UINT16), SLEG_CONDVAR( _cargo_paid_for, SLE_UINT16, SLV_45, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, vehicle_flags, SLE_FILE_U8 | SLE_VAR_U16, SLV_40, SLV_180), - SLE_CONDVAR(Vehicle, vehicle_flags, SLE_UINT16, SLV_180, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, vehicle_flags, SLE_FILE_U8 | SLE_VAR_U16, SLV_40, SLV_180), + SLE_CONDVAR(Vehicle, vehicle_flags, SLE_UINT16, SLV_180, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, profit_this_year, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_65), - SLE_CONDVAR(Vehicle, profit_this_year, SLE_INT64, SLV_65, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, profit_last_year, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_65), - SLE_CONDVAR(Vehicle, profit_last_year, SLE_INT64, SLV_65, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, profit_this_year, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_65), + SLE_CONDVAR(Vehicle, profit_this_year, SLE_INT64, SLV_65, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, profit_last_year, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_65), + SLE_CONDVAR(Vehicle, profit_last_year, SLE_INT64, SLV_65, SL_MAX_VERSION), SLEG_CONDVAR( _cargo_feeder_share, SLE_FILE_I32 | SLE_VAR_I64, SLV_51, SLV_65), SLEG_CONDVAR( _cargo_feeder_share, SLE_INT64, SLV_65, SLV_68), SLEG_CONDVAR( _cargo_loaded_at_xy, SLE_UINT32, SLV_51, SLV_68), - SLE_CONDVAR(Vehicle, value, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_65), - SLE_CONDVAR(Vehicle, value, SLE_INT64, SLV_65, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, value, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_65), + SLE_CONDVAR(Vehicle, value, SLE_INT64, SLV_65, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, random_bits, SLE_UINT8, SLV_2, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, waiting_triggers, SLE_UINT8, SLV_2, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, random_bits, SLE_UINT8, SLV_2, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, waiting_triggers, SLE_UINT8, SLV_2, SL_MAX_VERSION), - SLE_CONDREF(Vehicle, next_shared, REF_VEHICLE, SLV_2, SL_MAX_VERSION), + SLE_CONDREF(Vehicle, next_shared, REF_VEHICLE, SLV_2, SL_MAX_VERSION), SLE_CONDNULL(2, SLV_2, SLV_69), SLE_CONDNULL(4, SLV_69, SLV_101), - SLE_CONDVAR(Vehicle, group_id, SLE_UINT16, SLV_60, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, group_id, SLE_UINT16, SLV_60, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, current_order_time, SLE_UINT32, SLV_67, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, lateness_counter, SLE_INT32, SLV_67, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, current_order_time, SLE_UINT32, SLV_67, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, lateness_counter, SLE_INT32, SLV_67, SL_MAX_VERSION), SLE_CONDNULL(10, SLV_2, SLV_144), // old reserved space }; +#if defined(_MSC_VER) && (_MSC_VER == 1915 || _MSC_VER == 1916) + return description; + } +#endif + + void GenericSaveLoad(Vehicle *v) const + { + SlObject(v, this->GetDescription()); + } - static const SaveLoad _train_desc[] = { - SLE_WRITEBYTE(Vehicle, type), - SLE_VEH_INCLUDE(), + void Save(Vehicle *v) const override { this->GenericSaveLoad(v); } + void Load(Vehicle *v) const override { this->GenericSaveLoad(v); } + void FixPointers(Vehicle *v) const override { this->GenericSaveLoad(v); } +}; + +class SlVehicleTrain : public DefaultSaveLoadHandler<SlVehicleTrain, Vehicle> { +public: + inline static const SaveLoad description[] = { + SLEG_STRUCT(SlVehicleCommon), SLE_VAR(Train, crash_anim_pos, SLE_UINT16), SLE_VAR(Train, force_proceed, SLE_UINT8), SLE_VAR(Train, railtype, SLE_UINT8), @@ -733,9 +752,21 @@ SaveLoadTable GetVehicleDescription(VehicleType vt) SLE_CONDNULL(11, SLV_2, SLV_144), // old reserved space }; - static const SaveLoad _roadveh_desc[] = { - SLE_WRITEBYTE(Vehicle, type), - SLE_VEH_INCLUDE(), + void GenericSaveLoad(Vehicle *v) const + { + if (v->type != VEH_TRAIN) return; + SlObject(v, this->GetDescription()); + } + + void Save(Vehicle *v) const override { this->GenericSaveLoad(v); } + void Load(Vehicle *v) const override { this->GenericSaveLoad(v); } + void FixPointers(Vehicle *v) const override { this->GenericSaveLoad(v); } +}; + +class SlVehicleRoadVeh : public DefaultSaveLoadHandler<SlVehicleRoadVeh, Vehicle> { +public: + inline static const SaveLoad description[] = { + SLEG_STRUCT(SlVehicleCommon), SLE_VAR(RoadVehicle, state, SLE_UINT8), SLE_VAR(RoadVehicle, frame, SLE_UINT8), SLE_VAR(RoadVehicle, blocked_ctr, SLE_UINT16), @@ -753,9 +784,21 @@ SaveLoadTable GetVehicleDescription(VehicleType vt) SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space }; - static const SaveLoad _ship_desc[] = { - SLE_WRITEBYTE(Vehicle, type), - SLE_VEH_INCLUDE(), + void GenericSaveLoad(Vehicle *v) const + { + if (v->type != VEH_ROAD) return; + SlObject(v, this->GetDescription()); + } + + void Save(Vehicle *v) const override { this->GenericSaveLoad(v); } + void Load(Vehicle *v) const override { this->GenericSaveLoad(v); } + void FixPointers(Vehicle *v) const override { this->GenericSaveLoad(v); } +}; + +class SlVehicleShip : public DefaultSaveLoadHandler<SlVehicleShip, Vehicle> { +public: + inline static const SaveLoad description[] = { + SLEG_STRUCT(SlVehicleCommon), SLE_VAR(Ship, state, SLE_UINT8), SLE_CONDDEQUE(Ship, path, SLE_UINT8, SLV_SHIP_PATH_CACHE, SL_MAX_VERSION), SLE_CONDVAR(Ship, rotation, SLE_UINT8, SLV_SHIP_ROTATION, SL_MAX_VERSION), @@ -763,9 +806,21 @@ SaveLoadTable GetVehicleDescription(VehicleType vt) SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space }; - static const SaveLoad _aircraft_desc[] = { - SLE_WRITEBYTE(Vehicle, type), - SLE_VEH_INCLUDE(), + void GenericSaveLoad(Vehicle *v) const + { + if (v->type != VEH_SHIP) return; + SlObject(v, this->GetDescription()); + } + + void Save(Vehicle *v) const override { this->GenericSaveLoad(v); } + void Load(Vehicle *v) const override { this->GenericSaveLoad(v); } + void FixPointers(Vehicle *v) const override { this->GenericSaveLoad(v); } +}; + +class SlVehicleAircraft : public DefaultSaveLoadHandler<SlVehicleAircraft, Vehicle> { +public: + inline static const SaveLoad description[] = { + SLEG_STRUCT(SlVehicleCommon), SLE_VAR(Aircraft, crashed_counter, SLE_UINT16), SLE_VAR(Aircraft, pos, SLE_UINT8), @@ -784,9 +839,20 @@ SaveLoadTable GetVehicleDescription(VehicleType vt) SLE_CONDNULL(13, SLV_2, SLV_144), // old reserved space }; - static const SaveLoad _special_desc[] = { - SLE_WRITEBYTE(Vehicle, type), + void GenericSaveLoad(Vehicle *v) const + { + if (v->type != VEH_AIRCRAFT) return; + SlObject(v, this->GetDescription()); + } + void Save(Vehicle *v) const override { this->GenericSaveLoad(v); } + void Load(Vehicle *v) const override { this->GenericSaveLoad(v); } + void FixPointers(Vehicle *v) const override { this->GenericSaveLoad(v); } +}; + +class SlVehicleEffect : public DefaultSaveLoadHandler<SlVehicleEffect, Vehicle> { +public: + inline static const SaveLoad description[] = { SLE_VAR(Vehicle, subtype, SLE_UINT8), SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), @@ -812,58 +878,90 @@ SaveLoadTable GetVehicleDescription(VehicleType vt) SLE_CONDNULL(15, SLV_2, SLV_144), // old reserved space }; - static const SaveLoad _disaster_desc[] = { - SLE_WRITEBYTE(Vehicle, type), - - SLE_REF(Vehicle, next, REF_VEHICLE_OLD), + void GenericSaveLoad(Vehicle *v) const + { + if (v->type != VEH_EFFECT) return; + SlObject(v, this->GetDescription()); + } - SLE_VAR(Vehicle, subtype, SLE_UINT8), - SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), - SLE_CONDVAR(Vehicle, tile, SLE_UINT32, SLV_6, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), - SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, SLV_6, SL_MAX_VERSION), + void Save(Vehicle *v) const override { this->GenericSaveLoad(v); } + void Load(Vehicle *v) const override { this->GenericSaveLoad(v); } + void FixPointers(Vehicle *v) const override { this->GenericSaveLoad(v); } +}; - SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6), - SLE_CONDVAR(Vehicle, x_pos, SLE_INT32, SLV_6, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6), - SLE_CONDVAR(Vehicle, y_pos, SLE_INT32, SLV_6, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, z_pos, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_164), - SLE_CONDVAR(Vehicle, z_pos, SLE_INT32, SLV_164, SL_MAX_VERSION), - SLE_VAR(Vehicle, direction, SLE_UINT8), +class SlVehicleDisaster : public DefaultSaveLoadHandler<SlVehicleDisaster, Vehicle> { +public: +#if defined(_MSC_VER) && (_MSC_VER == 1915 || _MSC_VER == 1916) + /* This table access private members of other classes; they have this + * class as friend. For MSVC CL 19.15 and 19.16 this doesn't work for + * "inline static const", so we are forced to wrap the table in a + * function. CL 19.16 is the latest for VS2017. */ + inline static const SaveLoad description[] = {{}}; + SaveLoadTable GetDescription() const override { +#else + inline +#endif + static const SaveLoad description[] = { + SLE_REF(Vehicle, next, REF_VEHICLE_OLD), + + SLE_VAR(Vehicle, subtype, SLE_UINT8), + SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), + SLE_CONDVAR(Vehicle, tile, SLE_UINT32, SLV_6, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), + SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, SLV_6, SL_MAX_VERSION), + + SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6), + SLE_CONDVAR(Vehicle, x_pos, SLE_INT32, SLV_6, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6), + SLE_CONDVAR(Vehicle, y_pos, SLE_INT32, SLV_6, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, z_pos, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_164), + SLE_CONDVAR(Vehicle, z_pos, SLE_INT32, SLV_164, SL_MAX_VERSION), + SLE_VAR(Vehicle, direction, SLE_UINT8), SLE_CONDNULL(5, SL_MIN_VERSION, SLV_58), - SLE_VAR(Vehicle, owner, SLE_UINT8), - SLE_VAR(Vehicle, vehstatus, SLE_UINT8), - SLE_CONDVAR(Vehicle, current_order.dest, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5), - SLE_CONDVAR(Vehicle, current_order.dest, SLE_UINT16, SLV_5, SL_MAX_VERSION), - - SLE_VAR(Vehicle, sprite_cache.sprite_seq.seq[0].sprite, SLE_FILE_U16 | SLE_VAR_U32), - SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), - SLE_CONDVAR(Vehicle, age, SLE_INT32, SLV_31, SL_MAX_VERSION), - SLE_VAR(Vehicle, tick_counter, SLE_UINT8), - - SLE_CONDVAR(DisasterVehicle, image_override, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_191), - SLE_CONDVAR(DisasterVehicle, image_override, SLE_UINT32, SLV_191, SL_MAX_VERSION), - SLE_CONDVAR(DisasterVehicle, big_ufo_destroyer_target, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_191), - SLE_CONDVAR(DisasterVehicle, big_ufo_destroyer_target, SLE_UINT32, SLV_191, SL_MAX_VERSION), - SLE_CONDVAR(DisasterVehicle, flags, SLE_UINT8, SLV_194, SL_MAX_VERSION), + SLE_VAR(Vehicle, owner, SLE_UINT8), + SLE_VAR(Vehicle, vehstatus, SLE_UINT8), + SLE_CONDVAR(Vehicle, current_order.dest, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5), + SLE_CONDVAR(Vehicle, current_order.dest, SLE_UINT16, SLV_5, SL_MAX_VERSION), + + SLE_VAR(Vehicle, sprite_cache.sprite_seq.seq[0].sprite, SLE_FILE_U16 | SLE_VAR_U32), + SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), + SLE_CONDVAR(Vehicle, age, SLE_INT32, SLV_31, SL_MAX_VERSION), + SLE_VAR(Vehicle, tick_counter, SLE_UINT8), + + SLE_CONDVAR(DisasterVehicle, image_override, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_191), + SLE_CONDVAR(DisasterVehicle, image_override, SLE_UINT32, SLV_191, SL_MAX_VERSION), + SLE_CONDVAR(DisasterVehicle, big_ufo_destroyer_target, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_191), + SLE_CONDVAR(DisasterVehicle, big_ufo_destroyer_target, SLE_UINT32, SLV_191, SL_MAX_VERSION), + SLE_CONDVAR(DisasterVehicle, flags, SLE_UINT8, SLV_194, SL_MAX_VERSION), SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space }; +#if defined(_MSC_VER) && (_MSC_VER == 1915 || _MSC_VER == 1916) + return description; + } +#endif + void GenericSaveLoad(Vehicle *v) const + { + if (v->type != VEH_DISASTER) return; + SlObject(v, this->GetDescription()); + } - static const SaveLoadTable _veh_descs[] = { - _train_desc, - _roadveh_desc, - _ship_desc, - _aircraft_desc, - _special_desc, - _disaster_desc, - _common_veh_desc, - }; + void Save(Vehicle *v) const override { this->GenericSaveLoad(v); } + void Load(Vehicle *v) const override { this->GenericSaveLoad(v); } + void FixPointers(Vehicle *v) const override { this->GenericSaveLoad(v); } +}; - return _veh_descs[vt]; -} +const static SaveLoad _vehicle_desc[] = { + SLE_SAVEBYTE(Vehicle, type), + SLEG_STRUCT(SlVehicleTrain), + SLEG_STRUCT(SlVehicleRoadVeh), + SLEG_STRUCT(SlVehicleShip), + SLEG_STRUCT(SlVehicleAircraft), + SLEG_STRUCT(SlVehicleEffect), + SLEG_STRUCT(SlVehicleDisaster), +}; /** Will be called when the vehicles need to be saved. */ static void Save_VEHS() @@ -871,7 +969,7 @@ static void Save_VEHS() /* Write the vehicles */ for (Vehicle *v : Vehicle::Iterate()) { SlSetArrayIndex(v->index); - SlObject(v, GetVehicleDescription(v->type)); + SlObject(v, _vehicle_desc); } } @@ -897,7 +995,7 @@ void Load_VEHS() default: SlErrorCorrupt("Invalid vehicle type"); } - SlObject(v, GetVehicleDescription(vtype)); + SlObject(v, _vehicle_desc); if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v) && CargoPacket::CanAllocateItem()) { /* Don't construct the packet with station here, because that'll fail with old savegames */ @@ -924,10 +1022,10 @@ void Load_VEHS() } } -static void Ptrs_VEHS() +void Ptrs_VEHS() { for (Vehicle *v : Vehicle::Iterate()) { - SlObject(v, GetVehicleDescription(v->type)); + SlObject(v, _vehicle_desc); } } |