OpenTTD Source  20240919-master-gdf0233f4c2
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);
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:507
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:439
ChunkHandlerRef
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition: saveload.h:501
SLE_CONDVARNAME
#define SLE_CONDVARNAME(base, variable, name, type, from, to)
Storage of a variable in some savegame versions.
Definition: saveload.h:868
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:857
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:254
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:245
ChunkHandler
Handlers and description of chunk.
Definition: saveload.h:455
Vehicle
Vehicle data structure.
Definition: vehicle_base.h:244
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:305
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
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:391
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:971
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:504
BaseStation::xy
TileIndex xy
Base tile of the station.
Definition: base_station_base.h:60
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:1888
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:1697
IsSavegameVersionBefore
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
Definition: saveload.h:1234
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:1750
SaveLoad
SaveLoad type struct.
Definition: saveload.h:707
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:980
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:658
_cargopacket_sl_compat
const SaveLoadCompat _cargopacket_sl_compat[]
Original field order for _cargopacket_desc.
Definition: cargopacket_sl_compat.h:16