OpenTTD Source 20260512-master-g20b387b91f
engine_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 "saveload_internal.h"
16#include "../engine_base.h"
17#include "../string_func.h"
18
19#include "../safeguards.h"
20
21static const SaveLoad _engine_desc[] = {
22 SLE_CONDVAR(Engine, intro_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
23 SLE_CONDVAR(Engine, intro_date, SLE_INT32, SLV_31, SL_MAX_VERSION),
24 SLE_CONDVAR(Engine, age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
25 SLE_CONDVAR(Engine, age, SLE_INT32, SLV_31, SL_MAX_VERSION),
26 SLE_VAR(Engine, reliability, SLE_UINT16),
27 SLE_VAR(Engine, reliability_spd_dec, SLE_UINT16),
28 SLE_VAR(Engine, reliability_start, SLE_UINT16),
29 SLE_VAR(Engine, reliability_max, SLE_UINT16),
30 SLE_VAR(Engine, reliability_final, SLE_UINT16),
31 SLE_VAR(Engine, duration_phase_1, SLE_UINT16),
32 SLE_VAR(Engine, duration_phase_2, SLE_UINT16),
33 SLE_VAR(Engine, duration_phase_3, SLE_UINT16),
34 SLE_VAR(Engine, flags, SLE_UINT8),
35 SLE_CONDVAR(Engine, preview_asked, SLE_UINT16, SLV_179, SL_MAX_VERSION),
36 SLE_CONDVAR(Engine, preview_company, SLE_UINT8, SLV_179, SL_MAX_VERSION),
37 SLE_VAR(Engine, preview_wait, SLE_UINT8),
38 SLE_CONDVAR(Engine, company_avail, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
39 SLE_CONDVAR(Engine, company_avail, SLE_UINT16, SLV_104, SL_MAX_VERSION),
40 SLE_CONDVAR(Engine, company_hidden, SLE_UINT16, SLV_193, SL_MAX_VERSION),
41 SLE_CONDSSTR(Engine, name, SLE_STR, SLV_84, SL_MAX_VERSION),
42};
43
45
53Engine *GetTempDataEngine(EngineID index, VehicleType type, uint16_t local_id)
54{
55 if (index < _temp_engine.size()) {
56 return &_temp_engine[index];
57 } else if (index == _temp_engine.size()) {
58 return &_temp_engine.emplace_back(index, type, local_id);
59 } else {
60 NOT_REACHED();
61 }
62}
63
64struct ENGNChunkHandler : ChunkHandler {
65 ENGNChunkHandler() : ChunkHandler('ENGN', CH_TABLE) {}
66
67 void Save() const override
68 {
69 SlTableHeader(_engine_desc);
70
71 for (Engine *e : Engine::Iterate()) {
72 SlSetArrayIndex(e->index);
73 SlObject(e, _engine_desc);
74 }
75 }
76
77 void Load() const override
78 {
79 const std::vector<SaveLoad> slt = SlCompatTableHeader(_engine_desc, _engine_sl_compat);
80
81 /* As engine data is loaded before engines are initialized we need to load
82 * this information into a temporary array. This is then copied into the
83 * engine pool after processing NewGRFs by CopyTempEngineData(). */
84 int index;
85 while ((index = SlIterateArray()) != -1) {
86 Engine *e = GetTempDataEngine(static_cast<EngineID>(index));
87 SlObject(e, slt);
88
90 /* preview_company_rank was replaced with preview_company and preview_asked.
91 * Just cancel any previews. */
92 e->flags.Reset(EngineFlag{2}); // ENGINE_OFFER_WINDOW_OPEN
93 e->preview_company = CompanyID::Invalid();
94 e->preview_asked.Set();
95 }
96 }
97 }
98};
99
104{
105 for (Engine *e : Engine::Iterate()) {
106 if (e->index >= _temp_engine.size()) break;
107
108 const Engine *se = GetTempDataEngine(e->index);
109 e->intro_date = se->intro_date;
110 e->age = se->age;
111 e->reliability = se->reliability;
112 e->reliability_spd_dec = se->reliability_spd_dec;
113 e->reliability_start = se->reliability_start;
114 e->reliability_max = se->reliability_max;
115 e->reliability_final = se->reliability_final;
116 e->duration_phase_1 = se->duration_phase_1;
117 e->duration_phase_2 = se->duration_phase_2;
118 e->duration_phase_3 = se->duration_phase_3;
119 e->flags = se->flags;
120 e->preview_asked = se->preview_asked;
121 e->preview_company = se->preview_company;
122 e->preview_wait = se->preview_wait;
123 e->company_avail = se->company_avail;
124 e->company_hidden = se->company_hidden;
125 e->name = se->name;
126 }
127
128 ResetTempEngineData();
129}
130
131void ResetTempEngineData()
132{
133 _temp_engine.clear();
134 _temp_engine.shrink_to_fit();
135}
136
137struct ENGSChunkHandler : ChunkHandler {
138 ENGSChunkHandler() : ChunkHandler('ENGS', CH_READONLY) {}
139
140 void Load() const override
141 {
142 /* Load old separate String ID list into a temporary array. This
143 * was always 256 entries. */
145
146 SlCopy(names.data(), std::size(names), SLE_STRINGID);
147
148 /* Copy each string into the temporary engine array. */
149 for (EngineID engine = EngineID::Begin(); engine < std::size(names); ++engine) {
150 Engine *e = GetTempDataEngine(engine);
151 e->name = CopyFromOldName(names[engine]);
152 }
153 }
154};
155
158 SLE_VAR(EngineIDMapping, grfid, SLE_UINT32),
159 SLE_VAR(EngineIDMapping, internal_id, SLE_UINT16),
160 SLE_VAR(EngineIDMapping, type, SLE_UINT8),
161 SLE_VAR(EngineIDMapping, substitute_id, SLE_UINT8),
162};
163
164struct EIDSChunkHandler : ChunkHandler {
165 EIDSChunkHandler() : ChunkHandler('EIDS', CH_TABLE) {}
166
167 void Save() const override
168 {
170
171 /* Count total entries needed for combined list. */
172 size_t total = 0;
173 for (const auto &mapping : _engine_mngr.mappings) {
174 total += std::size(mapping);
175 }
176
177 /* Combine per-type mappings into single list for all types. */
178 std::vector<EngineIDMapping> temp;
179 temp.reserve(total);
180 for (const auto &mapping : _engine_mngr.mappings) {
181 temp.insert(std::end(temp), std::begin(mapping), std::end(mapping));
182 }
183
184 /* Sort combined list by EngineID */
185 std::ranges::sort(temp, std::less{}, &EngineIDMapping::engine);
186
187 for (EngineIDMapping &eid : temp) {
188 SlSetArrayIndex(eid.engine);
190 }
191 }
192
193 void Load() const override
194 {
196
197 _engine_mngr.mappings = {};
198
199 int index;
200 while ((index = SlIterateArray()) != -1) {
201 EngineIDMapping eid;
202 SlObject(&eid, slt);
203 _engine_mngr.SetID(eid.type, eid.internal_id, eid.grfid, eid.substitute_id, static_cast<EngineID>(index));
204 }
205 }
206};
207
208static const EIDSChunkHandler EIDS;
209static const ENGNChunkHandler ENGN;
210static const ENGSChunkHandler ENGS;
211static const ChunkHandlerRef engine_chunk_handlers[] = {
212 EIDS,
213 ENGN,
214 ENGS,
215};
216
217extern const ChunkHandlerTable _engine_chunk_handlers(engine_chunk_handlers);
constexpr Timpl & Reset()
Reset all bits.
constexpr Timpl & Set()
Set all bits.
uint16_t reliability_spd_dec
Speed of reliability decay between services (per day).
Definition engine_base.h:50
uint16_t reliability_start
Initial reliability of the engine.
Definition engine_base.h:51
TimerGameCalendar::Date intro_date
Date of introduction of the engine.
Definition engine_base.h:46
EngineFlags flags
Flags of the engine.
Definition engine_base.h:57
CompanyMask company_avail
Bit for each company whether the engine is available for that company.
Definition engine_base.h:40
uint16_t reliability_max
Maximal reliability of the engine.
Definition engine_base.h:52
uint16_t reliability_final
Final reliability of the engine.
Definition engine_base.h:53
CompanyID preview_company
Company which is currently being offered a preview CompanyID::Invalid() means no company.
Definition engine_base.h:59
uint16_t duration_phase_3
Third reliability phase in months, decaying to reliability_final.
Definition engine_base.h:56
uint16_t duration_phase_2
Second reliability phase in months, keeping reliability_max.
Definition engine_base.h:55
uint8_t preview_wait
Daily countdown timer for timeout of offering the engine to the preview_company company.
Definition engine_base.h:60
CompanyMask company_hidden
Bit for each company whether the engine is normally hidden in the build gui for that company.
Definition engine_base.h:41
uint16_t reliability
Current reliability of the engine.
Definition engine_base.h:49
CompanyMask preview_asked
Bit for each company which has already been offered a preview.
Definition engine_base.h:42
int32_t age
Age of the engine in months.
Definition engine_base.h:47
std::string name
Custom name of engine.
Definition engine_base.h:44
uint16_t duration_phase_1
First reliability phase in months, increasing reliability from reliability_start to reliability_max.
Definition engine_base.h:54
A sort-of mixin that implements 'at(pos)' and 'operator[](pos)' only for a specific type.
Base class for engines.
Engine * GetTempDataEngine(EngineID index, VehicleType type, uint16_t local_id)
Get temporary engine data for loading savegame engine information.
Definition engine_sl.cpp:53
static const SaveLoad _engine_id_mapping_desc[]
Save and load the mapping between the engine id in the pool, and the grf file it came from.
void CopyTempEngineData()
Copy data from temporary engine array into the real engine pool.
Loading for engine chunks before table headers were added.
const SaveLoadCompat _engine_id_mapping_sl_compat[]
Original field order for _engine_id_mapping_desc.
const SaveLoadCompat _engine_sl_compat[]
Original field order for _engine_desc.
PoolID< uint16_t, struct EngineIDTag, 64000, 0xFFFF > EngineID
Unique identification number of an engine.
Definition engine_type.h:26
EngineFlag
Engine.flags is a bitmask, with the following values.
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.
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition saveload.cpp:686
void SlCopy(void *object, size_t length, VarType conv)
Copy a list of SL_VARs to/from a savegame.
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.
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition saveload.h:529
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition saveload.h:532
#define SLE_CONDSSTR(base, variable, type, from, to)
Storage of a std::string in some savegame versions.
Definition saveload.h:974
#define SLE_CONDVAR(base, variable, type, from, to)
Storage of a variable in some savegame versions.
Definition saveload.h:909
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
Definition saveload.h:1304
@ SLV_84
84 11822
Definition saveload.h:143
@ SLV_193
193 26802
Definition saveload.h:275
@ SL_MAX_VERSION
Highest possible saveload version.
Definition saveload.h:420
@ SL_MIN_VERSION
First savegame version.
Definition saveload.h:31
@ SLV_104
104 14735
Definition saveload.h:167
@ SLV_179
179 24810
Definition saveload.h:257
@ SLV_31
31 5999
Definition saveload.h:80
@ CH_READONLY
Chunk is never saved.
Definition saveload.h:478
#define SLE_VAR(base, variable, type)
Storage of a variable in every version of a savegame.
Definition saveload.h:1043
Declaration of functions used in more save/load files.
std::string CopyFromOldName(StringID id)
Copy and convert old custom names to UTF-8.
Definition of base types and functions in a cross-platform compatible way.
Functions related to low-level strings.
void Load() const override
Load the chunk.
void Save() const override
Save the chunk.
void Load() const override
Load the chunk.
Definition engine_sl.cpp:77
void Save() const override
Save the chunk.
Definition engine_sl.cpp:67
void Load() const override
Load the chunk.
VehicleType type
The engine type.
uint32_t grfid
The GRF ID of the file the entity belongs to.
uint8_t substitute_id
The (original) entity ID to use if this GRF is not available (currently not used).
uint16_t internal_id
The internal ID within the GRF file.
static Pool::IterateWrapper< Engine > Iterate(size_t from=0)
SaveLoad type struct.
Definition saveload.h:758
VehicleType
Available vehicle types.