OpenTTD Source 20260917-master-gec444f7315
industry_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
9
10#include "../stdafx.h"
11
12#include "saveload.h"
14
15#include "../industry.h"
16#include "../town.h"
17#include "newgrf_sl.h"
18
19#include "../safeguards.h"
20
21static OldPersistentStorage _old_ind_persistent_storage;
22
23class SlIndustryAcceptedHistory : public DefaultSaveLoadHandler<SlIndustryAcceptedHistory, Industry::AcceptedCargo> {
24public:
25 static inline const SaveLoad description[] = {
28 };
29 static inline const SaveLoadCompatTable compat_description = _industry_produced_history_sl_compat;
30
31 void Save(Industry::AcceptedCargo *a) const override
32 {
33 if (!IsValidCargoType(a->cargo) || a->history == nullptr) {
34 /* Don't save any history if cargo slot isn't used. */
36 return;
37 }
38
40
41 for (auto &h : *a->history) {
42 SlObject(&h, this->GetDescription());
43 }
44 }
45
46 void Load(Industry::AcceptedCargo *a) const override
47 {
48 size_t len = SlGetStructListLength(UINT32_MAX);
49 if (len == 0) return;
50
51 auto &history = a->GetOrCreateHistory();
52 for (auto &h : history) {
53 if (--len > history.size()) break; // unsigned so wraps after hitting zero.
54 SlObject(&h, this->GetLoadDescription());
55 }
56 }
57};
58
59class SlIndustryAccepted : public VectorSaveLoadHandler<SlIndustryAccepted, Industry, Industry::AcceptedCargo, INDUSTRY_NUM_INPUTS> {
60public:
61 static inline const SaveLoad description[] = {
67 };
68 static inline const SaveLoadCompatTable compat_description = _industry_accepts_sl_compat;
69
70 std::vector<Industry::AcceptedCargo> &GetVector(Industry *i) const override { return i->accepted; }
71
74 static inline std::array<CargoType, INDUSTRY_NUM_INPUTS> old_cargo;
75 static inline std::array<uint16_t, INDUSTRY_NUM_INPUTS> old_waiting;
76 static inline std::array<TimerGameEconomy::Date, INDUSTRY_NUM_INPUTS> old_last_accepted;
78
79 static void ResetOldStructure()
80 {
81 SlIndustryAccepted::old_cargo.fill(INVALID_CARGO);
84 }
85};
86
87class SlIndustryProducedHistory : public DefaultSaveLoadHandler<SlIndustryProducedHistory, Industry::ProducedCargo> {
88public:
89 static inline const SaveLoad description[] = {
92 };
93 static inline const SaveLoadCompatTable compat_description = _industry_produced_history_sl_compat;
94
95 void Save(Industry::ProducedCargo *p) const override
96 {
97 if (!IsValidCargoType(p->cargo)) {
98 /* Don't save any history if cargo slot isn't used. */
100 return;
101 }
102
104
105 for (auto &h : p->history) {
106 SlObject(&h, this->GetDescription());
107 }
108 }
109
110 void Load(Industry::ProducedCargo *p) const override
111 {
112 size_t len = SlGetStructListLength(p->history.size());
113
114 for (auto &h : p->history) {
115 if (--len > p->history.size()) break; // unsigned so wraps after hitting zero.
116 SlObject(&h, this->GetLoadDescription());
117 }
118 }
119};
120
121class SlIndustryProduced : public VectorSaveLoadHandler<SlIndustryProduced, Industry, Industry::ProducedCargo, INDUSTRY_NUM_OUTPUTS> {
122public:
123 static inline const SaveLoad description[] = {
128 };
129 static inline const SaveLoadCompatTable compat_description = _industry_produced_sl_compat;
130
131 std::vector<Industry::ProducedCargo> &GetVector(Industry *i) const override { return i->produced; }
132
135 static inline std::array<CargoType, INDUSTRY_NUM_OUTPUTS> old_cargo;
136 static inline std::array<uint16_t, INDUSTRY_NUM_OUTPUTS> old_waiting;
137 static inline std::array<uint8_t, INDUSTRY_NUM_OUTPUTS> old_rate;
138 static inline std::array<uint16_t, INDUSTRY_NUM_OUTPUTS> old_this_month_production;
139 static inline std::array<uint16_t, INDUSTRY_NUM_OUTPUTS> old_this_month_transported;
140 static inline std::array<uint16_t, INDUSTRY_NUM_OUTPUTS> old_last_month_production;
141 static inline std::array<uint16_t, INDUSTRY_NUM_OUTPUTS> old_last_month_transported;
143
144 static void ResetOldStructure()
145 {
146 SlIndustryProduced::old_cargo.fill(INVALID_CARGO);
153 }
154};
155
156static const SaveLoad _industry_desc[] = {
182
184
187 SaveLoad::Variable<VarFileType::U8>("random_colour", SLE_OBJECT_ADDRESS(Industry, random_colour)),
190 SaveLoad::Variable<VarFileType::U8>("was_cargo_delivered", SLE_OBJECT_ADDRESS(Industry, was_cargo_delivered)),
192
201
204
207
209
212};
213
214struct INDYChunkHandler : ChunkHandler {
215 INDYChunkHandler() : ChunkHandler("INDY", ChunkType::Table) {}
216
217 void Save() const override
218 {
219 SlTableHeader(_industry_desc);
220
221 /* Write the industries */
222 for (Industry *ind : Industry::Iterate()) {
223 SlSetArrayIndex(ind->index);
224 SlObject(ind, _industry_desc);
225 }
226 }
227
228 void LoadMoveAcceptsProduced(Industry *i, uint inputs, uint outputs) const
229 {
230 i->accepted.reserve(inputs);
231 for (uint j = 0; j != inputs; ++j) {
232 auto &a = i->accepted.emplace_back();
234 a.waiting = SlIndustryAccepted::old_waiting[j];
235 a.last_accepted = SlIndustryAccepted::old_last_accepted[j];
236 }
237
238 i->produced.reserve(outputs);
239 for (uint j = 0; j != outputs; ++j) {
240 auto &p = i->produced.emplace_back();
242 p.waiting = SlIndustryProduced::old_waiting[j];
244 p.history[THIS_MONTH].production = SlIndustryProduced::old_this_month_production[j];
245 p.history[THIS_MONTH].transported = SlIndustryProduced::old_this_month_transported[j];
246 p.history[LAST_MONTH].production = SlIndustryProduced::old_last_month_production[j];
247 p.history[LAST_MONTH].transported = SlIndustryProduced::old_last_month_transported[j];
248 }
249 }
250
251 void Load() const override
252 {
253 const std::vector<SaveLoad> slt = SlCompatTableHeader(_industry_desc, _industry_sl_compat);
254
255 int index;
256
257 SlIndustryAccepted::ResetOldStructure();
258 SlIndustryProduced::ResetOldStructure();
259
260 while ((index = SlIterateArray()) != -1) {
261 Industry *i = Industry::CreateAtIndex(IndustryID(index));
262 SlObject(i, slt);
263
264 /* Before savegame version 161, persistent storages were not stored in a pool. */
266 /* Store the old persistent storage. The GRFID will be added later. */
269 std::copy(std::begin(_old_ind_persistent_storage.storage), std::end(_old_ind_persistent_storage.storage), std::begin(i->psa->storage));
270 }
274 LoadMoveAcceptsProduced(i, INDUSTRY_NUM_INPUTS, INDUSTRY_NUM_OUTPUTS);
275 }
276
278 /* The last month has always been recorded. */
279 size_t oldest_valid = LAST_MONTH;
281 /* History was extended but we did not keep track of valid history, so assume it from the oldest non-zero value. */
282 for (const auto &p : i->produced) {
283 if (!IsValidCargoType(p.cargo)) continue;
284 for (size_t n = LAST_MONTH; n < std::size(p.history); ++n) {
285 if (p.history[n].production == 0 && p.history[n].transported == 0) continue;
286 oldest_valid = std::max(oldest_valid, n);
287 }
288 }
289 }
290 /* Set mask bits up to and including the oldest valid record. */
291 i->valid_history = (std::numeric_limits<uint64_t>::max() >> (std::numeric_limits<uint64_t>::digits - (oldest_valid + 1 - LAST_MONTH))) << LAST_MONTH;
292 }
293
294 Industry::industries[i->type].insert(i->index);
295 }
296 }
297
298 void FixPointers() const override
299 {
300 for (Industry *i : Industry::Iterate()) {
301 SlObject(i, _industry_desc);
302 }
303 }
304};
305
306struct IIDSChunkHandler : NewGRFMappingChunkHandler {
307 IIDSChunkHandler() : NewGRFMappingChunkHandler("IIDS", _industry_mngr) {}
308};
309
310struct TIDSChunkHandler : NewGRFMappingChunkHandler {
311 TIDSChunkHandler() : NewGRFMappingChunkHandler("TIDS", _industile_mngr) {}
312};
313
318
320struct IBLDChunkHandler : ChunkHandler {
321 IBLDChunkHandler() : ChunkHandler("IBLD", ChunkType::Table) {}
322
323 void Save() const override
324 {
326
327 SlSetArrayIndex(0);
329 }
330
331 void Load() const override
332 {
334
336 SlGlobList(slt);
338 }
339};
340
349
351struct ITBLChunkHandler : ChunkHandler {
352 ITBLChunkHandler() : ChunkHandler("ITBL", ChunkType::Table) {}
353
354 void Save() const override
355 {
357
358 for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
359 SlSetArrayIndex(i);
361 }
362 }
363
364 void Load() const override
365 {
367
368 for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
369 _industry_builder.builddata[it].Reset();
370 }
371 int index;
372 while ((index = SlIterateArray()) != -1) {
373 if ((uint)index >= NUM_INDUSTRYTYPES) SlErrorCorrupt("Too many industry builder datas");
374 SlObject(_industry_builder.builddata + index, slt);
375 }
376 }
377};
378
379static const INDYChunkHandler INDY;
380static const IIDSChunkHandler IIDS;
381static const TIDSChunkHandler TIDS;
382static const IBLDChunkHandler IBLD;
383static const ITBLChunkHandler ITBL;
384static const ChunkHandlerRef industry_chunk_handlers[] = {
385 INDY,
386 IIDS,
387 TIDS,
388 IBLD,
389 ITBL,
390};
391
392extern const ChunkHandlerTable _industry_chunk_handlers(industry_chunk_handlers);
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:110
Default handler for saving/loading an object to/from disk.
Definition saveload.h:586
SaveLoadTable GetLoadDescription() const
Get the description for how to load the chunk.
void Load(Industry::AcceptedCargo *a) const override
Load the object from disk.
void Save(Industry::AcceptedCargo *a) const override
Save the object to disk.
static std::array< uint16_t, INDUSTRY_NUM_INPUTS > old_waiting
std::vector< Industry::AcceptedCargo > & GetVector(Industry *i) const override
Get instance of vector to load/save.
static std::array< CargoType, INDUSTRY_NUM_INPUTS > old_cargo
static std::array< TimerGameEconomy::Date, INDUSTRY_NUM_INPUTS > old_last_accepted
void Save(Industry::ProducedCargo *p) const override
Save the object to disk.
void Load(Industry::ProducedCargo *p) const override
Load the object from disk.
static std::array< uint16_t, INDUSTRY_NUM_OUTPUTS > old_last_month_production
static std::array< uint16_t, INDUSTRY_NUM_OUTPUTS > old_this_month_transported
std::vector< Industry::ProducedCargo > & GetVector(Industry *i) const override
Get instance of vector to load/save.
static std::array< CargoType, INDUSTRY_NUM_OUTPUTS > old_cargo
static std::array< uint16_t, INDUSTRY_NUM_OUTPUTS > old_last_month_transported
static std::array< uint16_t, INDUSTRY_NUM_OUTPUTS > old_waiting
static std::array< uint16_t, INDUSTRY_NUM_OUTPUTS > old_this_month_production
static std::array< uint8_t, INDUSTRY_NUM_OUTPUTS > old_rate
StrongType::Typedef< int32_t, DateTag< struct Economy >, StrongType::Compare, StrongType::Integer > Date
Default handler for saving/loading a vector to/from disk.
Definition saveload.h:1341
Base of all industries.
IndustryBuildData _industry_builder
In-game manager of industries.
static const SaveLoad _industrytype_builder_desc[]
Description of the data to save and load in IndustryTypeBuildData.
static const SaveLoad _industry_builder_desc[]
Description of the data to save and load in IndustryBuildData.
Loading of industry chunks before table headers were added.
const SaveLoadCompat _industry_sl_compat[]
Original field order for _industry_desc.
const SaveLoadCompat _industry_builder_sl_compat[]
Original field order for _industry_builder_desc.
const SaveLoadCompat _industrytype_builder_sl_compat[]
Original field order for _industrytype_builder_desc.
static const int INDUSTRY_ORIGINAL_NUM_INPUTS
Original number of accepted cargo types.
static const int INDUSTRY_NUM_OUTPUTS
Number of cargo types an industry can produce.
static const int INDUSTRY_NUM_INPUTS
Number of cargo types an industry can accept.
static const IndustryType NUM_INDUSTRYTYPES
total number of industry types, new and old; limited to 240 because we need some special ids like IT_...
static const int INDUSTRY_ORIGINAL_NUM_OUTPUTS
Original number of produced cargo types.
@ Invalid
An invalid spec feature.
Definition newgrf.h:110
Code handling saving and loading of NewGRF mappings.
Label< struct GrfIDTag > GrfID
The unique identifier of a NewGRF.
Definition newgrf_type.h:17
A number of safeguards to prevent using unsafe methods.
std::vector< SaveLoad > SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
Load a table header in a savegame compatible way.
size_t SlGetStructListLength(size_t limit)
Get the length of this list; if it exceeds the limit, error out.
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition saveload.cpp:745
void SlErrorCorrupt(const std::string &msg)
Error handler for corrupt savegames.
Definition saveload.cpp:369
void SlObject(void *object, const SaveLoadTable &slt)
Main SaveLoad function.
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
void SlGlobList(const SaveLoadTable &slt)
Save or Load (a list of) global variables.
void SlSetStructListLength(size_t length)
Set the length of this list.
Functions/types related to saving and loading games.
#define SLE_OBJECT_ADDRESS(base, variable)
Macro to be able to pass the variable type and construct the SaveLoad::AddressFunction given a base c...
Definition saveload.h:754
#define SLE_GLOBAL_ADDRESS(variable)
Macro to be able to pass the variable type and construct the SaveLoad::AddressFunction given a global...
Definition saveload.h:761
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition saveload.h:513
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition saveload.h:516
std::span< const struct SaveLoadCompat > SaveLoadCompatTable
A table of SaveLoadCompat entries.
Definition saveload.h:519
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
Definition saveload.h:1226
@ BigDates
Saveload version: 31, SVN revision: 5999 Change date from 1920 - 2090 to 0 - 5 000 000.
Definition saveload.h:87
@ StoreIndustryCargo
Saveload version: 78, SVN revision: 11176 Store an industry's cargo, so it can be customised upon bu...
Definition saveload.h:143
@ IndustryText
Saveload version: 289, GitHub pull request: 8576, release: 1.11.0-RC1 Additional GS text for industr...
Definition saveload.h:332
@ ProductionHistory
Saveload version: 343, GitHub pull request: 10541 Industry production history.
Definition saveload.h:397
@ NewGRFIndustryRandomTriggers
Saveload version: 82, SVN revision: 11410 NewGRF random triggers for industries.
Definition saveload.h:148
@ NewGRFPersistentStorage
Saveload version: 76, SVN revision: 11139 Persistently store some state of NewGRF objects/entities.
Definition saveload.h:141
@ ExtendIndustryCargoSlots
Saveload version: 202, GitHub pull request: 6867 Increase industry cargo slots to 16 in,...
Definition saveload.h:292
@ MultipleRoadStops
Saveload version: 6.0, SVN revision: 1721 Multi tile road stops, and some map size related fixes.
Definition saveload.h:53
@ NewGRFIndustryLayout
Saveload version: 73, SVN revision: 10903 NewGRF provided layouts for industries.
Definition saveload.h:137
@ MinVersion
First savegame version.
Definition saveload.h:37
@ IndustryAcceptedHistory
Saveload version: 357, GitHub pull request: 14321 Add per-industry history of cargo delivered and wa...
Definition saveload.h:414
@ IndustryCargoReorganise
Saveload version: 315, GitHub pull request: 10853 Industry accepts/produced data reorganised.
Definition saveload.h:364
@ IndustryNumValidHistory
Saveload version: 356, GitHub pull request: 14416 Store number of valid history records for industri...
Definition saveload.h:413
@ ServeNeutralIndustries
Saveload version: 210, GitHub pull request: 7234 Company stations can serve industries with attached...
Definition saveload.h:302
@ PersistentStoragePool
Saveload version: 161, SVN revision: 22567 Store persistent storage in a pool.
Definition saveload.h:243
@ CargoPaymentOverflow
Saveload version: 70, SVN revision: 10541 Fix overflow of cargo payment rates, plus preparation for ...
Definition saveload.h:134
@ RiffToArray
Saveload version: 294, GitHub pull request: 9375 Changed many ChunkType::Riff chunks to ChunkType::A...
Definition saveload.h:338
@ GSIndustryControl
Saveload version: 287, GitHub pull request: 7912 and 8115 GS industry control.
Definition saveload.h:330
@ Table
An Array with a header describing the elements.
Definition saveload.h:450
Definition of base types and functions in a cross-platform compatible way.
@ AllowControlCode
Allow the special control codes.
Definition string_type.h:47
ChunkHandler(ChunkId id, ChunkType type)
Create this ChunkHandler.
Definition saveload.h:470
Industry builder.
void Load() const override
Load the chunk.
void Save() const override
Save the chunk.
void Save() const override
Save the chunk.
void Load() const override
Load the chunk.
void FixPointers() const override
Fix the pointers.
Industry-type build data.
void Load() const override
Load the chunk.
void Save() const override
Save the chunk.
Data for managing the number of industries of a single industry type.
Definition industry.h:294
CargoType cargo
Cargo type.
Definition industry.h:88
HistoryData< AcceptedHistory > & GetOrCreateHistory()
Get history data, creating it if necessary.
Definition industry.h:98
std::unique_ptr< HistoryData< AcceptedHistory > > history
History of accepted and waiting cargo.
Definition industry.h:92
CargoType cargo
Cargo type.
Definition industry.h:76
HistoryData< ProducedHistory > history
History of cargo produced and transported for this month and 24 previous months.
Definition industry.h:79
Defines the internal data of a functional industry.
Definition industry.h:64
IndustryType type
type of industry.
Definition industry.h:117
PersistentStorage * psa
Persistent storage for NewGRF industries.
Definition industry.h:138
ValidHistoryMask valid_history
Mask of valid history records.
Definition industry.h:111
ProducedCargoes produced
produced cargo slots
Definition industry.h:112
AcceptedCargoes accepted
accepted cargo slots
Definition industry.h:113
static std::array< FlatSet< IndustryID >, NUM_INDUSTRYTYPES > industries
List of industries of each type.
Definition industry.h:279
NewGRFMappingChunkHandler(ChunkId id, OverrideManagerBase &mapping)
Create the handler.
Definition newgrf_sl.h:25
StorageType storage
Memory for the storage array.
static Pool::IterateWrapper< Industry > Iterate(size_t from=0)
static T * CreateAtIndex(IndustryID index, Targs &&... args)
SaveLoad type struct.
Definition saveload.h:764
static SaveLoad StructList(std::string name, SaveLoadVersion from=SaveLoadVersion::MinVersion, SaveLoadVersion to=SaveLoadVersion::MaxVersion)
Storage of a list of structs, optionally in some savegame versions.
Definition saveload.h:1103
static SaveLoad Variable(std::string name, AddressFunction< T > address_func, SaveLoadVersion from=SaveLoadVersion::MinVersion, SaveLoadVersion to=SaveLoadVersion::MaxVersion, size_t extra=0)
Storage of a variable in some savegame versions.
Definition saveload.h:926
static SaveLoad Array(std::string name, AddressFunction< T > address_func, SaveLoadVersion from=SaveLoadVersion::MinVersion, SaveLoadVersion to=SaveLoadVersion::MaxVersion, size_t extra=0)
Storage of an array in some savegame versions.
Definition saveload.h:1026
static SaveLoad Reference(std::string name, AddressFunction< T > address_func, SaveLoadVersion from=SaveLoadVersion::MinVersion, SaveLoadVersion to=SaveLoadVersion::MaxVersion)
Storage of a reference to a pool element in some savegame versions.
Definition saveload.h:951
static SaveLoad String(std::string name, AddressFunction< T > address_func, StringValidationSettings string_validation_settings={}, SaveLoadVersion from=SaveLoadVersion::MinVersion, SaveLoadVersion to=SaveLoadVersion::MaxVersion, size_t extra=0)
Storage of a string in some savegame versions.
Definition saveload.h:977
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:92
Base of the town class.