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