OpenTTD Source 20250717-master-g55605ae8f2
company_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 "../company_func.h"
16#include "../company_manager_face.h"
17#include "../fios.h"
18#include "../tunnelbridge_map.h"
19#include "../tunnelbridge.h"
20#include "../station_base.h"
21#include "../strings_func.h"
22
23#include "table/strings.h"
24
25#include "../safeguards.h"
26
34static const FaceVar *FindFaceVar(FaceVars style, FaceVarType type, StringID name)
35{
36 auto it = std::ranges::find_if(style, [type, name](const FaceVar &facevar) { return facevar.type == type && facevar.name == name; });
37 if (it != std::end(style)) return &*it;
38 return nullptr;
39}
40
60{
62
63 if (HasBit(face, 31)) cmf.style += 1;
64 if (HasBit(face, 27) && (HasBit(face, 26) == HasBit(face, 19))) cmf.style += 2;
65
66 const FaceSpec *spec = GetCompanyManagerFaceSpec(cmf.style);
67 FaceVars vars = spec->GetFaceVars();
68
69 cmf.style_label = spec->label;
70
71 if (auto var = FindFaceVar(vars, FaceVarType::Toggle, STR_FACE_GLASSES); var != nullptr) var->SetBits(cmf, GB(face, 28, 3) <= 1);
72 if (auto var = FindFaceVar(vars, FaceVarType::Palette, STR_FACE_EYECOLOUR); var != nullptr) var->SetBits(cmf, ClampU(GB(face, 20, 3), 5, 7) - 5);
73 if (auto var = FindFaceVar(vars, FaceVarType::Sprite, STR_FACE_CHIN); var != nullptr) var->SetBits(cmf, var->ScaleBits(GB(face, 4, 2)));
74 if (auto var = FindFaceVar(vars, FaceVarType::Sprite, STR_FACE_EYEBROWS); var != nullptr) var->SetBits(cmf, var->ScaleBits(GB(face, 6, 4)));
75 if (auto var = FindFaceVar(vars, FaceVarType::Sprite, STR_FACE_HAIR); var != nullptr) var->SetBits(cmf, var->ScaleBits(GB(face, 16, 4)));
76 if (auto var = FindFaceVar(vars, FaceVarType::Sprite, STR_FACE_JACKET); var != nullptr) var->SetBits(cmf, var->ScaleBits(GB(face, 20, 2)));
77 if (auto var = FindFaceVar(vars, FaceVarType::Sprite, STR_FACE_COLLAR); var != nullptr) var->SetBits(cmf, var->ScaleBits(GB(face, 22, 2)));
78 if (auto var = FindFaceVar(vars, FaceVarType::Sprite, STR_FACE_GLASSES); var != nullptr) var->SetBits(cmf, GB(face, 28, 1));
79
80 uint lips = GB(face, 10, 4);
81 if (cmf.style != 1 && cmf.style != 3 && lips < 4) {
82 if (auto var = FindFaceVar(vars, FaceVarType::Toggle, STR_FACE_MOUSTACHE); var != nullptr) var->SetBits(cmf, true);
83 if (auto var = FindFaceVar(vars, FaceVarType::Sprite, STR_FACE_MOUSTACHE); var != nullptr) var->SetBits(cmf, std::max(lips, 1U) - 1);
84 } else {
85 if (auto var = FindFaceVar(vars, FaceVarType::Sprite, STR_FACE_LIPS); var != nullptr) {
86 if (cmf.style == 0 || cmf.style == 2) {
87 lips = lips * 15 / 16;
88 lips -= 3;
89 if (cmf.style == 2 && lips > 8) lips = 0;
90 } else {
91 lips = var->ScaleBits(lips);
92 }
93 var->SetBits(cmf, lips);
94 }
95
96 if (auto var = FindFaceVar(vars, FaceVarType::Sprite, STR_FACE_NOSE); var != nullptr) {
97 uint nose = GB(face, 13, 3);
98 if (cmf.style == 1) {
99 nose = (nose * 3 >> 3) * 3 >> 2; // There is 'hole' in the nose sprites for women
100 } else {
101 nose = var->ScaleBits(nose);
102 }
103 var->SetBits(cmf, nose);
104 }
105 }
106
107 if (auto var = FindFaceVar(vars, FaceVarType::Sprite, STR_FACE_TIE); var != nullptr) {
108 uint tie = GB(face, 24, 4);
109 var->SetBits(cmf, var->ScaleBits(tie / 2));
110 }
111
112 if (auto var = FindFaceVar(vars, FaceVarType::Sprite, STR_FACE_EARRING); var != nullptr) {
113 uint earring = GB(face, 24, 4);
114 if (earring < 3) { // Not all women have an earring
115 if (auto has_earring = FindFaceVar(vars, FaceVarType::Toggle, STR_FACE_EARRING)) {
116 has_earring->SetBits(cmf, true);
117 var->SetBits(cmf, earring);
118 }
119 }
120 }
121
122 return cmf;
123}
124
127{
128 /* Reset infrastructure statistics to zero. */
129 for (Company *c : Company::Iterate()) c->infrastructure = {};
130
131 /* Collect airport count. */
132 for (const Station *st : Station::Iterate()) {
133 if (st->facilities.Test(StationFacility::Airport) && Company::IsValidID(st->owner)) {
134 Company::Get(st->owner)->infrastructure.airport++;
135 }
136 }
137
138 Company *c;
139 for (const auto tile : Map::Iterate()) {
140 switch (GetTileType(tile)) {
141 case MP_RAILWAY:
143 if (c != nullptr) {
144 uint pieces = 1;
145 if (IsPlainRail(tile)) {
146 TrackBits bits = GetTrackBits(tile);
147 pieces = CountBits(bits);
148 if (TracksOverlap(bits)) pieces *= pieces;
149 }
150 c->infrastructure.rail[GetRailType(tile)] += pieces;
151
153 }
154 break;
155
156 case MP_ROAD: {
157 if (IsLevelCrossing(tile)) {
159 if (c != nullptr) c->infrastructure.rail[GetRailType(tile)] += LEVELCROSSING_TRACKBIT_FACTOR;
160 }
161
162 /* Iterate all present road types as each can have a different owner. */
163 for (RoadTramType rtt : _roadtramtypes) {
164 RoadType rt = GetRoadType(tile, rtt);
165 if (rt == INVALID_ROADTYPE) continue;
166 c = Company::GetIfValid(IsRoadDepot(tile) ? GetTileOwner(tile) : GetRoadOwner(tile, rtt));
167 /* A level crossings and depots have two road bits. */
168 if (c != nullptr) c->infrastructure.road[rt] += IsNormalRoad(tile) ? CountBits(GetRoadBits(tile, rtt)) : 2;
169 }
170 break;
171 }
172
173 case MP_STATION:
175 if (c != nullptr && GetStationType(tile) != StationType::Airport && !IsBuoy(tile)) c->infrastructure.station++;
176
177 switch (GetStationType(tile)) {
178 case StationType::Rail:
179 case StationType::RailWaypoint:
180 if (c != nullptr && !IsStationTileBlocked(tile)) c->infrastructure.rail[GetRailType(tile)]++;
181 break;
182
183 case StationType::Bus:
184 case StationType::Truck:
185 case StationType::RoadWaypoint: {
186 /* Iterate all present road types as each can have a different owner. */
187 for (RoadTramType rtt : _roadtramtypes) {
188 RoadType rt = GetRoadType(tile, rtt);
189 if (rt == INVALID_ROADTYPE) continue;
190 c = Company::GetIfValid(GetRoadOwner(tile, rtt));
191 if (c != nullptr) c->infrastructure.road[rt] += 2; // A road stop has two road bits.
192 }
193 break;
194 }
195
196 case StationType::Dock:
197 case StationType::Buoy:
198 if (GetWaterClass(tile) == WATER_CLASS_CANAL) {
199 if (c != nullptr) c->infrastructure.water++;
200 }
201 break;
202
203 default:
204 break;
205 }
206 break;
207
208 case MP_WATER:
209 if (IsShipDepot(tile) || IsLock(tile)) {
211 if (c != nullptr) {
213 if (IsLock(tile) && GetLockPart(tile) == LOCK_PART_MIDDLE) {
214 /* The middle tile specifies the owner of the lock. */
215 c->infrastructure.water += 3 * LOCK_DEPOT_TILE_FACTOR; // the middle tile specifies the owner of the
216 break; // do not count the middle tile as canal
217 }
218 }
219 }
220 [[fallthrough]];
221
222 case MP_OBJECT:
223 if (GetWaterClass(tile) == WATER_CLASS_CANAL) {
225 if (c != nullptr) c->infrastructure.water++;
226 }
227 break;
228
229 case MP_TUNNELBRIDGE: {
230 /* Only count the tunnel/bridge if we're on the northern end tile. */
231 TileIndex other_end = GetOtherTunnelBridgeEnd(tile);
232 if (tile < other_end) {
233 /* Count each tunnel/bridge TUNNELBRIDGE_TRACKBIT_FACTOR times to simulate
234 * the higher structural maintenance needs, and don't forget the end tiles. */
235 uint len = (GetTunnelBridgeLength(tile, other_end) + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR;
236
237 switch (GetTunnelBridgeTransportType(tile)) {
238 case TRANSPORT_RAIL:
240 if (c != nullptr) c->infrastructure.rail[GetRailType(tile)] += len;
241 break;
242
243 case TRANSPORT_ROAD: {
244 /* Iterate all present road types as each can have a different owner. */
245 for (RoadTramType rtt : _roadtramtypes) {
246 RoadType rt = GetRoadType(tile, rtt);
247 if (rt == INVALID_ROADTYPE) continue;
248 c = Company::GetIfValid(GetRoadOwner(tile, rtt));
249 if (c != nullptr) c->infrastructure.road[rt] += len * 2; // A full diagonal road has two road bits.
250 }
251 break;
252 }
253
254 case TRANSPORT_WATER:
256 if (c != nullptr) c->infrastructure.water += len;
257 break;
258
259 default:
260 break;
261 }
262 }
263 break;
264 }
265
266 default:
267 break;
268 }
269 }
270}
271
272/* We do need to read this single value, as the bigger it gets, the more data is stored */
274 uint8_t num_build_rec;
275};
276
277class SlCompanyOldAIBuildRec : public DefaultSaveLoadHandler<SlCompanyOldAIBuildRec, CompanyOldAI> {
278public:
279 static inline const SaveLoad description[] = {{}}; // Needed to keep DefaultSaveLoadHandler happy.
280 static inline const SaveLoadCompatTable compat_description = _company_old_ai_buildrec_compat;
281
282 SaveLoadTable GetDescription() const override { return {}; }
283
284 void Load(CompanyOldAI *old_ai) const override
285 {
286 for (int i = 0; i != old_ai->num_build_rec; i++) {
287 SlObject(nullptr, this->GetLoadDescription());
288 }
289 }
290
291 void LoadCheck(CompanyOldAI *old_ai) const override { this->Load(old_ai); }
292};
293
294class SlCompanyOldAI : public DefaultSaveLoadHandler<SlCompanyOldAI, CompanyProperties> {
295public:
296 static inline const SaveLoad description[] = {
297 SLE_CONDVAR(CompanyOldAI, num_build_rec, SLE_UINT8, SL_MIN_VERSION, SLV_107),
299 };
300 static inline const SaveLoadCompatTable compat_description = _company_old_ai_compat;
301
302 void Load(CompanyProperties *c) const override
303 {
304 if (!c->is_ai) return;
305
306 CompanyOldAI old_ai;
307 SlObject(&old_ai, this->GetLoadDescription());
308 }
309
310 void LoadCheck(CompanyProperties *c) const override { this->Load(c); }
311};
312
313class SlCompanySettings : public DefaultSaveLoadHandler<SlCompanySettings, CompanyProperties> {
314public:
315 static inline const SaveLoad description[] = {
316 /* Engine renewal settings */
319 SLE_CONDVAR(CompanyProperties, settings.engine_renew_months, SLE_INT16, SLV_16, SL_MAX_VERSION),
320 SLE_CONDVAR(CompanyProperties, settings.engine_renew_money, SLE_UINT32, SLV_16, SL_MAX_VERSION),
321 SLE_CONDVAR(CompanyProperties, settings.renew_keep_length, SLE_BOOL, SLV_2, SL_MAX_VERSION),
322
323 /* Default vehicle settings */
324 SLE_CONDVAR(CompanyProperties, settings.vehicle.servint_ispercent, SLE_BOOL, SLV_120, SL_MAX_VERSION),
325 SLE_CONDVAR(CompanyProperties, settings.vehicle.servint_trains, SLE_UINT16, SLV_120, SL_MAX_VERSION),
326 SLE_CONDVAR(CompanyProperties, settings.vehicle.servint_roadveh, SLE_UINT16, SLV_120, SL_MAX_VERSION),
327 SLE_CONDVAR(CompanyProperties, settings.vehicle.servint_aircraft, SLE_UINT16, SLV_120, SL_MAX_VERSION),
328 SLE_CONDVAR(CompanyProperties, settings.vehicle.servint_ships, SLE_UINT16, SLV_120, SL_MAX_VERSION),
329 };
330 static inline const SaveLoadCompatTable compat_description = _company_settings_compat;
331
332 void Save(CompanyProperties *c) const override
333 {
334 SlObject(c, this->GetDescription());
335 }
336
337 void Load(CompanyProperties *c) const override
338 {
339 SlObject(c, this->GetLoadDescription());
340 }
341
342 void FixPointers(CompanyProperties *c) const override
343 {
344 SlObject(c, this->GetDescription());
345 }
346
347 void LoadCheck(CompanyProperties *c) const override { this->Load(c); }
348};
349
350class SlCompanyEconomy : public DefaultSaveLoadHandler<SlCompanyEconomy, CompanyProperties> {
351public:
352 static inline const SaveLoad description[] = {
353 SLE_CONDVAR(CompanyEconomyEntry, income, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_2),
355 SLE_CONDVAR(CompanyEconomyEntry, expenses, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_2),
356 SLE_CONDVAR(CompanyEconomyEntry, expenses, SLE_INT64, SLV_2, SL_MAX_VERSION),
357 SLE_CONDVAR(CompanyEconomyEntry, company_value, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_2),
358 SLE_CONDVAR(CompanyEconomyEntry, company_value, SLE_INT64, SLV_2, SL_MAX_VERSION),
359
360 SLE_CONDVAR(CompanyEconomyEntry, delivered_cargo[NUM_CARGO - 1], SLE_INT32, SL_MIN_VERSION, SLV_170),
361 SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, 32, SLV_170, SLV_EXTEND_CARGOTYPES),
363 SLE_VAR(CompanyEconomyEntry, performance_history, SLE_INT32),
364 };
365 static inline const SaveLoadCompatTable compat_description = _company_economy_compat;
366
367 void Save(CompanyProperties *c) const override
368 {
369 SlObject(&c->cur_economy, this->GetDescription());
370 }
371
372 void Load(CompanyProperties *c) const override
373 {
374 SlObject(&c->cur_economy, this->GetLoadDescription());
375 }
376
377 void FixPointers(CompanyProperties *c) const override
378 {
379 SlObject(&c->cur_economy, this->GetDescription());
380 }
381
382 void LoadCheck(CompanyProperties *c) const override { this->Load(c); }
383};
384
386public:
387 void Save(CompanyProperties *c) const override
388 {
390 for (int i = 0; i < c->num_valid_stat_ent; i++) {
391 SlObject(&c->old_economy[i], this->GetDescription());
392 }
393 }
394
395 void Load(CompanyProperties *c) const override
396 {
398 c->num_valid_stat_ent = (uint8_t)SlGetStructListLength(UINT8_MAX);
399 }
400 if (c->num_valid_stat_ent > std::size(c->old_economy)) SlErrorCorrupt("Too many old economy entries");
401
402 for (int i = 0; i < c->num_valid_stat_ent; i++) {
403 SlObject(&c->old_economy[i], this->GetLoadDescription());
404 }
405 }
406
407 void LoadCheck(CompanyProperties *c) const override { this->Load(c); }
408};
409
410class SlCompanyLiveries : public DefaultSaveLoadHandler<SlCompanyLiveries, CompanyProperties> {
411public:
412 static inline const SaveLoad description[] = {
413 SLE_CONDVAR(Livery, in_use, SLE_UINT8, SLV_34, SL_MAX_VERSION),
414 SLE_CONDVAR(Livery, colour1, SLE_UINT8, SLV_34, SL_MAX_VERSION),
415 SLE_CONDVAR(Livery, colour2, SLE_UINT8, SLV_34, SL_MAX_VERSION),
416 };
417 static inline const SaveLoadCompatTable compat_description = _company_liveries_compat;
418
423 size_t GetNumLiveries() const
424 {
425 if (IsSavegameVersionBefore(SLV_63)) return LS_END - 4;
426 if (IsSavegameVersionBefore(SLV_85)) return LS_END - 2;
428 /* Read from the savegame how long the list is. */
429 return SlGetStructListLength(LS_END);
430 }
431
432 void Save(CompanyProperties *c) const override
433 {
434 SlSetStructListLength(LS_END);
435 for (int i = 0; i < LS_END; i++) {
436 SlObject(&c->livery[i], this->GetDescription());
437 }
438 }
439
440 void Load(CompanyProperties *c) const override
441 {
442 size_t num_liveries = this->GetNumLiveries();
443 bool update_in_use = IsSavegameVersionBefore(SLV_GROUP_LIVERIES);
444
445 for (size_t i = 0; i < num_liveries; i++) {
446 SlObject(&c->livery[i], this->GetLoadDescription());
447 if (update_in_use && i != LS_DEFAULT) {
448 if (c->livery[i].in_use == 0) {
449 c->livery[i].colour1 = c->livery[LS_DEFAULT].colour1;
450 c->livery[i].colour2 = c->livery[LS_DEFAULT].colour2;
451 } else {
452 c->livery[i].in_use = 3;
453 }
454 }
455 }
456
458 /* We want to insert some liveries somewhere in between. This means some have to be moved. */
459 std::move_backward(&c->livery[LS_FREIGHT_WAGON - 2], &c->livery[LS_END - 2], &c->livery[LS_END]);
460 c->livery[LS_PASSENGER_WAGON_MONORAIL] = c->livery[LS_MONORAIL];
461 c->livery[LS_PASSENGER_WAGON_MAGLEV] = c->livery[LS_MAGLEV];
462 }
463
465 /* Copy bus/truck liveries over to trams */
466 c->livery[LS_PASSENGER_TRAM] = c->livery[LS_BUS];
467 c->livery[LS_FREIGHT_TRAM] = c->livery[LS_TRUCK];
468 }
469 }
470
471 void LoadCheck(CompanyProperties *c) const override { this->Load(c); }
472};
473
474class SlAllowListData : public VectorSaveLoadHandler<SlAllowListData, CompanyProperties, std::string> {
475public:
476 struct KeyWrapper {
477 std::string key;
478 };
479
480 static inline const SaveLoad description[] = {
481 SLE_SSTR(KeyWrapper, key, SLE_STR),
482 };
483 static inline const SaveLoadCompatTable compat_description = {};
484
485 std::vector<std::string> &GetVector(CompanyProperties *cprops) const override { return cprops->allow_list; }
486
487 void LoadCheck(CompanyProperties *cprops) const override { this->Load(cprops); }
488};
489
490/* Save/load of companies */
491static const SaveLoad _company_desc[] = {
492 SLE_VAR(CompanyProperties, name_2, SLE_UINT32),
493 SLE_VAR(CompanyProperties, name_1, SLE_STRINGID),
495
496 SLE_VAR(CompanyProperties, president_name_1, SLE_STRINGID),
497 SLE_VAR(CompanyProperties, president_name_2, SLE_UINT32),
499
502
503 SLE_VARNAME(CompanyProperties, face.bits, "face", SLE_UINT32),
504 SLE_CONDSSTRNAME(CompanyProperties, face.style_label, "face_style", SLE_STR, SLV_FACE_STYLES, SL_MAX_VERSION),
505
506 /* money was changed to a 64 bit field in savegame version 1. */
507 SLE_CONDVAR(CompanyProperties, money, SLE_VAR_I64 | SLE_FILE_I32, SL_MIN_VERSION, SLV_1),
509
510 SLE_CONDVAR(CompanyProperties, current_loan, SLE_VAR_I64 | SLE_FILE_I32, SL_MIN_VERSION, SLV_65),
511 SLE_CONDVAR(CompanyProperties, current_loan, SLE_INT64, SLV_65, SL_MAX_VERSION),
513
514 SLE_VAR(CompanyProperties, colour, SLE_UINT8),
515 SLE_VAR(CompanyProperties, money_fraction, SLE_UINT8),
516 SLE_VAR(CompanyProperties, block_preview, SLE_UINT8),
517
518 SLE_CONDVAR(CompanyProperties, location_of_HQ, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
519 SLE_CONDVAR(CompanyProperties, location_of_HQ, SLE_UINT32, SLV_6, SL_MAX_VERSION),
520 SLE_CONDVAR(CompanyProperties, last_build_coordinate, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
521 SLE_CONDVAR(CompanyProperties, last_build_coordinate, SLE_UINT32, SLV_6, SL_MAX_VERSION),
522 SLE_CONDVAR(CompanyProperties, inaugurated_year, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
523 SLE_CONDVAR(CompanyProperties, inaugurated_year, SLE_INT32, SLV_31, SL_MAX_VERSION),
524 SLE_CONDVAR(CompanyProperties, inaugurated_year_calendar, SLE_INT32, SLV_COMPANY_INAUGURATED_PERIOD_V2, SL_MAX_VERSION),
525
527
528 SLE_VAR(CompanyProperties, months_of_bankruptcy, SLE_UINT8),
529 SLE_CONDVAR(CompanyProperties, bankrupt_asked, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
530 SLE_CONDVAR(CompanyProperties, bankrupt_asked, SLE_UINT16, SLV_104, SL_MAX_VERSION),
531 SLE_VAR(CompanyProperties, bankrupt_timeout, SLE_INT16),
532 SLE_CONDVAR(CompanyProperties, bankrupt_value, SLE_VAR_I64 | SLE_FILE_I32, SL_MIN_VERSION, SLV_65),
533 SLE_CONDVAR(CompanyProperties, bankrupt_value, SLE_INT64, SLV_65, SL_MAX_VERSION),
534
535 /* yearly expenses was changed to 64-bit in savegame version 2. */
536 SLE_CONDARR(CompanyProperties, yearly_expenses, SLE_FILE_I32 | SLE_VAR_I64, 3 * 13, SL_MIN_VERSION, SLV_2),
537 SLE_CONDARR(CompanyProperties, yearly_expenses, SLE_INT64, 3 * 13, SLV_2, SL_MAX_VERSION),
538
540
541 SLE_CONDVAR(CompanyProperties, terraform_limit, SLE_UINT32, SLV_156, SL_MAX_VERSION),
542 SLE_CONDVAR(CompanyProperties, clear_limit, SLE_UINT32, SLV_156, SL_MAX_VERSION),
543 SLE_CONDVAR(CompanyProperties, tree_limit, SLE_UINT32, SLV_175, SL_MAX_VERSION),
544 SLEG_STRUCT("settings", SlCompanySettings),
546 SLEG_STRUCT("cur_economy", SlCompanyEconomy),
547 SLEG_STRUCTLIST("old_economy", SlCompanyOldEconomy),
549};
550
552 PLYRChunkHandler() : ChunkHandler('PLYR', CH_TABLE) {}
553
554 void Save() const override
555 {
556 SlTableHeader(_company_desc);
557
558 for (Company *c : Company::Iterate()) {
559 SlSetArrayIndex(c->index);
560 SlObject(c, _company_desc);
561 }
562 }
563
564 void Load() const override
565 {
566 const std::vector<SaveLoad> slt = SlCompatTableHeader(_company_desc, _company_sl_compat);
567
568 int index;
569 while ((index = SlIterateArray()) != -1) {
570 Company *c = new (CompanyID(index)) Company();
571 SlObject(c, slt);
572 _company_colours[index] = c->colour;
573 }
574 }
575
576
577 void LoadCheck(size_t) const override
578 {
579 const std::vector<SaveLoad> slt = SlCompatTableHeader(_company_desc, _company_sl_compat);
580
581 int index;
582 while ((index = SlIterateArray()) != -1) {
583 std::unique_ptr<CompanyProperties> cprops = std::make_unique<CompanyProperties>();
584 SlObject(cprops.get(), slt);
585
586 /* We do not load old custom names */
588 if (GetStringTab(cprops->name_1) == TEXT_TAB_OLD_CUSTOM) {
589 cprops->name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE;
590 }
591
592 if (GetStringTab(cprops->president_name_1) == TEXT_TAB_OLD_CUSTOM) {
593 cprops->president_name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE;
594 }
595 }
596
597 if (cprops->name.empty() && !IsInsideMM(cprops->name_1, SPECSTR_COMPANY_NAME_START, SPECSTR_COMPANY_NAME_END) &&
598 cprops->name_1 != STR_GAME_SAVELOAD_NOT_AVAILABLE && cprops->name_1 != STR_SV_UNNAMED &&
599 cprops->name_1 != SPECSTR_ANDCO_NAME && cprops->name_1 != SPECSTR_PRESIDENT_NAME &&
600 cprops->name_1 != SPECSTR_SILLY_NAME) {
601 cprops->name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE;
602 }
603
604 if (_load_check_data.companies.count(index) == 0) {
605 _load_check_data.companies[index] = std::move(cprops);
606 }
607 }
608 }
609
610 void FixPointers() const override
611 {
612 for (Company *c : Company::Iterate()) {
613 SlObject(c, _company_desc);
614 }
615 }
616};
617
618static const PLYRChunkHandler PLYR;
619static const ChunkHandlerRef company_chunk_handlers[] = {
620 PLYR,
621};
622
623extern const ChunkHandlerTable _company_chunk_handlers(company_chunk_handlers);
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr uint CountBits(T value)
Counts the number of set bits in a variable.
debug_inline static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
static const CargoType NUM_CARGO
Maximum number of cargo types in a game.
Definition cargo_type.h:75
Default handler for saving/loading an object to/from disk.
Definition saveload.h:589
SaveLoadTable GetLoadDescription() const
Get the description for how to load the chunk.
std::vector< std::string > & GetVector(CompanyProperties *cprops) const override
Get instance of vector to load/save.
size_t GetNumLiveries() const
Get the number of liveries used by this savegame version.
SaveLoadTable GetDescription() const override
Get the description of the fields in the savegame.
Default handler for saving/loading a vector to/from disk.
Definition saveload.h:1375
const FaceSpec * GetCompanyManagerFaceSpec(uint style_index)
Get the definition of a company manager face style.
TypedIndexContainer< std::array< Colours, MAX_COMPANIES >, CompanyID > _company_colours
NOSAVE: can be determined from company structs.
static const FaceVar * FindFaceVar(FaceVars style, FaceVarType type, StringID name)
Search for a face variable by type and name.
void AfterLoadCompanyStats()
Rebuilding of company statistics after loading a savegame.
CompanyManagerFace ConvertFromOldCompanyManagerFace(uint32_t face)
Converts an old company manager's face format to the new company manager's face format.
Loading of company chunks before table headers were added.
const SaveLoadCompat _company_liveries_compat[]
Original field order for SlCompanyLiveries.
const SaveLoadCompat _company_old_ai_compat[]
Original field order for SlCompanyOldAI.
const SaveLoadCompat _company_old_ai_buildrec_compat[]
Original field order for SlCompanyOldAIBuildRec.
const SaveLoadCompat _company_economy_compat[]
Original field order for SlCompanyEconomy.
const SaveLoadCompat _company_sl_compat[]
Original field order for company_desc.
const SaveLoadCompat _company_settings_compat[]
Original field order for SlCompanySettings.
static const uint LOCK_DEPOT_TILE_FACTOR
Multiplier for how many regular tiles a lock counts.
static const uint LEVELCROSSING_TRACKBIT_FACTOR
Multiplier for how many regular track bits a level crossing counts.
static const uint TUNNELBRIDGE_TRACKBIT_FACTOR
Multiplier for how many regular track bits a tunnel/bridge counts.
LoadCheckData _load_check_data
Data loaded from save during SL_LOAD_CHECK.
Definition fios_gui.cpp:41
fluid_settings_t * settings
FluidSynth settings handle.
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
constexpr uint ClampU(const uint a, const uint min, const uint max)
Clamp an unsigned integer between an interval.
RailType GetRailType(Tile t)
Gets the rail type of the given tile.
Definition rail_map.h:115
TrackBits GetTrackBits(Tile tile)
Gets the track bits of the given tile.
Definition rail_map.h:136
uint GetPresentSignals(Tile tile)
Get whether the given signals are present (Along/AgainstTrackDir)
Definition rail_map.h:392
static debug_inline bool IsPlainRail(Tile t)
Returns whether this is plain rails, with or without signals.
Definition rail_map.h:49
bool HasSignals(Tile t)
Checks if a rail tile has signals.
Definition rail_map.h:72
static debug_inline bool IsRoadDepot(Tile t)
Return whether a tile is a road depot.
Definition road_map.h:90
RoadBits GetRoadBits(Tile t, RoadTramType rtt)
Get the present road bits for a specific road type.
Definition road_map.h:112
Owner GetRoadOwner(Tile t, RoadTramType rtt)
Get the owner of a specific road type.
Definition road_map.h:218
bool IsLevelCrossing(Tile t)
Return whether a tile is a level crossing.
Definition road_map.h:69
static debug_inline bool IsNormalRoad(Tile t)
Return whether a tile is a normal road.
Definition road_map.h:48
RoadType
The different roadtypes we support.
Definition road_type.h:23
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:28
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:665
void SlErrorCorrupt(const std::string &msg)
Error handler for corrupt savegames.
Definition saveload.cpp:357
void SlObject(void *object, const SaveLoadTable &slt)
Main SaveLoad function.
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
void SlSetStructListLength(size_t length)
Set the length of this list.
Functions/types related to saving and loading games.
#define SLEG_STRUCTLIST(name, handler)
Storage of a list of structs in every savegame version.
Definition saveload.h:1249
#define SLE_CONDSSTRNAME(base, variable, name, type, from, to)
Storage of a std::string in some savegame versions.
Definition saveload.h:952
@ SLF_ALLOW_CONTROL
Allow control codes in the strings.
Definition saveload.h:695
#define SLE_VARNAME(base, variable, name, type)
Storage of a variable in every version of a savegame.
Definition saveload.h:1019
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition saveload.h:517
@ REF_ENGINE_RENEWS
Load/save a reference to an engine renewal (autoreplace).
Definition saveload.h:614
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition saveload.h:520
#define SLE_CONDARR(base, variable, type, length, from, to)
Storage of a fixed-size array of SL_VAR elements in some savegame versions.
Definition saveload.h:908
std::span< const struct SaveLoadCompat > SaveLoadCompatTable
A table of SaveLoadCompat entries.
Definition saveload.h:526
#define SLEG_STRUCT(name, handler)
Storage of a structs in every savegame version.
Definition saveload.h:1226
#define SLEG_CONDSTRUCT(name, handler, from, to)
Storage of a structs in some savegame versions.
Definition saveload.h:1157
#define SLE_CONDSSTR(base, variable, type, from, to)
Storage of a std::string in some savegame versions.
Definition saveload.h:941
#define SLE_CONDVECTOR(base, variable, type, from, to)
Storage of a vector of SL_VAR elements in some savegame versions.
Definition saveload.h:982
#define SLE_CONDVAR(base, variable, type, from, to)
Storage of a variable in some savegame versions.
Definition saveload.h:876
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
Definition saveload.h:1271
#define SLE_SSTR(base, variable, type)
Storage of a std::string in every savegame version.
Definition saveload.h:1054
@ SLV_COMPANY_INAUGURATED_PERIOD_V2
349 PR#13448 Fix savegame storage for company inaugurated year in wallclock mode.
Definition saveload.h:398
@ SLV_175
175 24136
Definition saveload.h:253
@ SLV_16
16.0 2817 16.1 3155
Definition saveload.h:60
@ SLV_84
84 11822
Definition saveload.h:143
@ SLV_107
107 15027
Definition saveload.h:171
@ SLV_85
85 11874
Definition saveload.h:145
@ SLV_6
6.0 1721 6.1 1768
Definition saveload.h:46
@ SLV_34
34 6455
Definition saveload.h:83
@ SLV_EXTEND_CARGOTYPES
199 PR#6802 Extend cargotypes to 64
Definition saveload.h:282
@ SLV_SAVELOAD_LIST_LENGTH
293 PR#9374 Consistency in list length with SL_STRUCT / SL_STRUCTLIST / SL_DEQUE / SL_REFLIST.
Definition saveload.h:331
@ SLV_65
65 10210
Definition saveload.h:121
@ SLV_120
120 16439
Definition saveload.h:187
@ SLV_FACE_STYLES
355 PR#14319 Addition of face styles, replacing gender and ethnicity.
Definition saveload.h:406
@ SLV_170
170 23826
Definition saveload.h:247
@ SL_MAX_VERSION
Highest possible saveload version.
Definition saveload.h:409
@ SLV_1
1.0 0.1.x, 0.2.x
Definition saveload.h:33
@ SL_MIN_VERSION
First savegame version.
Definition saveload.h:31
@ SLV_63
63 9956
Definition saveload.h:118
@ SLV_104
104 14735
Definition saveload.h:167
@ SLV_2
2.0 0.3.0 2.1 0.3.1, 0.3.2
Definition saveload.h:34
@ SLV_GROUP_LIVERIES
205 PR#7108 Livery storage change and group liveries.
Definition saveload.h:290
@ SLV_COMPANY_ALLOW_LIST_V2
341 PR#12908 Fixed savegame format for saving of list of client keys that are allowed to join this co...
Definition saveload.h:389
@ SLV_COMPANY_ALLOW_LIST
335 PR#12337 Saving of list of client keys that are allowed to join this company.
Definition saveload.h:382
@ SLV_19
19 3396
Definition saveload.h:65
@ SLV_156
156 21728
Definition saveload.h:230
@ SLV_31
31 5999
Definition saveload.h:80
@ SLV_MAX_LOAN_FOR_COMPANY
330 PR#11224 Separate max loan for each company.
Definition saveload.h:376
#define SLE_CONDREF(base, variable, type, from, to)
Storage of a reference in some savegame versions.
Definition saveload.h:897
std::span< const struct SaveLoad > SaveLoadTable
A table of SaveLoad entries.
Definition saveload.h:523
#define SLEG_CONDSTRUCTLIST(name, handler, from, to)
Storage of a list of structs in some savegame versions.
Definition saveload.h:1186
#define SLE_VAR(base, variable, type)
Storage of a variable in every version of a savegame.
Definition saveload.h:1010
StationType GetStationType(Tile t)
Get the station type of this tile.
Definition station_map.h:44
bool IsBuoy(Tile t)
Is tile t a buoy tile?
bool IsStationTileBlocked(Tile t)
Is tile t a blocked tile?
@ Airport
Station with an airport.
StringTab GetStringTab(StringID str)
Extract the StringTab from a StringID.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
static constexpr StringID SPECSTR_COMPANY_NAME_START
Special strings for company names on the form "TownName transport".
static constexpr StringID SPECSTR_SILLY_NAME
Special string for silly company names.
static constexpr StringID SPECSTR_ANDCO_NAME
Special string for Surname & Co company names.
static constexpr StringID SPECSTR_PRESIDENT_NAME
Special string for the president's name.
Handlers and description of chunk.
Definition saveload.h:471
Statistics about the economy.
std::array< uint32_t, ROADTYPE_END > road
Count of company owned track bits for each road type.
uint32_t station
Count of company owned station tiles.
uint32_t signal
Count of company owned signals.
std::array< uint32_t, RAILTYPE_END > rail
Count of company owned track bits for each rail type.
uint32_t water
Count of company owned track bits for canals.
uint style
Company manager face style.
Statically loadable part of Company pool item.
NetworkAuthorizedKeys allow_list
Public keys of clients that are allowed to join this company.
bool is_ai
If true, the company is (also) controlled by the computer (a NoAI program).
CompanyEconomyEntry cur_economy
Economic data of the company of this quarter.
Colours colour
Company colour.
std::array< CompanyEconomyEntry, MAX_HISTORY_QUARTERS > old_economy
Economic data of the company of the last MAX_HISTORY_QUARTERS quarters.
uint8_t num_valid_stat_ent
Number of valid statistical entries in old_economy.
CompanyInfrastructure infrastructure
NOSAVE: Counts of company owned infrastructure.
Information about the valid values of CompanyManagerFace bitgroups as well as the sprites to draw.
Information about a particular livery.
Definition livery.h:78
CompanyPropertiesMap companies
Company information.
Definition fios.h:45
Size related data of the map.
Definition map_func.h:206
void Save() const override
Save the chunk.
void Load() const override
Load the chunk.
void FixPointers() const override
Fix the pointers.
void LoadCheck(size_t) const override
Load the chunk for game preview.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static Titem * Get(auto index)
Returns Titem with given index.
static bool IsValidID(auto index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
static Titem * GetIfValid(auto index)
Returns Titem with given index.
SaveLoad type struct.
Definition saveload.h:725
Station data structure.
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
Definition tile_map.h:178
static debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
@ MP_ROAD
A tile with road (or tram tracks)
Definition tile_type.h:50
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
@ MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition tile_type.h:57
@ MP_WATER
Water tile.
Definition tile_type.h:54
@ MP_RAILWAY
A railway.
Definition tile_type.h:49
@ MP_OBJECT
Contains objects such as transmitters and owned land.
Definition tile_type.h:58
bool TracksOverlap(TrackBits bits)
Checks if the given tracks overlap, ie form a crossing.
Definition track_func.h:645
TrackBits
Allow incrementing of Track variables.
Definition track_type.h:35
@ TRANSPORT_RAIL
Transport by train.
@ TRANSPORT_ROAD
Transport by road vehicle.
@ TRANSPORT_WATER
Transport over water.
uint GetTunnelBridgeLength(TileIndex begin, TileIndex end)
Calculates the length of a tunnel or a bridge (without end tiles)
TransportType GetTunnelBridgeTransportType(Tile t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...
TileIndex GetOtherTunnelBridgeEnd(Tile t)
Determines type of the wormhole and returns its other end.
bool IsShipDepot(Tile t)
Is it a water tile with a ship depot on it?
Definition water_map.h:222
@ WATER_CLASS_CANAL
Canal.
Definition water_map.h:41
WaterClass GetWaterClass(Tile t)
Get the water class at a tile.
Definition water_map.h:112
uint8_t GetLockPart(Tile t)
Get the part of a lock.
Definition water_map.h:326
@ LOCK_PART_MIDDLE
Middle part of a lock.
Definition water_map.h:66
bool IsLock(Tile t)
Is there a lock on a given water tile?
Definition water_map.h:303