00001
00002
00005 #include "../stdafx.h"
00006 #include "../vehicle_func.h"
00007 #include "../train.h"
00008 #include "../roadveh.h"
00009 #include "../ship.h"
00010 #include "../aircraft.h"
00011 #include "../effectvehicle_base.h"
00012
00013 #include "saveload.h"
00014
00015 #include <map>
00016
00017
00018
00019
00020
00021 void ConnectMultiheadedTrains()
00022 {
00023 Vehicle *v;
00024
00025 FOR_ALL_VEHICLES(v) {
00026 if (v->type == VEH_TRAIN) {
00027 v->u.rail.other_multiheaded_part = NULL;
00028 }
00029 }
00030
00031 FOR_ALL_VEHICLES(v) {
00032 if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 bool sequential_matching = IsFrontEngine(v);
00047
00048 for (Vehicle *u = v; u != NULL; u = GetNextVehicle(u)) {
00049 if (u->u.rail.other_multiheaded_part != NULL) continue;
00050
00051 if (IsMultiheaded(u)) {
00052 if (!IsTrainEngine(u)) {
00053
00054 SetTrainEngine(u);
00055 u->spritenum--;
00056 }
00057
00058
00059 EngineID eid = u->engine_type;
00060 Vehicle *w;
00061 if (sequential_matching) {
00062 for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
00063 if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
00064
00065
00066 if (IsTrainEngine(w)) {
00067 ClearTrainEngine(w);
00068 w->spritenum++;
00069 }
00070 break;
00071 }
00072 } else {
00073 uint stack_pos = 0;
00074 for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
00075 if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
00076
00077 if (IsTrainEngine(w)) {
00078 stack_pos++;
00079 } else {
00080 if (stack_pos == 0) break;
00081 stack_pos--;
00082 }
00083 }
00084 }
00085
00086 if (w != NULL) {
00087 w->u.rail.other_multiheaded_part = u;
00088 u->u.rail.other_multiheaded_part = w;
00089 } else {
00090
00091 ClearMultiheaded(u);
00092 }
00093 }
00094 }
00095 }
00096 }
00097 }
00098
00103 void ConvertOldMultiheadToNew()
00104 {
00105 Vehicle *v;
00106 FOR_ALL_VEHICLES(v) {
00107 if (v->type == VEH_TRAIN) {
00108 SetBit(v->subtype, 7);
00109 }
00110 }
00111
00112 FOR_ALL_VEHICLES(v) {
00113 if (v->type == VEH_TRAIN) {
00114 if (HasBit(v->subtype, 7) && ((v->subtype & ~0x80) == 0 || (v->subtype & ~0x80) == 4)) {
00115 for (Vehicle *u = v; u != NULL; u = u->Next()) {
00116 const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
00117
00118 ClrBit(u->subtype, 7);
00119 switch (u->subtype) {
00120 case 0:
00121 if (rvi->railveh_type == RAILVEH_MULTIHEAD) SetMultiheaded(u);
00122 SetFrontEngine(u);
00123 SetTrainEngine(u);
00124 break;
00125
00126 case 1:
00127 u->subtype = 0;
00128 SetArticulatedPart(u);
00129 break;
00130
00131 case 2:
00132 u->subtype = 0;
00133 if (rvi->railveh_type == RAILVEH_WAGON) {
00134
00135 SetTrainWagon(u);
00136 break;
00137 }
00138 if (rvi->railveh_type == RAILVEH_MULTIHEAD && rvi->image_index == u->spritenum - 1) {
00139
00140 SetMultiheaded(u);
00141 break;
00142 }
00143 if (rvi->railveh_type == RAILVEH_MULTIHEAD) SetMultiheaded(u);
00144 SetTrainEngine(u);
00145 break;
00146
00147 case 4:
00148 u->subtype = 0;
00149 SetTrainWagon(u);
00150 SetFreeWagon(u);
00151 break;
00152 default: NOT_REACHED(); break;
00153 }
00154 }
00155 }
00156 }
00157 }
00158 }
00159
00160
00162 void UpdateOldAircraft()
00163 {
00164
00165 Station *st;
00166 FOR_ALL_STATIONS(st) {
00167 st->airport_flags = 0;
00168 }
00169
00170 Vehicle *v_oldstyle;
00171 FOR_ALL_VEHICLES(v_oldstyle) {
00172
00173
00174 if (v_oldstyle->type == VEH_AIRCRAFT && IsNormalAircraft(v_oldstyle)) {
00175
00176 if (v_oldstyle->vehstatus & VS_STOPPED && v_oldstyle->u.air.state == 0) {
00177 v_oldstyle->u.air.state = HANGAR;
00178 continue;
00179 }
00180
00181 AircraftLeaveHangar(v_oldstyle);
00182 v_oldstyle->vehstatus &= ~VS_STOPPED;
00183 v_oldstyle->cur_speed = v_oldstyle->max_speed;
00184 if (!v_oldstyle->current_order.IsType(OT_GOTO_STATION) && !v_oldstyle->current_order.IsType(OT_GOTO_DEPOT)) {
00185
00186 v_oldstyle->current_order.MakeDummy();
00187 }
00188 v_oldstyle->u.air.state = FLYING;
00189 AircraftNextAirportPos_and_Order(v_oldstyle);
00190 GetNewVehiclePosResult gp = GetNewVehiclePos(v_oldstyle);
00191 v_oldstyle->tile = 0;
00192
00193
00194 if (v_oldstyle->subtype == AIR_HELICOPTER) v_oldstyle->Next()->Next()->cur_speed = 32;
00195
00196
00197 SetAircraftPosition(v_oldstyle, gp.x, gp.y, GetAircraftFlyingAltitude(v_oldstyle));
00198 }
00199 }
00200 }
00201
00209 static void CheckValidVehicles()
00210 {
00211 uint total_engines = GetEnginePoolSize();
00212 EngineID first_engine[4] = { INVALID_ENGINE, INVALID_ENGINE, INVALID_ENGINE, INVALID_ENGINE };
00213
00214 Engine *e;
00215 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) { first_engine[VEH_TRAIN] = e->index; break; }
00216 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) { first_engine[VEH_ROAD] = e->index; break; }
00217 FOR_ALL_ENGINES_OF_TYPE(e, VEH_SHIP) { first_engine[VEH_SHIP] = e->index; break; }
00218 FOR_ALL_ENGINES_OF_TYPE(e, VEH_AIRCRAFT) { first_engine[VEH_AIRCRAFT] = e->index; break; }
00219
00220 Vehicle *v;
00221 FOR_ALL_VEHICLES(v) {
00222
00223 switch (v->type) {
00224 case VEH_TRAIN:
00225 case VEH_ROAD:
00226 case VEH_SHIP:
00227 case VEH_AIRCRAFT:
00228 if (v->engine_type >= total_engines || v->type != GetEngine(v->engine_type)->type) {
00229 v->engine_type = first_engine[v->type];
00230 }
00231 break;
00232
00233 default:
00234 break;
00235 }
00236 }
00237 }
00238
00240 void AfterLoadVehicles(bool part_of_load)
00241 {
00242 Vehicle *v;
00243
00244 FOR_ALL_VEHICLES(v) {
00245
00246 if (v->Next() != NULL) v->Next()->previous = v;
00247 if (v->NextShared() != NULL) v->NextShared()->previous_shared = v;
00248
00249 v->UpdateDeltaXY(v->direction);
00250
00251 if (part_of_load) v->fill_percent_te_id = INVALID_TE_ID;
00252 v->first = NULL;
00253 if (v->type == VEH_TRAIN) v->u.rail.first_engine = INVALID_ENGINE;
00254 if (v->type == VEH_ROAD) v->u.road.first_engine = INVALID_ENGINE;
00255
00256 v->cargo.InvalidateCache();
00257 }
00258
00259
00260
00261 if (part_of_load) {
00262
00263
00264
00265
00266
00267
00268 std::map<Order*, OrderList*> mapping;
00269
00270 FOR_ALL_VEHICLES(v) {
00271 if (v->orders.old != NULL) {
00272 if (CheckSavegameVersion(105)) {
00273 if (mapping[v->orders.old] == NULL) {
00274
00275 v->orders.list = mapping[v->orders.old] = new OrderList(v->orders.old, v);
00276 } else {
00277 v->orders.list = mapping[v->orders.old];
00278
00279 if (CheckSavegameVersionOldStyle(5, 2)) {
00280 v->AddToShared(v->orders.list->GetFirstSharedVehicle());
00281 }
00282 }
00283 } else {
00284 if (v->PreviousShared() == NULL) {
00285 new (v->orders.list) OrderList(v->orders.list->GetFirstOrder(), v);
00286 }
00287 }
00288 }
00289 }
00290 }
00291
00292 FOR_ALL_VEHICLES(v) {
00293
00294 if (v->Previous() == NULL) {
00295 for (Vehicle *u = v; u != NULL; u = u->Next()) {
00296 u->first = v;
00297 }
00298 }
00299 }
00300
00301 CheckValidVehicles();
00302
00303 FOR_ALL_VEHICLES(v) {
00304 assert(v->first != NULL);
00305
00306 if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
00307 if (IsFrontEngine(v)) v->u.rail.last_speed = v->cur_speed;
00308 TrainConsistChanged(v, false);
00309 } else if (v->type == VEH_ROAD && IsRoadVehFront(v)) {
00310 RoadVehUpdateCache(v);
00311 }
00312 }
00313
00314
00315 if (CheckSavegameVersion(112)) {
00316 FOR_ALL_VEHICLES(v) {
00317 if (v->type == VEH_TRAIN && !IsFrontEngine(v)) {
00318 if (IsTrainEngine(v)) v->vehstatus |= VS_STOPPED;
00319
00320
00321 v->cur_speed = 0;
00322 }
00323
00324
00325 if ((v->vehstatus & VS_STOPPED) && (v->type != VEH_TRAIN || CheckSavegameVersionOldStyle(2, 1))) {
00326 v->cur_speed = 0;
00327 }
00328 }
00329 }
00330
00331 FOR_ALL_VEHICLES(v) {
00332 switch (v->type) {
00333 case VEH_ROAD:
00334 v->u.road.roadtype = HasBit(EngInfo(v->First()->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
00335 v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype);
00336
00337 case VEH_TRAIN:
00338 case VEH_SHIP:
00339 v->cur_image = v->GetImage(v->direction);
00340 break;
00341
00342 case VEH_AIRCRAFT:
00343 if (IsNormalAircraft(v)) {
00344 v->cur_image = v->GetImage(v->direction);
00345
00346
00347 Vehicle *shadow = v->Next();
00348 shadow->cur_image = v->cur_image;
00349
00350
00351 if (v->subtype == AIR_HELICOPTER) {
00352 Vehicle *rotor = shadow->Next();
00353 rotor->cur_image = GetRotorImage(v);
00354 }
00355
00356 UpdateAircraftCache(v);
00357 }
00358 break;
00359 default: break;
00360 }
00361
00362 v->left_coord = INVALID_COORD;
00363 VehiclePositionChanged(v);
00364 }
00365 }
00366
00367 static uint8 _cargo_days;
00368 static uint16 _cargo_source;
00369 static uint32 _cargo_source_xy;
00370 static uint16 _cargo_count;
00371 static uint16 _cargo_paid_for;
00372 static Money _cargo_feeder_share;
00373 static uint32 _cargo_loaded_at_xy;
00374
00380 const SaveLoad *GetVehicleDescription(VehicleType vt)
00381 {
00383 static const SaveLoad _common_veh_desc[] = {
00384 SLE_VAR(Vehicle, subtype, SLE_UINT8),
00385
00386 SLE_REF(Vehicle, next, REF_VEHICLE_OLD),
00387 SLE_CONDVAR(Vehicle, name, SLE_NAME, 0, 83),
00388 SLE_CONDSTR(Vehicle, name, SLE_STR, 0, 84, SL_MAX_VERSION),
00389 SLE_CONDVAR(Vehicle, unitnumber, SLE_FILE_U8 | SLE_VAR_U16, 0, 7),
00390 SLE_CONDVAR(Vehicle, unitnumber, SLE_UINT16, 8, SL_MAX_VERSION),
00391 SLE_VAR(Vehicle, owner, SLE_UINT8),
00392 SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
00393 SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
00394 SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
00395 SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, 6, SL_MAX_VERSION),
00396
00397 SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
00398 SLE_CONDVAR(Vehicle, x_pos, SLE_UINT32, 6, SL_MAX_VERSION),
00399 SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
00400 SLE_CONDVAR(Vehicle, y_pos, SLE_UINT32, 6, SL_MAX_VERSION),
00401 SLE_VAR(Vehicle, z_pos, SLE_UINT8),
00402 SLE_VAR(Vehicle, direction, SLE_UINT8),
00403
00404 SLE_CONDNULL(2, 0, 57),
00405 SLE_VAR(Vehicle, spritenum, SLE_UINT8),
00406 SLE_CONDNULL(5, 0, 57),
00407 SLE_VAR(Vehicle, engine_type, SLE_UINT16),
00408
00409 SLE_VAR(Vehicle, max_speed, SLE_UINT16),
00410 SLE_VAR(Vehicle, cur_speed, SLE_UINT16),
00411 SLE_VAR(Vehicle, subspeed, SLE_UINT8),
00412 SLE_VAR(Vehicle, acceleration, SLE_UINT8),
00413 SLE_VAR(Vehicle, progress, SLE_UINT8),
00414
00415 SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
00416 SLE_CONDVAR(Vehicle, last_station_visited, SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
00417 SLE_CONDVAR(Vehicle, last_station_visited, SLE_UINT16, 5, SL_MAX_VERSION),
00418
00419 SLE_VAR(Vehicle, cargo_type, SLE_UINT8),
00420 SLE_CONDVAR(Vehicle, cargo_subtype, SLE_UINT8, 35, SL_MAX_VERSION),
00421 SLEG_CONDVAR( _cargo_days, SLE_UINT8, 0, 67),
00422 SLEG_CONDVAR( _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, 0, 6),
00423 SLEG_CONDVAR( _cargo_source, SLE_UINT16, 7, 67),
00424 SLEG_CONDVAR( _cargo_source_xy, SLE_UINT32, 44, 67),
00425 SLE_VAR(Vehicle, cargo_cap, SLE_UINT16),
00426 SLEG_CONDVAR( _cargo_count, SLE_UINT16, 0, 67),
00427 SLE_CONDLST(Vehicle, cargo, REF_CARGO_PACKET, 68, SL_MAX_VERSION),
00428
00429 SLE_VAR(Vehicle, day_counter, SLE_UINT8),
00430 SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
00431 SLE_CONDVAR(Vehicle, running_ticks, SLE_UINT8, 88, SL_MAX_VERSION),
00432
00433 SLE_VAR(Vehicle, cur_order_index, SLE_UINT8),
00434
00435 SLE_CONDNULL(1, 0, 104),
00436
00437
00438
00439
00440 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type), SLE_UINT8, 0, 4),
00441 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
00442
00443
00444 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type), SLE_UINT8, 5, SL_MAX_VERSION),
00445 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, flags), SLE_UINT8, 5, SL_MAX_VERSION),
00446 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION),
00447
00448
00449 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_cargo), SLE_UINT8, 36, SL_MAX_VERSION),
00450 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_subtype), SLE_UINT8, 36, SL_MAX_VERSION),
00451
00452
00453 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, wait_time), SLE_UINT16, 67, SL_MAX_VERSION),
00454 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, travel_time), SLE_UINT16, 67, SL_MAX_VERSION),
00455
00456 SLE_CONDREF(Vehicle, orders, REF_ORDER, 0, 104),
00457 SLE_CONDREF(Vehicle, orders, REF_ORDERLIST, 105, SL_MAX_VERSION),
00458
00459 SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
00460 SLE_CONDVAR(Vehicle, age, SLE_INT32, 31, SL_MAX_VERSION),
00461 SLE_CONDVAR(Vehicle, max_age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
00462 SLE_CONDVAR(Vehicle, max_age, SLE_INT32, 31, SL_MAX_VERSION),
00463 SLE_CONDVAR(Vehicle, date_of_last_service, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
00464 SLE_CONDVAR(Vehicle, date_of_last_service, SLE_INT32, 31, SL_MAX_VERSION),
00465 SLE_CONDVAR(Vehicle, service_interval, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
00466 SLE_CONDVAR(Vehicle, service_interval, SLE_INT32, 31, SL_MAX_VERSION),
00467 SLE_VAR(Vehicle, reliability, SLE_UINT16),
00468 SLE_VAR(Vehicle, reliability_spd_dec, SLE_UINT16),
00469 SLE_VAR(Vehicle, breakdown_ctr, SLE_UINT8),
00470 SLE_VAR(Vehicle, breakdown_delay, SLE_UINT8),
00471 SLE_VAR(Vehicle, breakdowns_since_last_service, SLE_UINT8),
00472 SLE_VAR(Vehicle, breakdown_chance, SLE_UINT8),
00473 SLE_CONDVAR(Vehicle, build_year, SLE_FILE_U8 | SLE_VAR_I32, 0, 30),
00474 SLE_CONDVAR(Vehicle, build_year, SLE_INT32, 31, SL_MAX_VERSION),
00475
00476 SLE_VAR(Vehicle, load_unload_time_rem, SLE_UINT16),
00477 SLEG_CONDVAR( _cargo_paid_for, SLE_UINT16, 45, SL_MAX_VERSION),
00478 SLE_CONDVAR(Vehicle, vehicle_flags, SLE_UINT8, 40, SL_MAX_VERSION),
00479
00480 SLE_CONDVAR(Vehicle, profit_this_year, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
00481 SLE_CONDVAR(Vehicle, profit_this_year, SLE_INT64, 65, SL_MAX_VERSION),
00482 SLE_CONDVAR(Vehicle, profit_last_year, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
00483 SLE_CONDVAR(Vehicle, profit_last_year, SLE_INT64, 65, SL_MAX_VERSION),
00484 SLEG_CONDVAR( _cargo_feeder_share, SLE_FILE_I32 | SLE_VAR_I64, 51, 64),
00485 SLEG_CONDVAR( _cargo_feeder_share, SLE_INT64, 65, 67),
00486 SLEG_CONDVAR( _cargo_loaded_at_xy, SLE_UINT32, 51, 67),
00487 SLE_CONDVAR(Vehicle, value, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
00488 SLE_CONDVAR(Vehicle, value, SLE_INT64, 65, SL_MAX_VERSION),
00489
00490 SLE_CONDVAR(Vehicle, random_bits, SLE_UINT8, 2, SL_MAX_VERSION),
00491 SLE_CONDVAR(Vehicle, waiting_triggers, SLE_UINT8, 2, SL_MAX_VERSION),
00492
00493 SLE_CONDREF(Vehicle, next_shared, REF_VEHICLE, 2, SL_MAX_VERSION),
00494 SLE_CONDNULL(2, 2, 68),
00495 SLE_CONDNULL(4, 69, 100),
00496
00497 SLE_CONDVAR(Vehicle, group_id, SLE_UINT16, 60, SL_MAX_VERSION),
00498
00499 SLE_CONDVAR(Vehicle, current_order_time, SLE_UINT32, 67, SL_MAX_VERSION),
00500 SLE_CONDVAR(Vehicle, lateness_counter, SLE_INT32, 67, SL_MAX_VERSION),
00501
00502
00503 SLE_CONDNULL(10, 2, SL_MAX_VERSION),
00504
00505 SLE_END()
00506 };
00507
00508
00509 static const SaveLoad _train_desc[] = {
00510 SLE_WRITEBYTE(Vehicle, type, VEH_TRAIN),
00511 SLE_VEH_INCLUDEX(),
00512 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, crash_anim_pos), SLE_UINT16),
00513 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, force_proceed), SLE_UINT8),
00514 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, railtype), SLE_UINT8),
00515 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, track), SLE_UINT8),
00516
00517 SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags), SLE_FILE_U8 | SLE_VAR_U16, 2, 99),
00518 SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags), SLE_UINT16, 100, SL_MAX_VERSION),
00519 SLE_CONDNULL(2, 2, 59),
00520
00521 SLE_CONDNULL(2, 2, 19),
00522
00523 SLE_CONDNULL(11, 2, SL_MAX_VERSION),
00524
00525 SLE_END()
00526 };
00527
00528 static const SaveLoad _roadveh_desc[] = {
00529 SLE_WRITEBYTE(Vehicle, type, VEH_ROAD),
00530 SLE_VEH_INCLUDEX(),
00531 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, state), SLE_UINT8),
00532 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, frame), SLE_UINT8),
00533 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, blocked_ctr), SLE_UINT16),
00534 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking), SLE_UINT8),
00535 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking_ctr), SLE_UINT8),
00536 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, crashed_ctr), SLE_UINT16),
00537 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, reverse_ctr), SLE_UINT8),
00538
00539 SLE_CONDREFX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot), REF_ROADSTOPS, 6, SL_MAX_VERSION),
00540 SLE_CONDNULL(1, 6, SL_MAX_VERSION),
00541 SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot_age), SLE_UINT8, 6, SL_MAX_VERSION),
00542
00543 SLE_CONDNULL(16, 2, SL_MAX_VERSION),
00544
00545 SLE_END()
00546 };
00547
00548 static const SaveLoad _ship_desc[] = {
00549 SLE_WRITEBYTE(Vehicle, type, VEH_SHIP),
00550 SLE_VEH_INCLUDEX(),
00551 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleShip, state), SLE_UINT8),
00552
00553
00554 SLE_CONDNULL(16, 2, SL_MAX_VERSION),
00555
00556 SLE_END()
00557 };
00558
00559 static const SaveLoad _aircraft_desc[] = {
00560 SLE_WRITEBYTE(Vehicle, type, VEH_AIRCRAFT),
00561 SLE_VEH_INCLUDEX(),
00562 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, crashed_counter), SLE_UINT16),
00563 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, pos), SLE_UINT8),
00564
00565 SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
00566 SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport), SLE_UINT16, 5, SL_MAX_VERSION),
00567
00568 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, state), SLE_UINT8),
00569
00570 SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, previous_pos), SLE_UINT8, 2, SL_MAX_VERSION),
00571
00572
00573 SLE_CONDNULL(15, 2, SL_MAX_VERSION),
00574
00575 SLE_END()
00576 };
00577
00578 static const SaveLoad _special_desc[] = {
00579 SLE_WRITEBYTE(Vehicle, type, VEH_EFFECT),
00580
00581 SLE_VAR(Vehicle, subtype, SLE_UINT8),
00582
00583 SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
00584 SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
00585
00586 SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
00587 SLE_CONDVAR(Vehicle, x_pos, SLE_INT32, 6, SL_MAX_VERSION),
00588 SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
00589 SLE_CONDVAR(Vehicle, y_pos, SLE_INT32, 6, SL_MAX_VERSION),
00590 SLE_VAR(Vehicle, z_pos, SLE_UINT8),
00591
00592 SLE_VAR(Vehicle, cur_image, SLE_UINT16),
00593 SLE_CONDNULL(5, 0, 57),
00594 SLE_VAR(Vehicle, progress, SLE_UINT8),
00595 SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
00596
00597 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleEffect, animation_state), SLE_UINT16),
00598 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleEffect, animation_substate), SLE_UINT8),
00599
00600 SLE_CONDVAR(Vehicle, spritenum, SLE_UINT8, 2, SL_MAX_VERSION),
00601
00602
00603 SLE_CONDNULL(15, 2, SL_MAX_VERSION),
00604
00605 SLE_END()
00606 };
00607
00608 static const SaveLoad _disaster_desc[] = {
00609 SLE_WRITEBYTE(Vehicle, type, VEH_DISASTER),
00610
00611 SLE_REF(Vehicle, next, REF_VEHICLE_OLD),
00612
00613 SLE_VAR(Vehicle, subtype, SLE_UINT8),
00614 SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
00615 SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
00616 SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
00617 SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, 6, SL_MAX_VERSION),
00618
00619 SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
00620 SLE_CONDVAR(Vehicle, x_pos, SLE_INT32, 6, SL_MAX_VERSION),
00621 SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
00622 SLE_CONDVAR(Vehicle, y_pos, SLE_INT32, 6, SL_MAX_VERSION),
00623 SLE_VAR(Vehicle, z_pos, SLE_UINT8),
00624 SLE_VAR(Vehicle, direction, SLE_UINT8),
00625
00626 SLE_CONDNULL(5, 0, 57),
00627 SLE_VAR(Vehicle, owner, SLE_UINT8),
00628 SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
00629 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
00630 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION),
00631
00632 SLE_VAR(Vehicle, cur_image, SLE_UINT16),
00633 SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
00634 SLE_CONDVAR(Vehicle, age, SLE_INT32, 31, SL_MAX_VERSION),
00635 SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
00636
00637 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, image_override), SLE_UINT16),
00638 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, big_ufo_destroyer_target), SLE_UINT16),
00639
00640
00641 SLE_CONDNULL(16, 2, SL_MAX_VERSION),
00642
00643 SLE_END()
00644 };
00645
00646
00647 static const SaveLoad *_veh_descs[] = {
00648 _train_desc,
00649 _roadveh_desc,
00650 _ship_desc,
00651 _aircraft_desc,
00652 _special_desc,
00653 _disaster_desc,
00654 _common_veh_desc,
00655 };
00656
00657 return _veh_descs[vt];
00658 }
00659
00661 static void Save_VEHS()
00662 {
00663 Vehicle *v;
00664
00665 FOR_ALL_VEHICLES(v) {
00666 SlSetArrayIndex(v->index);
00667 SlObject(v, GetVehicleDescription(v->type));
00668 }
00669 }
00670
00672 void Load_VEHS()
00673 {
00674 int index;
00675
00676 _cargo_count = 0;
00677
00678 while ((index = SlIterateArray()) != -1) {
00679 Vehicle *v;
00680 VehicleType vtype = (VehicleType)SlReadByte();
00681
00682 switch (vtype) {
00683 case VEH_TRAIN: v = new (index) Train(); break;
00684 case VEH_ROAD: v = new (index) RoadVehicle(); break;
00685 case VEH_SHIP: v = new (index) Ship(); break;
00686 case VEH_AIRCRAFT: v = new (index) Aircraft(); break;
00687 case VEH_EFFECT: v = new (index) EffectVehicle(); break;
00688 case VEH_DISASTER: v = new (index) DisasterVehicle(); break;
00689 case VEH_INVALID: v = new (index) InvalidVehicle(); break;
00690 default: NOT_REACHED();
00691 }
00692
00693 SlObject(v, GetVehicleDescription(vtype));
00694
00695 if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v)) {
00696
00697 CargoPacket *cp = new CargoPacket();
00698 cp->source = _cargo_source;
00699 cp->source_xy = _cargo_source_xy;
00700 cp->count = _cargo_count;
00701 cp->days_in_transit = _cargo_days;
00702 cp->feeder_share = _cargo_feeder_share;
00703 cp->loaded_at_xy = _cargo_loaded_at_xy;
00704 v->cargo.Append(cp);
00705 }
00706
00707
00708 if (CheckSavegameVersion(5) && v->last_station_visited == 0xFF)
00709 v->last_station_visited = INVALID_STATION;
00710
00711 if (CheckSavegameVersion(5)) {
00712
00713
00714 v->current_order.flags = GB(v->current_order.type, 4, 4);
00715 v->current_order.type &= 0x0F;
00716 }
00717
00718
00719 if (CheckSavegameVersion(60)) v->group_id = DEFAULT_GROUP;
00720 }
00721 }
00722
00723 extern const ChunkHandler _veh_chunk_handlers[] = {
00724 { 'VEHS', Save_VEHS, Load_VEHS, CH_SPARSE_ARRAY | CH_LAST},
00725 };