OpenTTD Source: src/saveload/cargopacket_sl.cpp Source File

OpenTTD Source 14.1

cargopacket_sl.cpp
Go to the documentation of this file.
1 /*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10 #include "../stdafx.h"
11
12 #include "saveload.h"
13 #include "compat/cargopacket_sl_compat.h"
14
15 #include "../vehicle_base.h"
16 #include "../station_base.h"
17
18 #include "../safeguards.h"
19
23 /* static */ void CargoPacket::AfterLoad()
24 {
25 if (IsSavegameVersionBefore(SLV_44)) {
26 /* If we remove a station while cargo from it is still en route, payment calculation will assume
27 * 0, 0 to be the source of the cargo, resulting in very high payments usually. v->source_xy
28 * stores the coordinates, preserving them even if the station is removed. However, if a game is loaded
29 * where this situation exists, the cargo-source information is lost. in this case, we set the source
30 * to the current tile of the vehicle to prevent excessive profits
31 */
32 for (const Vehicle *v : Vehicle::Iterate()) {
33 const CargoPacketList *packets = v->cargo.Packets();
34 for (VehicleCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) {
35 CargoPacket *cp = *it;
36 cp->source_xy = Station::IsValidID(cp->first_station) ? Station::Get(cp->first_station)->xy : v->tile;
37 }
38 }
39
40 /* Store position of the station where the goods come from, so there
41 * are no very high payments when stations get removed. However, if the
42 * station where the goods came from is already removed, the source
43 * information is lost. In that case we set it to the position of this
44 * station */
45 for (Station *st : Station::Iterate()) {
46 for (GoodsEntry &ge : st->goods) {
47 const StationCargoPacketMap *packets = ge.cargo.Packets();
48 for (StationCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) {
49 CargoPacket *cp = *it;
50 cp->source_xy = Station::IsValidID(cp->first_station) ? Station::Get(cp->first_station)->xy : st->xy;
51 }
52 }
53 }
54 }
55
56 if (IsSavegameVersionBefore(SLV_120)) {
57 /* CargoPacket's source should be either INVALID_STATION or a valid station */
58 for (CargoPacket *cp : CargoPacket::Iterate()) {
59 if (!Station::IsValidID(cp->first_station)) cp->first_station = INVALID_STATION;
60 }
61 }
62
63 if (!IsSavegameVersionBefore(SLV_68)) {
64 /* Only since version 68 we have cargo packets. Savegames from before used
65 * 'new CargoPacket' + cargolist.Append so their caches are already
66 * correct and do not need rebuilding. */
67 for (Vehicle *v : Vehicle::Iterate()) v->cargo.InvalidateCache();
68
69 for (Station *st : Station::Iterate()) {
70 for (GoodsEntry &ge : st->goods) ge.cargo.InvalidateCache();
71 }
72 }
73
74 if (IsSavegameVersionBefore(SLV_181)) {
75 for (Vehicle *v : Vehicle::Iterate()) v->cargo.KeepAll();
76 }
77
78 /* Before this version, we didn't track how far cargo actually traveled in vehicles. Make best-effort estimates of this. */
79 if (IsSavegameVersionBefore(SLV_CARGO_TRAVELLED)) {
80 /* Update the cargo-traveled in stations as if they arrived from the source tile. */
81 for (Station *st : Station::Iterate()) {
82 for (GoodsEntry &ge : st->goods) {
83 for (auto it = ge.cargo.Packets()->begin(); it != ge.cargo.Packets()->end(); ++it) {
84 for (CargoPacket *cp : it->second) {
85 if (cp->source_xy != INVALID_TILE && cp->source_xy != st->xy) {
86 cp->travelled.x = TileX(cp->source_xy) - TileX(st->xy);
87 cp->travelled.y = TileY(cp->source_xy) - TileY(st->xy);
88 }
89 }
90 }
91 }
92 }
93
94 /* Update the cargo-traveled in vehicles as if they were loaded at the source tile. */
95 for (Vehicle *v : Vehicle::Iterate()) {
96 for (auto it = v->cargo.Packets()->begin(); it != v->cargo.Packets()->end(); it++) {
97 if ((*it)->source_xy != INVALID_TILE) {
98 (*it)->UpdateLoadingTile((*it)->source_xy);
99 }
100 }
101 }
102 }
103
104 #ifdef WITH_ASSERT
105 /* in_vehicle is a NOSAVE; it tells if cargo is in a vehicle or not. Restore the value in here. */
106 for (Vehicle *v : Vehicle::Iterate()) {
107 for (auto it = v->cargo.Packets()->begin(); it != v->cargo.Packets()->end(); it++) {
108 (*it)->in_vehicle = true;
109 }
110 }
111 #endif /* WITH_ASSERT */
112 }
113
119 SaveLoadTable GetCargoPacketDesc()
120 {
121 static const SaveLoad _cargopacket_desc[] = {
122 SLE_VARNAME(CargoPacket, first_station, "source", SLE_UINT16),
123 SLE_VAR(CargoPacket, source_xy, SLE_UINT32),
124 SLE_CONDVARNAME(CargoPacket, next_hop, "loaded_at_xy", SLE_FILE_U32 | SLE_VAR_U16, SL_MIN_VERSION, SLV_REMOVE_LOADED_AT_XY),
125 SLE_CONDVARNAME(CargoPacket, next_hop, "loaded_at_xy", SLE_UINT16, SLV_REMOVE_LOADED_AT_XY, SL_MAX_VERSION),
126 SLE_VAR(CargoPacket, count, SLE_UINT16),
127 SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_MORE_CARGO_AGE),
128 SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_UINT16, SLV_MORE_CARGO_AGE, SLV_PERIODS_IN_TRANSIT_RENAME),
129 SLE_CONDVAR(CargoPacket, periods_in_transit, SLE_UINT16, SLV_PERIODS_IN_TRANSIT_RENAME, SL_MAX_VERSION),
130 SLE_VAR(CargoPacket, feeder_share, SLE_INT64),
131 SLE_CONDVAR(CargoPacket, source_type, SLE_UINT8, SLV_125, SL_MAX_VERSION),
132 SLE_CONDVAR(CargoPacket, source_id, SLE_UINT16, SLV_125, SL_MAX_VERSION),
133 SLE_CONDVAR(CargoPacket, travelled.x, SLE_INT16, SLV_CARGO_TRAVELLED, SL_MAX_VERSION),
134 SLE_CONDVAR(CargoPacket, travelled.y, SLE_INT16, SLV_CARGO_TRAVELLED, SL_MAX_VERSION),
135 };
136 return _cargopacket_desc;
137 }
138
139 struct CAPAChunkHandler : ChunkHandler {
140 CAPAChunkHandler() : ChunkHandler('CAPA', CH_TABLE) {}
141
142 void Save() const override
143 {
144 SlTableHeader(GetCargoPacketDesc());
145
146 for (CargoPacket *cp : CargoPacket::Iterate()) {
147 SlSetArrayIndex(cp->index);
148 SlObject(cp, GetCargoPacketDesc());
149 }
150 }
151
152 void Load() const override
153 {
154 const std::vector<SaveLoad> slt = SlCompatTableHeader(GetCargoPacketDesc(), _cargopacket_sl_compat);
155
156 int index;
157
158 while ((index = SlIterateArray()) != -1) {
159 CargoPacket *cp = new (index) CargoPacket();
160 SlObject(cp, slt);
161 }
162 }
163 };
164
165 static const CAPAChunkHandler CAPA;
166 static const ChunkHandlerRef cargopacket_chunk_handlers[] = {
167 CAPA,
168 };
169
170 extern const ChunkHandlerTable _cargopacket_chunk_handlers(cargopacket_chunk_handlers);
TileY
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:437
CargoList< VehicleCargoList, CargoPacketList >::ConstIterator
CargoPacketList ::const_iterator ConstIterator
The const iterator for our container.
Definition: cargopacket.h:290
CAPAChunkHandler
Definition: cargopacket_sl.cpp:139
SaveLoadTable
std::span< const struct SaveLoad > SaveLoadTable
A table of SaveLoad entries.
Definition: saveload.h:497
CargoPacket::travelled
Vector travelled
If cargo is in station: the vector from the unload tile to the source tile. If in vehicle: an interme...
Definition: cargopacket.h:54
SLV_REMOVE_LOADED_AT_XY
@ SLV_REMOVE_LOADED_AT_XY
318 PR#11276 Remove loaded_at_xy variable from CargoPacket.
Definition: saveload.h:361
CargoList::Packets
const Tcont * Packets() const
Returns a pointer to the cargo packet list (so you can iterate over it etc).
Definition: cargopacket.h:329
Station
Station data structure.
Definition: station_base.h:442
ChunkHandlerRef
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition: saveload.h:491
SLE_CONDVARNAME
#define SLE_CONDVARNAME(base, variable, name, type, from, to)
Storage of a variable in some savegame versions.
Definition: saveload.h:859
SL_MIN_VERSION
@ SL_MIN_VERSION
First savegame version.
Definition: saveload.h:31
SLE_CONDVAR
#define SLE_CONDVAR(base, variable, type, from, to)
Storage of a variable in some savegame versions.
Definition: saveload.h:848
INVALID_TILE
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:95
saveload.h
SpecializedStation< Station, false >::Get
static Station * Get(size_t index)
Gets station with given index.
Definition: base_station_base.h:259
SpecializedStation< Station, false >::IsValidID
static bool IsValidID(size_t index)
Tests whether given index is a valid index for station of this type.
Definition: base_station_base.h:250
ChunkHandler
Handlers and description of chunk.
Definition: saveload.h:445
Vehicle
Vehicle data structure.
Definition: vehicle_base.h:240
SpecializedStation< Station, false >::Iterate
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
Definition: base_station_base.h:310
CargoPacket::first_station
StationID first_station
The station where the cargo came from first.
Definition: cargopacket.h:63
GoodsEntry::cargo
StationCargoList cargo
The cargo packets of cargo waiting in this station.
Definition: station_base.h:210
cargopacket_sl_compat.h
SLV_125
@ SLV_125
125 17113
Definition: saveload.h:193
CargoPacket::source_xy
TileIndex source_xy
The origin of the cargo.
Definition: cargopacket.h:53
IsSavegameVersionBefore
bool IsSavegameVersionBefore(SaveLoadVersion major, byte minor=0)
Checks whether the savegame is below major.
Definition: saveload.h:1215
GetCargoPacketDesc
SaveLoadTable GetCargoPacketDesc()
Wrapper function to get the CargoPacket's internal structure while some of the variables itself are p...
Definition: cargopacket_sl.cpp:119
CargoList::InvalidateCache
void InvalidateCache()
Invalidates the cached data and rebuilds it.
Definition: cargopacket.cpp:210
SLV_PERIODS_IN_TRANSIT_RENAME
@ SLV_PERIODS_IN_TRANSIT_RENAME
316 PR#11112 Rename days in transit to (cargo) periods in transit.
Definition: saveload.h:359
SL_MAX_VERSION
@ SL_MAX_VERSION
Highest possible saveload version.
Definition: saveload.h:382
CAPAChunkHandler::Save
void Save() const override
Save the chunk.
Definition: cargopacket_sl.cpp:142
CargoPacket::AfterLoad
static void AfterLoad()
Savegame conversion for cargopackets.
Definition: cargopacket_sl.cpp:23
SLV_181
@ SLV_181
181 25012
Definition: saveload.h:260
SLV_120
@ SLV_120
120 16439
Definition: saveload.h:187
GoodsEntry
Stores station stats for a single cargo.
Definition: station_base.h:166
SLE_VAR
#define SLE_VAR(base, variable, type)
Storage of a variable in every version of a savegame.
Definition: saveload.h:952
Pool::PoolItem<&_vehicle_pool >::Iterate
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:388
CAPAChunkHandler::Load
void Load() const override
Load the chunk.
Definition: cargopacket_sl.cpp:152
SLV_CARGO_TRAVELLED
@ SLV_CARGO_TRAVELLED
319 PR#11283 CargoPacket now tracks how far it travelled inside a vehicle.
Definition: saveload.h:362
ChunkHandlerTable
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition: saveload.h:494
BaseStation::xy
TileIndex xy
Base tile of the station.
Definition: base_station_base.h:65
CargoPacket
Container for cargo from the same location and time.
Definition: cargopacket.h:40
SlCompatTableHeader
std::vector< SaveLoad > SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
Load a table header in a savegame compatible way.
Definition: saveload.cpp:1852
SLV_68
@ SLV_68
68 10266
Definition: saveload.h:124
TileX
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:427
SlObject
void SlObject(void *object, const SaveLoadTable &slt)
Main SaveLoad function.
Definition: saveload.cpp:1661
SLV_MORE_CARGO_AGE
@ SLV_MORE_CARGO_AGE
307 PR#10596 Track cargo age for a longer period.
Definition: saveload.h:348
SlTableHeader
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
Definition: saveload.cpp:1714
SaveLoad
SaveLoad type struct.
Definition: saveload.h:697
MultiMap
Hand-rolled multimap as map of lists.
Definition: multimap.hpp:14
SLE_VARNAME
#define SLE_VARNAME(base, variable, name, type)
Storage of a variable in every version of a savegame.
Definition: saveload.h:961
SLV_44
@ SLV_44
44 8144
Definition: saveload.h:95
SlIterateArray
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition: saveload.cpp:656
_cargopacket_sl_compat
const SaveLoadCompat _cargopacket_sl_compat[]
Original field order for _cargopacket_desc.
Definition: cargopacket_sl_compat.h:16