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 | |
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')
-rw-r--r-- | src/cargopacket.h | 4 | ||||
-rw-r--r-- | src/order_base.h | 4 | ||||
-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 | ||||
-rw-r--r-- | src/vehicle_base.h | 6 |
8 files changed, 389 insertions, 264 deletions
diff --git a/src/cargopacket.h b/src/cargopacket.h index abb8d98c2..a5166e959 100644 --- a/src/cargopacket.h +++ b/src/cargopacket.h @@ -305,8 +305,8 @@ public: friend class StationCargoList; /** The super class ought to know what it's doing. */ friend class CargoList<VehicleCargoList, CargoPacketList>; - /** The vehicles have a cargo list (and we want that saved). */ - friend SaveLoadTable GetVehicleDescription(VehicleType vt); + /* So we can use private/protected variables in the saveload code */ + friend class SlVehicleCommon; friend class CargoShift; friend class CargoTransfer; diff --git a/src/order_base.h b/src/order_base.h index c510bd3e0..84f5289ec 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -32,9 +32,11 @@ extern OrderListPool _orderlist_pool; */ struct Order : OrderPool::PoolItem<&_order_pool> { private: - friend SaveLoadTable GetVehicleDescription(VehicleType vt); ///< Saving and loading the current order of vehicles. friend void Load_VEHS(); ///< Loading of ancient vehicles. friend SaveLoadTable GetOrderDescription(); ///< Saving and loading of orders. + /* So we can use private/protected variables in the saveload code */ + friend class SlVehicleCommon; + friend class SlVehicleDisaster; uint8 type; ///< The type of order + non-stop flags uint8 flags; ///< Load/unload types, depot order/action types. 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); } } diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 029ddcf66..a5549b444 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -200,7 +200,6 @@ extern VehiclePool _vehicle_pool; /* Some declarations of functions, so we can make them friendly */ struct GroundVehicleCache; -extern SaveLoadTable GetVehicleDescription(VehicleType vt); struct LoadgameState; extern bool LoadOldVehicle(LoadgameState *ls, int num); extern void FixOldVehicles(); @@ -232,10 +231,13 @@ private: Vehicle *previous_shared; ///< NOSAVE: pointer to the previous vehicle in the shared order chain public: - friend SaveLoadTable GetVehicleDescription(VehicleType vt); ///< So we can use private/protected variables in the saveload code friend void FixOldVehicles(); friend void AfterLoadVehicles(bool part_of_load); ///< So we can set the #previous and #first pointers while loading friend bool LoadOldVehicle(LoadgameState *ls, int num); ///< So we can set the proper next pointer while loading + /* So we can use private/protected variables in the saveload code */ + friend class SlVehicleCommon; + friend class SlVehicleDisaster; + friend void Ptrs_VEHS(); TileIndex tile; ///< Current tile index |