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