OpenTTD Source  20241120-master-g6d3adc6169
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"
14 
15 #include "../vehicle_base.h"
16 #include "../station_base.h"
17 
18 #include "../safeguards.h"
19 
23 /* static */ void CargoPacket::AfterLoad()
24 {
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;
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;
51  }
52  }
53  }
54  }
55 
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 
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 
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. */
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 
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 
140  CAPAChunkHandler() : ChunkHandler('CAPA', CH_TABLE) {}
141 
142  void Save() const override
143  {
145 
146  for (CargoPacket *cp : CargoPacket::Iterate()) {
147  SlSetArrayIndex(cp->index);
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);
SaveLoadTable GetCargoPacketDesc()
Wrapper function to get the CargoPacket's internal structure while some of the variables itself are p...
Loading for cargopacket chunks before table headers were added.
const SaveLoadCompat _cargopacket_sl_compat[]
Original field order for _cargopacket_desc.
Tcont::const_iterator ConstIterator
The const iterator for our container.
Definition: cargopacket.h:290
const Tcont * Packets() const
Returns a pointer to the cargo packet list (so you can iterate over it etc).
Definition: cargopacket.h:329
void InvalidateCache()
Invalidates the cached data and rebuilds it.
Hand-rolled multimap as map of lists.
Definition: multimap.hpp:281
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:425
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:415
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition: saveload.cpp:658
std::vector< SaveLoad > SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
Load a table header in a savegame compatible way.
Definition: saveload.cpp:1893
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
Definition: saveload.cpp:1755
void SlObject(void *object, const SaveLoadTable &slt)
Main SaveLoad function.
Definition: saveload.cpp:1702
Functions/types related to saving and loading games.
#define SLE_VARNAME(base, variable, name, type)
Storage of a variable in every version of a savegame.
Definition: saveload.h:996
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition: saveload.h:507
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition: saveload.h:510
#define SLE_CONDVAR(base, variable, type, from, to)
Storage of a variable in some savegame versions.
Definition: saveload.h:863
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
Definition: saveload.h:1239
@ SLV_44
44 8144
Definition: saveload.h:95
@ SLV_181
181 25012
Definition: saveload.h:260
@ SLV_120
120 16439
Definition: saveload.h:187
@ SLV_125
125 17113
Definition: saveload.h:193
@ SL_MAX_VERSION
Highest possible saveload version.
Definition: saveload.h:397
@ SL_MIN_VERSION
First savegame version.
Definition: saveload.h:31
@ SLV_CARGO_TRAVELLED
319 PR#11283 CargoPacket now tracks how far it travelled inside a vehicle.
Definition: saveload.h:362
@ SLV_68
68 10266
Definition: saveload.h:124
@ SLV_PERIODS_IN_TRANSIT_RENAME
316 PR#11112 Rename days in transit to (cargo) periods in transit.
Definition: saveload.h:359
@ SLV_MORE_CARGO_AGE
307 PR#10596 Track cargo age for a longer period.
Definition: saveload.h:348
@ SLV_REMOVE_LOADED_AT_XY
318 PR#11276 Remove loaded_at_xy variable from CargoPacket.
Definition: saveload.h:361
std::span< const struct SaveLoad > SaveLoadTable
A table of SaveLoad entries.
Definition: saveload.h:513
#define SLE_VAR(base, variable, type)
Storage of a variable in every version of a savegame.
Definition: saveload.h:987
#define SLE_CONDVARNAME(base, variable, name, type, from, to)
Storage of a variable in some savegame versions.
Definition: saveload.h:874
TileIndex xy
Base tile of the station.
void Load() const override
Load the chunk.
void Save() const override
Save the chunk.
Container for cargo from the same location and time.
Definition: cargopacket.h:40
TileIndex source_xy
The origin of the cargo.
Definition: cargopacket.h:53
static void AfterLoad()
Savegame conversion for cargopackets.
StationID first_station
The station where the cargo came from first.
Definition: cargopacket.h:63
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
Handlers and description of chunk.
Definition: saveload.h:461
Stores station stats for a single cargo.
Definition: station_base.h:166
StationCargoList cargo
The cargo packets of cargo waiting in this station.
Definition: station_base.h:210
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:388
SaveLoad type struct.
Definition: saveload.h:713
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
static Station * Get(size_t index)
Gets station with given index.
static bool IsValidID(size_t index)
Tests whether given index is a valid index for station of this type.
Station data structure.
Definition: station_base.h:439
Vehicle data structure.
Definition: vehicle_base.h:244
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:95