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 if (CheckSavegameVersion(105)) {
00302
00303 FOR_ALL_VEHICLES(v) {
00304 if (v->First() != v || v->orders.list != NULL || v->previous_shared != NULL || v->next_shared == NULL) continue;
00305
00306 v->orders.list = new OrderList(NULL, v);
00307 for (Vehicle *u = v; u != NULL; u = u->next_shared) {
00308 u->orders.list = v->orders.list;
00309 }
00310 }
00311 }
00312
00313 CheckValidVehicles();
00314
00315 FOR_ALL_VEHICLES(v) {
00316 assert(v->first != NULL);
00317
00318 if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
00319 if (IsFrontEngine(v)) v->u.rail.last_speed = v->cur_speed;
00320 TrainConsistChanged(v, false);
00321 } else if (v->type == VEH_ROAD && IsRoadVehFront(v)) {
00322 RoadVehUpdateCache(v);
00323 }
00324 }
00325
00326
00327 if (CheckSavegameVersion(112)) {
00328 FOR_ALL_VEHICLES(v) {
00329 if (v->type == VEH_TRAIN && !IsFrontEngine(v)) {
00330 if (IsTrainEngine(v)) v->vehstatus |= VS_STOPPED;
00331
00332
00333 v->cur_speed = 0;
00334 }
00335
00336
00337 if ((v->vehstatus & VS_STOPPED) && (v->type != VEH_TRAIN || CheckSavegameVersionOldStyle(2, 1))) {
00338 v->cur_speed = 0;
00339 }
00340 }
00341 }
00342
00343 FOR_ALL_VEHICLES(v) {
00344 switch (v->type) {
00345 case VEH_ROAD:
00346 v->u.road.roadtype = HasBit(EngInfo(v->First()->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
00347 v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype);
00348
00349 case VEH_TRAIN:
00350 case VEH_SHIP:
00351 v->cur_image = v->GetImage(v->direction);
00352 break;
00353
00354 case VEH_AIRCRAFT:
00355 if (IsNormalAircraft(v)) {
00356 v->cur_image = v->GetImage(v->direction);
00357
00358
00359 Vehicle *shadow = v->Next();
00360 shadow->cur_image = v->cur_image;
00361
00362
00363 if (v->subtype == AIR_HELICOPTER) {
00364 Vehicle *rotor = shadow->Next();
00365 rotor->cur_image = GetRotorImage(v);
00366 }
00367
00368 UpdateAircraftCache(v);
00369 }
00370 break;
00371 default: break;
00372 }
00373
00374 v->coord.left = INVALID_COORD;
00375 VehicleMove(v, false);
00376 }
00377 }
00378
00379 static uint8 _cargo_days;
00380 static uint16 _cargo_source;
00381 static uint32 _cargo_source_xy;
00382 static uint16 _cargo_count;
00383 static uint16 _cargo_paid_for;
00384 static Money _cargo_feeder_share;
00385 static uint32 _cargo_loaded_at_xy;
00386
00392 const SaveLoad *GetVehicleDescription(VehicleType vt)
00393 {
00395 static const SaveLoad _common_veh_desc[] = {
00396 SLE_VAR(Vehicle, subtype, SLE_UINT8),
00397
00398 SLE_REF(Vehicle, next, REF_VEHICLE_OLD),
00399 SLE_CONDVAR(Vehicle, name, SLE_NAME, 0, 83),
00400 SLE_CONDSTR(Vehicle, name, SLE_STR, 0, 84, SL_MAX_VERSION),
00401 SLE_CONDVAR(Vehicle, unitnumber, SLE_FILE_U8 | SLE_VAR_U16, 0, 7),
00402 SLE_CONDVAR(Vehicle, unitnumber, SLE_UINT16, 8, SL_MAX_VERSION),
00403 SLE_VAR(Vehicle, owner, SLE_UINT8),
00404 SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
00405 SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
00406 SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
00407 SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, 6, SL_MAX_VERSION),
00408
00409 SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
00410 SLE_CONDVAR(Vehicle, x_pos, SLE_UINT32, 6, SL_MAX_VERSION),
00411 SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
00412 SLE_CONDVAR(Vehicle, y_pos, SLE_UINT32, 6, SL_MAX_VERSION),
00413 SLE_VAR(Vehicle, z_pos, SLE_UINT8),
00414 SLE_VAR(Vehicle, direction, SLE_UINT8),
00415
00416 SLE_CONDNULL(2, 0, 57),
00417 SLE_VAR(Vehicle, spritenum, SLE_UINT8),
00418 SLE_CONDNULL(5, 0, 57),
00419 SLE_VAR(Vehicle, engine_type, SLE_UINT16),
00420
00421 SLE_VAR(Vehicle, max_speed, SLE_UINT16),
00422 SLE_VAR(Vehicle, cur_speed, SLE_UINT16),
00423 SLE_VAR(Vehicle, subspeed, SLE_UINT8),
00424 SLE_VAR(Vehicle, acceleration, SLE_UINT8),
00425 SLE_VAR(Vehicle, progress, SLE_UINT8),
00426
00427 SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
00428 SLE_CONDVAR(Vehicle, last_station_visited, SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
00429 SLE_CONDVAR(Vehicle, last_station_visited, SLE_UINT16, 5, SL_MAX_VERSION),
00430
00431 SLE_VAR(Vehicle, cargo_type, SLE_UINT8),
00432 SLE_CONDVAR(Vehicle, cargo_subtype, SLE_UINT8, 35, SL_MAX_VERSION),
00433 SLEG_CONDVAR( _cargo_days, SLE_UINT8, 0, 67),
00434 SLEG_CONDVAR( _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, 0, 6),
00435 SLEG_CONDVAR( _cargo_source, SLE_UINT16, 7, 67),
00436 SLEG_CONDVAR( _cargo_source_xy, SLE_UINT32, 44, 67),
00437 SLE_VAR(Vehicle, cargo_cap, SLE_UINT16),
00438 SLEG_CONDVAR( _cargo_count, SLE_UINT16, 0, 67),
00439 SLE_CONDLST(Vehicle, cargo, REF_CARGO_PACKET, 68, SL_MAX_VERSION),
00440
00441 SLE_VAR(Vehicle, day_counter, SLE_UINT8),
00442 SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
00443 SLE_CONDVAR(Vehicle, running_ticks, SLE_UINT8, 88, SL_MAX_VERSION),
00444
00445 SLE_VAR(Vehicle, cur_order_index, SLE_UINT8),
00446
00447 SLE_CONDNULL(1, 0, 104),
00448
00449
00450
00451
00452 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type), SLE_UINT8, 0, 4),
00453 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
00454
00455
00456 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type), SLE_UINT8, 5, SL_MAX_VERSION),
00457 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, flags), SLE_UINT8, 5, SL_MAX_VERSION),
00458 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION),
00459
00460
00461 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_cargo), SLE_UINT8, 36, SL_MAX_VERSION),
00462 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_subtype), SLE_UINT8, 36, SL_MAX_VERSION),
00463
00464
00465 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, wait_time), SLE_UINT16, 67, SL_MAX_VERSION),
00466 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, travel_time), SLE_UINT16, 67, SL_MAX_VERSION),
00467
00468 SLE_CONDREF(Vehicle, orders, REF_ORDER, 0, 104),
00469 SLE_CONDREF(Vehicle, orders, REF_ORDERLIST, 105, SL_MAX_VERSION),
00470
00471 SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
00472 SLE_CONDVAR(Vehicle, age, SLE_INT32, 31, SL_MAX_VERSION),
00473 SLE_CONDVAR(Vehicle, max_age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
00474 SLE_CONDVAR(Vehicle, max_age, SLE_INT32, 31, SL_MAX_VERSION),
00475 SLE_CONDVAR(Vehicle, date_of_last_service, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
00476 SLE_CONDVAR(Vehicle, date_of_last_service, SLE_INT32, 31, SL_MAX_VERSION),
00477 SLE_CONDVAR(Vehicle, service_interval, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
00478 SLE_CONDVAR(Vehicle, service_interval, SLE_INT32, 31, SL_MAX_VERSION),
00479 SLE_VAR(Vehicle, reliability, SLE_UINT16),
00480 SLE_VAR(Vehicle, reliability_spd_dec, SLE_UINT16),
00481 SLE_VAR(Vehicle, breakdown_ctr, SLE_UINT8),
00482 SLE_VAR(Vehicle, breakdown_delay, SLE_UINT8),
00483 SLE_VAR(Vehicle, breakdowns_since_last_service, SLE_UINT8),
00484 SLE_VAR(Vehicle, breakdown_chance, SLE_UINT8),
00485 SLE_CONDVAR(Vehicle, build_year, SLE_FILE_U8 | SLE_VAR_I32, 0, 30),
00486 SLE_CONDVAR(Vehicle, build_year, SLE_INT32, 31, SL_MAX_VERSION),
00487
00488 SLE_VAR(Vehicle, load_unload_time_rem, SLE_UINT16),
00489 SLEG_CONDVAR( _cargo_paid_for, SLE_UINT16, 45, SL_MAX_VERSION),
00490 SLE_CONDVAR(Vehicle, vehicle_flags, SLE_UINT8, 40, SL_MAX_VERSION),
00491
00492 SLE_CONDVAR(Vehicle, profit_this_year, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
00493 SLE_CONDVAR(Vehicle, profit_this_year, SLE_INT64, 65, SL_MAX_VERSION),
00494 SLE_CONDVAR(Vehicle, profit_last_year, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
00495 SLE_CONDVAR(Vehicle, profit_last_year, SLE_INT64, 65, SL_MAX_VERSION),
00496 SLEG_CONDVAR( _cargo_feeder_share, SLE_FILE_I32 | SLE_VAR_I64, 51, 64),
00497 SLEG_CONDVAR( _cargo_feeder_share, SLE_INT64, 65, 67),
00498 SLEG_CONDVAR( _cargo_loaded_at_xy, SLE_UINT32, 51, 67),
00499 SLE_CONDVAR(Vehicle, value, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
00500 SLE_CONDVAR(Vehicle, value, SLE_INT64, 65, SL_MAX_VERSION),
00501
00502 SLE_CONDVAR(Vehicle, random_bits, SLE_UINT8, 2, SL_MAX_VERSION),
00503 SLE_CONDVAR(Vehicle, waiting_triggers, SLE_UINT8, 2, SL_MAX_VERSION),
00504
00505 SLE_CONDREF(Vehicle, next_shared, REF_VEHICLE, 2, SL_MAX_VERSION),
00506 SLE_CONDNULL(2, 2, 68),
00507 SLE_CONDNULL(4, 69, 100),
00508
00509 SLE_CONDVAR(Vehicle, group_id, SLE_UINT16, 60, SL_MAX_VERSION),
00510
00511 SLE_CONDVAR(Vehicle, current_order_time, SLE_UINT32, 67, SL_MAX_VERSION),
00512 SLE_CONDVAR(Vehicle, lateness_counter, SLE_INT32, 67, SL_MAX_VERSION),
00513
00514
00515 SLE_CONDNULL(10, 2, SL_MAX_VERSION),
00516
00517 SLE_END()
00518 };
00519
00520
00521 static const SaveLoad _train_desc[] = {
00522 SLE_WRITEBYTE(Vehicle, type, VEH_TRAIN),
00523 SLE_VEH_INCLUDEX(),
00524 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, crash_anim_pos), SLE_UINT16),
00525 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, force_proceed), SLE_UINT8),
00526 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, railtype), SLE_UINT8),
00527 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, track), SLE_UINT8),
00528
00529 SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags), SLE_FILE_U8 | SLE_VAR_U16, 2, 99),
00530 SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags), SLE_UINT16, 100, SL_MAX_VERSION),
00531 SLE_CONDNULL(2, 2, 59),
00532
00533 SLE_CONDNULL(2, 2, 19),
00534
00535 SLE_CONDNULL(11, 2, SL_MAX_VERSION),
00536
00537 SLE_END()
00538 };
00539
00540 static const SaveLoad _roadveh_desc[] = {
00541 SLE_WRITEBYTE(Vehicle, type, VEH_ROAD),
00542 SLE_VEH_INCLUDEX(),
00543 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, state), SLE_UINT8),
00544 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, frame), SLE_UINT8),
00545 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, blocked_ctr), SLE_UINT16),
00546 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking), SLE_UINT8),
00547 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking_ctr), SLE_UINT8),
00548 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, crashed_ctr), SLE_UINT16),
00549 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, reverse_ctr), SLE_UINT8),
00550
00551 SLE_CONDREFX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot), REF_ROADSTOPS, 6, SL_MAX_VERSION),
00552 SLE_CONDNULL(1, 6, SL_MAX_VERSION),
00553 SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot_age), SLE_UINT8, 6, SL_MAX_VERSION),
00554
00555 SLE_CONDNULL(16, 2, SL_MAX_VERSION),
00556
00557 SLE_END()
00558 };
00559
00560 static const SaveLoad _ship_desc[] = {
00561 SLE_WRITEBYTE(Vehicle, type, VEH_SHIP),
00562 SLE_VEH_INCLUDEX(),
00563 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleShip, state), SLE_UINT8),
00564
00565
00566 SLE_CONDNULL(16, 2, SL_MAX_VERSION),
00567
00568 SLE_END()
00569 };
00570
00571 static const SaveLoad _aircraft_desc[] = {
00572 SLE_WRITEBYTE(Vehicle, type, VEH_AIRCRAFT),
00573 SLE_VEH_INCLUDEX(),
00574 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, crashed_counter), SLE_UINT16),
00575 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, pos), SLE_UINT8),
00576
00577 SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
00578 SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport), SLE_UINT16, 5, SL_MAX_VERSION),
00579
00580 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, state), SLE_UINT8),
00581
00582 SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, previous_pos), SLE_UINT8, 2, SL_MAX_VERSION),
00583
00584
00585 SLE_CONDNULL(15, 2, SL_MAX_VERSION),
00586
00587 SLE_END()
00588 };
00589
00590 static const SaveLoad _special_desc[] = {
00591 SLE_WRITEBYTE(Vehicle, type, VEH_EFFECT),
00592
00593 SLE_VAR(Vehicle, subtype, SLE_UINT8),
00594
00595 SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
00596 SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
00597
00598 SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
00599 SLE_CONDVAR(Vehicle, x_pos, SLE_INT32, 6, SL_MAX_VERSION),
00600 SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
00601 SLE_CONDVAR(Vehicle, y_pos, SLE_INT32, 6, SL_MAX_VERSION),
00602 SLE_VAR(Vehicle, z_pos, SLE_UINT8),
00603
00604 SLE_VAR(Vehicle, cur_image, SLE_UINT16),
00605 SLE_CONDNULL(5, 0, 57),
00606 SLE_VAR(Vehicle, progress, SLE_UINT8),
00607 SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
00608
00609 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleEffect, animation_state), SLE_UINT16),
00610 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleEffect, animation_substate), SLE_UINT8),
00611
00612 SLE_CONDVAR(Vehicle, spritenum, SLE_UINT8, 2, SL_MAX_VERSION),
00613
00614
00615 SLE_CONDNULL(15, 2, SL_MAX_VERSION),
00616
00617 SLE_END()
00618 };
00619
00620 static const SaveLoad _disaster_desc[] = {
00621 SLE_WRITEBYTE(Vehicle, type, VEH_DISASTER),
00622
00623 SLE_REF(Vehicle, next, REF_VEHICLE_OLD),
00624
00625 SLE_VAR(Vehicle, subtype, SLE_UINT8),
00626 SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
00627 SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
00628 SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
00629 SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, 6, SL_MAX_VERSION),
00630
00631 SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
00632 SLE_CONDVAR(Vehicle, x_pos, SLE_INT32, 6, SL_MAX_VERSION),
00633 SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
00634 SLE_CONDVAR(Vehicle, y_pos, SLE_INT32, 6, SL_MAX_VERSION),
00635 SLE_VAR(Vehicle, z_pos, SLE_UINT8),
00636 SLE_VAR(Vehicle, direction, SLE_UINT8),
00637
00638 SLE_CONDNULL(5, 0, 57),
00639 SLE_VAR(Vehicle, owner, SLE_UINT8),
00640 SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
00641 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
00642 SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION),
00643
00644 SLE_VAR(Vehicle, cur_image, SLE_UINT16),
00645 SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
00646 SLE_CONDVAR(Vehicle, age, SLE_INT32, 31, SL_MAX_VERSION),
00647 SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
00648
00649 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, image_override), SLE_UINT16),
00650 SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, big_ufo_destroyer_target), SLE_UINT16),
00651
00652
00653 SLE_CONDNULL(16, 2, SL_MAX_VERSION),
00654
00655 SLE_END()
00656 };
00657
00658
00659 static const SaveLoad *_veh_descs[] = {
00660 _train_desc,
00661 _roadveh_desc,
00662 _ship_desc,
00663 _aircraft_desc,
00664 _special_desc,
00665 _disaster_desc,
00666 _common_veh_desc,
00667 };
00668
00669 return _veh_descs[vt];
00670 }
00671
00673 static void Save_VEHS()
00674 {
00675 Vehicle *v;
00676
00677 FOR_ALL_VEHICLES(v) {
00678 SlSetArrayIndex(v->index);
00679 SlObject(v, GetVehicleDescription(v->type));
00680 }
00681 }
00682
00684 void Load_VEHS()
00685 {
00686 int index;
00687
00688 _cargo_count = 0;
00689
00690 while ((index = SlIterateArray()) != -1) {
00691 Vehicle *v;
00692 VehicleType vtype = (VehicleType)SlReadByte();
00693
00694 switch (vtype) {
00695 case VEH_TRAIN: v = new (index) Train(); break;
00696 case VEH_ROAD: v = new (index) RoadVehicle(); break;
00697 case VEH_SHIP: v = new (index) Ship(); break;
00698 case VEH_AIRCRAFT: v = new (index) Aircraft(); break;
00699 case VEH_EFFECT: v = new (index) EffectVehicle(); break;
00700 case VEH_DISASTER: v = new (index) DisasterVehicle(); break;
00701 case VEH_INVALID: v = new (index) InvalidVehicle(); break;
00702 default: NOT_REACHED();
00703 }
00704
00705 SlObject(v, GetVehicleDescription(vtype));
00706
00707 if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v)) {
00708
00709 CargoPacket *cp = new CargoPacket();
00710 cp->source = _cargo_source;
00711 cp->source_xy = _cargo_source_xy;
00712 cp->count = _cargo_count;
00713 cp->days_in_transit = _cargo_days;
00714 cp->feeder_share = _cargo_feeder_share;
00715 cp->loaded_at_xy = _cargo_loaded_at_xy;
00716 v->cargo.Append(cp);
00717 }
00718
00719
00720 if (CheckSavegameVersion(5) && v->last_station_visited == 0xFF)
00721 v->last_station_visited = INVALID_STATION;
00722
00723 if (CheckSavegameVersion(5)) {
00724
00725
00726 v->current_order.flags = GB(v->current_order.type, 4, 4);
00727 v->current_order.type &= 0x0F;
00728 }
00729
00730
00731 if (CheckSavegameVersion(60)) v->group_id = DEFAULT_GROUP;
00732 }
00733 }
00734
00735 extern const ChunkHandler _veh_chunk_handlers[] = {
00736 { 'VEHS', Save_VEHS, Load_VEHS, CH_SPARSE_ARRAY | CH_LAST},
00737 };