36#include "table/strings.h"
52static void FixTTDMapArray()
60 case 0x53:
case 0x54: tile.m5() += 170 - 0x53;
break;
61 case 0x57:
case 0x58: tile.m5() += 168 - 0x57;
break;
62 case 0x55:
case 0x56: tile.m5() += 170 - 0x55;
break;
63 case 0x59:
case 0x5A: tile.m5() += 168 - 0x59;
break;
70 if (
GB(tile.m5(), 6, 2) == 1) {
73 tile.m4() = (tile.m4() >> 1) & 7;
83 if (
GB(tile.m3(), 0, 2) == 3) {
111static uint32_t RemapOldTownName(uint32_t townnameparts, uint8_t old_town_name_type)
113 auto fix_num = [](uint32_t i, uint32_t n, uint8_t s) -> uint32_t {
114 return ((i << 16) / n + 1) << s;
117 switch (old_town_name_type) {
120 return townnameparts;
125 return fix_num(townnameparts - 86,
lengthof(_name_french_real), 0);
128 Debug(misc, 0,
"German Townnames are buggy ({})", townnameparts);
129 return townnameparts;
133 return fix_num(townnameparts,
lengthof(_name_spanish_real), 0);
139 return fix_num(townnameparts,
lengthof(_name_silly_1), 0) | fix_num(
GB(townnameparts, 16, 8),
lengthof(_name_silly_2), 16);
144static void FixOldTowns()
148 if (
IsInsideMM(town->townnametype, 0x20C1, 0x20C3)) {
150 town->townnameparts = RemapOldTownName(town->townnameparts,
_settings_game.game_creation.town_name);
164 if ((
size_t)v->next == 0xFFFF) {
171 switch (v->spritenum) {
173 case 0xff: v->spritenum = 0xfe;
break;
174 default: v->spritenum >>= 1;
break;
178 if (v->type ==
VEH_EFFECT) v->subtype = v->subtype >> 1;
203 (v->IsPrimaryVehicle() && v->current_order.IsType(OT_NOTHING))) {
204 v->current_order.MakeDummy();
211static bool FixTTOMapArray()
229 switch (
GB(tile.m5(), 6, 2)) {
233 tile.m4() = (~tile.m5() & 1) << 2;
234 SB(tile.m2(), 6, 2,
GB(tile.m5(), 3, 2));
236 tile.m5() =
HasBit(tile.m5(), 5) ? 2 : 1;
248 switch (
GB(tile.m5(), 4, 4)) {
250 if (tile.m2() == 4) tile.m2() = 5;
253 tile.m3() = tile.m1();
263 tile.m3() = tile.m2() & 0xC0;
265 if (tile.m2() >= 5) tile.m2()++;
269 tile.m3() =
GB(tile.m5(), 3, 3);
274 tile.m3() = (tile.m5() >= 0x08 && tile.m5() <= 0x0F) ? 1 : 0;
275 if (tile.m5() >= 8) tile.m5() -= 8;
276 if (tile.m5() >= 0x42) tile.m5()++;
280 tile.m3() = tile.m2() = 0;
284 tile.m2() = tile.m3() = tile.m5() = 0;
293 case 0x25:
case 0x27:
294 case 0x28:
case 0x29:
case 0x2A:
case 0x2B:
298 if (tile.m5() >= 0x2C) tile.m5() += 3;
304 if (
HasBit(tile.m5(), 7)) {
305 uint8_t m5 = tile.m5();
306 tile.m5() = m5 & 0xE1;
307 if (
GB(m5, 1, 2) == 1) tile.m5() |= 0x02;
308 if (
GB(m5, 1, 2) == 3) tile.m2() |= 0xA0;
310 tile.m3() = (
GB(m5, 1, 2) == 3) ? 1 : 0;
312 tile.m3() =
HasBit(m5, 2) ? 0x10 : 0;
313 if (
GB(m5, 3, 2) == 3) tile.m3() |= 1;
314 if (
GB(m5, 3, 2) == 1) tile.m5() |= 0x08;
318 tile.m3() =
HasBit(tile.m5(), 3);
319 tile.m5() &=
HasBit(tile.m5(), 3) ? 0x03 : 0x07 ;
339static Engine *_old_engines;
343 using OldEngineID = uint8_t;
345 static const OldEngineID ttd_to_tto[] = {
346 0, 255, 255, 255, 255, 255, 255, 255, 5, 7, 8, 9, 10, 11, 12, 13,
347 255, 255, 255, 255, 255, 255, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
348 25, 26, 27, 29, 28, 30, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
349 255, 255, 255, 255, 255, 255, 255, 31, 255, 32, 33, 34, 35, 36, 37, 38,
350 39, 40, 41, 42, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
351 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
352 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
353 255, 255, 255, 255, 44, 45, 46, 255, 255, 255, 255, 47, 48, 255, 49, 50,
354 255, 255, 255, 255, 51, 52, 255, 53, 54, 255, 55, 56, 255, 57, 59, 255,
355 58, 60, 255, 61, 62, 255, 63, 64, 255, 65, 66, 255, 255, 255, 255, 255,
356 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
357 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
358 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 67, 68, 69, 70,
359 71, 255, 255, 76, 77, 255, 255, 78, 79, 80, 81, 82, 83, 84, 85, 86,
360 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 255,
361 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 102, 255, 255
365 static const OldEngineID tto_to_ttd[] = {
366 0, 0, 8, 8, 8, 8, 8, 9, 10, 11, 12, 13, 14, 15, 15, 22,
367 23, 24, 25, 26, 27, 29, 28, 30, 31, 32, 33, 34, 35, 36, 37, 55,
368 57, 59, 58, 60, 61, 62, 63, 64, 65, 66, 67, 116, 116, 117, 118, 123,
369 124, 126, 127, 132, 133, 135, 136, 138, 139, 141, 142, 144, 145, 147, 148, 150,
370 151, 153, 154, 204, 205, 206, 207, 208, 211, 212, 211, 212, 211, 212, 215, 216,
371 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
372 233, 234, 235, 236, 237, 238, 253
376 if (v->engine_type >=
lengthof(tto_to_ttd))
return false;
377 v->engine_type =
static_cast<EngineID>(tto_to_ttd[v->engine_type.base()]);
383 for (uint16_t i = 0; i <
lengthof(_orig_rail_vehicle_info); ++i, ++j) GetTempDataEngine(j,
VEH_TRAIN, i);
384 for (uint16_t i = 0; i <
lengthof(_orig_road_vehicle_info); ++i, ++j) GetTempDataEngine(j,
VEH_ROAD, i);
385 for (uint16_t i = 0; i <
lengthof(_orig_ship_vehicle_info); ++i, ++j) GetTempDataEngine(j,
VEH_SHIP, i);
386 for (uint16_t i = 0; i <
lengthof(_orig_aircraft_vehicle_info); ++i, ++j) GetTempDataEngine(j,
VEH_AIRCRAFT, i);
392 for (
EngineID i = EngineID::Begin(); i < 256; ++i) {
393 OldEngineID oi = ttd_to_tto[i.base()];
394 Engine *e = GetTempDataEngine(i);
412 Engine *oe = &_old_engines[oi];
430 for (uint j = 0; j <
lengthof(tto_to_ttd); j++) {
431 if (tto_to_ttd[j] == i && _old_engines[j].company_avail.Any()) {
444 e->
name = std::string{};
450static void FixTTOCompanies()
460 static const Colours tto_colour_remap[] = {
461 COLOUR_DARK_BLUE, COLOUR_GREY, COLOUR_YELLOW, COLOUR_RED,
462 COLOUR_PURPLE, COLOUR_DARK_GREEN, COLOUR_ORANGE, COLOUR_PALE_GREEN,
463 COLOUR_BLUE, COLOUR_GREEN, COLOUR_CREAM, COLOUR_BROWN,
464 COLOUR_WHITE, COLOUR_LIGHT_BLUE, COLOUR_MAUVE, COLOUR_PINK
467 if (
static_cast<size_t>(tto) >= std::size(tto_colour_remap))
return COLOUR_GREY;
469 return tto_colour_remap[tto];
472static inline uint RemapTownIndex(uint x)
477static inline uint RemapOrderIndex(uint x)
486static uint32_t _old_town_index;
487static uint16_t _old_string_id;
488static uint16_t _old_string_id_2;
520 _bump_assert_value = 0;
523 ls.vehicle_names.resize(800);
551 if (ttdp2_header_first.m3() ==
'T' && ttdp2_header_first.m4() ==
'T' &&
552 ttdp2_header_second.m3() ==
'D' && ttdp2_header_second.m4() ==
'p') {
560 for (
TileIndex i{}; i < 9; i++) ClearOldMap3(i);
568static std::array<Town::SuppliedHistory, 2> _old_pass_supplied{};
569static std::array<Town::SuppliedHistory, 2> _old_mail_supplied{};
576 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16,
Town, grow_counter ),
592 OCL_SVAR( OC_FILE_U32 | OC_VAR_U16,
Town, have_ratings ),
595 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16,
Town, time_until_rebuild ),
599 OCL_VAR( OC_FILE_U16 | OC_VAR_U32, 1, &_old_pass_supplied[THIS_MONTH].production ),
600 OCL_VAR( OC_FILE_U16 | OC_VAR_U32, 1, &_old_mail_supplied[THIS_MONTH].production ),
601 OCL_VAR( OC_FILE_U16 | OC_VAR_U32, 1, &_old_pass_supplied[THIS_MONTH].transported ),
602 OCL_VAR( OC_FILE_U16 | OC_VAR_U32, 1, &_old_mail_supplied[THIS_MONTH].transported ),
603 OCL_VAR( OC_FILE_U16 | OC_VAR_U32, 1, &_old_pass_supplied[LAST_MONTH].production ),
604 OCL_VAR( OC_FILE_U16 | OC_VAR_U32, 1, &_old_mail_supplied[LAST_MONTH].production ),
605 OCL_VAR( OC_FILE_U16 | OC_VAR_U32, 1, &_old_pass_supplied[LAST_MONTH].transported ),
606 OCL_VAR( OC_FILE_U16 | OC_VAR_U32, 1, &_old_mail_supplied[LAST_MONTH].transported ),
626 if (!
LoadChunk(ls, t, town_chunk))
return false;
634 auto &pass = t->
supplied.emplace_back(0);
635 pass.history[LAST_MONTH] = _old_pass_supplied[LAST_MONTH];
636 pass.history[THIS_MONTH] = _old_pass_supplied[THIS_MONTH];
637 auto &mail = t->
supplied.emplace_back(2);
638 mail.history[LAST_MONTH] = _old_mail_supplied[LAST_MONTH];
639 mail.history[THIS_MONTH] = _old_mail_supplied[THIS_MONTH];
647static uint16_t _old_order;
649 OCL_VAR ( OC_UINT16, 1, &_old_order ),
655 if (!
LoadChunk(ls,
nullptr, order_chunk))
return false;
664 if (prev !=
nullptr) prev->
next = num + 1;
674 OCL_VAR ( OC_TILE, 256, anim_list ),
678 if (!
LoadChunk(ls,
nullptr, anim_chunk))
return false;
681 for (
int i = 0; i < 256; i++) {
682 if (anim_list[i] == 0)
break;
691 OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
698 if (!
LoadChunk(ls, d, depot_chunk))
return false;
701 d->town = RemapTown(d->xy);
709static StationID _current_station_id;
710static uint16_t _waiting_acceptance;
711static uint8_t _cargo_source;
712static uint8_t _cargo_periods;
715 OCL_VAR ( OC_UINT16, 1, &_waiting_acceptance ),
718 OCL_VAR ( OC_UINT8, 1, &_cargo_source ),
719 OCL_VAR ( OC_UINT8, 1, &_cargo_periods ),
734 if (!
LoadChunk(ls, ge, goods_chunk))
return false;
740 StationID::Invalid());
746static const OldChunks station_chunk[] = {
748 OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
759 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
786 _current_station_id = st->index;
788 if (!
LoadChunk(ls, st, station_chunk))
return false;
791 st->
town = RemapTown(st->
xy);
795 st->
string_id = STR_SV_STNAME + (_old_string_id - 0x180F);
818static std::array<Industry::AcceptedCargo, INDUSTRY_ORIGINAL_NUM_INPUTS> _old_accepted{};
819static std::array<Industry::ProducedCargo, INDUSTRY_ORIGINAL_NUM_OUTPUTS> _old_produced{};
821static const OldChunks industry_chunk[] = {
823 OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
830 OCL_VAR(
OC_TTO | OC_FILE_U8 | OC_VAR_U16, 1, &_old_produced[0].waiting ),
831 OCL_VAR(
OC_TTO | OC_FILE_U8 | OC_VAR_U16, 1, &_old_produced[1].waiting ),
833 OCL_VAR( OC_UINT8, 1, &_old_produced[0].rate ),
834 OCL_VAR( OC_UINT8, 1, &_old_produced[1].rate ),
840 OCL_VAR( OC_UINT16, 1, &_old_produced[0].history[THIS_MONTH].production ),
841 OCL_VAR( OC_UINT16, 1, &_old_produced[1].history[THIS_MONTH].production ),
842 OCL_VAR( OC_UINT16, 1, &_old_produced[0].history[THIS_MONTH].transported ),
843 OCL_VAR( OC_UINT16, 1, &_old_produced[1].history[THIS_MONTH].transported ),
847 OCL_VAR( OC_UINT16, 1, &_old_produced[0].history[LAST_MONTH].production ),
848 OCL_VAR( OC_UINT16, 1, &_old_produced[1].history[LAST_MONTH].production ),
849 OCL_VAR( OC_UINT16, 1, &_old_produced[0].history[LAST_MONTH].transported ),
850 OCL_VAR( OC_UINT16, 1, &_old_produced[1].history[LAST_MONTH].transported ),
868 if (!
LoadChunk(ls, i, industry_chunk))
return false;
872 std::move(std::begin(_old_accepted), std::end(_old_accepted), std::back_inserter(i->
accepted));
873 std::copy(std::begin(_old_produced), std::end(_old_produced), std::back_inserter(i->
produced));
879 if (i->
type == 0x0A) i->
type = 0x12;
895static CompanyID _current_company_id;
896static int32_t _old_yearly;
898static const OldChunks _company_yearly_chunk[] = {
899 OCL_VAR( OC_INT32, 1, &_old_yearly ),
907 for (uint i = 0; i < 13; i++) {
911 if (!
LoadChunk(ls,
nullptr, _company_yearly_chunk))
return false;
920static const OldChunks _company_economy_chunk[] = {
940 for (uint i = 0; i < 24; i++) {
950static const OldChunks _company_chunk[] = {
951 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
954 OCL_VAR ( OC_UINT16, 1, &_old_string_id_2 ),
995 _current_company_id = (CompanyID)num;
997 if (!
LoadChunk(ls, c, _company_chunk))
return false;
999 if (_old_string_id == 0) {
1012 if (_old_string_id == 0 || _old_string_id == 0x4C00) {
1013 _old_string_id = STR_SV_UNNAMED;
1014 }
else if (
GB(_old_string_id, 8, 8) == 0x52) {
1015 _old_string_id += 0x2A00;
1019 c->
name_1 = _old_string_id;
1022 switch (_old_string_id_2) {
1024 case 0x0006: _old_string_id_2 = STR_SV_EMPTY;
break;
1025 default: _old_string_id_2 = _old_string_id_2 + 0x2A00;
break;
1031 if (num != 0) c->
is_ai =
true;
1038 if (c->
name_1 == STR_NULL) {
1039 c->
name_1 = STR_SV_UNNAMED;
1061static uint32_t _old_order_ptr;
1062static uint16_t _old_next_ptr;
1063static typename VehicleID::BaseType _current_vehicle_id;
1065static const OldChunks vehicle_train_chunk[] = {
1076static const OldChunks vehicle_road_chunk[] = {
1090static const OldChunks vehicle_ship_chunk[] = {
1098static const OldChunks vehicle_air_chunk[] = {
1109static const OldChunks vehicle_effect_chunk[] = {
1118static const OldChunks vehicle_disaster_chunk[] = {
1127static const OldChunks vehicle_empty_chunk[] = {
1136 uint temp = ls.total_read;
1140 res =
LoadChunk(ls,
nullptr, vehicle_empty_chunk);
1154 if (ls.total_read - temp != 10) {
1155 Debug(oldloader, 0,
"Assert failed in VehicleUnion: invalid chunk size");
1162static uint16_t _cargo_count;
1164static const OldChunks vehicle_chunk[] = {
1170 OCL_VAR ( OC_UINT32, 1, &_old_order_ptr ),
1171 OCL_VAR ( OC_UINT16, 1, &_old_order ),
1194 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32,
Vehicle, sprite_cache.sprite_seq.seq[0].sprite ),
1209 OCL_VAR (
OC_TTO | OC_FILE_U8 | OC_VAR_U16, 1, &_cargo_count ),
1210 OCL_VAR ( OC_UINT8, 1, &_cargo_source ),
1211 OCL_VAR ( OC_UINT8, 1, &_cargo_periods ),
1239 OCL_VAR ( OC_UINT16, 1, &_old_next_ptr ),
1243 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
1262 ReadTTDPatchFlags(ls);
1272 default:
return false;
1273 case 0x00 : v =
nullptr;
break;
1283 if (!
LoadChunk(ls, v, vehicle_chunk))
return false;
1284 if (v ==
nullptr)
continue;
1302 static const uint8_t spriteset_rail[] = {
1303 0, 2, 4, 4, 8, 10, 12, 14, 16, 18, 20, 22, 40, 42, 44, 46,
1304 48, 52, 54, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 120, 122,
1305 124, 126, 128, 130, 132, 134, 136, 138, 140
1335 switch (_old_string_id) {
1337 case 0x0006: _old_string_id = STR_SV_EMPTY;
break;
1338 case 0x8495: _old_string_id = STR_SV_TRAIN_NAME;
break;
1339 case 0x8842: _old_string_id = STR_SV_ROAD_VEHICLE_NAME;
break;
1340 case 0x8C3B: _old_string_id = STR_SV_SHIP_NAME;
break;
1341 case 0x9047: _old_string_id = STR_SV_AIRCRAFT_NAME;
break;
1342 default: _old_string_id += 0x2A00;
break;
1345 ls.vehicle_names[_current_vehicle_id] = _old_string_id;
1350 case 0x00 : v =
nullptr;
break;
1359 if (!
LoadChunk(ls, v, vehicle_chunk))
return false;
1360 if (v ==
nullptr)
continue;
1365 if (v->index != _current_vehicle_id) {
1366 Debug(oldloader, 0,
"Loading failed - vehicle-array is invalid");
1371 if (_old_order_ptr != 0 && _old_order_ptr != 0xFFFFFFFF) {
1373 uint old_id = RemapOrderIndex(_old_order_ptr);
1374 if (old_id < max) v->
old_orders = old_id + 1;
1385 StationID source = (_cargo_source == 0xFF) ? StationID::Invalid() : StationID{_cargo_source};
1408 for (
auto &c : str) c =
ReadByte(ls);
1414 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
1427 if (!
LoadChunk(ls, si, sign_chunk))
return false;
1429 if (_old_string_id != 0) {
1431 if (_old_string_id != 0x140A) si->name =
CopyFromOldName(_old_string_id + 0x2A00);
1443static const OldChunks engine_chunk[] = {
1479static const OldChunks subsidy_chunk[] = {
1491 bool ret =
LoadChunk(ls, s, subsidy_chunk);
1496static const OldChunks game_difficulty_chunk[] = {
1545 for (
auto it = range.begin(); it != range.end(); ) {
1547 for (
int i = 0; i < 8; i += 2, ++it) (*it).m6() =
GB(b, i, 2);
1568 ReadTTDPatchFlags(ls);
1573 uint16_t
id = ReadUint16(ls);
1574 uint32_t len = ReadUint32(ls);
1582 ReadUint32(ls);
ReadByte(ls); len -= 5;
1586 uint32_t grfid = ReadUint32(ls);
1589 auto c = std::make_unique<GRFConfig>(
"TTDP game, no information");
1590 c->ident.grfid = grfid;
1592 Debug(oldloader, 3,
"TTDPatch game using GRF file with GRFID {:08X}",
std::byteswap(c->ident.grfid));
1606 Debug(oldloader, 3,
"Game saved with TTDPatch version {}.{}.{} r{}",
1607 GB(
_ttdp_version, 24, 8),
GB(
_ttdp_version, 20, 4),
GB(
_ttdp_version, 16, 4),
GB(
_ttdp_version, 0, 16));
1613 Debug(oldloader, 4,
"Skipping unknown extra chunk {}",
id);
1626extern uint8_t _old_diff_level;
1627extern uint8_t _old_units;
1639 OCL_CCHUNK(
OC_TTD, 70, LoadOldTown ),
1640 OCL_CCHUNK(
OC_TTO, 80, LoadOldTown ),
1645 OCL_CCHUNK(
OC_TTD, 5000, LoadOldOrder ),
1646 OCL_CCHUNK(
OC_TTO, 3000, LoadOldOrder ),
1656 OCL_CCHUNK(
OC_TTD, 255, LoadOldDepot ),
1657 OCL_CCHUNK(
OC_TTO, 252, LoadOldDepot ),
1668 OCL_VAR ( OC_TILE, 1, &_cur_tileloop_tile ),
1672 OCL_CNULL(
OC_TTO, 48 * 6 ),
1673 OCL_CNULL(
OC_TTD, 49 * 6 ),
1677 OCL_CNULL(
OC_TTO, 11 * 8 ),
1678 OCL_CNULL(
OC_TTD, 12 * 8 ),
1688 OCL_CCHUNK(
OC_TTD, 250, LoadOldStation ),
1689 OCL_CCHUNK(
OC_TTO, 200, LoadOldStation ),
1693 OCL_CCHUNK(
OC_TTD, 90, LoadOldIndustry ),
1694 OCL_CCHUNK(
OC_TTO, 100, LoadOldIndustry ),
1720 OCL_CCHUNK(
OC_TTD, 256, LoadOldEngine ),
1721 OCL_CCHUNK(
OC_TTO, 103, LoadOldEngine ),
1740 OCL_VAR ( OC_FILE_U32 | OC_VAR_I64, 1, &_economy.old_max_loan_unround ),
1741 OCL_VAR ( OC_INT16, 1, &_economy.fluct ),
1747 OCL_CNULL(
OC_TTD, 144 ),
1749 OCL_CCHUNK(
OC_TTD, 256, LoadOldEngineName ),
1751 OCL_CNULL(
OC_TTD, 144 ),
1756 OCL_VAR ( OC_UINT8, 1, &_old_units ),
1762 OCL_VAR ( OC_UINT8, 1, &_economy.infl_amount ),
1763 OCL_VAR ( OC_UINT8, 1, &_economy.infl_amount_pr ),
1764 OCL_VAR ( OC_UINT8, 1, &_economy.interest_rate ),
1773 OCL_VAR ( OC_UINT8, 1, &_old_diff_level ),
1800 Debug(oldloader, 3,
"Reading main chunk...");
1805 if (!
LoadChunk(ls,
nullptr, main_chunk)) {
1806 Debug(oldloader, 0,
"Loading failed");
1810 Debug(oldloader, 3,
"Done, converting game data...");
1825 Debug(oldloader, 3,
"Finished converting game data");
1826 Debug(oldloader, 1,
"TTD(Patch) savegame successfully converted");
1833 Debug(oldloader, 3,
"Reading main chunk...");
1837 std::array<uint8_t, 103 *
sizeof(
Engine)> engines;
1838 _old_engines = (
Engine *)engines.data();
1841 if (!
LoadChunk(ls,
nullptr, main_chunk)) {
1842 Debug(oldloader, 0,
"Loading failed");
1845 Debug(oldloader, 3,
"Done, converting game data...");
1853 Debug(oldloader, 0,
"Conversion failed");
1868 _economy.inflation_payment = std::min(_economy.inflation_payment * 124 / 74,
MAX_INFLATION);
1870 Debug(oldloader, 3,
"Finished converting game data");
1871 Debug(oldloader, 1,
"TTO savegame successfully converted");
AirportBlock
Movement Blocks on Airports blocks (eg_airport_flags).
std::vector< TileIndex > _animated_tiles
The table/list with animated tiles.
constexpr T SB(T &x, const uint8_t s, const uint8_t n, const U d)
Set n bits in x starting at bit s to d.
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr enable_if_t< is_integral_v< T >, T > byteswap(T x) noexcept
Custom implementation of std::byteswap; remove once we build with C++23.
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
static const CargoType NUM_CARGO
Maximum number of cargo types in a game.
@ TAE_FOOD
Cargo behaves food/fizzy-drinks-like.
@ TAE_WATER
Cargo behaves water-like.
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).
uint16_t reliability_start
Initial reliability of the engine.
TimerGameCalendar::Date intro_date
Date of introduction of the engine.
EngineFlags flags
Flags of the engine.
CompanyMask company_avail
Bit for each company whether the engine is available for that company.
uint16_t reliability_max
Maximal reliability of the engine.
uint16_t reliability_final
Final reliability of the engine.
CompanyID preview_company
Company which is currently being offered a preview CompanyID::Invalid() means no company.
uint16_t duration_phase_3
Third reliability phase in months, decaying to reliability_final.
uint16_t duration_phase_2
Second reliability phase in months, keeping reliability_max.
uint8_t preview_wait
Daily countdown timer for timeout of offering the engine to the preview_company company.
uint16_t reliability
Current reliability of the engine.
CompanyMask preview_asked
Bit for each company which has already been offered a preview.
int32_t age
Age of the engine in months.
std::string name
Custom name of engine.
uint16_t duration_phase_1
First reliability phase in months, increasing reliability from reliability_start to reliability_max.
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.
uint8_t & m4()
General purpose.
uint8_t & m3()
General purpose.
A timeout timer will fire once after the interval.
static Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
static YearMonthDay ConvertDateToYMD(Date date)
Converts a Date to a Year, Month & Day.
static Date date
Current date in days (day counter).
static DateFract date_fract
Fractional part of the day.
static constexpr TimerGame< struct Economy >::Year ORIGINAL_BASE_YEAR
static constexpr TimerGame< struct Calendar >::Date DAYS_TILL_ORIGINAL_BASE_YEAR
static Date date
Current date in days (day counter).
static YearMonthDay ConvertDateToYMD(Date date)
Converts a Date to a Year, Month & Day.
static TickCounter counter
Monotonic counter, in ticks, since start of game.
void Append(CargoPacket *cp, MoveToAction action=MTA_KEEP)
Appends the given cargo packet.
Definition of stuff that is very close to a company, like the company struct itself.
Money CalculateCompanyValue(const Company *c, bool including_loan=true)
Calculate the value of the company.
uint _cur_company_tick_index
used to generate a name for one company that doesn't have a name yet per tick
TimeoutTimer< TimerGameTick > _new_competitor_timeout({ TimerGameTick::Priority::CompetitorTimeout, 0 }, []() { if(_game_mode==GM_MENU||!AI::CanStartNew()) return;if(_networking &&Company::GetNumItems() >=_settings_client.network.max_companies) return;if(_settings_game.difficulty.competitors_interval==0) return;uint8_t n=0;for(const Company *c :Company::Iterate()) { if(c->is_ai) n++;} if(n >=_settings_game.difficulty.max_no_competitors) return;Command< Commands::CompanyControl >::Post(CompanyCtrlAction::NewAI, CompanyID::Invalid(), CompanyRemoveReason::None, INVALID_CLIENT_ID);})
Start a new competitor company if possible.
TypedIndexContainer< std::array< Colours, MAX_COMPANIES >, CompanyID > _company_colours
NOSAVE: can be determined from company structs.
Functions related to companies.
static constexpr Owner OWNER_NONE
The tile has no ownership.
static constexpr Owner OWNER_WATER
The tile/execution is done by "water".
Functions related to debugging.
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Base for all depots (except hangars).
DepotID GetDepotIndex(Tile t)
Get the index of which depot is attached to the tile.
bool IsDepotTile(Tile tile)
Is the given tile a tile with a depot on it?
PoolID< uint16_t, struct DepotIDTag, 64000, 0xFFFF > DepotID
Type for the unique identifier of depots.
uint16_t _disaster_delay
Delay counter for considering the next disaster.
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.
void CalcEngineReliability(Engine *e, bool new_month)
Update Engine::reliability and (if needed) update the engine GUIs.
Functions related to engines.
PoolID< uint16_t, struct EngineIDTag, 64000, 0xFFFF > EngineID
Unique identification number of an engine.
@ 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).
uint32_t _ttdp_version
version of TTDP savegame (if applicable)
SavegameType _savegame_type
type of savegame we are loading
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
@ Temperate
Base landscape.
static TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
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.
ZoomLevel _saved_scrollpos_zoom
uint8_t _age_cargo_skip_counter
Skip aging of cargo? Used before savegame version 162.
uint8_t _trees_tick_ctr
Determines when to consider building more trees.
GRFConfigList _grfconfig
First item in list of current GRF set up.
void AppendStaticGRFConfigs(GRFConfigList &dst)
Appends the static GRFs to a list of GRFs.
void AppendToGRFConfigList(GRFConfigList &dst, std::unique_ptr< GRFConfig > &&el)
Appends an element to a list of GRFs.
void ClearGRFConfigList(GRFConfigList &config)
Clear a GRF Config list, freeing all nodes.
bool LoadChunk(LoadgameState &ls, void *base, const OldChunks *chunks)
Loads a chunk from the old savegame.
uint8_t ReadByte(LoadgameState &ls)
Reads a byte from the buffer and decompress if needed.
Declarations of structures and functions used in loader of old savegames.
@ OC_TTO
-//- TTO (default is neither of these)
@ OC_TTD
chunk is valid ONLY for TTD savegames
#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...
#define OCL_NULL(amount)
Read 'amount' of bytes and send them to /dev/null or something.
#define OCL_END()
Every struct must end with this.
#define OCL_VAR(type, amount, pointer)
Load 'type' to a global var.
#define OCL_ASSERT(type, size)
To check if we are really at the place we expect to be.
#define OCL_CHUNK(amount, proc)
Load another proc to load a part of the savegame, 'amount' times.
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.
OldOrderSaveLoadItem & AllocateOldOrder(size_t pool_index)
Allocate an old order with the given pool index.
Order UnpackOldOrder(uint16_t packed)
Unpacks a order from savegames made with TTD(Patch).
Randomizer _random
Random used in the game state calculations.
@ RVS_IN_DT_ROAD_STOP
The vehicle is in a drive-through road stop.
@ RVSB_IN_DEPOT
The vehicle is in a depot.
@ RVSB_WORMHOLE
The vehicle is in a tunnel and/or bridge.
A number of safeguards to prevent using unsafe methods.
void SlErrorCorrupt(const std::string &msg)
Error handler for corrupt savegames.
@ SGT_TTDP2
TTDP savegame in new format (data at SE border).
@ SGT_TTDP1
TTDP savegame ( -//- ) (data at NW border).
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.
PoolID< uint16_t, struct SignIDTag, 64000, 0xFFFF > SignID
The type of the IDs of signs.
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.
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.
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.
IndustryType type
type of industry.
Colours random_colour
randomized colour of the industry, for display purpose
TimerGameEconomy::Year last_prod_year
last economy year of production
ProducedCargoes produced
produced cargo slots
AcceptedCargoes accepted
accepted cargo slots
TileArea location
Location of the industry.
static std::array< FlatSet< IndustryID >, NUM_INDUSTRYTYPES > industries
List of industries of each type.
uint8_t vehicle_multiplier
TTDPatch vehicle multiplier.
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
static uint MaxY()
Gets the maximum Y coordinate within the map, including TileType::Void.
static void Allocate(uint size_x, uint size_y)
(Re)allocates a map with the given dimension
static uint Size()
Get the size of the map.
VehicleSpriteSeq sprite_seq
Vehicle appearance.
Compatibility struct to allow saveload of pool-based orders.
Order order
The order data.
uint32_t next
The next order index (1-based).
DestinationID GetDestination() const
Gets the destination of this order.
bool IsType(OrderType type) const
Check whether this order is of the given type.
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 bool CanAllocateItem(size_t n=1)
static T * Create(Targs &&... args)
static Vehicle * GetIfValid(auto index)
Buses, trucks and trams belong to this class.
All ships have this type.
Owner owner
Placed by this company. Anyone can delete them though. OWNER_NONE for gray signs from old games.
static Station * CreateAtIndex(StationID index, Targs &&... args)
static Station * Get(auto index)
static RoadVehicle * From(Vehicle *v)
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.
TileIndex xy
town center tile
SuppliedCargoes supplied
Cargo statistics about supplied cargo.
uint16_t townnametype
Custom town name. If empty, the town was not renamed and uses the generated name.
'Train' is either a loco or a wagon.
VehicleCargoList cargo
The cargo this vehicle is carrying.
uint16_t cargo_cap
total capacity
CargoType cargo_type
type of cargo this vehicle is carrying
Order current_order
The current order (+ status, like: loading).
Vehicle(VehicleID index, VehicleType type=VEH_INVALID)
Vehicle constructor.
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.
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.
void SetTileType(Tile tile, TileType type)
Set the type of a tile.
void SetTileOwner(Tile tile, Owner owner)
Sets the owner of a tile.
static TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
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.
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
TileType
The different types of tiles.
@ TunnelBridge
Tunnel entry/exit and bridge heads.
@ Station
A tile of a station or airport.
@ Object
Contains objects such as transmitters and owned land.
@ Industry
Part of an industry.
@ Railway
A tile with railway.
@ Void
Invisible tiles at the SW and SE border.
@ Trees
Tile with one or more trees.
@ House
A house by a town.
@ Road
A tile with road and/or tram tracks.
@ Clear
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition of Interval and OneShot timers.
Definition of the game-calendar-timer.
Definition of the tick-based game-timer.
Town * CalcClosestTownFromTile(TileIndex tile, uint threshold=UINT_MAX)
Return the town closest to the given tile within threshold.
Namepart tables for the town name generator.
Base for the train class.
Functions related to vehicles.
bool IsCompanyBuildableVehicleType(VehicleType type)
Is the given vehicle type buildable by a company?
PoolID< uint32_t, struct VehicleIDTag, 0xFF000, 0xFFFFF > VehicleID
The type all our vehicle IDs have.
@ VEH_ROAD
Road vehicle type.
@ VEH_DISASTER
Disaster vehicle type.
@ VEH_AIRCRAFT
Aircraft vehicle type.
@ VEH_SHIP
Ship vehicle type.
@ VEH_EFFECT
Effect vehicle type (smoke, explosions, sparks, bubbles).
@ VEH_TRAIN
Train vehicle type.
void MakeSea(Tile t)
Make a sea tile.