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

OpenTTD Source 15.0-RC2

oldloader_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#include "../town.h"
12#include "../industry.h"
13#include "../company_func.h"
14#include "../aircraft.h"
15#include "../roadveh.h"
16#include "../ship.h"
17#include "../train.h"
18#include "../signs_base.h"
19#include "../station_base.h"
20#include "../subsidy_base.h"
21#include "../debug.h"
22#include "../depot_base.h"
23#include "../timer/timer_game_calendar.h"
24#include "../timer/timer_game_calendar.h"
25#include "../vehicle_func.h"
26#include "../effectvehicle_base.h"
27#include "../engine_func.h"
28#include "../company_base.h"
29#include "../disaster_vehicle.h"
30#include "../timer/timer.h"
31#include "../timer/timer_game_tick.h"
32#include "../timer/timer_game_calendar.h"
33#include "saveload_internal.h"
34#include "oldloader.h"
35
36#include "table/strings.h"
37#include "../table/engines.h"
38#include "../table/townname.h"
39
40#include "../safeguards.h"
41
42 static bool _read_ttdpatch_flags;
43 static uint16_t _old_extra_chunk_nums;
44
45void FixOldMapArray()
46{
47 /* TTO/TTD/TTDP savegames could have buoys at tile 0
48 * (without assigned station struct) */
49 MakeSea(0);
50}
51
52static void FixTTDMapArray()
53{
54 for (auto tile : Map::Iterate()) {
55 switch (GetTileType(tile)) {
56 case MP_STATION:
57 tile.m4() = 0; // We do not understand this TTDP station mapping (yet)
58 switch (tile.m5()) {
59 /* We have drive through stops at a totally different place */
60 case 0x53: case 0x54: tile.m5() += 170 - 0x53; break; // Bus drive through
61 case 0x57: case 0x58: tile.m5() += 168 - 0x57; break; // Truck drive through
62 case 0x55: case 0x56: tile.m5() += 170 - 0x55; break; // Bus tram stop
63 case 0x59: case 0x5A: tile.m5() += 168 - 0x59; break; // Truck tram stop
64 default: break;
65 }
66 break;
67
68 case MP_RAILWAY:
69 /* We save presignals different from TTDPatch, convert them */
70 if (GB(tile.m5(), 6, 2) == 1) { // RailTileType::Signals
71 /* This byte is always zero in TTD for this type of tile */
72 if (tile.m4()) { // Convert the presignals to our own format
73 tile.m4() = (tile.m4() >> 1) & 7;
74 }
75 }
76 /* TTDPatch stores PBS things in L6 and all elsewhere; so we'll just
77 * clear it for ourselves and let OTTD's rebuild PBS itself */
78 tile.m4() &= 0xF; // Only keep the lower four bits; upper four is PBS
79 break;
80
81 case MP_WATER:
82 /* if water class == 3, make river there */
83 if (GB(tile.m3(), 0, 2) == 3) {
84 SetTileType(tile, MP_WATER);
85 SetTileOwner(tile, OWNER_WATER);
86 tile.m2() = 0;
87 tile.m3() = 2; // WaterClass::River
88 tile.m4() = Random();
89 tile.m5() = 0;
90 }
91 break;
92
93 default:
94 break;
95 }
96 }
97
98 FixOldMapArray();
99}
100
101 static void FixTTDDepots()
102{
103 for (const Depot *d : Depot::Iterate(252)) {
104 if (!IsDepotTile(d->xy) || GetDepotIndex(d->xy) != d->index) {
106 delete d;
107 }
108 }
109}
110
111static uint32_t RemapOldTownName(uint32_t townnameparts, uint8_t old_town_name_type)
112{
113 auto fix_num = [](uint32_t i, uint32_t n, uint8_t s) -> uint32_t {
114 return ((i << 16) / n + 1) << s;
115 };
116
117 switch (old_town_name_type) {
118 case 0: case 3: // English, American
119 /* Already OK */
120 return townnameparts;
121
122 case 1: // French
123 /* For some reason 86 needs to be subtracted from townnameparts
124 * 0000 0000 0000 0000 0000 0000 1111 1111 */
125 return fix_num(townnameparts - 86, lengthof(_name_french_real), 0);
126
127 case 2: // German
128 Debug(misc, 0, "German Townnames are buggy ({})", townnameparts);
129 return townnameparts;
130
131 case 4: // Latin-American
132 /* 0000 0000 0000 0000 0000 0000 1111 1111 */
133 return fix_num(townnameparts, lengthof(_name_spanish_real), 0);
134
135 case 5: // Silly
136 /* NUM_SILLY_1 - lower 16 bits
137 * NUM_SILLY_2 - upper 16 bits without leading 1 (first 8 bytes)
138 * 1000 0000 2222 2222 0000 0000 1111 1111 */
139 return fix_num(townnameparts, lengthof(_name_silly_1), 0) | fix_num(GB(townnameparts, 16, 8), lengthof(_name_silly_2), 16);
140 }
141 return 0;
142}
143
144static void FixOldTowns()
145{
146 /* Convert town-names if needed */
147 for (Town *town : Town::Iterate()) {
148 if (IsInsideMM(town->townnametype, 0x20C1, 0x20C3)) {
149 town->townnametype = SPECSTR_TOWNNAME_START + _settings_game.game_creation.town_name;
150 town->townnameparts = RemapOldTownName(town->townnameparts, _settings_game.game_creation.town_name);
151 }
152 }
153}
154
160 void FixOldVehicles(LoadgameState &ls)
161{
162 for (Vehicle *v : Vehicle::Iterate()) {
163 if ((size_t)v->next == 0xFFFF) {
164 v->next = nullptr;
165 } else {
166 v->next = Vehicle::GetIfValid((size_t)v->next);
167 }
168
169 /* For some reason we need to correct for this */
170 switch (v->spritenum) {
171 case 0xfd: break;
172 case 0xff: v->spritenum = 0xfe; break;
173 default: v->spritenum >>= 1; break;
174 }
175
176 /* Vehicle-subtype is different in TTD(Patch) */
177 if (v->type == VEH_EFFECT) v->subtype = v->subtype >> 1;
178
179 v->name = CopyFromOldName(ls.vehicle_names[v->index.base()]);
180
181 /* We haven't used this bit for stations for ages */
182 if (v->type == VEH_ROAD) {
183 RoadVehicle *rv = RoadVehicle::From(v);
184 if (rv->state != RVSB_IN_DEPOT && rv->state != RVSB_WORMHOLE) {
185 ClrBit(rv->state, 2);
186 Tile tile(rv->tile);
187 if (IsTileType(tile, MP_STATION) && tile.m5() >= 168) {
188 /* Update the vehicle's road state to show we're in a drive through road stop. */
189 SetBit(rv->state, RVS_IN_DT_ROAD_STOP);
190 }
191 }
192 }
193
194 /* The subtype should be 0, but it sometimes isn't :( */
195 if (v->type == VEH_ROAD || v->type == VEH_SHIP) v->subtype = 0;
196
197 /* Sometimes primary vehicles would have a nothing (invalid) order
198 * or vehicles that could not have an order would still have a
199 * (loading) order which causes assertions and the like later on.
200 */
201 if (!IsCompanyBuildableVehicleType(v) ||
202 (v->IsPrimaryVehicle() && v->current_order.IsType(OT_NOTHING))) {
203 v->current_order.MakeDummy();
204 }
205
206 /* Shared orders are fixed in AfterLoadVehicles now */
207 }
208}
209
210static bool FixTTOMapArray()
211{
212 for (auto tile : Map::Iterate()) {
213 TileType tt = GetTileType(tile);
214 if (tt == 11) {
215 /* TTO has a different way of storing monorail.
216 * Instead of using bits in m3 it uses a different tile type. */
217 tile.m3() = 1; // rail type = monorail (in TTD)
218 SetTileType(tile, MP_RAILWAY);
219 tile.m2() = 1; // set monorail ground to RailGroundType::Grass
220 tt = MP_RAILWAY;
221 }
222
223 switch (tt) {
224 case MP_CLEAR:
225 break;
226
227 case MP_RAILWAY:
228 switch (GB(tile.m5(), 6, 2)) {
229 case 0: // RailTileType::Normal
230 break;
231 case 1: // RailTileType::Signals
232 tile.m4() = (~tile.m5() & 1) << 2; // signal variant (present only in OTTD)
233 SB(tile.m2(), 6, 2, GB(tile.m5(), 3, 2)); // signal status
234 tile.m3() |= 0xC0; // both signals are present
235 tile.m5() = HasBit(tile.m5(), 5) ? 2 : 1; // track direction (only X or Y)
236 tile.m5() |= 0x40; // RailTileType::Signals
237 break;
238 case 3: // RailTileType::Depot
239 tile.m2() = 0;
240 break;
241 default:
242 return false;
243 }
244 break;
245
246 case MP_ROAD: // road (depot) or level crossing
247 switch (GB(tile.m5(), 4, 4)) {
248 case 0: // RoadTileType::Normal
249 if (tile.m2() == 4) tile.m2() = 5; // 'small trees' -> Roadside::Trees
250 break;
251 case 1: // RoadTileType::Crossing (there aren't monorail crossings in TTO)
252 tile.m3() = tile.m1(); // set owner of road = owner of rail
253 break;
254 case 2: // RoadTileType::Depot
255 break;
256 default:
257 return false;
258 }
259 break;
260
261 case MP_HOUSE:
262 tile.m3() = tile.m2() & 0xC0; // construction stage
263 tile.m2() &= 0x3F; // building type
264 if (tile.m2() >= 5) tile.m2()++; // skip "large office block on snow"
265 break;
266
267 case MP_TREES:
268 tile.m3() = GB(tile.m5(), 3, 3); // type of trees
269 tile.m5() &= 0xC7; // number of trees and growth status
270 break;
271
272 case MP_STATION:
273 tile.m3() = (tile.m5() >= 0x08 && tile.m5() <= 0x0F) ? 1 : 0; // monorail -> 1, others 0 (rail, road, airport, dock)
274 if (tile.m5() >= 8) tile.m5() -= 8; // shift for monorail
275 if (tile.m5() >= 0x42) tile.m5()++; // skip heliport
276 break;
277
278 case MP_WATER:
279 tile.m3() = tile.m2() = 0;
280 break;
281
282 case MP_VOID:
283 tile.m2() = tile.m3() = tile.m5() = 0;
284 break;
285
286 case MP_INDUSTRY:
287 tile.m3() = 0;
288 switch (tile.m5()) {
289 case 0x24: // farm silo
290 tile.m5() = 0x25;
291 break;
292 case 0x25: case 0x27: // farm
293 case 0x28: case 0x29: case 0x2A: case 0x2B: // factory
294 tile.m5()--;
295 break;
296 default:
297 if (tile.m5() >= 0x2C) tile.m5() += 3; // iron ore mine, steel mill or bank
298 break;
299 }
300 break;
301
302 case MP_TUNNELBRIDGE:
303 if (HasBit(tile.m5(), 7)) { // bridge
304 uint8_t m5 = tile.m5();
305 tile.m5() = m5 & 0xE1; // copy bits 7..5, 1
306 if (GB(m5, 1, 2) == 1) tile.m5() |= 0x02; // road bridge
307 if (GB(m5, 1, 2) == 3) tile.m2() |= 0xA0; // monorail bridge -> tubular, steel bridge
308 if (!HasBit(m5, 6)) { // bridge head
309 tile.m3() = (GB(m5, 1, 2) == 3) ? 1 : 0; // track subtype (1 for monorail, 0 for others)
310 } else { // middle bridge part
311 tile.m3() = HasBit(m5, 2) ? 0x10 : 0; // track subtype on bridge
312 if (GB(m5, 3, 2) == 3) tile.m3() |= 1; // track subtype under bridge
313 if (GB(m5, 3, 2) == 1) tile.m5() |= 0x08; // set for road/water under (0 for rail/clear)
314 }
315 } else { // tunnel entrance/exit
316 tile.m2() = 0;
317 tile.m3() = HasBit(tile.m5(), 3); // monorail
318 tile.m5() &= HasBit(tile.m5(), 3) ? 0x03 : 0x07 ; // direction, transport type (== 0 for rail)
319 }
320 break;
321
322 case MP_OBJECT:
323 tile.m2() = 0;
324 tile.m3() = 0;
325 break;
326
327 default:
328 return false;
329
330 }
331 }
332
333 FixOldMapArray();
334
335 return true;
336}
337
338static Engine *_old_engines;
339
340 static bool FixTTOEngines()
341{
342 using OldEngineID = uint8_t;
344 static const OldEngineID ttd_to_tto[] = {
345 0, 255, 255, 255, 255, 255, 255, 255, 5, 7, 8, 9, 10, 11, 12, 13,
346 255, 255, 255, 255, 255, 255, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
347 25, 26, 27, 29, 28, 30, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
348 255, 255, 255, 255, 255, 255, 255, 31, 255, 32, 33, 34, 35, 36, 37, 38,
349 39, 40, 41, 42, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
350 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
351 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
352 255, 255, 255, 255, 44, 45, 46, 255, 255, 255, 255, 47, 48, 255, 49, 50,
353 255, 255, 255, 255, 51, 52, 255, 53, 54, 255, 55, 56, 255, 57, 59, 255,
354 58, 60, 255, 61, 62, 255, 63, 64, 255, 65, 66, 255, 255, 255, 255, 255,
355 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
356 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
357 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 67, 68, 69, 70,
358 71, 255, 255, 76, 77, 255, 255, 78, 79, 80, 81, 82, 83, 84, 85, 86,
359 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 255,
360 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 102, 255, 255
361 };
362
364 static const OldEngineID tto_to_ttd[] = {
365 0, 0, 8, 8, 8, 8, 8, 9, 10, 11, 12, 13, 14, 15, 15, 22,
366 23, 24, 25, 26, 27, 29, 28, 30, 31, 32, 33, 34, 35, 36, 37, 55,
367 57, 59, 58, 60, 61, 62, 63, 64, 65, 66, 67, 116, 116, 117, 118, 123,
368 124, 126, 127, 132, 133, 135, 136, 138, 139, 141, 142, 144, 145, 147, 148, 150,
369 151, 153, 154, 204, 205, 206, 207, 208, 211, 212, 211, 212, 211, 212, 215, 216,
370 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
371 233, 234, 235, 236, 237, 238, 253
372 };
373
374 for (Vehicle *v : Vehicle::Iterate()) {
375 if (v->engine_type >= lengthof(tto_to_ttd)) return false;
376 v->engine_type = static_cast<EngineID>(tto_to_ttd[v->engine_type.base()]);
377 }
378
379 /* Load the default engine set. Many of them will be overridden later */
380 {
381 EngineID j = EngineID::Begin();
382 for (uint16_t i = 0; i < lengthof(_orig_rail_vehicle_info); ++i, ++j) new (GetTempDataEngine(j)) Engine(VEH_TRAIN, i);
383 for (uint16_t i = 0; i < lengthof(_orig_road_vehicle_info); ++i, ++j) new (GetTempDataEngine(j)) Engine(VEH_ROAD, i);
384 for (uint16_t i = 0; i < lengthof(_orig_ship_vehicle_info); ++i, ++j) new (GetTempDataEngine(j)) Engine(VEH_SHIP, i);
385 for (uint16_t i = 0; i < lengthof(_orig_aircraft_vehicle_info); ++i, ++j) new (GetTempDataEngine(j)) Engine(VEH_AIRCRAFT, i);
386 }
387
388 TimerGameCalendar::Date aging_date = std::min(TimerGameCalendar::date + CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR, TimerGameCalendar::ConvertYMDToDate(TimerGameCalendar::Year{2050}, 0, 1));
389 TimerGameCalendar::YearMonthDay aging_ymd = TimerGameCalendar::ConvertDateToYMD(aging_date);
390
391 for (EngineID i = EngineID::Begin(); i < 256; ++i) {
392 OldEngineID oi = ttd_to_tto[i.base()];
393 Engine *e = GetTempDataEngine(i);
394
395 if (oi == 255) {
396 /* Default engine is used */
397 TimerGameCalendar::date += CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR;
398 StartupOneEngine(e, aging_ymd, 0);
399 CalcEngineReliability(e, false);
400 e->intro_date -= CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR;
401 TimerGameCalendar::date -= CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR;
402
403 /* Make sure for example monorail and maglev are available when they should be */
404 if (TimerGameCalendar::date >= e->intro_date && e->info.climates.Test(LandscapeType::Temperate)) {
405 e->flags.Set(EngineFlag::Available);
406 e->company_avail.Set();
407 e->age = TimerGameCalendar::date > e->intro_date ? (TimerGameCalendar::date - e->intro_date).base() / 30 : 0;
408 }
409 } else {
410 /* Using data from TTO savegame */
411 Engine *oe = &_old_engines[oi];
412
413 e->intro_date = oe->intro_date;
414 e->age = oe->age;
415 e->reliability = oe->reliability;
416 e->reliability_spd_dec = oe->reliability_spd_dec;
417 e->reliability_start = oe->reliability_start;
418 e->reliability_max = oe->reliability_max;
419 e->reliability_final = oe->reliability_final;
420 e->duration_phase_1 = oe->duration_phase_1;
421 e->duration_phase_2 = oe->duration_phase_2;
422 e->duration_phase_3 = oe->duration_phase_3;
423 e->flags = oe->flags;
424
425 e->company_avail = CompanyMask{};
426
427 /* One or more engines were remapped to this one. Make this engine available
428 * if at least one of them was available. */
429 for (uint j = 0; j < lengthof(tto_to_ttd); j++) {
430 if (tto_to_ttd[j] == i && _old_engines[j].company_avail.Any()) {
431 e->company_avail.Set();
432 e->flags.Set(EngineFlag::Available);
433 break;
434 }
435 }
436
437 e->info.climates = LandscapeType::Temperate;
438 }
439
440 e->preview_company = CompanyID::Invalid();
441 e->preview_asked.Set();
442 e->preview_wait = 0;
443 e->name = std::string{};
444 }
445
446 return true;
447}
448
449static void FixTTOCompanies()
450{
451 for (Company *c : Company::Iterate()) {
452 c->cur_economy.company_value = CalculateCompanyValue(c); // company value history is zeroed
453 }
454}
455
456 static inline Colours RemapTTOColour(Colours tto)
457{
459 static const Colours tto_colour_remap[] = {
460 COLOUR_DARK_BLUE, COLOUR_GREY, COLOUR_YELLOW, COLOUR_RED,
461 COLOUR_PURPLE, COLOUR_DARK_GREEN, COLOUR_ORANGE, COLOUR_PALE_GREEN,
462 COLOUR_BLUE, COLOUR_GREEN, COLOUR_CREAM, COLOUR_BROWN,
463 COLOUR_WHITE, COLOUR_LIGHT_BLUE, COLOUR_MAUVE, COLOUR_PINK
464 };
465
466 if (static_cast<size_t>(tto) >= std::size(tto_colour_remap)) return COLOUR_GREY; // this shouldn't happen
467
468 return tto_colour_remap[tto];
469}
470
471static inline uint RemapTownIndex(uint x)
472{
473 return _savegame_type == SGT_TTO ? (x - 0x264) / 78 : (x - 0x264) / 94;
474}
475
476static inline uint RemapOrderIndex(uint x)
477{
478 return _savegame_type == SGT_TTO ? (x - 0x1AC4) / 2 : (x - 0x1C18) / 2;
479}
480
481extern std::vector<TileIndex> _animated_tiles;
482extern TimeoutTimer<TimerGameTick> _new_competitor_timeout;
483extern std::unique_ptr<std::string[]> _old_name_array;
484
485static uint32_t _old_town_index;
486static uint16_t _old_string_id;
487static uint16_t _old_string_id_2;
488
489static void ClearOldMap3(TileIndex t)
490{
491 Tile tile(t);
492 tile.m3() = 0;
493 tile.m4() = 0;
494}
495
496static Town *RemapTown(TileIndex fallback)
497{
498 /* In some cases depots, industries and stations could refer to a missing town. */
499 Town *t = Town::GetIfValid(RemapTownIndex(_old_town_index));
500 if (t == nullptr) {
501 /* In case the town that was referred to does not exist, find the closest.
502 * However, this needs the kd-tree to be present. */
503 RebuildTownKdtree();
504 t = CalcClosestTownFromTile(fallback);
505 }
506 return t;
507}
508
509static void ReadTTDPatchFlags(LoadgameState &ls)
510{
511 if (_read_ttdpatch_flags) return;
512
513 _read_ttdpatch_flags = true;
514
515 /* Set default values */
516 ls.vehicle_multiplier = 1;
517 _ttdp_version = 0;
518 _old_extra_chunk_nums = 0;
519 _bump_assert_value = 0;
520
521 if (_savegame_type == SGT_TTO) {
522 ls.vehicle_names.resize(800);
523 return;
524 }
525
526 /* TTDPatch misuses old map3 (now m3/m4) for flags.. read them! */
527 ls.vehicle_multiplier = Tile(0).m3();
528 /* Somehow.... there was an error in some savegames, so 0 becomes 1
529 * and 1 becomes 2. The rest of the values are okay */
530 if (ls.vehicle_multiplier < 2) ls.vehicle_multiplier++;
531
532 ls.vehicle_names.resize(ls.vehicle_multiplier * 850);
533
534 /* TTDPatch increases the Vehicle-part in the middle of the game,
535 * so if the multiplier is anything else but 1, the assert fails..
536 * bump the assert value so it doesn't!
537 * (1 multiplier == 850 vehicles
538 * 1 vehicle == 128 bytes */
539 _bump_assert_value = (ls.vehicle_multiplier - 1) * 850 * 128;
540
541 /* The first 17 bytes are used by TTDP1, which translates to the first 9 m3s and first 8 m4s. */
542 for (TileIndex i{}; i <= 8; i++) { // check tile 0, too
543 Tile tile(i);
544 if (tile.m3() != 0 || (i != 8 && tile.m4() != 0)) _savegame_type = SGT_TTDP1;
545 }
546
547 /* Check if we have a modern TTDPatch savegame (has extra data all around) */
548 Tile ttdp2_header_first(Map::Size() - 3);
549 Tile ttdp2_header_second(Map::Size() - 2);
550 if (ttdp2_header_first.m3() == 'T' && ttdp2_header_first.m4() == 'T' &&
551 ttdp2_header_second.m3() == 'D' && ttdp2_header_second.m4() == 'p') {
552 _savegame_type = SGT_TTDP2;
553 }
554
555 Tile extra_chunk_tile = Tile(_savegame_type == SGT_TTDP2 ? Map::Size() - 1 : 1);
556 _old_extra_chunk_nums = extra_chunk_tile.m3() | extra_chunk_tile.m4() << 8;
557
558 /* Clean the misused places */
559 for (TileIndex i{}; i < 9; i++) ClearOldMap3(i);
560 for (TileIndex i = TileXY(0, Map::MaxY()); i < Map::Size(); i++) ClearOldMap3(i);
561
562 if (_savegame_type == SGT_TTDP2) Debug(oldloader, 2, "Found TTDPatch game");
563
564 Debug(oldloader, 3, "Vehicle-multiplier is set to {} ({} vehicles)", ls.vehicle_multiplier, ls.vehicle_multiplier * 850);
565}
566
567static std::array<Town::SuppliedHistory, 2> _old_pass_supplied{};
568static std::array<Town::SuppliedHistory, 2> _old_mail_supplied{};
569
570static const OldChunks town_chunk[] = {
571 OCL_SVAR( OC_TILE, Town, xy ),
572 OCL_NULL( 2 ),
573 OCL_SVAR( OC_UINT16, Town, townnametype ),
574 OCL_SVAR( OC_UINT32, Town, townnameparts ),
575 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Town, grow_counter ),
576 OCL_NULL( 1 ),
577 OCL_NULL( 4 ),
578 OCL_NULL( 2 ),
579 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Town, flags ),
580 OCL_NULL( 10 ),
581
582 OCL_SVAR( OC_INT16, Town, ratings[0] ),
583 OCL_SVAR( OC_INT16, Town, ratings[1] ),
584 OCL_SVAR( OC_INT16, Town, ratings[2] ),
585 OCL_SVAR( OC_INT16, Town, ratings[3] ),
586 OCL_SVAR( OC_INT16, Town, ratings[4] ),
587 OCL_SVAR( OC_INT16, Town, ratings[5] ),
588 OCL_SVAR( OC_INT16, Town, ratings[6] ),
589 OCL_SVAR( OC_INT16, Town, ratings[7] ),
590
591 OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, have_ratings ),
592 OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, statues ),
593 OCL_NULL( 2 ),
594 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Town, time_until_rebuild ),
595 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Town, growth_rate ),
596
597 /* Slots 0 and 2 are passengers and mail respectively for old saves. */
598 OCL_VAR( OC_FILE_U16 | OC_VAR_U32, 1, &_old_pass_supplied[THIS_MONTH].production ),
599 OCL_VAR( OC_FILE_U16 | OC_VAR_U32, 1, &_old_mail_supplied[THIS_MONTH].production ),
600 OCL_VAR( OC_FILE_U16 | OC_VAR_U32, 1, &_old_pass_supplied[THIS_MONTH].transported ),
601 OCL_VAR( OC_FILE_U16 | OC_VAR_U32, 1, &_old_mail_supplied[THIS_MONTH].transported ),
602 OCL_VAR( OC_FILE_U16 | OC_VAR_U32, 1, &_old_pass_supplied[LAST_MONTH].production ),
603 OCL_VAR( OC_FILE_U16 | OC_VAR_U32, 1, &_old_mail_supplied[LAST_MONTH].production ),
604 OCL_VAR( OC_FILE_U16 | OC_VAR_U32, 1, &_old_pass_supplied[LAST_MONTH].transported ),
605 OCL_VAR( OC_FILE_U16 | OC_VAR_U32, 1, &_old_mail_supplied[LAST_MONTH].transported ),
606
607 OCL_NULL( 2 ),
608
609 OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TAE_FOOD].new_act ),
610 OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TAE_WATER].new_act ),
611 OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TAE_FOOD].old_act ),
612 OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TAE_WATER].old_act ),
613
614 OCL_SVAR( OC_UINT8, Town, road_build_months ),
615 OCL_SVAR( OC_UINT8, Town, fund_buildings_months ),
616
617 OCL_CNULL( OC_TTD, 8 ),
618
619 OCL_END()
620};
621
622static bool LoadOldTown(LoadgameState &ls, int num)
623{
624 Town *t = new (TownID(num)) Town();
625 if (!LoadChunk(ls, t, town_chunk)) return false;
626
627 if (t->xy != 0) {
628 if (_savegame_type == SGT_TTO) {
629 /* 0x10B6 is auto-generated name, others are custom names */
630 t->townnametype = t->townnametype == 0x10B6 ? 0x20C1 : t->townnametype + 0x2A00;
631 }
632 /* Passengers and mail were always treated as slots 0 and 2 in older saves. */
633 auto &pass = t->supplied.emplace_back(0);
634 pass.history[LAST_MONTH] = _old_pass_supplied[LAST_MONTH];
635 pass.history[THIS_MONTH] = _old_pass_supplied[THIS_MONTH];
636 auto &mail = t->supplied.emplace_back(2);
637 mail.history[LAST_MONTH] = _old_mail_supplied[LAST_MONTH];
638 mail.history[THIS_MONTH] = _old_mail_supplied[THIS_MONTH];
639 } else {
640 delete t;
641 }
642
643 return true;
644}
645
646static uint16_t _old_order;
647static const OldChunks order_chunk[] = {
648 OCL_VAR ( OC_UINT16, 1, &_old_order ),
649 OCL_END()
650};
651
652static bool LoadOldOrder(LoadgameState &ls, int num)
653{
654 if (!LoadChunk(ls, nullptr, order_chunk)) return false;
655
656 OldOrderSaveLoadItem &o = AllocateOldOrder(num);
657 o.order.AssignOrder(UnpackOldOrder(_old_order));
658
659 if (!o.order.IsType(OT_NOTHING) && num > 0) {
660 /* Relink the orders to each other (in the orders for one vehicle are behind each other,
661 * with an invalid order (OT_NOTHING) as indication that it is the last order */
662 OldOrderSaveLoadItem *prev = GetOldOrder(num + 1 - 1);
663 if (prev != nullptr) prev->next = num + 1; // next is 1-based.
664 }
665
666 return true;
667}
668
669static bool LoadOldAnimTileList(LoadgameState &ls, int)
670{
671 TileIndex anim_list[256];
672 const OldChunks anim_chunk[] = {
673 OCL_VAR ( OC_TILE, 256, anim_list ),
674 OCL_END ()
675 };
676
677 if (!LoadChunk(ls, nullptr, anim_chunk)) return false;
678
679 /* The first zero in the loaded array indicates the end of the list. */
680 for (int i = 0; i < 256; i++) {
681 if (anim_list[i] == 0) break;
682 _animated_tiles.push_back(anim_list[i]);
683 }
684
685 return true;
686}
687
688static const OldChunks depot_chunk[] = {
689 OCL_SVAR( OC_TILE, Depot, xy ),
690 OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
691 OCL_END()
692};
693
694static bool LoadOldDepot(LoadgameState &ls, int num)
695{
696 Depot *d = new (DepotID(num)) Depot();
697 if (!LoadChunk(ls, d, depot_chunk)) return false;
698
699 if (d->xy != 0) {
700 d->town = RemapTown(d->xy);
701 } else {
702 delete d;
703 }
704
705 return true;
706}
707
708static StationID _current_station_id;
709static uint16_t _waiting_acceptance;
710static uint8_t _cargo_source;
711static uint8_t _cargo_periods;
712
713static const OldChunks goods_chunk[] = {
714 OCL_VAR ( OC_UINT16, 1, &_waiting_acceptance ),
715 OCL_SVAR( OC_UINT8, GoodsEntry, time_since_pickup ),
716 OCL_SVAR( OC_UINT8, GoodsEntry, rating ),
717 OCL_VAR ( OC_UINT8, 1, &_cargo_source ),
718 OCL_VAR ( OC_UINT8, 1, &_cargo_periods ),
719 OCL_SVAR( OC_UINT8, GoodsEntry, last_speed ),
720 OCL_SVAR( OC_UINT8, GoodsEntry, last_age ),
721
722 OCL_END()
723};
724
725static bool LoadOldGood(LoadgameState &ls, int num)
726{
727 /* for TTO games, 12th (num == 11) goods entry is created in the Station constructor */
728 if (_savegame_type == SGT_TTO && num == 11) return true;
729
730 Station *st = Station::Get(_current_station_id);
731 GoodsEntry *ge = &st->goods[num];
732
733 if (!LoadChunk(ls, ge, goods_chunk)) return false;
734
735 ge->status.Set(GoodsEntry::State::Acceptance, HasBit(_waiting_acceptance, 15));
736 ge->status.Set(GoodsEntry::State::Rating, _cargo_source != 0xFF);
737 if (GB(_waiting_acceptance, 0, 12) != 0 && CargoPacket::CanAllocateItem()) {
738 ge->GetOrCreateData().cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, (_cargo_source == 0xFF) ? StationID::Invalid() : StationID{_cargo_source}, INVALID_TILE, 0),
739 StationID::Invalid());
740 }
741
742 return true;
743}
744
745static const OldChunks station_chunk[] = {
746 OCL_SVAR( OC_TILE, Station, xy ),
747 OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
748
749 OCL_NULL( 4 ),
750 OCL_SVAR( OC_TILE, Station, train_station.tile ),
751 OCL_SVAR( OC_TILE, Station, airport.tile ),
752 OCL_NULL( 2 ),
753 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Station, train_station.w ),
754
755 OCL_NULL( 1 ),
756 OCL_NULL( 2 ),
757
758 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
759
760 OCL_NULL( 4 ),
761
762 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Station, had_vehicle_of_type ),
763
764 OCL_CHUNK( 12, LoadOldGood ),
765
766 OCL_SVAR( OC_UINT8, Station, time_since_load ),
767 OCL_SVAR( OC_UINT8, Station, time_since_unload ),
768 OCL_SVAR( OC_UINT8, Station, delete_ctr ),
769 OCL_SVAR( OC_UINT8, Station, owner ),
770 OCL_SVAR( OC_UINT8, Station, facilities ),
771 OCL_SVAR( OC_TTD | OC_UINT8, Station, airport.type ),
772 OCL_SVAR( OC_TTO | OC_FILE_U16 | OC_VAR_U64, Station, airport.blocks ),
773 OCL_NULL( 3 ),
774 OCL_CNULL( OC_TTD, 1 ),
775 OCL_SVAR( OC_TTD | OC_FILE_U16 | OC_VAR_U64, Station, airport.blocks ),
776 OCL_CNULL( OC_TTD, 2 ),
777 OCL_CNULL( OC_TTD, 4 ),
778
779 OCL_END()
780};
781
782static bool LoadOldStation(LoadgameState &ls, int num)
783{
784 Station *st = new (StationID(num)) Station();
785 _current_station_id = st->index;
786
787 if (!LoadChunk(ls, st, station_chunk)) return false;
788
789 if (st->xy != 0) {
790 st->town = RemapTown(st->xy);
791
792 if (_savegame_type == SGT_TTO) {
793 if (IsInsideBS(_old_string_id, 0x180F, 32)) {
794 st->string_id = STR_SV_STNAME + (_old_string_id - 0x180F); // automatic name
795 } else {
796 st->string_id = _old_string_id + 0x2800; // custom name
797 }
798
799 if (st->airport.blocks.Test(AirportBlock{8})) {
800 st->airport.type = 1; // large airport
801 } else if (st->airport.blocks.Test(AirportBlock{6})) {
802 st->airport.type = 3; // oil rig
803 } else {
804 st->airport.type = 0; // small airport
805 }
806 } else {
807 st->string_id = RemapOldStringID(_old_string_id);
808 }
809 } else {
810 delete st;
811 }
812
813 return true;
814}
815
816/* Old save games always have 3 input and 2 output slots per industry. */
817static std::array<Industry::AcceptedCargo, INDUSTRY_ORIGINAL_NUM_INPUTS> _old_accepted{};
818static std::array<Industry::ProducedCargo, INDUSTRY_ORIGINAL_NUM_OUTPUTS> _old_produced{};
819
820static const OldChunks industry_chunk[] = {
821 OCL_SVAR( OC_TILE, Industry, location.tile ),
822 OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
823 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Industry, location.w ),
824 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Industry, location.h ),
825 OCL_NULL( 2 ),
826
827 OCL_VAR( OC_TTD | OC_UINT16, 1, &_old_produced[0].waiting ),
828 OCL_VAR( OC_TTD | OC_UINT16, 1, &_old_produced[1].waiting ),
829 OCL_VAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, 1, &_old_produced[0].waiting ),
830 OCL_VAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, 1, &_old_produced[1].waiting ),
831
832 OCL_VAR( OC_UINT8, 1, &_old_produced[0].rate ),
833 OCL_VAR( OC_UINT8, 1, &_old_produced[1].rate ),
834
835 OCL_NULL( 3 ),
836
837 OCL_SVAR( OC_UINT8, Industry, prod_level ),
838
839 OCL_VAR( OC_UINT16, 1, &_old_produced[0].history[THIS_MONTH].production ),
840 OCL_VAR( OC_UINT16, 1, &_old_produced[1].history[THIS_MONTH].production ),
841 OCL_VAR( OC_UINT16, 1, &_old_produced[0].history[THIS_MONTH].transported ),
842 OCL_VAR( OC_UINT16, 1, &_old_produced[1].history[THIS_MONTH].transported ),
843
844 OCL_NULL( 2 ),
845
846 OCL_VAR( OC_UINT16, 1, &_old_produced[0].history[LAST_MONTH].production ),
847 OCL_VAR( OC_UINT16, 1, &_old_produced[1].history[LAST_MONTH].production ),
848 OCL_VAR( OC_UINT16, 1, &_old_produced[0].history[LAST_MONTH].transported ),
849 OCL_VAR( OC_UINT16, 1, &_old_produced[1].history[LAST_MONTH].transported ),
850
851 OCL_SVAR( OC_UINT8, Industry, type ),
852 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, counter ),
853 OCL_SVAR( OC_UINT8, Industry, owner ),
854 OCL_SVAR( OC_UINT8, Industry, random_colour ),
855 OCL_SVAR( OC_TTD | OC_FILE_U8 | OC_VAR_I32, Industry, last_prod_year ),
856 OCL_SVAR( OC_TTD | OC_UINT16, Industry, counter ),
857 OCL_SVAR( OC_TTD | OC_UINT8, Industry, was_cargo_delivered ),
858
859 OCL_CNULL( OC_TTD, 9 ),
860
861 OCL_END()
862};
863
864static bool LoadOldIndustry(LoadgameState &ls, int num)
865{
866 Industry *i = new (IndustryID(num)) Industry();
867 if (!LoadChunk(ls, i, industry_chunk)) return false;
868
869 if (i->location.tile != 0) {
870 /* Copy data from old fixed arrays to industry. */
871 std::move(std::begin(_old_accepted), std::end(_old_accepted), std::back_inserter(i->accepted));
872 std::copy(std::begin(_old_produced), std::end(_old_produced), std::back_inserter(i->produced));
873
874 i->town = RemapTown(i->location.tile);
875
876 if (_savegame_type == SGT_TTO) {
877 if (i->type > 0x06) i->type++; // Printing Works were added
878 if (i->type == 0x0A) i->type = 0x12; // Iron Ore Mine has different ID
879
880 TimerGameEconomy::YearMonthDay ymd = TimerGameEconomy::ConvertDateToYMD(TimerGameEconomy::date);
881 i->last_prod_year = ymd.year;
882
883 i->random_colour = RemapTTOColour(i->random_colour);
884 }
885
886 Industry::industries[i->type].insert(i->index);
887 } else {
888 delete i;
889 }
890
891 return true;
892}
893
894static CompanyID _current_company_id;
895static int32_t _old_yearly;
896
897static const OldChunks _company_yearly_chunk[] = {
898 OCL_VAR( OC_INT32, 1, &_old_yearly ),
899 OCL_END()
900};
901
902static bool LoadOldCompanyYearly(LoadgameState &ls, int num)
903{
904 Company *c = Company::Get(_current_company_id);
905
906 for (uint i = 0; i < 13; i++) {
907 if (_savegame_type == SGT_TTO && i == 6) {
908 _old_yearly = 0; // property maintenance
909 } else {
910 if (!LoadChunk(ls, nullptr, _company_yearly_chunk)) return false;
911 }
912
913 c->yearly_expenses[num][i] = _old_yearly;
914 }
915
916 return true;
917}
918
919static const OldChunks _company_economy_chunk[] = {
920 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, income ),
921 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, expenses ),
922 OCL_SVAR( OC_INT32, CompanyEconomyEntry, delivered_cargo[NUM_CARGO - 1] ),
923 OCL_SVAR( OC_INT32, CompanyEconomyEntry, performance_history ),
924 OCL_SVAR( OC_TTD | OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, company_value ),
925
926 OCL_END()
927};
928
929static bool LoadOldCompanyEconomy(LoadgameState &ls, int)
930{
931 Company *c = Company::Get(_current_company_id);
932
933 if (!LoadChunk(ls, &c->cur_economy, _company_economy_chunk)) return false;
934
935 /* Don't ask, but the number in TTD(Patch) are inverted to OpenTTD */
936 c->cur_economy.income = -c->cur_economy.income;
937 c->cur_economy.expenses = -c->cur_economy.expenses;
938
939 for (uint i = 0; i < 24; i++) {
940 if (!LoadChunk(ls, &c->old_economy[i], _company_economy_chunk)) return false;
941
942 c->old_economy[i].income = -c->old_economy[i].income;
943 c->old_economy[i].expenses = -c->old_economy[i].expenses;
944 }
945
946 return true;
947}
948
949static const OldChunks _company_chunk[] = {
950 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
951 OCL_SVAR( OC_UINT32, Company, name_2 ),
952 OCL_SVAR( OC_UINT32, Company, face.bits ),
953 OCL_VAR ( OC_UINT16, 1, &_old_string_id_2 ),
954 OCL_SVAR( OC_UINT32, Company, president_name_2 ),
955
956 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Company, money ),
957 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Company, current_loan ),
958
959 OCL_SVAR( OC_UINT8, Company, colour ),
960 OCL_SVAR( OC_UINT8, Company, money_fraction ),
961 OCL_SVAR( OC_UINT8, Company, months_of_bankruptcy ),
962 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Company, bankrupt_asked ),
963 OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Company, bankrupt_value ),
964 OCL_SVAR( OC_UINT16, Company, bankrupt_timeout ),
965
966 OCL_CNULL( OC_TTD, 4 ), // cargo_types
967 OCL_CNULL( OC_TTO, 2 ), // cargo_types
968
969 OCL_CHUNK( 3, LoadOldCompanyYearly ),
970 OCL_CHUNK( 1, LoadOldCompanyEconomy ),
971
972 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Company, inaugurated_year),
973 OCL_SVAR( OC_TILE, Company, last_build_coordinate ),
974 OCL_SVAR( OC_UINT8, Company, num_valid_stat_ent ),
975
976 OCL_NULL( 230 ), // Old AI
977
978 OCL_SVAR( OC_UINT8, Company, block_preview ),
979 OCL_CNULL( OC_TTD, 1 ), // Old AI
980 OCL_CNULL( OC_TTD, 1 ), // avail_railtypes
981 OCL_SVAR( OC_TILE, Company, location_of_HQ ),
982
983 OCL_CNULL( OC_TTD, 4 ), // Shares
984
985 OCL_CNULL( OC_TTD, 8 ), // junk at end of chunk
986
987 OCL_END()
988};
989
990static bool LoadOldCompany(LoadgameState &ls, int num)
991{
992 Company *c = new (CompanyID(num)) Company();
993
994 _current_company_id = (CompanyID)num;
995
996 if (!LoadChunk(ls, c, _company_chunk)) return false;
997
998 if (_old_string_id == 0) {
999 delete c;
1000 return true;
1001 }
1002
1003 if (_savegame_type == SGT_TTO) {
1004 /* adjust manager's face */
1005 if (HasBit(c->face.bits, 27) && GB(c->face.bits, 26, 1) == GB(c->face.bits, 19, 1)) {
1006 /* if face would be black in TTD, adjust tie colour and thereby face colour */
1007 ClrBit(c->face.bits, 27);
1008 }
1009
1010 /* Company name */
1011 if (_old_string_id == 0 || _old_string_id == 0x4C00) {
1012 _old_string_id = STR_SV_UNNAMED; // "Unnamed"
1013 } else if (GB(_old_string_id, 8, 8) == 0x52) {
1014 _old_string_id += 0x2A00; // Custom name
1015 } else {
1016 _old_string_id = RemapOldStringID(_old_string_id += 0x240D); // Automatic name
1017 }
1018 c->name_1 = _old_string_id;
1019
1020 /* Manager name */
1021 switch (_old_string_id_2) {
1022 case 0x4CDA: _old_string_id_2 = SPECSTR_PRESIDENT_NAME; break; // automatic name
1023 case 0x0006: _old_string_id_2 = STR_SV_EMPTY; break; // empty name
1024 default: _old_string_id_2 = _old_string_id_2 + 0x2A00; break; // custom name
1025 }
1026 c->president_name_1 = _old_string_id_2;
1027
1028 c->colour = RemapTTOColour(c->colour);
1029
1030 if (num != 0) c->is_ai = true;
1031 } else {
1032 c->name_1 = RemapOldStringID(_old_string_id);
1033 c->president_name_1 = RemapOldStringID(_old_string_id_2);
1034
1035 if (num == 0) {
1036 /* If the first company has no name, make sure we call it UNNAMED */
1037 if (c->name_1 == STR_NULL) {
1038 c->name_1 = STR_SV_UNNAMED;
1039 }
1040 } else {
1041 /* Beside some multiplayer maps (1 on 1), which we don't official support,
1042 * all other companies are an AI.. mark them as such */
1043 c->is_ai = true;
1044 }
1045
1046 /* Sometimes it is better to not ask.. in old scenarios, the money
1047 * was always 893288 pounds. In the newer versions this is correct,
1048 * but correct for those oldies
1049 * Ps: this also means that if you had exact 893288 pounds, you will go back
1050 * to 100000.. this is a very VERY small chance ;) */
1051 if (c->money == 893288) c->money = c->current_loan = 100000;
1052 }
1053
1054 _company_colours[num] = c->colour;
1055 c->inaugurated_year -= EconomyTime::ORIGINAL_BASE_YEAR;
1056
1057 return true;
1058}
1059
1060static uint32_t _old_order_ptr;
1061static uint16_t _old_next_ptr;
1062static typename VehicleID::BaseType _current_vehicle_id;
1063
1064static const OldChunks vehicle_train_chunk[] = {
1065 OCL_SVAR( OC_UINT8, Train, track ),
1066 OCL_SVAR( OC_UINT8, Train, force_proceed ),
1067 OCL_SVAR( OC_UINT16, Train, crash_anim_pos ),
1068 OCL_NULL( 1 ), // railtype
1069
1070 OCL_NULL( 5 ),
1071
1072 OCL_END()
1073};
1074
1075static const OldChunks vehicle_road_chunk[] = {
1076 OCL_SVAR( OC_UINT8, RoadVehicle, state ),
1077 OCL_SVAR( OC_UINT8, RoadVehicle, frame ),
1078 OCL_SVAR( OC_UINT16, RoadVehicle, blocked_ctr ),
1079 OCL_SVAR( OC_UINT8, RoadVehicle, overtaking ),
1080 OCL_SVAR( OC_UINT8, RoadVehicle, overtaking_ctr ),
1081 OCL_SVAR( OC_UINT16, RoadVehicle, crashed_ctr ),
1082 OCL_SVAR( OC_UINT8, RoadVehicle, reverse_ctr ),
1083
1084 OCL_NULL( 1 ),
1085
1086 OCL_END()
1087};
1088
1089static const OldChunks vehicle_ship_chunk[] = {
1090 OCL_SVAR( OC_UINT8, Ship, state ),
1091
1092 OCL_NULL( 9 ),
1093
1094 OCL_END()
1095};
1096
1097static const OldChunks vehicle_air_chunk[] = {
1098 OCL_SVAR( OC_UINT8, Aircraft, pos ),
1099 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Aircraft, targetairport ),
1100 OCL_SVAR( OC_UINT16, Aircraft, crashed_counter ),
1101 OCL_SVAR( OC_UINT8, Aircraft, state ),
1102
1103 OCL_NULL( 5 ),
1104
1105 OCL_END()
1106};
1107
1108static const OldChunks vehicle_effect_chunk[] = {
1109 OCL_SVAR( OC_UINT16, EffectVehicle, animation_state ),
1110 OCL_SVAR( OC_UINT8, EffectVehicle, animation_substate ),
1111
1112 OCL_NULL( 7 ), // Junk
1113
1114 OCL_END()
1115};
1116
1117static const OldChunks vehicle_disaster_chunk[] = {
1118 OCL_SVAR( OC_UINT16, DisasterVehicle, image_override ),
1119 OCL_SVAR( OC_UINT16, DisasterVehicle, big_ufo_destroyer_target ),
1120
1121 OCL_NULL( 6 ),
1122
1123 OCL_END()
1124};
1125
1126static const OldChunks vehicle_empty_chunk[] = {
1127 OCL_NULL( 10 ),
1128
1129 OCL_END()
1130};
1131
1132static bool LoadOldVehicleUnion(LoadgameState &ls, int)
1133{
1134 Vehicle *v = Vehicle::GetIfValid(_current_vehicle_id);
1135 uint temp = ls.total_read;
1136 bool res;
1137
1138 if (v == nullptr) {
1139 res = LoadChunk(ls, nullptr, vehicle_empty_chunk);
1140 } else {
1141 switch (v->type) {
1142 default: SlErrorCorrupt("Invalid vehicle type");
1143 case VEH_TRAIN : res = LoadChunk(ls, v, vehicle_train_chunk); break;
1144 case VEH_ROAD : res = LoadChunk(ls, v, vehicle_road_chunk); break;
1145 case VEH_SHIP : res = LoadChunk(ls, v, vehicle_ship_chunk); break;
1146 case VEH_AIRCRAFT: res = LoadChunk(ls, v, vehicle_air_chunk); break;
1147 case VEH_EFFECT : res = LoadChunk(ls, v, vehicle_effect_chunk); break;
1148 case VEH_DISASTER: res = LoadChunk(ls, v, vehicle_disaster_chunk); break;
1149 }
1150 }
1151
1152 /* This chunk size should always be 10 bytes */
1153 if (ls.total_read - temp != 10) {
1154 Debug(oldloader, 0, "Assert failed in VehicleUnion: invalid chunk size");
1155 return false;
1156 }
1157
1158 return res;
1159}
1160
1161static uint16_t _cargo_count;
1162
1163static const OldChunks vehicle_chunk[] = {
1164 OCL_SVAR( OC_UINT8, Vehicle, subtype ),
1165
1166 OCL_NULL( 2 ),
1167 OCL_NULL( 2 ),
1168
1169 OCL_VAR ( OC_UINT32, 1, &_old_order_ptr ),
1170 OCL_VAR ( OC_UINT16, 1, &_old_order ),
1171
1172 OCL_NULL ( 1 ),
1173 OCL_SVAR( OC_UINT8, Vehicle, cur_implicit_order_index ),
1174 OCL_SVAR( OC_TILE, Vehicle, dest_tile ),
1175 OCL_SVAR( OC_UINT16, Vehicle, load_unload_ticks ),
1176 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, date_of_last_service ),
1177 OCL_SVAR( OC_UINT16, Vehicle, service_interval ),
1178 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, last_station_visited ),
1179 OCL_SVAR( OC_TTD | OC_UINT8, Vehicle, tick_counter ),
1180 OCL_CNULL( OC_TTD, 2 ),
1181 OCL_CNULL( OC_TTO, 1 ),
1182
1183 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, x_pos ),
1184 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, y_pos ),
1185 OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Vehicle, z_pos ),
1186 OCL_SVAR( OC_UINT8, Vehicle, direction ),
1187 OCL_NULL( 2 ),
1188 OCL_NULL( 2 ),
1189 OCL_NULL( 1 ),
1190
1191 OCL_SVAR( OC_UINT8, Vehicle, owner ),
1192 OCL_SVAR( OC_TILE, Vehicle, tile ),
1193 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, sprite_cache.sprite_seq.seq[0].sprite ),
1194
1195 OCL_NULL( 8 ),
1196
1197 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Vehicle, vehstatus ),
1198 OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, cur_speed ),
1199 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, cur_speed ),
1200 OCL_SVAR( OC_UINT8, Vehicle, subspeed ),
1201 OCL_SVAR( OC_UINT8, Vehicle, acceleration ),
1202 OCL_SVAR( OC_UINT8, Vehicle, progress ),
1203
1204 OCL_SVAR( OC_UINT8, Vehicle, cargo_type ),
1205 OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, cargo_cap ),
1206 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, cargo_cap ),
1207 OCL_VAR ( OC_TTD | OC_UINT16, 1, &_cargo_count ),
1208 OCL_VAR ( OC_TTO | OC_FILE_U8 | OC_VAR_U16, 1, &_cargo_count ),
1209 OCL_VAR ( OC_UINT8, 1, &_cargo_source ),
1210 OCL_VAR ( OC_UINT8, 1, &_cargo_periods ),
1211
1212 OCL_SVAR( OC_TTO | OC_UINT8, Vehicle, tick_counter ),
1213
1214 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, age ),
1215 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, max_age ),
1216 OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Vehicle, build_year ),
1217 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, unitnumber ),
1218
1219 OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, engine_type ),
1220 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, engine_type ),
1221
1222 OCL_SVAR( OC_UINT8, Vehicle, spritenum ),
1223 OCL_SVAR( OC_UINT8, Vehicle, day_counter ),
1224
1225 OCL_SVAR( OC_UINT8, Vehicle, breakdowns_since_last_service ),
1226 OCL_SVAR( OC_UINT8, Vehicle, breakdown_ctr ),
1227 OCL_SVAR( OC_UINT8, Vehicle, breakdown_delay ),
1228 OCL_SVAR( OC_UINT8, Vehicle, breakdown_chance ),
1229
1230 OCL_CNULL( OC_TTO, 1 ),
1231
1232 OCL_SVAR( OC_UINT16, Vehicle, reliability ),
1233 OCL_SVAR( OC_UINT16, Vehicle, reliability_spd_dec ),
1234
1235 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_this_year ),
1236 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_last_year ),
1237
1238 OCL_VAR ( OC_UINT16, 1, &_old_next_ptr ),
1239
1240 OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Vehicle, value ),
1241
1242 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
1243
1244 OCL_CHUNK( 1, LoadOldVehicleUnion ),
1245
1246 OCL_CNULL( OC_TTO, 24 ),
1247 OCL_CNULL( OC_TTD, 20 ),
1248
1249 OCL_END()
1250};
1251
1258 bool LoadOldVehicle(LoadgameState &ls, int num)
1259{
1260 /* Read the TTDPatch flags, because we need some info from it */
1261 ReadTTDPatchFlags(ls);
1262
1263 for (uint i = 0; i < ls.vehicle_multiplier; i++) {
1264 _current_vehicle_id = num * ls.vehicle_multiplier + i;
1265
1266 Vehicle *v;
1267
1268 if (_savegame_type == SGT_TTO) {
1269 uint type = ReadByte(ls);
1270 switch (type) {
1271 default: return false;
1272 case 0x00 /* VEH_INVALID */: v = nullptr; break;
1273 case 0x25 /* MONORAIL */:
1274 case 0x20 /* VEH_TRAIN */: v = new (VehicleID(_current_vehicle_id)) Train(); break;
1275 case 0x21 /* VEH_ROAD */: v = new (VehicleID(_current_vehicle_id)) RoadVehicle(); break;
1276 case 0x22 /* VEH_SHIP */: v = new (VehicleID(_current_vehicle_id)) Ship(); break;
1277 case 0x23 /* VEH_AIRCRAFT */: v = new (VehicleID(_current_vehicle_id)) Aircraft(); break;
1278 case 0x24 /* VEH_EFFECT */: v = new (VehicleID(_current_vehicle_id)) EffectVehicle(); break;
1279 case 0x26 /* VEH_DISASTER */: v = new (VehicleID(_current_vehicle_id)) DisasterVehicle(); break;
1280 }
1281
1282 if (!LoadChunk(ls, v, vehicle_chunk)) return false;
1283 if (v == nullptr) continue;
1284 v->refit_cap = v->cargo_cap;
1285
1286 SpriteID sprite = v->sprite_cache.sprite_seq.seq[0].sprite;
1287 /* no need to override other sprites */
1288 if (IsInsideMM(sprite, 1460, 1465)) {
1289 sprite += 580; // aircraft smoke puff
1290 } else if (IsInsideMM(sprite, 2096, 2115)) {
1291 sprite += 977; // special effects part 1
1292 } else if (IsInsideMM(sprite, 2396, 2436)) {
1293 sprite += 1305; // special effects part 2
1294 } else if (IsInsideMM(sprite, 2516, 2539)) {
1295 sprite += 1385; // rotor or disaster-related vehicles
1296 }
1297 v->sprite_cache.sprite_seq.seq[0].sprite = sprite;
1298
1299 switch (v->type) {
1300 case VEH_TRAIN: {
1301 static const uint8_t spriteset_rail[] = {
1302 0, 2, 4, 4, 8, 10, 12, 14, 16, 18, 20, 22, 40, 42, 44, 46,
1303 48, 52, 54, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 120, 122,
1304 124, 126, 128, 130, 132, 134, 136, 138, 140
1305 };
1306 if (v->spritenum / 2 >= lengthof(spriteset_rail)) return false;
1307 v->spritenum = spriteset_rail[v->spritenum / 2]; // adjust railway sprite set offset
1308 break;
1309 }
1310
1311 case VEH_ROAD:
1312 if (v->spritenum >= 22) v->spritenum += 12;
1313 break;
1314
1315 case VEH_SHIP:
1316 v->spritenum += 2;
1317
1318 switch (v->spritenum) {
1319 case 2: // oil tanker && cargo type != oil
1320 if (v->cargo_type != 3) v->spritenum = 0; // make it a coal/goods ship
1321 break;
1322 case 4: // passenger ship && cargo type == mail
1323 if (v->cargo_type == 2) v->spritenum = 0; // make it a mail ship
1324 break;
1325 default:
1326 break;
1327 }
1328 break;
1329
1330 default:
1331 break;
1332 }
1333
1334 switch (_old_string_id) {
1335 case 0x0000: break; // empty (invalid vehicles)
1336 case 0x0006: _old_string_id = STR_SV_EMPTY; break; // empty (special vehicles)
1337 case 0x8495: _old_string_id = STR_SV_TRAIN_NAME; break; // "Train X"
1338 case 0x8842: _old_string_id = STR_SV_ROAD_VEHICLE_NAME; break; // "Road Vehicle X"
1339 case 0x8C3B: _old_string_id = STR_SV_SHIP_NAME; break; // "Ship X"
1340 case 0x9047: _old_string_id = STR_SV_AIRCRAFT_NAME; break; // "Aircraft X"
1341 default: _old_string_id += 0x2A00; break; // custom name
1342 }
1343
1344 ls.vehicle_names[_current_vehicle_id] = _old_string_id;
1345 } else {
1346 /* Read the vehicle type and allocate the right vehicle */
1347 switch (ReadByte(ls)) {
1348 default: SlErrorCorrupt("Invalid vehicle type");
1349 case 0x00 /* VEH_INVALID */: v = nullptr; break;
1350 case 0x10 /* VEH_TRAIN */: v = new (VehicleID(_current_vehicle_id)) Train(); break;
1351 case 0x11 /* VEH_ROAD */: v = new (VehicleID(_current_vehicle_id)) RoadVehicle(); break;
1352 case 0x12 /* VEH_SHIP */: v = new (VehicleID(_current_vehicle_id)) Ship(); break;
1353 case 0x13 /* VEH_AIRCRAFT*/: v = new (VehicleID(_current_vehicle_id)) Aircraft(); break;
1354 case 0x14 /* VEH_EFFECT */: v = new (VehicleID(_current_vehicle_id)) EffectVehicle(); break;
1355 case 0x15 /* VEH_DISASTER*/: v = new (VehicleID(_current_vehicle_id)) DisasterVehicle(); break;
1356 }
1357
1358 if (!LoadChunk(ls, v, vehicle_chunk)) return false;
1359 if (v == nullptr) continue;
1360
1361 ls.vehicle_names[_current_vehicle_id] = RemapOldStringID(_old_string_id);
1362
1363 /* This should be consistent, else we have a big problem... */
1364 if (v->index != _current_vehicle_id) {
1365 Debug(oldloader, 0, "Loading failed - vehicle-array is invalid");
1366 return false;
1367 }
1368 }
1369
1370 if (_old_order_ptr != 0 && _old_order_ptr != 0xFFFFFFFF) {
1371 uint max = _savegame_type == SGT_TTO ? 3000 : 5000;
1372 uint old_id = RemapOrderIndex(_old_order_ptr);
1373 if (old_id < max) v->old_orders = old_id + 1;
1374 }
1375 v->current_order.AssignOrder(UnpackOldOrder(_old_order));
1376
1377 if (v->type == VEH_DISASTER) {
1378 DisasterVehicle::From(v)->state = UnpackOldOrder(_old_order).GetDestination().value;
1379 }
1380
1381 v->next = (Vehicle *)(size_t)_old_next_ptr;
1382
1383 if (_cargo_count != 0 && CargoPacket::CanAllocateItem()) {
1384 StationID source = (_cargo_source == 0xFF) ? StationID::Invalid() : StationID{_cargo_source};
1385 TileIndex source_xy = (source != StationID::Invalid()) ? Station::Get(source)->xy : (TileIndex)0;
1386 v->cargo.Append(new CargoPacket(_cargo_count, _cargo_periods, source, source_xy, 0));
1387 }
1388 }
1389
1390 return true;
1391}
1392
1399 bool LoadOldCustomString(LoadgameState &ls, int index)
1400{
1401 /*
1402 * Data is stored in fixed size "cells"; read these completely.
1403 * Validation and conversion to UTF-8 are happening at a later stage.
1404 */
1405 std::string &str = _old_name_array[index];
1406 str.resize(_savegame_type == SGT_TTO ? 24 : 32);
1407 for (auto &c : str) c = ReadByte(ls);
1408
1409 return true;
1410}
1411
1412static const OldChunks sign_chunk[] = {
1413 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
1414 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, x ),
1415 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, y ),
1416 OCL_SVAR( OC_FILE_U16 | OC_VAR_I8, Sign, z ),
1417
1418 OCL_NULL( 6 ),
1419
1420 OCL_END()
1421};
1422
1423static bool LoadOldSign(LoadgameState &ls, int num)
1424{
1425 Sign *si = new (SignID(num)) Sign();
1426 if (!LoadChunk(ls, si, sign_chunk)) return false;
1427
1428 if (_old_string_id != 0) {
1429 if (_savegame_type == SGT_TTO) {
1430 if (_old_string_id != 0x140A) si->name = CopyFromOldName(_old_string_id + 0x2A00);
1431 } else {
1432 si->name = CopyFromOldName(RemapOldStringID(_old_string_id));
1433 }
1434 si->owner = OWNER_NONE;
1435 } else {
1436 delete si;
1437 }
1438
1439 return true;
1440}
1441
1442static const OldChunks engine_chunk[] = {
1443 OCL_SVAR( OC_UINT16, Engine, company_avail ),
1444 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, intro_date ),
1445 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, age ),
1446 OCL_SVAR( OC_UINT16, Engine, reliability ),
1447 OCL_SVAR( OC_UINT16, Engine, reliability_spd_dec ),
1448 OCL_SVAR( OC_UINT16, Engine, reliability_start ),
1449 OCL_SVAR( OC_UINT16, Engine, reliability_max ),
1450 OCL_SVAR( OC_UINT16, Engine, reliability_final ),
1451 OCL_SVAR( OC_UINT16, Engine, duration_phase_1 ),
1452 OCL_SVAR( OC_UINT16, Engine, duration_phase_2 ),
1453 OCL_SVAR( OC_UINT16, Engine, duration_phase_3 ),
1454
1455 OCL_NULL( 1 ), // lifelength
1456 OCL_SVAR( OC_UINT8, Engine, flags ),
1457 OCL_NULL( 1 ), // preview_company_rank
1458 OCL_SVAR( OC_UINT8, Engine, preview_wait ),
1459
1460 OCL_CNULL( OC_TTD, 2 ),
1461
1462 OCL_END()
1463};
1464
1465static bool LoadOldEngine(LoadgameState &ls, int num)
1466{
1467 Engine *e = _savegame_type == SGT_TTO ? &_old_engines[num] : GetTempDataEngine(static_cast<EngineID>(num));
1468 return LoadChunk(ls, e, engine_chunk);
1469}
1470
1471static bool LoadOldEngineName(LoadgameState &ls, int num)
1472{
1473 Engine *e = GetTempDataEngine(static_cast<EngineID>(num));
1474 e->name = CopyFromOldName(RemapOldStringID(ReadUint16(ls)));
1475 return true;
1476}
1477
1478static const OldChunks subsidy_chunk[] = {
1479 OCL_SVAR( OC_UINT8, Subsidy, cargo_type ),
1480 OCL_SVAR( OC_UINT8, Subsidy, remaining ),
1481 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Subsidy, src ),
1482 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Subsidy, dst ),
1483
1484 OCL_END()
1485};
1486
1487static bool LoadOldSubsidy(LoadgameState &ls, int num)
1488{
1489 Subsidy *s = new (SubsidyID(num)) Subsidy();
1490 bool ret = LoadChunk(ls, s, subsidy_chunk);
1491 if (!IsValidCargoType(s->cargo_type)) delete s;
1492 return ret;
1493}
1494
1495static const OldChunks game_difficulty_chunk[] = {
1496 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, max_no_competitors ),
1497 OCL_NULL( 2), // competitor_start_time
1498 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, number_towns ),
1499 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, industry_density ),
1500 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, DifficultySettings, max_loan ),
1501 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, initial_interest ),
1502 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, vehicle_costs ),
1503 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, competitor_speed ),
1504 OCL_NULL( 2), // competitor_intelligence
1505 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, vehicle_breakdowns ),
1506 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, subsidy_multiplier ),
1507 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, construction_cost ),
1508 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, terrain_type ),
1509 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, quantity_sea_lakes ),
1510 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, economy ),
1511 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, line_reverse_mode ),
1512 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, disasters ),
1513 OCL_END()
1514};
1515
1516static bool LoadOldGameDifficulty(LoadgameState &ls, int)
1517{
1518 bool ret = LoadChunk(ls, &_settings_game.difficulty, game_difficulty_chunk);
1519 _settings_game.difficulty.max_loan *= 1000;
1520 return ret;
1521}
1522
1523
1524static bool LoadOldMapPart1(LoadgameState &ls, int)
1525{
1526 if (_savegame_type == SGT_TTO) {
1527 Map::Allocate(OLD_MAP_SIZE, OLD_MAP_SIZE);
1528 }
1529
1530 for (auto t : Map::Iterate()) {
1531 t.m1() = ReadByte(ls);
1532 }
1533 for (auto t : Map::Iterate()) {
1534 t.m2() = ReadByte(ls);
1535 }
1536
1537 if (_savegame_type != SGT_TTO) {
1538 /* old map3 is split into to m3 and m4 */
1539 for (auto t : Map::Iterate()) {
1540 t.m3() = ReadByte(ls);
1541 t.m4() = ReadByte(ls);
1542 }
1543 auto range = Map::Iterate();
1544 for (auto it = range.begin(); it != range.end(); /* nothing. */) {
1545 uint8_t b = ReadByte(ls);
1546 for (int i = 0; i < 8; i += 2, ++it) (*it).m6() = GB(b, i, 2);
1547 }
1548 }
1549
1550 return true;
1551}
1552
1553static bool LoadOldMapPart2(LoadgameState &ls, int)
1554{
1555 for (auto t : Map::Iterate()) {
1556 t.type() = ReadByte(ls);
1557 }
1558 for (auto t : Map::Iterate()) {
1559 t.m5() = ReadByte(ls);
1560 }
1561
1562 return true;
1563}
1564
1565static bool LoadTTDPatchExtraChunks(LoadgameState &ls, int)
1566{
1567 ReadTTDPatchFlags(ls);
1568
1569 Debug(oldloader, 2, "Found {} extra chunk(s)", _old_extra_chunk_nums);
1570
1571 for (int i = 0; i != _old_extra_chunk_nums; i++) {
1572 uint16_t id = ReadUint16(ls);
1573 uint32_t len = ReadUint32(ls);
1574
1575 switch (id) {
1576 /* List of GRFIDs, used in the savegame. 0x8004 is the new ID
1577 * They are saved in a 'GRFID:4 active:1' format, 5 bytes for each entry */
1578 case 0x2:
1579 case 0x8004: {
1580 /* Skip the first element: TTDP hack for the Action D special variables (FFFF0000 01) */
1581 ReadUint32(ls); ReadByte(ls); len -= 5;
1582
1583 ClearGRFConfigList(_grfconfig);
1584 while (len != 0) {
1585 uint32_t grfid = ReadUint32(ls);
1586
1587 if (ReadByte(ls) == 1) {
1588 auto c = std::make_unique<GRFConfig>("TTDP game, no information");
1589 c->ident.grfid = grfid;
1590
1591 Debug(oldloader, 3, "TTDPatch game using GRF file with GRFID {:08X}", std::byteswap(c->ident.grfid));
1592 AppendToGRFConfigList(_grfconfig, std::move(c));
1593 }
1594 len -= 5;
1595 }
1596
1597 /* Append static NewGRF configuration */
1598 AppendStaticGRFConfigs(_grfconfig);
1599 break;
1600 }
1601
1602 /* TTDPatch version and configuration */
1603 case 0x3:
1604 _ttdp_version = ReadUint32(ls);
1605 Debug(oldloader, 3, "Game saved with TTDPatch version {}.{}.{} r{}",
1606 GB(_ttdp_version, 24, 8), GB(_ttdp_version, 20, 4), GB(_ttdp_version, 16, 4), GB(_ttdp_version, 0, 16));
1607 len -= 4;
1608 while (len-- != 0) ReadByte(ls); // skip the configuration
1609 break;
1610
1611 default:
1612 Debug(oldloader, 4, "Skipping unknown extra chunk {}", id);
1613 while (len-- != 0) ReadByte(ls);
1614 break;
1615 }
1616 }
1617
1618 return true;
1619}
1620
1621extern TileIndex _cur_tileloop_tile;
1622extern uint16_t _disaster_delay;
1623extern uint8_t _trees_tick_ctr;
1624extern uint8_t _age_cargo_skip_counter; // From misc_sl.cpp
1625extern uint8_t _old_diff_level;
1626extern uint8_t _old_units;
1627static const OldChunks main_chunk[] = {
1628 OCL_ASSERT( OC_TTD, 0 ),
1629 OCL_ASSERT( OC_TTO, 0 ),
1630 OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &TimerGameCalendar::date ),
1631 OCL_VAR ( OC_UINT16, 1, &TimerGameCalendar::date_fract ),
1632 OCL_NULL( 600 ),
1633 OCL_VAR ( OC_UINT32, 2, &_random.state ),
1634
1635 OCL_ASSERT( OC_TTD, 0x264 ),
1636 OCL_ASSERT( OC_TTO, 0x264 ),
1637
1638 OCL_CCHUNK( OC_TTD, 70, LoadOldTown ),
1639 OCL_CCHUNK( OC_TTO, 80, LoadOldTown ),
1640
1641 OCL_ASSERT( OC_TTD, 0x1C18 ),
1642 OCL_ASSERT( OC_TTO, 0x1AC4 ),
1643
1644 OCL_CCHUNK( OC_TTD, 5000, LoadOldOrder ),
1645 OCL_CCHUNK( OC_TTO, 3000, LoadOldOrder ),
1646
1647 OCL_ASSERT( OC_TTD, 0x4328 ),
1648 OCL_ASSERT( OC_TTO, 0x3234 ),
1649
1650 OCL_CHUNK( 1, LoadOldAnimTileList ),
1651 OCL_NULL( 4 ),
1652
1653 OCL_ASSERT( OC_TTO, 0x3438 ),
1654
1655 OCL_CCHUNK( OC_TTD, 255, LoadOldDepot ),
1656 OCL_CCHUNK( OC_TTO, 252, LoadOldDepot ),
1657
1658 OCL_ASSERT( OC_TTD, 0x4B26 ),
1659 OCL_ASSERT( OC_TTO, 0x3A20 ),
1660
1661 OCL_NULL( 4 ),
1662 OCL_NULL( 2 ),
1663 OCL_NULL( 2 ),
1664
1665 OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_age_cargo_skip_counter ),
1666 OCL_VAR ( OC_FILE_U16 | OC_VAR_U64, 1, &TimerGameTick::counter ),
1667 OCL_VAR ( OC_TILE, 1, &_cur_tileloop_tile ),
1668
1669 OCL_ASSERT( OC_TTO, 0x3A2E ),
1670
1671 OCL_CNULL( OC_TTO, 48 * 6 ),
1672 OCL_CNULL( OC_TTD, 49 * 6 ),
1673
1674 OCL_ASSERT( OC_TTO, 0x3B4E ),
1675
1676 OCL_CNULL( OC_TTO, 11 * 8 ),
1677 OCL_CNULL( OC_TTD, 12 * 8 ),
1678
1679 OCL_ASSERT( OC_TTD, 0x4CBA ),
1680 OCL_ASSERT( OC_TTO, 0x3BA6 ),
1681
1682 OCL_CHUNK( 1, LoadOldMapPart1 ),
1683
1684 OCL_ASSERT( OC_TTD, 0x48CBA ),
1685 OCL_ASSERT( OC_TTO, 0x23BA6 ),
1686
1687 OCL_CCHUNK( OC_TTD, 250, LoadOldStation ),
1688 OCL_CCHUNK( OC_TTO, 200, LoadOldStation ),
1689
1690 OCL_ASSERT( OC_TTO, 0x29E16 ),
1691
1692 OCL_CCHUNK( OC_TTD, 90, LoadOldIndustry ),
1693 OCL_CCHUNK( OC_TTO, 100, LoadOldIndustry ),
1694
1695 OCL_ASSERT( OC_TTO, 0x2ADB6 ),
1696
1697 OCL_CHUNK( 8, LoadOldCompany ),
1698
1699 OCL_ASSERT( OC_TTD, 0x547F2 ),
1700 OCL_ASSERT( OC_TTO, 0x2C746 ),
1701
1702 OCL_CCHUNK( OC_TTD, 850, LoadOldVehicle ),
1703 OCL_CCHUNK( OC_TTO, 800, LoadOldVehicle ),
1704
1705 OCL_ASSERT( OC_TTD, 0x6F0F2 ),
1706 OCL_ASSERT( OC_TTO, 0x45746 ),
1707
1708 OCL_CCHUNK( OC_TTD, 500, LoadOldCustomString ),
1709 OCL_CCHUNK( OC_TTO, 200, LoadOldCustomString ),
1710
1711 OCL_ASSERT( OC_TTO, 0x46A06 ),
1712
1713 OCL_NULL( 0x2000 ),
1714
1715 OCL_CHUNK( 40, LoadOldSign ),
1716
1717 OCL_ASSERT( OC_TTO, 0x48C36 ),
1718
1719 OCL_CCHUNK( OC_TTD, 256, LoadOldEngine ),
1720 OCL_CCHUNK( OC_TTO, 103, LoadOldEngine ),
1721
1722 OCL_ASSERT( OC_TTO, 0x496AC ),
1723
1724 OCL_NULL ( 2 ), // _vehicle_id_ctr_day
1725
1726 OCL_CHUNK( 8, LoadOldSubsidy ),
1727
1728 OCL_ASSERT( OC_TTO, 0x496CE ),
1729
1730 OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_new_competitor_timeout.period.value ),
1731
1732 OCL_CNULL( OC_TTO, 2 ),
1733
1734 OCL_VAR ( OC_FILE_I16 | OC_VAR_I32, 1, &_saved_scrollpos_x ),
1735 OCL_VAR ( OC_FILE_I16 | OC_VAR_I32, 1, &_saved_scrollpos_y ),
1736 OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_saved_scrollpos_zoom ),
1737
1738 OCL_NULL( 4 ),
1739 OCL_VAR ( OC_FILE_U32 | OC_VAR_I64, 1, &_economy.old_max_loan_unround ),
1740 OCL_VAR ( OC_INT16, 1, &_economy.fluct ),
1741
1742 OCL_VAR ( OC_UINT16, 1, &_disaster_delay ),
1743
1744 OCL_ASSERT( OC_TTO, 0x496E4 ),
1745
1746 OCL_CNULL( OC_TTD, 144 ),
1747
1748 OCL_CCHUNK( OC_TTD, 256, LoadOldEngineName ),
1749
1750 OCL_CNULL( OC_TTD, 144 ),
1751 OCL_NULL( 2 ),
1752 OCL_NULL( 1 ),
1753
1754 OCL_VAR ( OC_UINT8, 1, &_settings_game.locale.currency ),
1755 OCL_VAR ( OC_UINT8, 1, &_old_units ),
1756 OCL_VAR ( OC_FILE_U8 | OC_VAR_U32, 1, &_cur_company_tick_index ),
1757
1758 OCL_NULL( 2 ),
1759 OCL_NULL( 8 ),
1760
1761 OCL_VAR ( OC_UINT8, 1, &_economy.infl_amount ),
1762 OCL_VAR ( OC_UINT8, 1, &_economy.infl_amount_pr ),
1763 OCL_VAR ( OC_UINT8, 1, &_economy.interest_rate ),
1764 OCL_NULL( 1 ), // available airports
1765 OCL_VAR ( OC_UINT8, 1, &_settings_game.vehicle.road_side ),
1766 OCL_VAR ( OC_UINT8, 1, &_settings_game.game_creation.town_name ),
1767
1768 OCL_CHUNK( 1, LoadOldGameDifficulty ),
1769
1770 OCL_ASSERT( OC_TTD, 0x77130 ),
1771
1772 OCL_VAR ( OC_UINT8, 1, &_old_diff_level ),
1773
1774 OCL_VAR ( OC_TTD | OC_UINT8, 1, &_settings_game.game_creation.landscape ),
1775 OCL_VAR ( OC_TTD | OC_UINT8, 1, &_trees_tick_ctr ),
1776
1777 OCL_CNULL( OC_TTD, 1 ),
1778 OCL_VAR ( OC_TTD | OC_UINT8, 1, &_settings_game.game_creation.snow_line_height ),
1779
1780 OCL_CNULL( OC_TTD, 32 ),
1781 OCL_CNULL( OC_TTD, 36 ),
1782
1783 OCL_ASSERT( OC_TTD, 0x77179 ),
1784 OCL_ASSERT( OC_TTO, 0x4971D ),
1785
1786 OCL_CHUNK( 1, LoadOldMapPart2 ),
1787
1788 OCL_ASSERT( OC_TTD, 0x97179 ),
1789 OCL_ASSERT( OC_TTO, 0x6971D ),
1790
1791 /* Below any (if available) extra chunks from TTDPatch can follow */
1792 OCL_CHUNK(1, LoadTTDPatchExtraChunks),
1793
1794 OCL_END()
1795};
1796
1797bool LoadTTDMain(LoadgameState &ls)
1798{
1799 Debug(oldloader, 3, "Reading main chunk...");
1800
1801 _read_ttdpatch_flags = false;
1802
1803 /* Load the biggest chunk */
1804 if (!LoadChunk(ls, nullptr, main_chunk)) {
1805 Debug(oldloader, 0, "Loading failed");
1806 return false;
1807 }
1808
1809 Debug(oldloader, 3, "Done, converting game data...");
1810
1811 FixTTDMapArray();
1812 FixTTDDepots();
1813
1814 /* Fix some general stuff */
1815 if (to_underlying(_settings_game.game_creation.landscape) >= NUM_LANDSCAPE) _settings_game.game_creation.landscape = LandscapeType::Temperate;
1816
1817 /* Fix the game to be compatible with OpenTTD */
1818 FixOldTowns();
1819 FixOldVehicles(ls);
1820
1821 /* We have a new difficulty setting */
1822 _settings_game.difficulty.town_council_tolerance = Clamp(_old_diff_level, 0, 2);
1823
1824 Debug(oldloader, 3, "Finished converting game data");
1825 Debug(oldloader, 1, "TTD(Patch) savegame successfully converted");
1826
1827 return true;
1828}
1829
1830bool LoadTTOMain(LoadgameState &ls)
1831{
1832 Debug(oldloader, 3, "Reading main chunk...");
1833
1834 _read_ttdpatch_flags = false;
1835
1836 std::array<uint8_t, 103 * sizeof(Engine)> engines; // we don't want to call Engine constructor here
1837 _old_engines = (Engine *)engines.data();
1838
1839 /* Load the biggest chunk */
1840 if (!LoadChunk(ls, nullptr, main_chunk)) {
1841 Debug(oldloader, 0, "Loading failed");
1842 return false;
1843 }
1844 Debug(oldloader, 3, "Done, converting game data...");
1845
1846 if (_settings_game.game_creation.town_name != 0) _settings_game.game_creation.town_name++;
1847
1848 _settings_game.game_creation.landscape = LandscapeType::Temperate;
1849 _trees_tick_ctr = 0xFF;
1850
1851 if (!FixTTOMapArray() || !FixTTOEngines()) {
1852 Debug(oldloader, 0, "Conversion failed");
1853 return false;
1854 }
1855
1856 FixOldTowns();
1857 FixOldVehicles(ls);
1858 FixTTOCompanies();
1859
1860 /* We have a new difficulty setting */
1861 _settings_game.difficulty.town_council_tolerance = Clamp(_old_diff_level, 0, 2);
1862
1863 /* SVXConverter about cargo payment rates correction:
1864 * "increase them to compensate for the faster time advance in TTD compared to TTO
1865 * which otherwise would cause much less income while the annual running costs of
1866 * the vehicles stay the same" */
1867 _economy.inflation_payment = std::min(_economy.inflation_payment * 124 / 74, MAX_INFLATION);
1868
1869 Debug(oldloader, 3, "Finished converting game data");
1870 Debug(oldloader, 1, "TTO savegame successfully converted");
1871
1872 return true;
1873}
AirportBlock
AirportBlock
Movement Blocks on Airports blocks (eg_airport_flags).
Definition airport.h:90
SB
constexpr T SB(T &x, const uint8_t s, const uint8_t n, const U d)
Set n bits in x starting at bit s to d.
Definition bitmath_func.hpp:58
GB
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
Definition bitmath_func.hpp:32
SetBit
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
Definition bitmath_func.hpp:121
HasBit
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
Definition bitmath_func.hpp:103
ClrBit
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
Definition bitmath_func.hpp:139
IsValidCargoType
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:104
NUM_CARGO
static const CargoType NUM_CARGO
Maximum number of cargo types in a game.
Definition cargo_type.h:73
TAE_FOOD
@ TAE_FOOD
Cargo behaves food/fizzy-drinks-like.
Definition cargotype.h:29
TAE_WATER
@ TAE_WATER
Cargo behaves water-like.
Definition cargotype.h:28
BaseBitSet::Test
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Definition base_bitset_type.hpp:141
BaseBitSet::Set
constexpr Timpl & Set()
Set all bits.
Definition base_bitset_type.hpp:40
CompanyMask
Definition company_type.h:43
Engine
Definition engine_base.h:38
Engine::reliability_spd_dec
uint16_t reliability_spd_dec
Speed of reliability decay between services (per day).
Definition engine_base.h:50
Engine::reliability_start
uint16_t reliability_start
Initial reliability of the engine.
Definition engine_base.h:51
Engine::intro_date
TimerGameCalendar::Date intro_date
Date of introduction of the engine.
Definition engine_base.h:46
Engine::flags
EngineFlags flags
Flags of the engine.
Definition engine_base.h:57
Engine::company_avail
CompanyMask company_avail
Bit for each company whether the engine is available for that company.
Definition engine_base.h:40
Engine::reliability_max
uint16_t reliability_max
Maximal reliability of the engine.
Definition engine_base.h:52
Engine::reliability_final
uint16_t reliability_final
Final reliability of the engine.
Definition engine_base.h:53
Engine::preview_company
CompanyID preview_company
Company which is currently being offered a preview CompanyID::Invalid() means no company.
Definition engine_base.h:59
Engine::duration_phase_3
uint16_t duration_phase_3
Third reliability phase in months, decaying to reliability_final.
Definition engine_base.h:56
Engine::duration_phase_2
uint16_t duration_phase_2
Second reliability phase in months, keeping reliability_max.
Definition engine_base.h:55
Engine::preview_wait
uint8_t preview_wait
Daily countdown timer for timeout of offering the engine to the preview_company company.
Definition engine_base.h:60
Engine::reliability
uint16_t reliability
Current reliability of the engine.
Definition engine_base.h:49
Engine::preview_asked
CompanyMask preview_asked
Bit for each company which has already been offered a preview.
Definition engine_base.h:42
Engine::age
int32_t age
Age of the engine in months.
Definition engine_base.h:47
Engine::name
std::string name
Custom name of engine.
Definition engine_base.h:44
Engine::duration_phase_1
uint16_t duration_phase_1
First reliability phase in months, increasing reliability from reliability_start to reliability_max.
Definition engine_base.h:54
StationCargoList::Append
void Append(CargoPacket *cp, StationID next)
Appends the given cargo packet to the range of packets with the same next station.
Definition cargopacket.cpp:684
Tile
Wrapper class to abstract away the way the tiles are stored.
Definition map_func.h:25
Tile::m5
uint8_t & m5()
General purpose.
Definition map_func.h:161
Tile::m4
uint8_t & m4()
General purpose.
Definition map_func.h:149
Tile::m3
uint8_t & m3()
General purpose.
Definition map_func.h:137
TimeoutTimer
A timeout timer will fire once after the interval.
Definition timer.h:116
TimerGameCalendar::ConvertYMDToDate
static Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
Definition timer_game_calendar.cpp:55
TimerGameCalendar::ConvertDateToYMD
static YearMonthDay ConvertDateToYMD(Date date)
Converts a Date to a Year, Month & Day.
Definition timer_game_calendar.cpp:42
TimerGameCalendar::date
static Date date
Current date in days (day counter).
Definition timer_game_calendar.h:33
TimerGameCalendar::date_fract
static DateFract date_fract
Fractional part of the day.
Definition timer_game_calendar.h:34
TimerGameConst< struct Economy >::ORIGINAL_BASE_YEAR
static constexpr TimerGame< struct Economy >::Year ORIGINAL_BASE_YEAR
The minimum starting year/base year of the original TTD.
Definition timer_game_common.h:163
TimerGameConst< struct Calendar >::DAYS_TILL_ORIGINAL_BASE_YEAR
static constexpr TimerGame< struct Calendar >::Date DAYS_TILL_ORIGINAL_BASE_YEAR
The date of the first day of the original base year.
Definition timer_game_common.h:184
TimerGameEconomy::date
static Date date
Current date in days (day counter).
Definition timer_game_economy.h:38
TimerGameEconomy::ConvertDateToYMD
static YearMonthDay ConvertDateToYMD(Date date)
Converts a Date to a Year, Month & Day.
Definition timer_game_economy.cpp:47
TimerGameTick::counter
static TickCounter counter
Monotonic counter, in ticks, since start of game.
Definition timer_game_tick.h:60
VehicleCargoList::Append
void Append(CargoPacket *cp, MoveToAction action=MTA_KEEP)
Appends the given cargo packet.
Definition cargopacket.cpp:255
CalculateCompanyValue
Money CalculateCompanyValue(const Company *c, bool including_loan=true)
Calculate the value of the company.
Definition economy.cpp:150
_cur_company_tick_index
uint _cur_company_tick_index
used to generate a name for one company that doesn't have a name yet per tick
Definition company_cmd.cpp:59
_new_competitor_timeout
TimeoutTimer< TimerGameTick > _new_competitor_timeout({ TimerGameTick::Priority::COMPETITOR_TIMEOUT, 0 }, []() { if(_game_mode==GM_MENU||!AI::CanStartNew()) return;if(_networking &&Company::GetNumItems() >=_settings_client.network.max_companies) return;if(_settings_game.difficulty.competitors_interval==0) return;uint8_t n=0;for(const Company *c :Company::Iterate()) { if(c->is_ai) n++;} if(n >=_settings_game.difficulty.max_no_competitors) return;Command< CMD_COMPANY_CTRL >::Post(CCA_NEW_AI, CompanyID::Invalid(), CRR_NONE, INVALID_CLIENT_ID);})
Start a new competitor company if possible.
_company_colours
TypedIndexContainer< std::array< Colours, MAX_COMPANIES >, CompanyID > _company_colours
NOSAVE: can be determined from company structs.
Definition company_cmd.cpp:57
OWNER_NONE
static constexpr Owner OWNER_NONE
The tile has no ownership.
Definition company_type.h:26
OWNER_WATER
static constexpr Owner OWNER_WATER
The tile/execution is done by "water".
Definition company_type.h:27
Debug
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Definition debug.h:37
GetDepotIndex
DepotID GetDepotIndex(Tile t)
Get the index of which depot is attached to the tile.
Definition depot_map.h:53
IsDepotTile
bool IsDepotTile(Tile tile)
Is the given tile a tile with a depot on it?
Definition depot_map.h:42
DepotID
PoolID< uint16_t, struct DepotIDTag, 64000, 0xFFFF > DepotID
Type for the unique identifier of depots.
Definition depot_type.h:15
MAX_INFLATION
static const uint64_t MAX_INFLATION
Maximum inflation (including fractional part) without causing overflows in int64_t price computations...
Definition economy_type.h:225
StartupOneEngine
void StartupOneEngine(Engine *e, const TimerGameCalendar::YearMonthDay &aging_ymd, uint32_t seed)
Start/initialise one engine.
Definition engine.cpp:717
CalcEngineReliability
void CalcEngineReliability(Engine *e, bool new_month)
Update Engine::reliability and (if needed) update the engine GUIs.
Definition engine.cpp:646
EngineFlag::Available
@ Available
This vehicle is available to everyone.
to_underlying
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23)
Definition enum_type.hpp:17
_ttdp_version
uint32_t _ttdp_version
version of TTDP savegame (if applicable)
Definition saveload.cpp:80
_savegame_type
SavegameType _savegame_type
type of savegame we are loading
Definition saveload.cpp:77
SpriteID
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
BorderFlag::Random
@ Random
Randomise borders.
TileXY
static TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition map_func.h:385
IsInsideBS
constexpr bool IsInsideBS(const T x, const size_t base, const size_t size)
Checks if a value is between a window started at some base point.
Definition math_func.hpp:252
IsInsideMM
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
Definition math_func.hpp:267
Clamp
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
_grfconfig
GRFConfigList _grfconfig
First item in list of current GRF set up.
Definition newgrf_config.cpp:154
AppendStaticGRFConfigs
void AppendStaticGRFConfigs(GRFConfigList &dst)
Appends the static GRFs to a list of GRFs.
Definition newgrf_config.cpp:388
AppendToGRFConfigList
void AppendToGRFConfigList(GRFConfigList &dst, std::unique_ptr< GRFConfig > &&el)
Appends an element to a list of GRFs.
Definition newgrf_config.cpp:399
ClearGRFConfigList
void ClearGRFConfigList(GRFConfigList &config)
Clear a GRF Config list, freeing all nodes.
Definition newgrf_config.cpp:324
Invalid
@ Invalid
GRF is unusable with this version of OpenTTD.
Definition newgrf_config.h:28
LoadChunk
bool LoadChunk(LoadgameState &ls, void *base, const OldChunks *chunks)
Loads a chunk from the old savegame.
Definition oldloader.cpp:120
ReadByte
uint8_t ReadByte(LoadgameState &ls)
Reads a byte from the buffer and decompress if needed.
Definition oldloader.cpp:86
oldloader.h
Declarations of structures and functions used in loader of old savegames.
OC_TTO
@ OC_TTO
-//- TTO (default is neither of these)
Definition oldloader.h:46
OC_TTD
@ OC_TTD
chunk is valid ONLY for TTD savegames
Definition oldloader.h:45
_old_name_array
std::unique_ptr< std::string[]> _old_name_array
Location to load the old names to.
Definition strings_sl.cpp:50
LoadOldCustomString
bool LoadOldCustomString(LoadgameState &ls, int index)
Read a single string from the savegame.
Definition oldloader_sl.cpp:1399
FixOldVehicles
void FixOldVehicles(LoadgameState &ls)
Convert the old style vehicles into something that resembles the old new style savegames.
Definition oldloader_sl.cpp:160
LoadOldVehicle
bool LoadOldVehicle(LoadgameState &ls, int num)
Load the vehicles of an old style savegame.
Definition oldloader_sl.cpp:1258
FixTTDDepots
static void FixTTDDepots()
Definition oldloader_sl.cpp:101
_disaster_delay
uint16_t _disaster_delay
Delay counter for considering the next disaster.
Definition disaster_vehicle.cpp:57
_read_ttdpatch_flags
static bool _read_ttdpatch_flags
Have we (tried to) read TTDPatch extra flags?
Definition oldloader_sl.cpp:42
RemapTTOColour
static Colours RemapTTOColour(Colours tto)
Definition oldloader_sl.cpp:456
_old_extra_chunk_nums
static uint16_t _old_extra_chunk_nums
Number of extra TTDPatch chunks.
Definition oldloader_sl.cpp:43
FixTTOEngines
static bool FixTTOEngines()
Definition oldloader_sl.cpp:340
_age_cargo_skip_counter
uint8_t _age_cargo_skip_counter
Skip aging of cargo? Used before savegame version 162.
Definition misc_sl.cpp:79
_trees_tick_ctr
uint8_t _trees_tick_ctr
Determines when to consider building more trees.
Definition tree_cmd.cpp:45
_animated_tiles
std::vector< TileIndex > _animated_tiles
The table/list with animated tiles.
Definition animated_tile.cpp:20
GetOldOrder
OldOrderSaveLoadItem * GetOldOrder(size_t pool_index)
Get a pointer to an old order with the given reference index.
Definition order_sl.cpp:125
AllocateOldOrder
OldOrderSaveLoadItem & AllocateOldOrder(size_t pool_index)
Allocate an old order with the given pool index.
Definition order_sl.cpp:137
UnpackOldOrder
Order UnpackOldOrder(uint16_t packed)
Unpacks a order from savegames made with TTD(Patch)
Definition order_sl.cpp:95
_random
Randomizer _random
Random used in the game state calculations.
Definition random_func.cpp:36
RVS_IN_DT_ROAD_STOP
@ RVS_IN_DT_ROAD_STOP
The vehicle is in a drive-through road stop.
Definition roadveh.h:46
RVSB_IN_DEPOT
@ RVSB_IN_DEPOT
The vehicle is in a depot.
Definition roadveh.h:38
RVSB_WORMHOLE
@ RVSB_WORMHOLE
The vehicle is in a tunnel and/or bridge.
Definition roadveh.h:39
SlErrorCorrupt
void SlErrorCorrupt(const std::string &msg)
Error handler for corrupt savegames.
Definition saveload.cpp:369
SGT_TTDP2
@ SGT_TTDP2
TTDP savegame in new format (data at SE border)
Definition saveload.h:441
SGT_TTO
@ SGT_TTO
TTO savegame.
Definition saveload.h:443
SGT_TTDP1
@ SGT_TTDP1
TTDP savegame ( -//- ) (data at NW border)
Definition saveload.h:440
saveload_internal.h
Declaration of functions used in more save/load files.
RemapOldStringID
StringID RemapOldStringID(StringID s)
Remap a string ID from the old format to the new format.
Definition strings_sl.cpp:28
CopyFromOldName
std::string CopyFromOldName(StringID id)
Copy and convert old custom names to UTF-8.
Definition strings_sl.cpp:59
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
SignID
PoolID< uint16_t, struct SignIDTag, 64000, 0xFFFF > SignID
The type of the IDs of signs.
Definition signs_type.h:16
lengthof
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:271
SPECSTR_PRESIDENT_NAME
static constexpr StringID SPECSTR_PRESIDENT_NAME
Special string for the president's name.
Definition strings_type.h:73
SPECSTR_TOWNNAME_START
static constexpr StringID SPECSTR_TOWNNAME_START
Special strings for town names.
Definition strings_type.h:64
Aircraft
Aircraft, helicopters, rotors and their shadows belong to this class.
Definition aircraft.h:72
Airport::blocks
AirportBlocks blocks
stores which blocks on the airport are taken. was 16 bit earlier on, then 32
Definition station_base.h:354
Airport::type
uint8_t type
Type of this airport,.
Definition station_base.h:355
BaseStation::string_id
StringID string_id
Default name (town area) of station.
Definition base_station_base.h:64
BaseStation::xy
TileIndex xy
Base tile of the station.
Definition base_station_base.h:59
BaseStation::town
Town * town
The town this station is associated with.
Definition base_station_base.h:67
BaseVehicle::type
VehicleType type
Type of vehicle.
Definition vehicle_type.h:51
CargoPacket
Container for cargo from the same location and time.
Definition cargopacket.h:41
CompanyEconomyEntry
Statistics about the economy.
Definition company_base.h:24
CompanyEconomyEntry::income
Money income
The amount of income.
Definition company_base.h:25
CompanyEconomyEntry::expenses
Money expenses
The amount of expenses.
Definition company_base.h:26
CompanyManagerFace::bits
uint32_t bits
Company manager face bits, meaning is dependent on style.
Definition company_type.h:55
CompanyProperties::is_ai
bool is_ai
If true, the company is (also) controlled by the computer (a NoAI program).
Definition company_base.h:114
CompanyProperties::name_1
StringID name_1
Name of the company if the user did not change it.
Definition company_base.h:73
CompanyProperties::current_loan
Money current_loan
Amount of money borrowed from the bank.
Definition company_base.h:86
CompanyProperties::inaugurated_year
TimerGameEconomy::Year inaugurated_year
Economy year of starting the company.
Definition company_base.h:96
CompanyProperties::cur_economy
CompanyEconomyEntry cur_economy
Economic data of the company of this quarter.
Definition company_base.h:117
CompanyProperties::colour
Colours colour
Company colour.
Definition company_base.h:89
CompanyProperties::old_economy
std::array< CompanyEconomyEntry, MAX_HISTORY_QUARTERS > old_economy
Economic data of the company of the last MAX_HISTORY_QUARTERS quarters.
Definition company_base.h:118
CompanyProperties::face
CompanyManagerFace face
Face description of the president.
Definition company_base.h:82
CompanyProperties::yearly_expenses
std::array< Expenses, 3 > yearly_expenses
Expenses of the company for the last three years.
Definition company_base.h:116
CompanyProperties::president_name_1
StringID president_name_1
Name of the president if the user did not change it.
Definition company_base.h:76
CompanyProperties::money
Money money
Money owned by the company.
Definition company_base.h:84
Company
Definition company_base.h:127
Depot
Definition depot_base.h:20
DifficultySettings
Settings related to the difficulty of the game.
Definition settings_type.h:121
DifficultySettings::max_loan
uint32_t max_loan
the maximum initial loan
Definition settings_type.h:129
DifficultySettings::town_council_tolerance
uint8_t town_council_tolerance
minimum required town ratings to be allowed to demolish stuff
Definition settings_type.h:142
DisasterVehicle
Disasters, like submarines, skyrangers and their shadows, belong to this class.
Definition disaster_vehicle.h:37
DisasterVehicle::state
uint16_t state
Action stage of the disaster vehicle.
Definition disaster_vehicle.h:41
Economy::inflation_payment
uint64_t inflation_payment
Cumulated inflation of cargo payment since game start; 16 bit fractional part.
Definition economy_type.h:53
Economy::infl_amount
uint8_t infl_amount
inflation amount
Definition economy_type.h:48
Economy::old_max_loan_unround
Money old_max_loan_unround
Old: Unrounded max loan.
Definition economy_type.h:56
Economy::fluct
int16_t fluct
Economy fluctuation status.
Definition economy_type.h:46
Economy::infl_amount_pr
uint8_t infl_amount_pr
inflation rate for payment rates
Definition economy_type.h:49
Economy::interest_rate
uint8_t interest_rate
Interest.
Definition economy_type.h:47
EffectVehicle
A special vehicle is one of the following:
Definition effectvehicle_base.h:24
EngineInfo::climates
LandscapeTypes climates
Climates supported by the engine.
Definition engine_type.h:204
GameCreationSettings::landscape
LandscapeType landscape
the landscape we're currently in
Definition settings_type.h:395
GameCreationSettings::snow_line_height
uint8_t snow_line_height
the configured snow line height (deduced from "snow_coverage")
Definition settings_type.h:386
GameCreationSettings::town_name
uint8_t town_name
the town name generator used for town names
Definition settings_type.h:394
GameSettings::locale
LocaleSettings locale
settings related to used currency/unit system in the current game
Definition settings_type.h:645
GameSettings::difficulty
DifficultySettings difficulty
settings related to the difficulty
Definition settings_type.h:633
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition settings_type.h:634
GameSettings::vehicle
VehicleSettings vehicle
options for vehicles
Definition settings_type.h:641
GoodsEntry::GoodsEntryData::cargo
StationCargoList cargo
The cargo packets of cargo waiting in this station.
Definition station_base.h:213
GoodsEntry
Stores station stats for a single cargo.
Definition station_base.h:167
GoodsEntry::status
States status
Status of this cargo, see State.
Definition station_base.h:226
GoodsEntry::State::Acceptance
@ Acceptance
Set when the station accepts the cargo currently for final deliveries.
GoodsEntry::State::Rating
@ Rating
This indicates whether a cargo has a rating at the station.
GoodsEntry::GetOrCreateData
GoodsEntryData & GetOrCreateData()
Get optional cargo packet/flow data.
Definition station_base.h:338
Industry
Defines the internal data of a functional industry.
Definition industry.h:62
Industry::type
IndustryType type
type of industry.
Definition industry.h:115
Industry::random_colour
Colours random_colour
randomized colour of the industry, for display purpose
Definition industry.h:117
Industry::last_prod_year
TimerGameEconomy::Year last_prod_year
last economy year of production
Definition industry.h:118
Industry::produced
ProducedCargoes produced
produced cargo slots
Definition industry.h:110
Industry::town
Town * town
Nearest town.
Definition industry.h:107
Industry::accepted
AcceptedCargoes accepted
accepted cargo slots
Definition industry.h:111
Industry::location
TileArea location
Location of the industry.
Definition industry.h:106
Industry::industries
static std::array< FlatSet< IndustryID >, NUM_INDUSTRYTYPES > industries
List of industries of each type.
Definition industry.h:276
LoadgameState
Definition oldloader.h:19
LoadgameState::vehicle_multiplier
uint8_t vehicle_multiplier
TTDPatch vehicle multiplier.
Definition oldloader.h:33
LocaleSettings::currency
uint8_t currency
currency we currently use
Definition settings_type.h:295
Map
Size related data of the map.
Definition map_func.h:206
Map::Iterate
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
Definition map_func.h:375
Map::MaxY
static uint MaxY()
Gets the maximum Y coordinate within the map, including MP_VOID.
Definition map_func.h:308
Map::Allocate
static void Allocate(uint size_x, uint size_y)
(Re)allocates a map with the given dimension
Definition map.cpp:37
Map::Size
static uint Size()
Get the size of the map.
Definition map_func.h:290
MutableSpriteCache::sprite_seq
VehicleSpriteSeq sprite_seq
Vehicle appearance.
Definition vehicle_base.h:162
OldChunks
Definition oldloader.h:84
OldOrderSaveLoadItem
Compatibility struct to allow saveload of pool-based orders.
Definition order_base.h:258
OldOrderSaveLoadItem::order
Order order
The order data.
Definition order_base.h:261
OldOrderSaveLoadItem::next
uint32_t next
The next order index (1-based).
Definition order_base.h:260
Order::GetDestination
DestinationID GetDestination() const
Gets the destination of this order.
Definition order_base.h:99
Order::IsType
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition order_base.h:66
Order::AssignOrder
void AssignOrder(const Order &other)
Assign data to an order (from another order) This function makes sure that the index is maintained co...
Definition order_cmd.cpp:235
OrthogonalTileArea::tile
TileIndex tile
The base tile of the area.
Definition tilearea_type.h:19
PoolID< uint16_t, struct EngineIDTag, 64000, 0xFFFF >
Pool::PoolItem<&_depot_pool >::Iterate
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition pool_type.hpp:436
Pool::PoolItem<&_company_pool >::Get
static Titem * Get(auto index)
Returns Titem with given index.
Definition pool_type.hpp:387
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition pool_type.hpp:286
Pool::PoolItem<&_cargopacket_pool >::CanAllocateItem
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
Definition pool_type.hpp:357
Pool::PoolItem<&_vehicle_pool >::GetIfValid
static Titem * GetIfValid(auto index)
Returns Titem with given index.
Definition pool_type.hpp:398
Randomizer::state
uint32_t state[2]
The state of the randomizer.
Definition random_func.hpp:29
RoadVehicle
Buses, trucks and trams belong to this class.
Definition roadveh.h:98
RoadVehicle::state
uint8_t state
Definition roadveh.h:100
Ship
All ships have this type.
Definition ship.h:32
Sign
Definition signs_base.h:21
SpecializedStation< Station, false >::Get
static Station * Get(auto index)
Gets station with given index.
Definition base_station_base.h:248
SpecializedVehicle::From
static T * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
Definition vehicle_base.h:1134
Station
Station data structure.
Definition station_base.h:500
Station::goods
std::array< GoodsEntry, NUM_CARGO > goods
Goods at this station.
Definition station_base.h:529
Station::airport
Airport airport
Tile area the airport covers.
Definition station_base.h:514
StrongType::Typedef
Templated helper to make a type-safe 'typedef' representing a single POD value.
Definition strong_typedef_type.hpp:130
Subsidy
Struct about subsidies, offered and awarded.
Definition subsidy_base.h:23
Subsidy::cargo_type
CargoType cargo_type
Cargo type involved in this subsidy, INVALID_CARGO for invalid subsidy.
Definition subsidy_base.h:24
Town
Town data structure.
Definition town.h:63
Town::xy
TileIndex xy
town center tile
Definition town.h:64
Town::supplied
SuppliedCargoes supplied
Cargo statistics about supplied cargo.
Definition town.h:109
Train
'Train' is either a loco or a wagon.
Definition train.h:91
VehicleSettings::road_side
uint8_t road_side
the side of the road vehicles drive on
Definition settings_type.h:535
Vehicle
Vehicle data structure.
Definition vehicle_base.h:205
Vehicle::cargo
VehicleCargoList cargo
The cargo this vehicle is carrying.
Definition vehicle_base.h:296
Vehicle::cargo_cap
uint16_t cargo_cap
total capacity
Definition vehicle_base.h:299
Vehicle::cargo_type
CargoType cargo_type
type of cargo this vehicle is carrying
Definition vehicle_base.h:297
Vehicle::current_order
Order current_order
The current order (+ status, like: loading)
Definition vehicle_base.h:311
Vehicle::refit_cap
uint16_t refit_cap
Capacity left over from before last refit.
Definition vehicle_base.h:300
Vehicle::old_orders
uint32_t old_orders
Only used during conversion of old save games.
Definition vehicle_base.h:315
Vehicle::spritenum
uint8_t spritenum
currently displayed sprite index 0xfd == custom sprite, 0xfe == custom second head sprite 0xff == res...
Definition vehicle_base.h:276
Vehicle::next
Vehicle * next
pointer to the next vehicle in the chain
Definition vehicle_base.h:209
Vehicle::sprite_cache
MutableSpriteCache sprite_cache
Cache of sprites and values related to recalculating them, see MutableSpriteCache.
Definition vehicle_base.h:323
Vehicle::tile
TileIndex tile
Current tile index.
Definition vehicle_base.h:225
SubsidyID
PoolID< uint16_t, struct SubsidyIDTag, 256, 0xFFFF > SubsidyID
ID of a subsidy.
Definition subsidy_type.h:24
IsTileType
static bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
SetTileType
void SetTileType(Tile tile, TileType type)
Set the type of a tile.
Definition tile_map.h:131
SetTileOwner
void SetTileOwner(Tile tile, Owner owner)
Sets the owner of a tile.
Definition tile_map.h:198
GetTileType
static TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
INVALID_TILE
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95
TileIndex
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:87
TileType
TileType
The different types of tiles.
Definition tile_type.h:47
MP_TREES
@ MP_TREES
Tile got trees.
Definition tile_type.h:52
MP_ROAD
@ MP_ROAD
A tile with road (or tram tracks)
Definition tile_type.h:50
MP_STATION
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
MP_TUNNELBRIDGE
@ MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition tile_type.h:57
MP_CLEAR
@ MP_CLEAR
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition tile_type.h:48
MP_HOUSE
@ MP_HOUSE
A house by a town.
Definition tile_type.h:51
MP_WATER
@ MP_WATER
Water tile.
Definition tile_type.h:54
MP_RAILWAY
@ MP_RAILWAY
A railway.
Definition tile_type.h:49
MP_INDUSTRY
@ MP_INDUSTRY
Part of an industry.
Definition tile_type.h:56
MP_VOID
@ MP_VOID
Invisible tiles at the SW and SE border.
Definition tile_type.h:55
MP_OBJECT
@ MP_OBJECT
Contains objects such as transmitters and owned land.
Definition tile_type.h:58
CalcClosestTownFromTile
Town * CalcClosestTownFromTile(TileIndex tile, uint threshold=UINT_MAX)
Return the town closest to the given tile within threshold.
Definition town_cmd.cpp:3934
IsCompanyBuildableVehicleType
bool IsCompanyBuildableVehicleType(VehicleType type)
Is the given vehicle type buildable by a company?
Definition vehicle_func.h:228
VehicleID
PoolID< uint32_t, struct VehicleIDTag, 0xFF000, 0xFFFFF > VehicleID
The type all our vehicle IDs have.
Definition vehicle_type.h:17
VEH_ROAD
@ VEH_ROAD
Road vehicle type.
Definition vehicle_type.h:26
VEH_DISASTER
@ VEH_DISASTER
Disaster vehicle type.
Definition vehicle_type.h:33
VEH_AIRCRAFT
@ VEH_AIRCRAFT
Aircraft vehicle type.
Definition vehicle_type.h:28
VEH_SHIP
@ VEH_SHIP
Ship vehicle type.
Definition vehicle_type.h:27
VEH_EFFECT
@ VEH_EFFECT
Effect vehicle type (smoke, explosions, sparks, bubbles)
Definition vehicle_type.h:32
VEH_TRAIN
@ VEH_TRAIN
Train vehicle type.
Definition vehicle_type.h:25
MakeSea
void MakeSea(Tile t)
Make a sea tile.
Definition water_map.h:426