00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "../stdafx.h"
00013 #include "../town.h"
00014 #include "../industry.h"
00015 #include "../company_func.h"
00016 #include "../aircraft.h"
00017 #include "../roadveh.h"
00018 #include "../ship.h"
00019 #include "../train.h"
00020 #include "../signs_base.h"
00021 #include "../station_base.h"
00022 #include "../subsidy_base.h"
00023 #include "../debug.h"
00024 #include "../depot_base.h"
00025 #include "../date_func.h"
00026 #include "../vehicle_func.h"
00027 #include "../effectvehicle_base.h"
00028 #include "../engine_func.h"
00029 #include "../company_base.h"
00030 #include "saveload_internal.h"
00031 #include "oldloader.h"
00032
00033 #include "table/strings.h"
00034 #include "../table/engines.h"
00035 #include "../table/townname.h"
00036
00037 static bool _read_ttdpatch_flags;
00038
00039 static uint8 *_old_map3;
00040
00041 void FixOldMapArray()
00042 {
00043
00044
00045 MemSetT(&_m[0], 0);
00046 SetTileType(0, MP_WATER);
00047 SetTileOwner(0, OWNER_WATER);
00048 }
00049
00050 static void FixTTDMapArray()
00051 {
00052
00053 for (TileIndex t = 0; t < OLD_MAP_SIZE; t++) {
00054 _m[t].m3 = _old_map3[t * 2];
00055 _m[t].m4 = _old_map3[t * 2 + 1];
00056 }
00057
00058 for (TileIndex t = 0; t < OLD_MAP_SIZE; t++) {
00059 switch (GetTileType(t)) {
00060 case MP_STATION:
00061 _m[t].m4 = 0;
00062 switch (_m[t].m5) {
00063
00064 case 0x53: case 0x54: _m[t].m5 += 170 - 0x53; break;
00065 case 0x57: case 0x58: _m[t].m5 += 168 - 0x57; break;
00066 case 0x55: case 0x56: _m[t].m5 += 170 - 0x55; break;
00067 case 0x59: case 0x5A: _m[t].m5 += 168 - 0x59; break;
00068 default: break;
00069 }
00070 break;
00071
00072 case MP_RAILWAY:
00073
00074 if (GB(_m[t].m5, 6, 2) == 1) {
00075
00076 if (_m[t].m4) {
00077 _m[t].m4 = (_m[t].m4 >> 1) & 7;
00078 }
00079 }
00080
00081
00082 _m[t].m4 &= 0xF;
00083 break;
00084
00085 case MP_WATER:
00086
00087 if (GB(_m[t].m3, 0, 2) == 3) {
00088 SetTileType(t, MP_WATER);
00089 SetTileOwner(t, OWNER_WATER);
00090 _m[t].m2 = 0;
00091 _m[t].m3 = 2;
00092 _m[t].m4 = Random();
00093 _m[t].m5 = 0;
00094 }
00095 break;
00096
00097 default:
00098 break;
00099 }
00100 }
00101
00102 FixOldMapArray();
00103 }
00104
00105 static void FixTTDDepots()
00106 {
00107 const Depot *d;
00108 FOR_ALL_DEPOTS_FROM(d, 252) {
00109 if (!IsRoadDepotTile(d->xy) && !IsRailDepotTile(d->xy) && !IsShipDepotTile(d->xy) && !IsHangarTile(d->xy)) {
00111 delete d;
00112 }
00113 }
00114 }
00115
00116 #define FIXNUM(x, y, z) (((((x) << 16) / (y)) + 1) << z)
00117
00118 static uint32 RemapOldTownName(uint32 townnameparts, byte old_town_name_type)
00119 {
00120 switch (old_town_name_type) {
00121 case 0: case 3:
00122
00123 return townnameparts;
00124
00125 case 1:
00126
00127
00128 return FIXNUM(townnameparts - 86, lengthof(_name_french_real), 0);
00129
00130 case 2:
00131 DEBUG(misc, 0, "German Townnames are buggy (%d)", townnameparts);
00132 return townnameparts;
00133
00134 case 4:
00135
00136 return FIXNUM(townnameparts, lengthof(_name_spanish_real), 0);
00137
00138 case 5:
00139
00140
00141
00142 return FIXNUM(townnameparts, lengthof(_name_silly_1), 0) | FIXNUM(GB(townnameparts, 16, 8), lengthof(_name_silly_2), 16);
00143 }
00144 return 0;
00145 }
00146
00147 #undef FIXNUM
00148
00149 static void FixOldTowns()
00150 {
00151 Town *town;
00152
00153
00154 FOR_ALL_TOWNS(town) {
00155 if (IsInsideMM(town->townnametype, 0x20C1, 0x20C3)) {
00156 town->townnametype = SPECSTR_TOWNNAME_ENGLISH + _settings_game.game_creation.town_name;
00157 town->townnameparts = RemapOldTownName(town->townnameparts, _settings_game.game_creation.town_name);
00158 }
00159 }
00160 }
00161
00162 static StringID *_old_vehicle_names;
00163
00164 void FixOldVehicles()
00165 {
00166 Vehicle *v;
00167
00168 FOR_ALL_VEHICLES(v) {
00169 if ((size_t)v->next == 0xFFFF) {
00170 v->next = NULL;
00171 } else {
00172 v->next = Vehicle::GetIfValid((size_t)v->next);
00173 }
00174
00175
00176 switch (v->spritenum) {
00177 case 0xfd: break;
00178 case 0xff: v->spritenum = 0xfe; break;
00179 default: v->spritenum >>= 1; break;
00180 }
00181
00182
00183 if (v->type == VEH_EFFECT) v->subtype = v->subtype >> 1;
00184
00185 v->name = CopyFromOldName(_old_vehicle_names[v->index]);
00186
00187
00188 if (v->type == VEH_ROAD) {
00189 RoadVehicle *rv = RoadVehicle::From(v);
00190 if (rv->state != RVSB_IN_DEPOT && rv->state != RVSB_WORMHOLE) {
00191 ClrBit(rv->state, 2);
00192 }
00193 }
00194
00195
00196 if (v->type == VEH_ROAD || v->type == VEH_SHIP) v->subtype = 0;
00197
00198
00199
00200
00201
00202 if (!IsCompanyBuildableVehicleType(v) ||
00203 (v->IsPrimaryVehicle() && v->current_order.IsType(OT_NOTHING))) {
00204 v->current_order.MakeDummy();
00205 }
00206
00207
00208 }
00209 }
00210
00211 static bool FixTTOMapArray()
00212 {
00213 for (TileIndex t = 0; t < OLD_MAP_SIZE; t++) {
00214 TileType tt = GetTileType(t);
00215 if (tt == 11) {
00216
00217
00218 _m[t].m3 = 1;
00219 SetTileType(t, MP_RAILWAY);
00220 _m[t].m2 = 1;
00221 tt = MP_RAILWAY;
00222 }
00223
00224 switch (tt) {
00225 case MP_CLEAR:
00226 break;
00227
00228 case MP_RAILWAY:
00229 switch (GB(_m[t].m5, 6, 2)) {
00230 case 0:
00231 break;
00232 case 1:
00233 _m[t].m4 = (~_m[t].m5 & 1) << 2;
00234 SB(_m[t].m2, 6, 2, GB(_m[t].m5, 3, 2));
00235 _m[t].m3 |= 0xC0;
00236 _m[t].m5 = HasBit(_m[t].m5, 5) ? 2 : 1;
00237 _m[t].m5 |= 0x40;
00238 break;
00239 case 3:
00240 _m[t].m2 = 0;
00241 break;
00242 default:
00243 return false;
00244 }
00245 break;
00246
00247 case MP_ROAD:
00248 switch (GB(_m[t].m5, 4, 4)) {
00249 case 0:
00250 if (_m[t].m2 == 4) _m[t].m2 = 5;
00251 break;
00252 case 1:
00253 _m[t].m3 = _m[t].m1;
00254 break;
00255 case 2:
00256 break;
00257 default:
00258 return false;
00259 }
00260 break;
00261
00262 case MP_HOUSE:
00263 _m[t].m3 = _m[t].m2 & 0xC0;
00264 _m[t].m2 &= 0x3F;
00265 if (_m[t].m2 >= 5) _m[t].m2++;
00266 break;
00267
00268 case MP_TREES:
00269 _m[t].m3 = GB(_m[t].m5, 3, 3);
00270 _m[t].m5 &= 0xC7;
00271 break;
00272
00273 case MP_STATION:
00274 _m[t].m3 = (_m[t].m5 >= 0x08 && _m[t].m5 <= 0x0F) ? 1 : 0;
00275 if (_m[t].m5 >= 8) _m[t].m5 -= 8;
00276 if (_m[t].m5 >= 0x42) _m[t].m5++;
00277 break;
00278
00279 case MP_WATER:
00280 _m[t].m3 = _m[t].m2 = 0;
00281 break;
00282
00283 case MP_VOID:
00284 _m[t].m2 = _m[t].m3 = _m[t].m5 = 0;
00285 break;
00286
00287 case MP_INDUSTRY:
00288 _m[t].m3 = 0;
00289 switch (_m[t].m5) {
00290 case 0x24:
00291 _m[t].m5 = 0x25;
00292 break;
00293 case 0x25: case 0x27:
00294 case 0x28: case 0x29: case 0x2A: case 0x2B:
00295 _m[t].m5--;
00296 break;
00297 default:
00298 if (_m[t].m5 >= 0x2C) _m[t].m5 += 3;
00299 break;
00300 }
00301 break;
00302
00303 case MP_TUNNELBRIDGE:
00304 if (HasBit(_m[t].m5, 7)) {
00305 byte m5 = _m[t].m5;
00306 _m[t].m5 = m5 & 0xE1;
00307 if (GB(m5, 1, 2) == 1) _m[t].m5 |= 0x02;
00308 if (GB(m5, 1, 2) == 3) _m[t].m2 |= 0xA0;
00309 if (!HasBit(m5, 6)) {
00310 _m[t].m3 = (GB(m5, 1, 2) == 3) ? 1 : 0;
00311 } else {
00312 _m[t].m3 = HasBit(m5, 2) ? 0x10 : 0;
00313 if (GB(m5, 3, 2) == 3) _m[t].m3 |= 1;
00314 if (GB(m5, 3, 2) == 1) _m[t].m5 |= 0x08;
00315 }
00316 } else {
00317 _m[t].m2 = 0;
00318 _m[t].m3 = HasBit(_m[t].m5, 3);
00319 _m[t].m5 &= HasBit(_m[t].m5, 3) ? 0x03 : 0x07 ;
00320 }
00321 break;
00322
00323 case MP_OBJECT:
00324 _m[t].m2 = 0;
00325 _m[t].m3 = 0;
00326 break;
00327
00328 default:
00329 return false;
00330
00331 }
00332 }
00333
00334 FixOldMapArray();
00335
00336 return true;
00337 }
00338
00339 static Engine *_old_engines;
00340
00341 static bool FixTTOEngines()
00342 {
00344 static const EngineID ttd_to_tto[] = {
00345 0, 255, 255, 255, 255, 255, 255, 255, 5, 7, 8, 9, 10, 11, 12, 13,
00346 255, 255, 255, 255, 255, 255, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
00347 25, 26, 27, 28, 29, 30, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
00348 255, 255, 255, 255, 255, 255, 255, 31, 255, 32, 33, 34, 35, 36, 37, 38,
00349 39, 40, 41, 42, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
00350 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
00351 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
00352 255, 255, 255, 255, 44, 45, 46, 255, 255, 255, 255, 47, 48, 255, 49, 50,
00353 255, 255, 255, 255, 51, 52, 255, 53, 54, 255, 55, 56, 255, 57, 58, 255,
00354 59, 60, 255, 61, 62, 255, 63, 64, 255, 65, 66, 255, 255, 255, 255, 255,
00355 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
00356 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
00357 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 67, 68, 69, 70,
00358 71, 255, 255, 76, 77, 255, 255, 78, 79, 80, 81, 82, 83, 84, 85, 86,
00359 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 255,
00360 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 102, 255, 255
00361 };
00362
00364 static const EngineID tto_to_ttd[] = {
00365 0, 0, 8, 8, 8, 8, 8, 9, 10, 11, 12, 13, 14, 15, 15, 22,
00366 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 55,
00367 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 116, 116, 117, 118, 123,
00368 124, 126, 127, 132, 133, 135, 136, 138, 139, 141, 142, 144, 145, 147, 148, 150,
00369 151, 153, 154, 204, 205, 206, 207, 208, 211, 212, 211, 212, 211, 212, 215, 216,
00370 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
00371 233, 234, 235, 236, 237, 238, 253
00372 };
00373
00374 Vehicle *v;
00375 FOR_ALL_VEHICLES(v) {
00376 if (v->engine_type >= lengthof(tto_to_ttd)) return false;
00377 v->engine_type = tto_to_ttd[v->engine_type];
00378 }
00379
00380
00381 uint j = 0;
00382 for (uint i = 0; i < lengthof(_orig_rail_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_TRAIN, i);
00383 for (uint i = 0; i < lengthof(_orig_road_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_ROAD, i);
00384 for (uint i = 0; i < lengthof(_orig_ship_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_SHIP, i);
00385 for (uint i = 0; i < lengthof(_orig_aircraft_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_AIRCRAFT, i);
00386
00387 Date aging_date = min(_date + DAYS_TILL_ORIGINAL_BASE_YEAR, ConvertYMDToDate(2050, 0, 1));
00388
00389 for (EngineID i = 0; i < 256; i++) {
00390 int oi = ttd_to_tto[i];
00391 Engine *e = GetTempDataEngine(i);
00392
00393 if (oi == 255) {
00394
00395 _date += DAYS_TILL_ORIGINAL_BASE_YEAR;
00396 StartupOneEngine(e, aging_date);
00397 e->intro_date -= DAYS_TILL_ORIGINAL_BASE_YEAR;
00398 _date -= DAYS_TILL_ORIGINAL_BASE_YEAR;
00399
00400
00401 if (_date >= e->intro_date && HasBit(e->info.climates, 0)) {
00402 e->flags |= ENGINE_AVAILABLE;
00403 e->company_avail = (CompanyMask)0xFF;
00404 e->age = _date > e->intro_date ? (_date - e->intro_date) / 30 : 0;
00405 }
00406 } else {
00407
00408 Engine *oe = &_old_engines[oi];
00409
00410 e->intro_date = oe->intro_date;
00411 e->age = oe->age;
00412 e->reliability = oe->reliability;
00413 e->reliability_spd_dec = oe->reliability_spd_dec;
00414 e->reliability_start = oe->reliability_start;
00415 e->reliability_max = oe->reliability_max;
00416 e->reliability_final = oe->reliability_final;
00417 e->duration_phase_1 = oe->duration_phase_1;
00418 e->duration_phase_2 = oe->duration_phase_2;
00419 e->duration_phase_3 = oe->duration_phase_3;
00420 e->flags = oe->flags;
00421
00422 e->company_avail = 0;
00423
00424
00425
00426 for (uint j = 0; j < lengthof(tto_to_ttd); j++) {
00427 if (tto_to_ttd[j] == i && _old_engines[j].company_avail != 0) {
00428 e->company_avail = (CompanyMask)0xFF;
00429 e->flags |= ENGINE_AVAILABLE;
00430 break;
00431 }
00432 }
00433
00434 e->info.climates = 1;
00435 }
00436
00437 e->preview_company_rank = 0;
00438 e->preview_wait = 0;
00439 e->name = NULL;
00440 }
00441
00442 return true;
00443 }
00444
00445 static void FixTTOCompanies()
00446 {
00447 Company *c;
00448 FOR_ALL_COMPANIES(c) {
00449 c->cur_economy.company_value = CalculateCompanyValue(c);
00450 }
00451 }
00452
00453 static inline byte RemapTTOColour(byte tto)
00454 {
00456 static const byte tto_colour_remap[] = {
00457 COLOUR_DARK_BLUE, COLOUR_GREY, COLOUR_YELLOW, COLOUR_RED,
00458 COLOUR_PURPLE, COLOUR_DARK_GREEN, COLOUR_ORANGE, COLOUR_PALE_GREEN,
00459 COLOUR_BLUE, COLOUR_GREEN, COLOUR_CREAM, COLOUR_BROWN,
00460 COLOUR_WHITE, COLOUR_LIGHT_BLUE, COLOUR_MAUVE, COLOUR_PINK
00461 };
00462
00463 if ((size_t)tto >= lengthof(tto_colour_remap)) return COLOUR_GREY;
00464
00465 return tto_colour_remap[tto];
00466 }
00467
00468 static inline uint RemapTownIndex(uint x)
00469 {
00470 return _savegame_type == SGT_TTO ? (x - 0x264) / 78 : (x - 0x264) / 94;
00471 }
00472
00473 static inline uint RemapOrderIndex(uint x)
00474 {
00475 return _savegame_type == SGT_TTO ? (x - 0x1AC4) / 2 : (x - 0x1C18) / 2;
00476 }
00477
00478 extern TileIndex *_animated_tile_list;
00479 extern uint _animated_tile_count;
00480 extern char *_old_name_array;
00481
00482 static byte _old_vehicle_multiplier;
00483 static uint32 _old_town_index;
00484 static uint16 _old_string_id;
00485 static uint16 _old_string_id_2;
00486 static uint16 _old_extra_chunk_nums;
00487
00488 static void ReadTTDPatchFlags()
00489 {
00490 if (_read_ttdpatch_flags) return;
00491
00492 _read_ttdpatch_flags = true;
00493
00494 if (_savegame_type == SGT_TTO) {
00495 _old_vehicle_multiplier = 1;
00496 return;
00497 }
00498
00499
00500 _old_vehicle_multiplier = _old_map3[0];
00501
00502
00503 if (_old_vehicle_multiplier < 2) _old_vehicle_multiplier++;
00504
00505 _old_vehicle_names = MallocT<StringID>(_old_vehicle_multiplier * 850);
00506
00507
00508
00509
00510
00511
00512 _bump_assert_value = (_old_vehicle_multiplier - 1) * 850 * 128;
00513
00514 for (uint i = 0; i < 17; i++) {
00515 if (_old_map3[i] != 0) _savegame_type = SGT_TTDP1;
00516 }
00517
00518
00519 if (memcmp(&_old_map3[0x1FFFA], "TTDp", 4) == 0) _savegame_type = SGT_TTDP2;
00520
00521 _old_extra_chunk_nums = _old_map3[_savegame_type == SGT_TTDP2 ? 0x1FFFE : 0x2];
00522
00523
00524 for (uint i = 0; i < 17; i++) _old_map3[i] = 0;
00525 for (uint i = 0x1FE00; i < 0x20000; i++) _old_map3[i] = 0;
00526
00527 if (_savegame_type == SGT_TTDP2) DEBUG(oldloader, 2, "Found TTDPatch game");
00528
00529 DEBUG(oldloader, 3, "Vehicle-multiplier is set to %d (%d vehicles)", _old_vehicle_multiplier, _old_vehicle_multiplier * 850);
00530 }
00531
00532 static const OldChunks town_chunk[] = {
00533 OCL_SVAR( OC_TILE, Town, xy ),
00534 OCL_NULL( 2 ),
00535 OCL_SVAR( OC_UINT16, Town, townnametype ),
00536 OCL_SVAR( OC_UINT32, Town, townnameparts ),
00537 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Town, grow_counter ),
00538 OCL_NULL( 1 ),
00539 OCL_NULL( 4 ),
00540 OCL_NULL( 2 ),
00541 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Town, flags ),
00542 OCL_NULL( 10 ),
00543
00544 OCL_SVAR( OC_INT16, Town, ratings[0] ),
00545 OCL_SVAR( OC_INT16, Town, ratings[1] ),
00546 OCL_SVAR( OC_INT16, Town, ratings[2] ),
00547 OCL_SVAR( OC_INT16, Town, ratings[3] ),
00548 OCL_SVAR( OC_INT16, Town, ratings[4] ),
00549 OCL_SVAR( OC_INT16, Town, ratings[5] ),
00550 OCL_SVAR( OC_INT16, Town, ratings[6] ),
00551 OCL_SVAR( OC_INT16, Town, ratings[7] ),
00552
00553 OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, have_ratings ),
00554 OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, statues ),
00555 OCL_NULL( 2 ),
00556 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Town, time_until_rebuild ),
00557 OCL_SVAR( OC_FILE_U8 | OC_VAR_I16, Town, growth_rate ),
00558
00559 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, new_max_pass ),
00560 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, new_max_mail ),
00561 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, new_act_pass ),
00562 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, new_act_mail ),
00563 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, max_pass ),
00564 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, max_mail ),
00565 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, act_pass ),
00566 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, act_mail ),
00567
00568 OCL_SVAR( OC_UINT8, Town, pct_pass_transported ),
00569 OCL_SVAR( OC_UINT8, Town, pct_mail_transported ),
00570
00571 OCL_SVAR( OC_TTD | OC_UINT16, Town, new_act_food ),
00572 OCL_SVAR( OC_TTD | OC_UINT16, Town, new_act_water ),
00573 OCL_SVAR( OC_TTD | OC_UINT16, Town, act_food ),
00574 OCL_SVAR( OC_TTD | OC_UINT16, Town, act_water ),
00575
00576 OCL_SVAR( OC_UINT8, Town, road_build_months ),
00577 OCL_SVAR( OC_UINT8, Town, fund_buildings_months ),
00578
00579 OCL_CNULL( OC_TTD, 8 ),
00580
00581 OCL_END()
00582 };
00583
00584 static bool LoadOldTown(LoadgameState *ls, int num)
00585 {
00586 Town *t = new (num) Town();
00587 if (!LoadChunk(ls, t, town_chunk)) return false;
00588
00589 if (t->xy != 0) {
00590 if (_savegame_type == SGT_TTO) {
00591
00592 t->townnametype = t->townnametype == 0x10B6 ? 0x20C1 : t->townnametype + 0x2A00;
00593 }
00594 } else {
00595 delete t;
00596 }
00597
00598 return true;
00599 }
00600
00601 static uint16 _old_order;
00602 static const OldChunks order_chunk[] = {
00603 OCL_VAR ( OC_UINT16, 1, &_old_order ),
00604 OCL_END()
00605 };
00606
00607 static bool LoadOldOrder(LoadgameState *ls, int num)
00608 {
00609 if (!LoadChunk(ls, NULL, order_chunk)) return false;
00610
00611 Order *o = new (num) Order();
00612 o->AssignOrder(UnpackOldOrder(_old_order));
00613
00614 if (o->IsType(OT_NOTHING)) {
00615 delete o;
00616 } else {
00617
00618
00619 Order *prev = Order::GetIfValid(num - 1);
00620 if (prev != NULL) prev->next = o;
00621 }
00622
00623 return true;
00624 }
00625
00626 static bool LoadOldAnimTileList(LoadgameState *ls, int num)
00627 {
00628
00629
00630
00631
00632
00633
00634 const OldChunks anim_chunk[] = {
00635 OCL_VAR ( OC_TILE, 256, _animated_tile_list ),
00636 OCL_END ()
00637 };
00638
00639 if (!LoadChunk(ls, NULL, anim_chunk)) return false;
00640
00641
00642 for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
00643 if (_animated_tile_list[_animated_tile_count] == 0) break;
00644 }
00645
00646 return true;
00647 }
00648
00649 static const OldChunks depot_chunk[] = {
00650 OCL_SVAR( OC_TILE, Depot, xy ),
00651 OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
00652 OCL_END()
00653 };
00654
00655 static bool LoadOldDepot(LoadgameState *ls, int num)
00656 {
00657 Depot *d = new (num) Depot();
00658 if (!LoadChunk(ls, d, depot_chunk)) return false;
00659
00660 if (d->xy != 0) {
00661 d->town = Town::Get(RemapTownIndex(_old_town_index));
00662 } else {
00663 delete d;
00664 }
00665
00666 return true;
00667 }
00668
00669 static StationID _current_station_id;
00670 static uint16 _waiting_acceptance;
00671 static uint8 _cargo_source;
00672 static uint8 _cargo_days;
00673
00674 static const OldChunks goods_chunk[] = {
00675 OCL_VAR ( OC_UINT16, 1, &_waiting_acceptance ),
00676 OCL_SVAR( OC_UINT8, GoodsEntry, days_since_pickup ),
00677 OCL_SVAR( OC_UINT8, GoodsEntry, rating ),
00678 OCL_VAR ( OC_UINT8, 1, &_cargo_source ),
00679 OCL_VAR ( OC_UINT8, 1, &_cargo_days ),
00680 OCL_SVAR( OC_UINT8, GoodsEntry, last_speed ),
00681 OCL_SVAR( OC_UINT8, GoodsEntry, last_age ),
00682
00683 OCL_END()
00684 };
00685
00686 static bool LoadOldGood(LoadgameState *ls, int num)
00687 {
00688
00689 if (_savegame_type == SGT_TTO && num == 11) return true;
00690
00691 Station *st = Station::Get(_current_station_id);
00692 GoodsEntry *ge = &st->goods[num];
00693
00694 if (!LoadChunk(ls, ge, goods_chunk)) return false;
00695
00696 SB(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
00697 SB(ge->acceptance_pickup, GoodsEntry::PICKUP, 1, _cargo_source != 0xFF);
00698 if (GB(_waiting_acceptance, 0, 12) != 0) {
00699 ge->cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_days, (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, 0, 0));
00700 }
00701
00702 return true;
00703 }
00704
00705 static const OldChunks station_chunk[] = {
00706 OCL_SVAR( OC_TILE, Station, xy ),
00707 OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
00708
00709 OCL_NULL( 4 ),
00710 OCL_SVAR( OC_TILE, Station, train_station.tile ),
00711 OCL_SVAR( OC_TILE, Station, airport.tile ),
00712 OCL_SVAR( OC_TILE, Station, dock_tile ),
00713 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Station, train_station.w ),
00714
00715 OCL_NULL( 1 ),
00716 OCL_NULL( 2 ),
00717
00718 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
00719
00720 OCL_NULL( 4 ),
00721
00722 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Station, had_vehicle_of_type ),
00723
00724 OCL_CHUNK( 12, LoadOldGood ),
00725
00726 OCL_SVAR( OC_UINT8, Station, time_since_load ),
00727 OCL_SVAR( OC_UINT8, Station, time_since_unload ),
00728 OCL_SVAR( OC_UINT8, Station, delete_ctr ),
00729 OCL_SVAR( OC_UINT8, Station, owner ),
00730 OCL_SVAR( OC_UINT8, Station, facilities ),
00731 OCL_SVAR( OC_TTD | OC_UINT8, Station, airport.type ),
00732 OCL_SVAR( OC_TTO | OC_FILE_U16 | OC_VAR_U64, Station, airport.flags ),
00733 OCL_NULL( 3 ),
00734 OCL_CNULL( OC_TTD, 1 ),
00735 OCL_SVAR( OC_TTD | OC_FILE_U16 | OC_VAR_U64, Station, airport.flags ),
00736 OCL_CNULL( OC_TTD, 2 ),
00737 OCL_CNULL( OC_TTD, 4 ),
00738
00739 OCL_END()
00740 };
00741
00742 static bool LoadOldStation(LoadgameState *ls, int num)
00743 {
00744 Station *st = new (num) Station();
00745 _current_station_id = num;
00746
00747 if (!LoadChunk(ls, st, station_chunk)) return false;
00748
00749 if (st->xy != 0) {
00750 st->town = Town::Get(RemapTownIndex(_old_town_index));
00751
00752 if (_savegame_type == SGT_TTO) {
00753 if (IsInsideBS(_old_string_id, 0x180F, 32)) {
00754 st->string_id = STR_SV_STNAME + (_old_string_id - 0x180F);
00755 } else {
00756 st->string_id = _old_string_id + 0x2800;
00757 }
00758
00759 if (HasBit(st->airport.flags, 8)) {
00760 st->airport.type = 1;
00761 } else if (HasBit(st->airport.flags, 6)) {
00762 st->airport.type = 3;
00763 } else {
00764 st->airport.type = 0;
00765 }
00766 } else {
00767 st->string_id = RemapOldStringID(_old_string_id);
00768 }
00769 } else {
00770 delete st;
00771 }
00772
00773 return true;
00774 }
00775
00776 static const OldChunks industry_chunk[] = {
00777 OCL_SVAR( OC_TILE, Industry, location.tile ),
00778 OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
00779 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Industry, location.w ),
00780 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Industry, location.h ),
00781 OCL_NULL( 2 ),
00782
00783 OCL_SVAR( OC_TTD | OC_UINT16, Industry, produced_cargo_waiting[0] ),
00784 OCL_SVAR( OC_TTD | OC_UINT16, Industry, produced_cargo_waiting[1] ),
00785 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, produced_cargo_waiting[0] ),
00786 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, produced_cargo_waiting[1] ),
00787
00788 OCL_SVAR( OC_UINT8, Industry, production_rate[0] ),
00789 OCL_SVAR( OC_UINT8, Industry, production_rate[1] ),
00790
00791 OCL_NULL( 3 ),
00792
00793 OCL_SVAR( OC_UINT8, Industry, prod_level ),
00794
00795 OCL_SVAR( OC_UINT16, Industry, this_month_production[0] ),
00796 OCL_SVAR( OC_UINT16, Industry, this_month_production[1] ),
00797 OCL_SVAR( OC_UINT16, Industry, this_month_transported[0] ),
00798 OCL_SVAR( OC_UINT16, Industry, this_month_transported[1] ),
00799
00800 OCL_SVAR( OC_UINT8, Industry, last_month_pct_transported[0] ),
00801 OCL_SVAR( OC_UINT8, Industry, last_month_pct_transported[1] ),
00802
00803 OCL_SVAR( OC_UINT16, Industry, last_month_production[0] ),
00804 OCL_SVAR( OC_UINT16, Industry, last_month_production[1] ),
00805 OCL_SVAR( OC_UINT16, Industry, last_month_transported[0] ),
00806 OCL_SVAR( OC_UINT16, Industry, last_month_transported[1] ),
00807
00808 OCL_SVAR( OC_UINT8, Industry, type ),
00809 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, counter ),
00810 OCL_SVAR( OC_UINT8, Industry, owner ),
00811 OCL_SVAR( OC_UINT8, Industry, random_colour ),
00812 OCL_SVAR( OC_TTD | OC_FILE_U8 | OC_VAR_I32, Industry, last_prod_year ),
00813 OCL_SVAR( OC_TTD | OC_UINT16, Industry, counter ),
00814 OCL_SVAR( OC_TTD | OC_UINT8, Industry, was_cargo_delivered ),
00815
00816 OCL_CNULL( OC_TTD, 9 ),
00817
00818 OCL_END()
00819 };
00820
00821 static bool LoadOldIndustry(LoadgameState *ls, int num)
00822 {
00823 Industry *i = new (num) Industry();
00824 if (!LoadChunk(ls, i, industry_chunk)) return false;
00825
00826 if (i->location.tile != 0) {
00827 i->town = Town::Get(RemapTownIndex(_old_town_index));
00828
00829 if (_savegame_type == SGT_TTO) {
00830 if (i->type > 0x06) i->type++;
00831 if (i->type == 0x0A) i->type = 0x12;
00832
00833 YearMonthDay ymd;
00834 ConvertDateToYMD(_date, &ymd);
00835 i->last_prod_year = ymd.year;
00836
00837 i->random_colour = RemapTTOColour(i->random_colour);
00838 }
00839
00840 Industry::IncIndustryTypeCount(i->type);
00841 } else {
00842 delete i;
00843 }
00844
00845 return true;
00846 }
00847
00848 static CompanyID _current_company_id;
00849 static int32 _old_yearly;
00850
00851 static const OldChunks _company_yearly_chunk[] = {
00852 OCL_VAR( OC_INT32, 1, &_old_yearly ),
00853 OCL_END()
00854 };
00855
00856 static bool LoadOldCompanyYearly(LoadgameState *ls, int num)
00857 {
00858 Company *c = Company::Get(_current_company_id);
00859
00860 for (uint i = 0; i < 13; i++) {
00861 if (_savegame_type == SGT_TTO && i == 6) {
00862 _old_yearly = 0;
00863 } else {
00864 if (!LoadChunk(ls, NULL, _company_yearly_chunk)) return false;
00865 }
00866
00867 c->yearly_expenses[num][i] = _old_yearly;
00868 }
00869
00870 return true;
00871 }
00872
00873 static const OldChunks _company_economy_chunk[] = {
00874 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, income ),
00875 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, expenses ),
00876 OCL_SVAR( OC_INT32, CompanyEconomyEntry, delivered_cargo ),
00877 OCL_SVAR( OC_INT32, CompanyEconomyEntry, performance_history ),
00878 OCL_SVAR( OC_TTD | OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, company_value ),
00879
00880 OCL_END()
00881 };
00882
00883 static bool LoadOldCompanyEconomy(LoadgameState *ls, int num)
00884 {
00885 Company *c = Company::Get(_current_company_id);
00886
00887 if (!LoadChunk(ls, &c->cur_economy, _company_economy_chunk)) return false;
00888
00889
00890 c->cur_economy.income = -c->cur_economy.income;
00891 c->cur_economy.expenses = -c->cur_economy.expenses;
00892
00893 for (uint i = 0; i < 24; i++) {
00894 if (!LoadChunk(ls, &c->old_economy[i], _company_economy_chunk)) return false;
00895
00896 c->old_economy[i].income = -c->old_economy[i].income;
00897 c->old_economy[i].expenses = -c->old_economy[i].expenses;
00898 }
00899
00900 return true;
00901 }
00902
00903 static const OldChunks _company_chunk[] = {
00904 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
00905 OCL_SVAR( OC_UINT32, Company, name_2 ),
00906 OCL_SVAR( OC_UINT32, Company, face ),
00907 OCL_VAR ( OC_UINT16, 1, &_old_string_id_2 ),
00908 OCL_SVAR( OC_UINT32, Company, president_name_2 ),
00909
00910 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Company, money ),
00911 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Company, current_loan ),
00912
00913 OCL_SVAR( OC_UINT8, Company, colour ),
00914 OCL_SVAR( OC_UINT8, Company, money_fraction ),
00915 OCL_SVAR( OC_UINT8, Company, quarters_of_bankruptcy ),
00916 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Company, bankrupt_asked ),
00917 OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Company, bankrupt_value ),
00918 OCL_SVAR( OC_UINT16, Company, bankrupt_timeout ),
00919
00920 OCL_SVAR( OC_TTD | OC_UINT32, Company, cargo_types ),
00921 OCL_SVAR( OC_TTO | OC_FILE_U16 | OC_VAR_U32, Company, cargo_types ),
00922
00923 OCL_CHUNK( 3, LoadOldCompanyYearly ),
00924 OCL_CHUNK( 1, LoadOldCompanyEconomy ),
00925
00926 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Company, inaugurated_year),
00927 OCL_SVAR( OC_TILE, Company, last_build_coordinate ),
00928 OCL_SVAR( OC_UINT8, Company, num_valid_stat_ent ),
00929
00930 OCL_NULL( 230 ),
00931
00932 OCL_SVAR( OC_UINT8, Company, block_preview ),
00933 OCL_CNULL( OC_TTD, 1 ),
00934 OCL_SVAR( OC_TTD | OC_UINT8, Company, avail_railtypes ),
00935 OCL_SVAR( OC_TILE, Company, location_of_HQ ),
00936 OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[0] ),
00937 OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[1] ),
00938 OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[2] ),
00939 OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[3] ),
00940
00941 OCL_CNULL( OC_TTD, 8 ),
00942
00943 OCL_END()
00944 };
00945
00946 static bool LoadOldCompany(LoadgameState *ls, int num)
00947 {
00948 Company *c = new (num) Company();
00949
00950 _current_company_id = (CompanyID)num;
00951
00952 if (!LoadChunk(ls, c, _company_chunk)) return false;
00953
00954 if (_old_string_id == 0) {
00955 delete c;
00956 return true;
00957 }
00958
00959 if (_savegame_type == SGT_TTO) {
00960
00961 if (HasBit(c->face, 27) && GB(c->face, 26, 1) == GB(c->face, 19, 1)) {
00962
00963 ClrBit(c->face, 27);
00964 }
00965
00966
00967 if (_old_string_id == 0 || _old_string_id == 0x4C00) {
00968 _old_string_id = STR_SV_UNNAMED;
00969 } else if (GB(_old_string_id, 8, 8) == 0x52) {
00970 _old_string_id += 0x2A00;
00971 } else {
00972 _old_string_id = RemapOldStringID(_old_string_id += 0x240D);
00973 }
00974 c->name_1 = _old_string_id;
00975
00976
00977 switch (_old_string_id_2) {
00978 case 0x4CDA: _old_string_id_2 = SPECSTR_PRESIDENT_NAME; break;
00979 case 0x0006: _old_string_id_2 = STR_SV_EMPTY; break;
00980 default: _old_string_id_2 = _old_string_id_2 + 0x2A00; break;
00981 }
00982 c->president_name_1 = _old_string_id_2;
00983
00984 c->colour = RemapTTOColour(c->colour);
00985
00986 if (num != 0) c->is_ai = true;
00987 } else {
00988 c->name_1 = RemapOldStringID(_old_string_id);
00989 c->president_name_1 = RemapOldStringID(_old_string_id_2);
00990
00991 if (num == 0) {
00992
00993 if (c->name_1 == 0) {
00994 c->name_1 = STR_SV_UNNAMED;
00995 }
00996 } else {
00997
00998
00999 c->is_ai = true;
01000 }
01001
01002
01003
01004
01005
01006
01007 if (c->money == 893288) c->money = c->current_loan = 100000;
01008 }
01009
01010 _company_colours[num] = (Colours)c->colour;
01011 c->inaugurated_year -= ORIGINAL_BASE_YEAR;
01012
01013 return true;
01014 }
01015
01016 static uint32 _old_order_ptr;
01017 static uint16 _old_next_ptr;
01018 static VehicleID _current_vehicle_id;
01019
01020 static const OldChunks vehicle_train_chunk[] = {
01021 OCL_SVAR( OC_UINT8, Train, track ),
01022 OCL_SVAR( OC_UINT8, Train, force_proceed ),
01023 OCL_SVAR( OC_UINT16, Train, crash_anim_pos ),
01024 OCL_SVAR( OC_UINT8, Train, railtype ),
01025
01026 OCL_NULL( 5 ),
01027
01028 OCL_END()
01029 };
01030
01031 static const OldChunks vehicle_road_chunk[] = {
01032 OCL_SVAR( OC_UINT8, RoadVehicle, state ),
01033 OCL_SVAR( OC_UINT8, RoadVehicle, frame ),
01034 OCL_SVAR( OC_UINT16, RoadVehicle, blocked_ctr ),
01035 OCL_SVAR( OC_UINT8, RoadVehicle, overtaking ),
01036 OCL_SVAR( OC_UINT8, RoadVehicle, overtaking_ctr ),
01037 OCL_SVAR( OC_UINT16, RoadVehicle, crashed_ctr ),
01038 OCL_SVAR( OC_UINT8, RoadVehicle, reverse_ctr ),
01039
01040 OCL_NULL( 1 ),
01041
01042 OCL_END()
01043 };
01044
01045 static const OldChunks vehicle_ship_chunk[] = {
01046 OCL_SVAR( OC_UINT8, Ship, state ),
01047
01048 OCL_NULL( 9 ),
01049
01050 OCL_END()
01051 };
01052
01053 static const OldChunks vehicle_air_chunk[] = {
01054 OCL_SVAR( OC_UINT8, Aircraft, pos ),
01055 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Aircraft, targetairport ),
01056 OCL_SVAR( OC_UINT16, Aircraft, crashed_counter ),
01057 OCL_SVAR( OC_UINT8, Aircraft, state ),
01058
01059 OCL_NULL( 5 ),
01060
01061 OCL_END()
01062 };
01063
01064 static const OldChunks vehicle_effect_chunk[] = {
01065 OCL_SVAR( OC_UINT16, EffectVehicle, animation_state ),
01066 OCL_SVAR( OC_UINT8, EffectVehicle, animation_substate ),
01067
01068 OCL_NULL( 7 ),
01069
01070 OCL_END()
01071 };
01072
01073 static const OldChunks vehicle_disaster_chunk[] = {
01074 OCL_SVAR( OC_UINT16, DisasterVehicle, image_override ),
01075 OCL_SVAR( OC_UINT16, DisasterVehicle, big_ufo_destroyer_target ),
01076
01077 OCL_NULL( 6 ),
01078
01079 OCL_END()
01080 };
01081
01082 static const OldChunks vehicle_empty_chunk[] = {
01083 OCL_NULL( 10 ),
01084
01085 OCL_END()
01086 };
01087
01088 static bool LoadOldVehicleUnion(LoadgameState *ls, int num)
01089 {
01090 Vehicle *v = Vehicle::GetIfValid(_current_vehicle_id);
01091 uint temp = ls->total_read;
01092 bool res;
01093
01094 if (v == NULL) {
01095 res = LoadChunk(ls, NULL, vehicle_empty_chunk);
01096 } else {
01097 switch (v->type) {
01098 default: SlErrorCorrupt("Invalid vehicle type");
01099 case VEH_TRAIN : res = LoadChunk(ls, v, vehicle_train_chunk); break;
01100 case VEH_ROAD : res = LoadChunk(ls, v, vehicle_road_chunk); break;
01101 case VEH_SHIP : res = LoadChunk(ls, v, vehicle_ship_chunk); break;
01102 case VEH_AIRCRAFT: res = LoadChunk(ls, v, vehicle_air_chunk); break;
01103 case VEH_EFFECT : res = LoadChunk(ls, v, vehicle_effect_chunk); break;
01104 case VEH_DISASTER: res = LoadChunk(ls, v, vehicle_disaster_chunk); break;
01105 }
01106 }
01107
01108
01109 if (ls->total_read - temp != 10) {
01110 DEBUG(oldloader, 0, "Assert failed in VehicleUnion: invalid chunk size");
01111 return false;
01112 }
01113
01114 return res;
01115 }
01116
01117 static uint16 _cargo_count;
01118
01119 static const OldChunks vehicle_chunk[] = {
01120 OCL_SVAR( OC_UINT8, Vehicle, subtype ),
01121
01122 OCL_NULL( 2 ),
01123 OCL_NULL( 2 ),
01124
01125 OCL_VAR ( OC_UINT32, 1, &_old_order_ptr ),
01126 OCL_VAR ( OC_UINT16, 1, &_old_order ),
01127
01128 OCL_NULL ( 1 ),
01129 OCL_SVAR( OC_UINT8, Vehicle, cur_order_index ),
01130 OCL_SVAR( OC_TILE, Vehicle, dest_tile ),
01131 OCL_SVAR( OC_UINT16, Vehicle, load_unload_ticks ),
01132 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, date_of_last_service ),
01133 OCL_SVAR( OC_UINT16, Vehicle, service_interval ),
01134 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, last_station_visited ),
01135 OCL_SVAR( OC_TTD | OC_UINT8, Vehicle, tick_counter ),
01136 OCL_CNULL( OC_TTD, 2 ),
01137 OCL_CNULL( OC_TTO, 1 ),
01138
01139 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, x_pos ),
01140 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, y_pos ),
01141 OCL_SVAR( OC_UINT8, Vehicle, z_pos ),
01142 OCL_SVAR( OC_UINT8, Vehicle, direction ),
01143 OCL_NULL( 2 ),
01144 OCL_NULL( 2 ),
01145 OCL_NULL( 1 ),
01146
01147 OCL_SVAR( OC_UINT8, Vehicle, owner ),
01148 OCL_SVAR( OC_TILE, Vehicle, tile ),
01149 OCL_SVAR( OC_UINT16, Vehicle, cur_image ),
01150
01151 OCL_NULL( 8 ),
01152
01153 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Vehicle, vehstatus ),
01154 OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, cur_speed ),
01155 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, cur_speed ),
01156 OCL_SVAR( OC_UINT8, Vehicle, subspeed ),
01157 OCL_SVAR( OC_UINT8, Vehicle, acceleration ),
01158 OCL_SVAR( OC_UINT8, Vehicle, progress ),
01159
01160 OCL_SVAR( OC_UINT8, Vehicle, cargo_type ),
01161 OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, cargo_cap ),
01162 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, cargo_cap ),
01163 OCL_VAR ( OC_TTD | OC_UINT16, 1, &_cargo_count ),
01164 OCL_VAR ( OC_TTO | OC_FILE_U8 | OC_VAR_U16, 1, &_cargo_count ),
01165 OCL_VAR ( OC_UINT8, 1, &_cargo_source ),
01166 OCL_VAR ( OC_UINT8, 1, &_cargo_days ),
01167
01168 OCL_SVAR( OC_TTO | OC_UINT8, Vehicle, tick_counter ),
01169
01170 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, age ),
01171 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, max_age ),
01172 OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Vehicle, build_year ),
01173 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, unitnumber ),
01174
01175 OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, engine_type ),
01176 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, engine_type ),
01177
01178 OCL_SVAR( OC_UINT8, Vehicle, spritenum ),
01179 OCL_SVAR( OC_UINT8, Vehicle, day_counter ),
01180
01181 OCL_SVAR( OC_UINT8, Vehicle, breakdowns_since_last_service ),
01182 OCL_SVAR( OC_UINT8, Vehicle, breakdown_ctr ),
01183 OCL_SVAR( OC_UINT8, Vehicle, breakdown_delay ),
01184 OCL_SVAR( OC_UINT8, Vehicle, breakdown_chance ),
01185
01186 OCL_CNULL( OC_TTO, 1 ),
01187
01188 OCL_SVAR( OC_UINT16, Vehicle, reliability ),
01189 OCL_SVAR( OC_UINT16, Vehicle, reliability_spd_dec ),
01190
01191 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_this_year ),
01192 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_last_year ),
01193
01194 OCL_VAR ( OC_UINT16, 1, &_old_next_ptr ),
01195
01196 OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Vehicle, value ),
01197
01198 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
01199
01200 OCL_CHUNK( 1, LoadOldVehicleUnion ),
01201
01202 OCL_CNULL( OC_TTO, 24 ),
01203 OCL_CNULL( OC_TTD, 20 ),
01204
01205 OCL_END()
01206 };
01207
01208 bool LoadOldVehicle(LoadgameState *ls, int num)
01209 {
01210
01211 ReadTTDPatchFlags();
01212
01213 for (uint i = 0; i < _old_vehicle_multiplier; i++) {
01214 _current_vehicle_id = num * _old_vehicle_multiplier + i;
01215
01216 Vehicle *v;
01217
01218 if (_savegame_type == SGT_TTO) {
01219 uint type = ReadByte(ls);
01220 switch (type) {
01221 default: return false;
01222 case 0x00 : v = NULL; break;
01223 case 0x25 :
01224 case 0x20 : v = new (_current_vehicle_id) Train(); break;
01225 case 0x21 : v = new (_current_vehicle_id) RoadVehicle(); break;
01226 case 0x22 : v = new (_current_vehicle_id) Ship(); break;
01227 case 0x23 : v = new (_current_vehicle_id) Aircraft(); break;
01228 case 0x24 : v = new (_current_vehicle_id) EffectVehicle(); break;
01229 case 0x26 : v = new (_current_vehicle_id) DisasterVehicle(); break;
01230 }
01231
01232 if (!LoadChunk(ls, v, vehicle_chunk)) return false;
01233 if (v == NULL) continue;
01234
01235 SpriteID sprite = v->cur_image;
01236
01237 if (IsInsideMM(sprite, 1460, 1465)) {
01238 sprite += 580;
01239 } else if (IsInsideMM(sprite, 2096, 2115)) {
01240 sprite += 977;
01241 } else if (IsInsideMM(sprite, 2396, 2436)) {
01242 sprite += 1305;
01243 } else if (IsInsideMM(sprite, 2516, 2539)) {
01244 sprite += 1385;
01245 }
01246 v->cur_image = sprite;
01247
01248 switch (v->type) {
01249 case VEH_TRAIN: {
01250 static const byte spriteset_rail[] = {
01251 0, 2, 4, 4, 8, 10, 12, 14, 16, 18, 20, 22, 40, 42, 44, 46,
01252 48, 52, 54, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 120, 122,
01253 124, 126, 128, 130, 132, 134, 136, 138, 140
01254 };
01255 if (v->spritenum / 2 >= lengthof(spriteset_rail)) return false;
01256 v->spritenum = spriteset_rail[v->spritenum / 2];
01257 Train::From(v)->railtype = type == 0x25 ? 1 : 0;
01258 break;
01259 }
01260
01261 case VEH_ROAD:
01262 if (v->spritenum >= 22) v->spritenum += 12;
01263 break;
01264
01265 case VEH_SHIP:
01266 v->spritenum += 2;
01267
01268 switch (v->spritenum) {
01269 case 2:
01270 if (v->cargo_type != CT_OIL) v->spritenum = 0;
01271 break;
01272 case 4:
01273 if (v->cargo_type == CT_MAIL) v->spritenum = 0;
01274 break;
01275 default:
01276 break;
01277 }
01278 break;
01279
01280 default:
01281 break;
01282 }
01283
01284 switch (_old_string_id) {
01285 case 0x0000: break;
01286 case 0x0006: _old_string_id = STR_SV_EMPTY; break;
01287 case 0x8495: _old_string_id = STR_SV_TRAIN_NAME; break;
01288 case 0x8842: _old_string_id = STR_SV_ROAD_VEHICLE_NAME; break;
01289 case 0x8C3B: _old_string_id = STR_SV_SHIP_NAME; break;
01290 case 0x9047: _old_string_id = STR_SV_AIRCRAFT_NAME; break;
01291 default: _old_string_id += 0x2A00; break;
01292 }
01293
01294 _old_vehicle_names[_current_vehicle_id] = _old_string_id;
01295 } else {
01296
01297 switch (ReadByte(ls)) {
01298 default: SlErrorCorrupt("Invalid vehicle type");
01299 case 0x00 : v = NULL; break;
01300 case 0x10 : v = new (_current_vehicle_id) Train(); break;
01301 case 0x11 : v = new (_current_vehicle_id) RoadVehicle(); break;
01302 case 0x12 : v = new (_current_vehicle_id) Ship(); break;
01303 case 0x13 : v = new (_current_vehicle_id) Aircraft(); break;
01304 case 0x14 : v = new (_current_vehicle_id) EffectVehicle(); break;
01305 case 0x15 : v = new (_current_vehicle_id) DisasterVehicle(); break;
01306 }
01307
01308 if (!LoadChunk(ls, v, vehicle_chunk)) return false;
01309 if (v == NULL) continue;
01310
01311 _old_vehicle_names[_current_vehicle_id] = RemapOldStringID(_old_string_id);
01312
01313
01314 if (v->index != _current_vehicle_id) {
01315 DEBUG(oldloader, 0, "Loading failed - vehicle-array is invalid");
01316 return false;
01317 }
01318 }
01319
01320 if (_old_order_ptr != 0 && _old_order_ptr != 0xFFFFFFFF) {
01321 uint max = _savegame_type == SGT_TTO ? 3000 : 5000;
01322 uint old_id = RemapOrderIndex(_old_order_ptr);
01323 if (old_id < max) v->orders.old = Order::Get(old_id);
01324 }
01325 v->current_order.AssignOrder(UnpackOldOrder(_old_order));
01326
01327 v->next = (Vehicle *)(size_t)_old_next_ptr;
01328
01329 if (_cargo_count != 0) {
01330 StationID source = (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
01331 TileIndex source_xy = (source != INVALID_STATION) ? Station::Get(source)->xy : 0;
01332 v->cargo.Append(new CargoPacket(_cargo_count, _cargo_days, source, source_xy, source_xy));
01333 }
01334 }
01335
01336 return true;
01337 }
01338
01339 static const OldChunks sign_chunk[] = {
01340 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
01341 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, x ),
01342 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, y ),
01343 OCL_SVAR( OC_FILE_U16 | OC_VAR_I8, Sign, z ),
01344
01345 OCL_NULL( 6 ),
01346
01347 OCL_END()
01348 };
01349
01350 static bool LoadOldSign(LoadgameState *ls, int num)
01351 {
01352 Sign *si = new (num) Sign();
01353 if (!LoadChunk(ls, si, sign_chunk)) return false;
01354
01355 if (_old_string_id != 0) {
01356 if (_savegame_type == SGT_TTO) {
01357 if (_old_string_id != 0x140A) si->name = CopyFromOldName(_old_string_id + 0x2A00);
01358 } else {
01359 si->name = CopyFromOldName(RemapOldStringID(_old_string_id));
01360 }
01361 si->owner = OWNER_NONE;
01362 } else {
01363 delete si;
01364 }
01365
01366 return true;
01367 }
01368
01369 static const OldChunks engine_chunk[] = {
01370 OCL_SVAR( OC_UINT16, Engine, company_avail ),
01371 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, intro_date ),
01372 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, age ),
01373 OCL_SVAR( OC_UINT16, Engine, reliability ),
01374 OCL_SVAR( OC_UINT16, Engine, reliability_spd_dec ),
01375 OCL_SVAR( OC_UINT16, Engine, reliability_start ),
01376 OCL_SVAR( OC_UINT16, Engine, reliability_max ),
01377 OCL_SVAR( OC_UINT16, Engine, reliability_final ),
01378 OCL_SVAR( OC_UINT16, Engine, duration_phase_1 ),
01379 OCL_SVAR( OC_UINT16, Engine, duration_phase_2 ),
01380 OCL_SVAR( OC_UINT16, Engine, duration_phase_3 ),
01381
01382 OCL_NULL( 1 ),
01383 OCL_SVAR( OC_UINT8, Engine, flags ),
01384 OCL_SVAR( OC_UINT8, Engine, preview_company_rank ),
01385 OCL_SVAR( OC_UINT8, Engine, preview_wait ),
01386
01387 OCL_CNULL( OC_TTD, 2 ),
01388
01389 OCL_END()
01390 };
01391
01392 static bool LoadOldEngine(LoadgameState *ls, int num)
01393 {
01394 Engine *e = _savegame_type == SGT_TTO ? &_old_engines[num] : GetTempDataEngine(num);
01395 return LoadChunk(ls, e, engine_chunk);
01396 }
01397
01398 static bool LoadOldEngineName(LoadgameState *ls, int num)
01399 {
01400 Engine *e = GetTempDataEngine(num);
01401 e->name = CopyFromOldName(RemapOldStringID(ReadUint16(ls)));
01402 return true;
01403 }
01404
01405 static const OldChunks subsidy_chunk[] = {
01406 OCL_SVAR( OC_UINT8, Subsidy, cargo_type ),
01407 OCL_SVAR( OC_UINT8, Subsidy, remaining ),
01408 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Subsidy, src ),
01409 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Subsidy, dst ),
01410
01411 OCL_END()
01412 };
01413
01414 static bool LoadOldSubsidy(LoadgameState *ls, int num)
01415 {
01416 Subsidy *s = new (num) Subsidy();
01417 bool ret = LoadChunk(ls, s, subsidy_chunk);
01418 if (s->cargo_type == CT_INVALID) delete s;
01419 return ret;
01420 }
01421
01422 static const OldChunks game_difficulty_chunk[] = {
01423 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, max_no_competitors ),
01424 OCL_NULL( 2),
01425 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, number_towns ),
01426 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, number_industries ),
01427 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, DifficultySettings, max_loan ),
01428 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, initial_interest ),
01429 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, vehicle_costs ),
01430 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, competitor_speed ),
01431 OCL_NULL( 2),
01432 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, vehicle_breakdowns ),
01433 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, subsidy_multiplier ),
01434 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, construction_cost ),
01435 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, terrain_type ),
01436 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, quantity_sea_lakes ),
01437 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, economy ),
01438 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, line_reverse_mode ),
01439 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, disasters ),
01440 OCL_END()
01441 };
01442
01443 static bool LoadOldGameDifficulty(LoadgameState *ls, int num)
01444 {
01445 bool ret = LoadChunk(ls, &_settings_game.difficulty, game_difficulty_chunk);
01446 _settings_game.difficulty.max_loan *= 1000;
01447 return ret;
01448 }
01449
01450
01451 static bool LoadOldMapPart1(LoadgameState *ls, int num)
01452 {
01453 if (_savegame_type == SGT_TTO) {
01454 MemSetT(_m, 0, OLD_MAP_SIZE);
01455 MemSetT(_me, 0, OLD_MAP_SIZE);
01456 }
01457
01458 for (uint i = 0; i < OLD_MAP_SIZE; i++) {
01459 _m[i].m1 = ReadByte(ls);
01460 }
01461 for (uint i = 0; i < OLD_MAP_SIZE; i++) {
01462 _m[i].m2 = ReadByte(ls);
01463 }
01464
01465 if (_savegame_type != SGT_TTO) {
01466 for (uint i = 0; i < OLD_MAP_SIZE; i++) {
01467 _old_map3[i * 2] = ReadByte(ls);
01468 _old_map3[i * 2 + 1] = ReadByte(ls);
01469 }
01470 for (uint i = 0; i < OLD_MAP_SIZE / 4; i++) {
01471 byte b = ReadByte(ls);
01472 _m[i * 4 + 0].m6 = GB(b, 0, 2);
01473 _m[i * 4 + 1].m6 = GB(b, 2, 2);
01474 _m[i * 4 + 2].m6 = GB(b, 4, 2);
01475 _m[i * 4 + 3].m6 = GB(b, 6, 2);
01476 }
01477 }
01478
01479 return true;
01480 }
01481
01482 static bool LoadOldMapPart2(LoadgameState *ls, int num)
01483 {
01484 uint i;
01485
01486 for (i = 0; i < OLD_MAP_SIZE; i++) {
01487 _m[i].type_height = ReadByte(ls);
01488 }
01489 for (i = 0; i < OLD_MAP_SIZE; i++) {
01490 _m[i].m5 = ReadByte(ls);
01491 }
01492
01493 return true;
01494 }
01495
01496 static bool LoadTTDPatchExtraChunks(LoadgameState *ls, int num)
01497 {
01498 ReadTTDPatchFlags();
01499
01500 DEBUG(oldloader, 2, "Found %d extra chunk(s)", _old_extra_chunk_nums);
01501
01502 for (int i = 0; i != _old_extra_chunk_nums; i++) {
01503 uint16 id = ReadUint16(ls);
01504 uint32 len = ReadUint32(ls);
01505
01506 switch (id) {
01507
01508
01509 case 0x2:
01510 case 0x8004: {
01511
01512 ReadUint32(ls); ReadByte(ls); len -= 5;
01513
01514 ClearGRFConfigList(&_grfconfig);
01515 while (len != 0) {
01516 uint32 grfid = ReadUint32(ls);
01517
01518 if (ReadByte(ls) == 1) {
01519 GRFConfig *c = new GRFConfig("TTDP game, no information");
01520 c->ident.grfid = grfid;
01521
01522 AppendToGRFConfigList(&_grfconfig, c);
01523 DEBUG(oldloader, 3, "TTDPatch game using GRF file with GRFID %0X", BSWAP32(c->ident.grfid));
01524 }
01525 len -= 5;
01526 };
01527
01528
01529 AppendStaticGRFConfigs(&_grfconfig);
01530 break;
01531 }
01532
01533
01534 case 0x3:
01535 _ttdp_version = ReadUint32(ls);
01536 DEBUG(oldloader, 3, "Game saved with TTDPatch version %d.%d.%d r%d",
01537 GB(_ttdp_version, 24, 8), GB(_ttdp_version, 20, 4), GB(_ttdp_version, 16, 4), GB(_ttdp_version, 0, 16));
01538 len -= 4;
01539 while (len-- != 0) ReadByte(ls);
01540 break;
01541
01542 default:
01543 DEBUG(oldloader, 4, "Skipping unknown extra chunk %X", id);
01544 while (len-- != 0) ReadByte(ls);
01545 break;
01546 }
01547 }
01548
01549 return true;
01550 }
01551
01552 extern TileIndex _cur_tileloop_tile;
01553 extern uint16 _disaster_delay;
01554 extern byte _trees_tick_ctr;
01555 static const OldChunks main_chunk[] = {
01556 OCL_ASSERT( OC_TTD, 0 ),
01557 OCL_ASSERT( OC_TTO, 0 ),
01558 OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_date ),
01559 OCL_VAR ( OC_UINT16, 1, &_date_fract ),
01560 OCL_NULL( 600 ),
01561 OCL_VAR ( OC_UINT32, 2, &_random.state ),
01562
01563 OCL_ASSERT( OC_TTD, 0x264 ),
01564 OCL_ASSERT( OC_TTO, 0x264 ),
01565
01566 OCL_CCHUNK( OC_TTD, 70, LoadOldTown ),
01567 OCL_CCHUNK( OC_TTO, 80, LoadOldTown ),
01568
01569 OCL_ASSERT( OC_TTD, 0x1C18 ),
01570 OCL_ASSERT( OC_TTO, 0x1AC4 ),
01571
01572 OCL_CCHUNK( OC_TTD, 5000, LoadOldOrder ),
01573 OCL_CCHUNK( OC_TTO, 3000, LoadOldOrder ),
01574
01575 OCL_ASSERT( OC_TTD, 0x4328 ),
01576 OCL_ASSERT( OC_TTO, 0x3234 ),
01577
01578 OCL_CHUNK( 1, LoadOldAnimTileList ),
01579 OCL_NULL( 4 ),
01580
01581 OCL_ASSERT( OC_TTO, 0x3438 ),
01582
01583 OCL_CCHUNK( OC_TTD, 255, LoadOldDepot ),
01584 OCL_CCHUNK( OC_TTO, 252, LoadOldDepot ),
01585
01586 OCL_ASSERT( OC_TTD, 0x4B26 ),
01587 OCL_ASSERT( OC_TTO, 0x3A20 ),
01588
01589 OCL_NULL( 4 ),
01590 OCL_NULL( 2 ),
01591 OCL_NULL( 2 ),
01592
01593 OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_age_cargo_skip_counter ),
01594 OCL_VAR ( OC_UINT16, 1, &_tick_counter ),
01595 OCL_VAR ( OC_TILE, 1, &_cur_tileloop_tile ),
01596
01597 OCL_ASSERT( OC_TTO, 0x3A2E ),
01598
01599 OCL_CNULL( OC_TTO, 48 * 6 ),
01600 OCL_CNULL( OC_TTD, 49 * 6 ),
01601
01602 OCL_ASSERT( OC_TTO, 0x3B4E ),
01603
01604 OCL_CNULL( OC_TTO, 11 * 8 ),
01605 OCL_CNULL( OC_TTD, 12 * 8 ),
01606
01607 OCL_ASSERT( OC_TTD, 0x4CBA ),
01608 OCL_ASSERT( OC_TTO, 0x3BA6 ),
01609
01610 OCL_CHUNK( 1, LoadOldMapPart1 ),
01611
01612 OCL_ASSERT( OC_TTD, 0x48CBA ),
01613 OCL_ASSERT( OC_TTO, 0x23BA6 ),
01614
01615 OCL_CCHUNK( OC_TTD, 250, LoadOldStation ),
01616 OCL_CCHUNK( OC_TTO, 200, LoadOldStation ),
01617
01618 OCL_ASSERT( OC_TTO, 0x29E16 ),
01619
01620 OCL_CCHUNK( OC_TTD, 90, LoadOldIndustry ),
01621 OCL_CCHUNK( OC_TTO, 100, LoadOldIndustry ),
01622
01623 OCL_ASSERT( OC_TTO, 0x2ADB6 ),
01624
01625 OCL_CHUNK( 8, LoadOldCompany ),
01626
01627 OCL_ASSERT( OC_TTD, 0x547F2 ),
01628 OCL_ASSERT( OC_TTO, 0x2C746 ),
01629
01630 OCL_CCHUNK( OC_TTD, 850, LoadOldVehicle ),
01631 OCL_CCHUNK( OC_TTO, 800, LoadOldVehicle ),
01632
01633 OCL_ASSERT( OC_TTD, 0x6F0F2 ),
01634 OCL_ASSERT( OC_TTO, 0x45746 ),
01635
01636 OCL_VAR ( OC_TTD | OC_UINT8 | OC_DEREFERENCE_POINTER, 32 * 500, &_old_name_array ),
01637 OCL_VAR ( OC_TTO | OC_UINT8 | OC_DEREFERENCE_POINTER, 24 * 200, &_old_name_array ),
01638
01639 OCL_ASSERT( OC_TTO, 0x46A06 ),
01640
01641 OCL_NULL( 0x2000 ),
01642
01643 OCL_CHUNK( 40, LoadOldSign ),
01644
01645 OCL_ASSERT( OC_TTO, 0x48C36 ),
01646
01647 OCL_CCHUNK( OC_TTD, 256, LoadOldEngine ),
01648 OCL_CCHUNK( OC_TTO, 103, LoadOldEngine ),
01649
01650 OCL_ASSERT( OC_TTO, 0x496AC ),
01651
01652 OCL_VAR ( OC_UINT16, 1, &_vehicle_id_ctr_day ),
01653
01654 OCL_CHUNK( 8, LoadOldSubsidy ),
01655
01656 OCL_ASSERT( OC_TTO, 0x496CE ),
01657
01658 OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_next_competitor_start ),
01659
01660 OCL_CNULL( OC_TTO, 2 ),
01661
01662 OCL_VAR ( OC_FILE_I16 | OC_VAR_I32, 1, &_saved_scrollpos_x ),
01663 OCL_VAR ( OC_FILE_I16 | OC_VAR_I32, 1, &_saved_scrollpos_y ),
01664 OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_saved_scrollpos_zoom ),
01665
01666 OCL_NULL( 4 ),
01667 OCL_VAR ( OC_FILE_U32 | OC_VAR_I64, 1, &_economy.old_max_loan_unround ),
01668 OCL_VAR ( OC_INT16, 1, &_economy.fluct ),
01669
01670 OCL_VAR ( OC_UINT16, 1, &_disaster_delay ),
01671
01672 OCL_ASSERT( OC_TTO, 0x496E4 ),
01673
01674 OCL_CNULL( OC_TTD, 144 ),
01675
01676 OCL_CCHUNK( OC_TTD, 256, LoadOldEngineName ),
01677
01678 OCL_CNULL( OC_TTD, 144 ),
01679 OCL_NULL( 2 ),
01680 OCL_NULL( 1 ),
01681
01682 OCL_VAR ( OC_UINT8, 1, &_settings_game.locale.currency ),
01683 OCL_VAR ( OC_UINT8, 1, &_settings_game.locale.units ),
01684 OCL_VAR ( OC_FILE_U8 | OC_VAR_U32, 1, &_cur_company_tick_index ),
01685
01686 OCL_NULL( 2 ),
01687 OCL_NULL( 8 ),
01688
01689 OCL_VAR ( OC_UINT8, 1, &_economy.infl_amount ),
01690 OCL_VAR ( OC_UINT8, 1, &_economy.infl_amount_pr ),
01691 OCL_VAR ( OC_UINT8, 1, &_economy.interest_rate ),
01692 OCL_NULL( 1 ),
01693 OCL_VAR ( OC_UINT8, 1, &_settings_game.vehicle.road_side ),
01694 OCL_VAR ( OC_UINT8, 1, &_settings_game.game_creation.town_name ),
01695
01696 OCL_CHUNK( 1, LoadOldGameDifficulty ),
01697
01698 OCL_ASSERT( OC_TTD, 0x77130 ),
01699
01700 OCL_VAR ( OC_UINT8, 1, &_settings_game.difficulty.diff_level ),
01701
01702 OCL_VAR ( OC_TTD | OC_UINT8, 1, &_settings_game.game_creation.landscape ),
01703 OCL_VAR ( OC_TTD | OC_UINT8, 1, &_trees_tick_ctr ),
01704
01705 OCL_CNULL( OC_TTD, 1 ),
01706 OCL_VAR ( OC_TTD | OC_UINT8, 1, &_settings_game.game_creation.snow_line ),
01707
01708 OCL_CNULL( OC_TTD, 32 ),
01709 OCL_CNULL( OC_TTD, 36 ),
01710
01711 OCL_ASSERT( OC_TTD, 0x77179 ),
01712 OCL_ASSERT( OC_TTO, 0x4971D ),
01713
01714 OCL_CHUNK( 1, LoadOldMapPart2 ),
01715
01716 OCL_ASSERT( OC_TTD, 0x97179 ),
01717 OCL_ASSERT( OC_TTO, 0x6971D ),
01718
01719
01720 OCL_CHUNK(1, LoadTTDPatchExtraChunks),
01721
01722 OCL_END()
01723 };
01724
01725 bool LoadTTDMain(LoadgameState *ls)
01726 {
01727 _read_ttdpatch_flags = false;
01728 _ttdp_version = 0;
01729
01730 DEBUG(oldloader, 3, "Reading main chunk...");
01731
01732 SmallStackSafeStackAlloc<byte, OLD_MAP_SIZE * 2> map3;
01733 _old_map3 = map3.data;
01734 _old_vehicle_names = NULL;
01735 try {
01736 if (!LoadChunk(ls, NULL, main_chunk)) {
01737 DEBUG(oldloader, 0, "Loading failed");
01738 free(_old_vehicle_names);
01739 return false;
01740 }
01741 } catch (...) {
01742 free(_old_vehicle_names);
01743 throw;
01744 }
01745
01746 DEBUG(oldloader, 3, "Done, converting game data...");
01747
01748 FixTTDMapArray();
01749 FixTTDDepots();
01750
01751
01752 _settings_game.game_creation.landscape = _settings_game.game_creation.landscape & 0xF;
01753
01754
01755 FixOldTowns();
01756 FixOldVehicles();
01757
01758
01759 _settings_game.difficulty.town_council_tolerance = Clamp(_settings_game.difficulty.diff_level, 0, 2);
01760
01761 DEBUG(oldloader, 3, "Finished converting game data");
01762 DEBUG(oldloader, 1, "TTD(Patch) savegame successfully converted");
01763
01764 free(_old_vehicle_names);
01765
01766 return true;
01767 }
01768
01769 bool LoadTTOMain(LoadgameState *ls)
01770 {
01771 DEBUG(oldloader, 3, "Reading main chunk...");
01772
01773 SmallStackSafeStackAlloc<byte, 103 * sizeof(Engine)> engines;
01774 _old_engines = (Engine *)engines.data;
01775 SmallStackSafeStackAlloc<StringID, 800> vehnames;
01776 _old_vehicle_names = vehnames.data;
01777
01778
01779 if (!LoadChunk(ls, NULL, main_chunk)) {
01780 DEBUG(oldloader, 0, "Loading failed");
01781 return false;
01782 }
01783 DEBUG(oldloader, 3, "Done, converting game data...");
01784
01785 if (_settings_game.game_creation.town_name != 0) _settings_game.game_creation.town_name++;
01786
01787 _settings_game.game_creation.landscape = 0;
01788 _trees_tick_ctr = 0xFF;
01789
01790 if (!FixTTOMapArray() || !FixTTOEngines()) {
01791 DEBUG(oldloader, 0, "Conversion failed");
01792 return false;
01793 }
01794
01795 FixOldTowns();
01796 FixOldVehicles();
01797 FixTTOCompanies();
01798
01799
01800 _settings_game.difficulty.town_council_tolerance = Clamp(_settings_game.difficulty.diff_level, 0, 2);
01801
01802
01803
01804
01805
01806 _economy.inflation_payment = min(_economy.inflation_payment * 124 / 74, MAX_INFLATION);
01807
01808 DEBUG(oldloader, 3, "Finished converting game data");
01809 DEBUG(oldloader, 1, "TTO savegame successfully converted");
01810
01811 return true;
01812 }