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

OpenTTD Source 15.0-RC2

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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
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 if (!ge.HasData()) continue;
48 const StationCargoPacketMap *packets = ge.GetData().cargo.Packets();
49 for (StationCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) {
50 CargoPacket *cp = *it;
51 cp->source_xy = Station::IsValidID(cp->first_station) ? Station::Get(cp->first_station)->xy : st->xy;
52 }
53 }
54 }
55 }
56
57 if (IsSavegameVersionBefore(SLV_120)) {
58 /* CargoPacket's source should be either StationID::Invalid() or a valid station */
59 for (CargoPacket *cp : CargoPacket::Iterate()) {
60 if (!Station::IsValidID(cp->first_station)) cp->first_station = StationID::Invalid();
61 }
62 }
63
64 if (!IsSavegameVersionBefore(SLV_68)) {
65 /* Only since version 68 we have cargo packets. Savegames from before used
66 * 'new CargoPacket' + cargolist.Append so their caches are already
67 * correct and do not need rebuilding. */
68 for (Vehicle *v : Vehicle::Iterate()) v->cargo.InvalidateCache();
69
70 for (Station *st : Station::Iterate()) {
71 for (GoodsEntry &ge : st->goods) {
72 if (!ge.HasData()) continue;
73 ge.GetData().cargo.InvalidateCache();
74 }
75 }
76 }
77
78 if (IsSavegameVersionBefore(SLV_181)) {
79 for (Vehicle *v : Vehicle::Iterate()) v->cargo.KeepAll();
80 }
81
82 /* Before this version, we didn't track how far cargo actually traveled in vehicles. Make best-effort estimates of this. */
83 if (IsSavegameVersionBefore(SLV_CARGO_TRAVELLED)) {
84 /* Update the cargo-traveled in stations as if they arrived from the source tile. */
85 for (Station *st : Station::Iterate()) {
86 for (GoodsEntry &ge : st->goods) {
87 if (!ge.HasData()) continue;
88 StationCargoList &cargo_list = ge.GetData().cargo;
89 for (auto it = cargo_list.Packets()->begin(); it != cargo_list.Packets()->end(); ++it) {
90 for (CargoPacket *cp : it->second) {
91 if (cp->source_xy != INVALID_TILE && cp->source_xy != st->xy) {
92 cp->travelled.x = TileX(cp->source_xy) - TileX(st->xy);
93 cp->travelled.y = TileY(cp->source_xy) - TileY(st->xy);
94 }
95 }
96 }
97 }
98 }
99
100 /* Update the cargo-traveled in vehicles as if they were loaded at the source tile. */
101 for (Vehicle *v : Vehicle::Iterate()) {
102 for (auto it = v->cargo.Packets()->begin(); it != v->cargo.Packets()->end(); it++) {
103 if ((*it)->source_xy != INVALID_TILE) {
104 (*it)->UpdateLoadingTile((*it)->source_xy);
105 }
106 }
107 }
108 }
109
110#ifdef WITH_ASSERT
111 /* in_vehicle is a NOSAVE; it tells if cargo is in a vehicle or not. Restore the value in here. */
112 for (Vehicle *v : Vehicle::Iterate()) {
113 for (auto it = v->cargo.Packets()->begin(); it != v->cargo.Packets()->end(); it++) {
114 (*it)->in_vehicle = true;
115 }
116 }
117#endif /* WITH_ASSERT */
118}
119
125 SaveLoadTable GetCargoPacketDesc()
126{
127 static const SaveLoad _cargopacket_desc[] = {
128 SLE_VARNAME(CargoPacket, first_station, "source", SLE_UINT16),
129 SLE_VAR(CargoPacket, source_xy, SLE_UINT32),
130 SLE_CONDVARNAME(CargoPacket, next_hop, "loaded_at_xy", SLE_FILE_U32 | SLE_VAR_U16, SL_MIN_VERSION, SLV_REMOVE_LOADED_AT_XY),
131 SLE_CONDVARNAME(CargoPacket, next_hop, "loaded_at_xy", SLE_UINT16, SLV_REMOVE_LOADED_AT_XY, SL_MAX_VERSION),
132 SLE_VAR(CargoPacket, count, SLE_UINT16),
133 SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_MORE_CARGO_AGE),
134 SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_UINT16, SLV_MORE_CARGO_AGE, SLV_PERIODS_IN_TRANSIT_RENAME),
135 SLE_CONDVAR(CargoPacket, periods_in_transit, SLE_UINT16, SLV_PERIODS_IN_TRANSIT_RENAME, SL_MAX_VERSION),
136 SLE_VAR(CargoPacket, feeder_share, SLE_INT64),
137 SLE_CONDVARNAME(CargoPacket, source.type, "source_type", SLE_UINT8, SLV_125, SL_MAX_VERSION),
138 SLE_CONDVARNAME(CargoPacket, source.id, "source_id", SLE_UINT16, SLV_125, SL_MAX_VERSION),
139 SLE_CONDVAR(CargoPacket, travelled.x, SLE_INT16, SLV_CARGO_TRAVELLED, SL_MAX_VERSION),
140 SLE_CONDVAR(CargoPacket, travelled.y, SLE_INT16, SLV_CARGO_TRAVELLED, SL_MAX_VERSION),
141 };
142 return _cargopacket_desc;
143}
144
145 struct CAPAChunkHandler : ChunkHandler {
146 CAPAChunkHandler() : ChunkHandler('CAPA', CH_TABLE) {}
147
148 void Save() const override
149 {
150 SlTableHeader(GetCargoPacketDesc());
151
152 for (CargoPacket *cp : CargoPacket::Iterate()) {
153 SlSetArrayIndex(cp->index);
154 SlObject(cp, GetCargoPacketDesc());
155 }
156 }
157
158 void Load() const override
159 {
160 const std::vector<SaveLoad> slt = SlCompatTableHeader(GetCargoPacketDesc(), _cargopacket_sl_compat);
161
162 int index;
163
164 while ((index = SlIterateArray()) != -1) {
165 CargoPacket *cp = new (CargoPacketID(index)) CargoPacket();
166 SlObject(cp, slt);
167 }
168 }
169};
170
171static const CAPAChunkHandler CAPA;
172static const ChunkHandlerRef cargopacket_chunk_handlers[] = {
173 CAPA,
174};
175
176extern const ChunkHandlerTable _cargopacket_chunk_handlers(cargopacket_chunk_handlers);
CargoPacketID
PoolID< uint32_t, struct CargoPacketIDTag, 0xFFF000, 0xFFFFFF > CargoPacketID
Unique identifier for a single cargo packet.
Definition cargopacket.h:24
GetCargoPacketDesc
SaveLoadTable GetCargoPacketDesc()
Wrapper function to get the CargoPacket's internal structure while some of the variables itself are p...
Definition cargopacket_sl.cpp:125
cargopacket_sl_compat.h
Loading for cargopacket chunks before table headers were added.
_cargopacket_sl_compat
const SaveLoadCompat _cargopacket_sl_compat[]
Original field order for _cargopacket_desc.
Definition cargopacket_sl_compat.h:16
CargoList::Packets
const Tcont * Packets() const
Returns a pointer to the cargo packet list (so you can iterate over it etc).
Definition cargopacket.h:320
CargoList< VehicleCargoList, CargoPacketList >::ConstIterator
Tcont::const_iterator ConstIterator
The const iterator for our container.
Definition cargopacket.h:281
MultiMap
Hand-rolled multimap as map of lists.
Definition multimap.hpp:225
StationCargoList
CargoList that is used for stations.
Definition cargopacket.h:519
TileY
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:437
TileX
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:427
SlCompatTableHeader
std::vector< SaveLoad > SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
Load a table header in a savegame compatible way.
Definition saveload.cpp:2037
SlIterateArray
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition saveload.cpp:677
SlObject
void SlObject(void *object, const SaveLoadTable &slt)
Main SaveLoad function.
Definition saveload.cpp:1846
SlTableHeader
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
Definition saveload.cpp:1899
saveload.h
Functions/types related to saving and loading games.
SLE_VARNAME
#define SLE_VARNAME(base, variable, name, type)
Storage of a variable in every version of a savegame.
Definition saveload.h:1026
ChunkHandlerRef
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition saveload.h:524
ChunkHandlerTable
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition saveload.h:527
SLE_CONDVAR
#define SLE_CONDVAR(base, variable, type, from, to)
Storage of a variable in some savegame versions.
Definition saveload.h:883
IsSavegameVersionBefore
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
Definition saveload.h:1278
SLV_44
@ SLV_44
44 8144
Definition saveload.h:95
SLV_181
@ SLV_181
181 25012
Definition saveload.h:260
SLV_120
@ SLV_120
120 16439
Definition saveload.h:187
SLV_125
@ SLV_125
125 17113
Definition saveload.h:193
SL_MAX_VERSION
@ SL_MAX_VERSION
Highest possible saveload version.
Definition saveload.h:416
SL_MIN_VERSION
@ SL_MIN_VERSION
First savegame version.
Definition saveload.h:31
SLV_CARGO_TRAVELLED
@ SLV_CARGO_TRAVELLED
319 PR#11283 CargoPacket now tracks how far it travelled inside a vehicle.
Definition saveload.h:362
SLV_68
@ SLV_68
68 10266
Definition saveload.h:124
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
SLV_MORE_CARGO_AGE
@ SLV_MORE_CARGO_AGE
307 PR#10596 Track cargo age for a longer period.
Definition saveload.h:348
SLV_REMOVE_LOADED_AT_XY
@ SLV_REMOVE_LOADED_AT_XY
318 PR#11276 Remove loaded_at_xy variable from CargoPacket.
Definition saveload.h:361
SaveLoadTable
std::span< const struct SaveLoad > SaveLoadTable
A table of SaveLoad entries.
Definition saveload.h:530
SLE_VAR
#define SLE_VAR(base, variable, type)
Storage of a variable in every version of a savegame.
Definition saveload.h:1017
SLE_CONDVARNAME
#define SLE_CONDVARNAME(base, variable, name, type, from, to)
Storage of a variable in some savegame versions.
Definition saveload.h:894
BaseStation::xy
TileIndex xy
Base tile of the station.
Definition base_station_base.h:59
CAPAChunkHandler
Definition cargopacket_sl.cpp:145
CAPAChunkHandler::Load
void Load() const override
Load the chunk.
Definition cargopacket_sl.cpp:158
CAPAChunkHandler::Save
void Save() const override
Save the chunk.
Definition cargopacket_sl.cpp:148
CargoPacket
Container for cargo from the same location and time.
Definition cargopacket.h:41
CargoPacket::source_xy
TileIndex source_xy
The origin of the cargo.
Definition cargopacket.h:54
CargoPacket::AfterLoad
static void AfterLoad()
Savegame conversion for cargopackets.
Definition cargopacket_sl.cpp:23
CargoPacket::first_station
StationID first_station
The station where the cargo came from first.
Definition cargopacket.h:63
ChunkHandler
Handlers and description of chunk.
Definition saveload.h:478
GoodsEntry
Stores station stats for a single cargo.
Definition station_base.h:167
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:436
SaveLoad
SaveLoad type struct.
Definition saveload.h:732
SpecializedStation< Station, false >::IsValidID
static bool IsValidID(auto index)
Tests whether given index is a valid index for station of this type.
Definition base_station_base.h:239
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:299
SpecializedStation< Station, false >::Get
static Station * Get(auto index)
Gets station with given index.
Definition base_station_base.h:248
Station
Station data structure.
Definition station_base.h:500
Vehicle
Vehicle data structure.
Definition vehicle_base.h:205
INVALID_TILE
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95