OpenTTD Source 20250312-master-gcdcc6b491d
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 <http://www.gnu.org/licenses/>.
6 */
7
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
46Engine *GetTempDataEngine(EngineID index)
47{
48 if (index < _temp_engine.size()) {
49 return &_temp_engine[index];
50 } else if (index == _temp_engine.size()) {
51 return &_temp_engine.emplace_back();
52 } else {
53 NOT_REACHED();
54 }
55}
56
58 ENGNChunkHandler() : ChunkHandler('ENGN', CH_TABLE) {}
59
60 void Save() const override
61 {
62 SlTableHeader(_engine_desc);
63
64 for (Engine *e : Engine::Iterate()) {
65 SlSetArrayIndex(e->index);
66 SlObject(e, _engine_desc);
67 }
68 }
69
70 void Load() const override
71 {
72 const std::vector<SaveLoad> slt = SlCompatTableHeader(_engine_desc, _engine_sl_compat);
73
74 /* As engine data is loaded before engines are initialized we need to load
75 * this information into a temporary array. This is then copied into the
76 * engine pool after processing NewGRFs by CopyTempEngineData(). */
77 int index;
78 while ((index = SlIterateArray()) != -1) {
79 Engine *e = GetTempDataEngine(static_cast<EngineID>(index));
80 SlObject(e, slt);
81
83 /* preview_company_rank was replaced with preview_company and preview_asked.
84 * Just cancel any previews. */
85 e->flags.Reset(EngineFlag{2}); // ENGINE_OFFER_WINDOW_OPEN
86 e->preview_company = CompanyID::Invalid();
87 e->preview_asked.Set();
88 }
89 }
90 }
91};
92
97{
98 for (Engine *e : Engine::Iterate()) {
99 if (e->index >= _temp_engine.size()) break;
100
101 const Engine *se = GetTempDataEngine(e->index);
102 e->intro_date = se->intro_date;
103 e->age = se->age;
104 e->reliability = se->reliability;
105 e->reliability_spd_dec = se->reliability_spd_dec;
106 e->reliability_start = se->reliability_start;
107 e->reliability_max = se->reliability_max;
108 e->reliability_final = se->reliability_final;
109 e->duration_phase_1 = se->duration_phase_1;
110 e->duration_phase_2 = se->duration_phase_2;
111 e->duration_phase_3 = se->duration_phase_3;
112 e->flags = se->flags;
113 e->preview_asked = se->preview_asked;
114 e->preview_company = se->preview_company;
115 e->preview_wait = se->preview_wait;
116 e->company_avail = se->company_avail;
117 e->company_hidden = se->company_hidden;
118 e->name = se->name;
119 }
120
121 ResetTempEngineData();
122}
123
124void ResetTempEngineData()
125{
126 _temp_engine.clear();
127 _temp_engine.shrink_to_fit();
128}
129
132
133 void Load() const override
134 {
135 /* Load old separate String ID list into a temporary array. This
136 * was always 256 entries. */
138
139 SlCopy(names.data(), std::size(names), SLE_STRINGID);
140
141 /* Copy each string into the temporary engine array. */
142 for (EngineID engine = EngineID::Begin(); engine < std::size(names); ++engine) {
143 Engine *e = GetTempDataEngine(engine);
144 e->name = CopyFromOldName(names[engine]);
145 }
146 }
147};
148
151 SLE_VAR(EngineIDMapping, grfid, SLE_UINT32),
152 SLE_VAR(EngineIDMapping, internal_id, SLE_UINT16),
153 SLE_VAR(EngineIDMapping, type, SLE_UINT8),
154 SLE_VAR(EngineIDMapping, substitute_id, SLE_UINT8),
155};
156
158 EIDSChunkHandler() : ChunkHandler('EIDS', CH_TABLE) {}
159
160 void Save() const override
161 {
163
164 /* Count total entries needed for combined list. */
165 size_t total = 0;
166 for (const auto &mapping : _engine_mngr.mappings) {
167 total += std::size(mapping);
168 }
169
170 /* Combine per-type mappings into single list for all types. */
171 std::vector<EngineIDMapping> temp;
172 temp.reserve(total);
173 for (const auto &mapping : _engine_mngr.mappings) {
174 temp.insert(std::end(temp), std::begin(mapping), std::end(mapping));
175 }
176
177 /* Sort combined list by EngineID */
178 std::ranges::sort(temp, std::less{}, &EngineIDMapping::engine);
179
180 for (EngineIDMapping &eid : temp) {
181 SlSetArrayIndex(eid.engine);
183 }
184 }
185
186 void Load() const override
187 {
189
190 _engine_mngr.mappings = {};
191
192 int index;
193 while ((index = SlIterateArray()) != -1) {
194 EngineIDMapping eid;
195 SlObject(&eid, slt);
196 _engine_mngr.SetID(eid.type, eid.internal_id, eid.grfid, eid.substitute_id, static_cast<EngineID>(index));
197 }
198 }
199};
200
201static const EIDSChunkHandler EIDS;
202static const ENGNChunkHandler ENGN;
203static const ENGSChunkHandler ENGS;
204static const ChunkHandlerRef engine_chunk_handlers[] = {
205 EIDS,
206 ENGN,
207 ENGS,
208};
209
210extern const ChunkHandlerTable _engine_chunk_handlers(engine_chunk_handlers);
constexpr Timpl & Set()
Set all bits.
constexpr Timpl & Reset(Tvalue_type value)
Reset the value-th bit.
A sort-of mixin that adds 'at(pos)' and 'operator[](pos)' implementations for 'ConvertibleThroughBase...
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.
Definition engine_sl.cpp:96
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.
EngineFlag
Engine.flags is a bitmask, with the following values.
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:663
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:514
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition saveload.h:517
#define SLE_CONDSSTR(base, variable, type, from, to)
Storage of a std::string in some savegame versions.
Definition saveload.h:938
#define SLE_CONDVAR(base, variable, type, from, to)
Storage of a variable in some savegame versions.
Definition saveload.h:873
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
Definition saveload.h:1268
@ 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:404
@ 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:464
#define SLE_VAR(base, variable, type)
Storage of a variable in every version of a savegame.
Definition saveload.h:1007
Declaration of functions used in more save/load files.
std::string CopyFromOldName(StringID id)
Copy and convert old custom names to UTF-8.
Handlers and description of chunk.
Definition saveload.h:468
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:70
void Save() const override
Save the chunk.
Definition engine_sl.cpp:60
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.
uint16_t reliability_spd_dec
Speed of reliability decay between services (per day).
Definition engine_base.h:49
uint16_t reliability_start
Initial reliability of the engine.
Definition engine_base.h:50
TimerGameCalendar::Date intro_date
Date of introduction of the engine.
Definition engine_base.h:45
EngineFlags flags
Flags of the engine.
Definition engine_base.h:56
CompanyMask company_avail
Bit for each company whether the engine is available for that company.
Definition engine_base.h:39
uint16_t reliability_max
Maximal reliability of the engine.
Definition engine_base.h:51
uint16_t reliability_final
Final reliability of the engine.
Definition engine_base.h:52
CompanyID preview_company
Company which is currently being offered a preview CompanyID::Invalid() means no company.
Definition engine_base.h:58
uint16_t duration_phase_3
Third reliability phase in months, decaying to reliability_final.
Definition engine_base.h:55
uint16_t duration_phase_2
Second reliability phase in months, keeping reliability_max.
Definition engine_base.h:54
uint8_t preview_wait
Daily countdown timer for timeout of offering the engine to the preview_company company.
Definition engine_base.h:59
CompanyMask company_hidden
Bit for each company whether the engine is normally hidden in the build gui for that company.
Definition engine_base.h:40
uint16_t reliability
Current reliability of the engine.
Definition engine_base.h:48
CompanyMask preview_asked
Bit for each company which has already been offered a preview.
Definition engine_base.h:41
int32_t age
Age of the engine in months.
Definition engine_base.h:46
std::string name
Custom name of engine.
Definition engine_base.h:43
uint16_t duration_phase_1
First reliability phase in months, increasing reliability from reliability_start to reliability_max.
Definition engine_base.h:53
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
SaveLoad type struct.
Definition saveload.h:722