OpenTTD Source 20241224-master-gf74b0cf984
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),
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
165static const CAPAChunkHandler CAPA;
166static const ChunkHandlerRef cargopacket_chunk_handlers[] = {
167 CAPA,
168};
169
170extern 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.
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
std::vector< SaveLoad > SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
Load a table header in a savegame compatible way.
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition saveload.cpp:659
void SlObject(void *object, const SaveLoadTable &slt)
Main SaveLoad function.
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
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:1011
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition saveload.h:509
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition saveload.h:512
#define SLE_CONDVAR(base, variable, type, from, to)
Storage of a variable in some savegame versions.
Definition saveload.h:868
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
Definition saveload.h:1263
@ 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:399
@ 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:515
#define SLE_VAR(base, variable, type)
Storage of a variable in every version of a savegame.
Definition saveload.h:1002
#define SLE_CONDVARNAME(base, variable, name, type, from, to)
Storage of a variable in some savegame versions.
Definition saveload.h:879
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
Handlers and description of chunk.
Definition saveload.h:463
Stores station stats for a single cargo.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
SaveLoad type struct.
Definition saveload.h:717
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.
Vehicle data structure.
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95