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