src/vehicle.cpp
branchgamebalance
changeset 9911 0b8b245a2391
parent 9910 0b2aebc8283e
child 9912 1ac8aac92385
equal deleted inserted replaced
9910:0b2aebc8283e 9911:0b8b245a2391
    38 #include "date.h"
    38 #include "date.h"
    39 #include "newgrf_callbacks.h"
    39 #include "newgrf_callbacks.h"
    40 #include "newgrf_engine.h"
    40 #include "newgrf_engine.h"
    41 #include "newgrf_sound.h"
    41 #include "newgrf_sound.h"
    42 #include "helpers.hpp"
    42 #include "helpers.hpp"
       
    43 #include "group.h"
       
    44 #include "economy.h"
    43 
    45 
    44 #define INVALID_COORD (-0x8000)
    46 #define INVALID_COORD (-0x8000)
    45 #define GEN_HASH(x, y) ((GB((y), 6, 6) << 6) + GB((x), 7, 6))
    47 #define GEN_HASH(x, y) ((GB((y), 6, 6) << 6) + GB((x), 7, 6))
    46 
    48 
    47 
    49 
    87 
    89 
    88 	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
    90 	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
    89 	 * TODO - This is just a temporary stage, this will be removed. */
    91 	 * TODO - This is just a temporary stage, this will be removed. */
    90 	for (v = GetVehicle(start_item); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) {
    92 	for (v = GetVehicle(start_item); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) {
    91 		v->index = start_item++;
    93 		v->index = start_item++;
    92 		v->type  = VEH_INVALID;
    94 		v = new (v) InvalidVehicle();
    93 	}
    95 	}
    94 }
    96 }
    95 
    97 
    96 /* Initialize the vehicle-pool */
    98 /* Initialize the vehicle-pool */
    97 DEFINE_OLD_POOL(Vehicle, Vehicle, VehiclePoolNewBlock, NULL)
    99 DEFINE_OLD_POOL(Vehicle, Vehicle, VehiclePoolNewBlock, NULL)
   108 {
   110 {
   109 	if (v->vehstatus & VS_CRASHED)
   111 	if (v->vehstatus & VS_CRASHED)
   110 		return false; // Crashed vehicles don't need service anymore
   112 		return false; // Crashed vehicles don't need service anymore
   111 
   113 
   112 	if (_patches.no_servicing_if_no_breakdowns && _opt.diff.vehicle_breakdowns == 0) {
   114 	if (_patches.no_servicing_if_no_breakdowns && _opt.diff.vehicle_breakdowns == 0) {
   113 		return EngineHasReplacementForPlayer(GetPlayer(v->owner), v->engine_type);  /* Vehicles set for autoreplacing needs to go to a depot even if breakdowns are turned off */
   115 		return EngineHasReplacementForPlayer(GetPlayer(v->owner), v->engine_type, v->group_id);  /* Vehicles set for autoreplacing needs to go to a depot even if breakdowns are turned off */
   114 	}
   116 	}
   115 
   117 
   116 	return _patches.servint_ispercent ?
   118 	return _patches.servint_ispercent ?
   117 		(v->reliability < GetEngine(v->engine_type)->reliability * (100 - v->service_interval) / 100) :
   119 		(v->reliability < GetEngine(v->engine_type)->reliability * (100 - v->service_interval) / 100) :
   118 		(v->date_of_last_service + v->service_interval < _date);
   120 		(v->date_of_last_service + v->service_interval < _date);
   222 void AfterLoadVehicles()
   224 void AfterLoadVehicles()
   223 {
   225 {
   224 	Vehicle *v;
   226 	Vehicle *v;
   225 
   227 
   226 	FOR_ALL_VEHICLES(v) {
   228 	FOR_ALL_VEHICLES(v) {
       
   229 		v->UpdateDeltaXY(v->direction);
       
   230 
   227 		v->first = NULL;
   231 		v->first = NULL;
   228 		if (v->type == VEH_TRAIN) v->u.rail.first_engine = INVALID_ENGINE;
   232 		if (v->type == VEH_TRAIN) v->u.rail.first_engine = INVALID_ENGINE;
   229 	}
   233 	}
   230 
   234 
   231 	FOR_ALL_VEHICLES(v) {
   235 	FOR_ALL_VEHICLES(v) {
   269 	memset(v, 0, sizeof(Vehicle));
   273 	memset(v, 0, sizeof(Vehicle));
   270 	v->index = index;
   274 	v->index = index;
   271 
   275 
   272 	assert(v->orders == NULL);
   276 	assert(v->orders == NULL);
   273 
   277 
   274 	v->type = VEH_INVALID;
   278 	v = new (v) InvalidVehicle();
   275 	v->left_coord = INVALID_COORD;
   279 	v->left_coord = INVALID_COORD;
   276 	v->first = NULL;
   280 	v->first = NULL;
   277 	v->next = NULL;
   281 	v->next = NULL;
   278 	v->next_hash = NULL;
   282 	v->next_hash = NULL;
   279 	v->string_id = 0;
   283 	v->string_id = 0;
   280 	v->next_shared = NULL;
   284 	v->next_shared = NULL;
   281 	v->prev_shared = NULL;
   285 	v->prev_shared = NULL;
   282 	v->depot_list  = NULL;
   286 	v->depot_list  = NULL;
   283 	v->random_bits = 0;
   287 	v->random_bits = 0;
       
   288 	v->group_id = DEFAULT_GROUP;
       
   289 
   284 	return v;
   290 	return v;
   285 }
   291 }
   286 
   292 
   287 /**
   293 /**
   288  * Get a value for a vehicle's random_bits.
   294  * Get a value for a vehicle's random_bits.
   575 	}
   581 	}
   576 
   582 
   577 	if (IsEngineCountable(v)) {
   583 	if (IsEngineCountable(v)) {
   578 		GetPlayer(v->owner)->num_engines[v->engine_type]--;
   584 		GetPlayer(v->owner)->num_engines[v->engine_type]--;
   579 		if (v->owner == _local_player) InvalidateAutoreplaceWindow(v->engine_type);
   585 		if (v->owner == _local_player) InvalidateAutoreplaceWindow(v->engine_type);
       
   586 
       
   587 		if (IsValidGroupID(v->group_id)) GetGroup(v->group_id)->num_engines[v->engine_type]--;
       
   588 		if (v->type != VEH_TRAIN || IsFrontEngine(v)) DecreaseGroupNumVehicle(v->group_id);
   580 	}
   589 	}
   581 
   590 
   582 	DeleteVehicleNews(v->index, INVALID_STRING_ID);
   591 	DeleteVehicleNews(v->index, INVALID_STRING_ID);
   583 
   592 
   584 	DeleteName(v->string_id);
   593 	DeleteName(v->string_id);
   654 	DisasterVehicle_Tick,
   663 	DisasterVehicle_Tick,
   655 };
   664 };
   656 
   665 
   657 void CallVehicleTicks()
   666 void CallVehicleTicks()
   658 {
   667 {
   659 	Vehicle *v;
       
   660 
       
   661 #ifdef ENABLE_NETWORK
   668 #ifdef ENABLE_NETWORK
   662 	/* hotfix for desync problem:
   669 	/* hotfix for desync problem:
   663 	 *  for MP games invalidate the YAPF cache every tick to keep it exactly the same on the server and all clients */
   670 	 *  for MP games invalidate the YAPF cache every tick to keep it exactly the same on the server and all clients */
   664 	if (_networking) {
   671 	if (_networking) {
   665 		YapfNotifyTrackLayoutChange(INVALID_TILE, INVALID_TRACK);
   672 		YapfNotifyTrackLayoutChange(INVALID_TILE, INVALID_TRACK);
   666 	}
   673 	}
   667 #endif //ENABLE_NETWORK
   674 #endif //ENABLE_NETWORK
   668 
   675 
   669 	_first_veh_in_depot_list = NULL; // now we are sure it's initialized at the start of each tick
   676 	_first_veh_in_depot_list = NULL; // now we are sure it's initialized at the start of each tick
   670 
   677 
       
   678 	Station *st;
       
   679 	FOR_ALL_STATIONS(st) LoadUnloadStation(st);
       
   680 
       
   681 	Vehicle *v;
   671 	FOR_ALL_VEHICLES(v) {
   682 	FOR_ALL_VEHICLES(v) {
   672 		_vehicle_tick_procs[v->type](v);
   683 		_vehicle_tick_procs[v->type](v);
   673 
   684 
   674 		switch (v->type) {
   685 		switch (v->type) {
       
   686 			default: break;
       
   687 
   675 			case VEH_TRAIN:
   688 			case VEH_TRAIN:
   676 			case VEH_ROAD:
   689 			case VEH_ROAD:
   677 			case VEH_AIRCRAFT:
   690 			case VEH_AIRCRAFT:
   678 			case VEH_SHIP:
   691 			case VEH_SHIP:
   679 				if (v->type == VEH_TRAIN && IsTrainWagon(v)) continue;
   692 				if (v->type == VEH_TRAIN && IsTrainWagon(v)) continue;
   694 		Vehicle *w = v->depot_list;
   707 		Vehicle *w = v->depot_list;
   695 		v->depot_list = NULL; // it should always be NULL at the end of each tick
   708 		v->depot_list = NULL; // it should always be NULL at the end of each tick
   696 		MaybeReplaceVehicle(v, false, true);
   709 		MaybeReplaceVehicle(v, false, true);
   697 		v = w;
   710 		v = w;
   698 	}
   711 	}
   699 }
       
   700 
       
   701 static bool CanFillVehicle_FullLoadAny(Vehicle *v)
       
   702 {
       
   703 	uint32 full = 0, not_full = 0;
       
   704 	bool keep_loading = false;
       
   705 	const GoodsEntry *ge = GetStation(v->last_station_visited)->goods;
       
   706 
       
   707 	/* special handling of aircraft */
       
   708 
       
   709 	/* if the aircraft carries passengers and is NOT full, then
       
   710 	 *continue loading, no matter how much mail is in */
       
   711 	if (v->type == VEH_AIRCRAFT &&
       
   712 			IsCargoInClass(v->cargo_type, CC_PASSENGERS) &&
       
   713 			v->cargo_cap != v->cargo_count) {
       
   714 		return true;
       
   715 	}
       
   716 
       
   717 	/* patch should return "true" to continue loading, i.e. when there is no cargo type that is fully loaded. */
       
   718 	do {
       
   719 		/* Should never happen, but just in case future additions change this */
       
   720 		assert(v->cargo_type<32);
       
   721 
       
   722 		if (v->cargo_cap != 0) {
       
   723 			uint32 mask = 1 << v->cargo_type;
       
   724 
       
   725 			if (v->cargo_cap == v->cargo_count) {
       
   726 				full |= mask;
       
   727 			} else if (GB(ge[v->cargo_type].waiting_acceptance, 0, 12) > 0 ||
       
   728 					(HASBIT(v->vehicle_flags, VF_CARGO_UNLOADING) && (ge[v->cargo_type].waiting_acceptance & 0x8000))) {
       
   729 				/* If there is any cargo waiting, or this vehicle is still unloading
       
   730 				 * and the station accepts the cargo, don't leave the station. */
       
   731 				keep_loading = true;
       
   732 			} else {
       
   733 				not_full |= mask;
       
   734 			}
       
   735 		}
       
   736 	} while ((v = v->next) != NULL);
       
   737 
       
   738 	/* continue loading if there is a non full cargo type and no cargo type that is full */
       
   739 	return keep_loading || (not_full && (full & ~not_full) == 0);
       
   740 }
       
   741 
       
   742 bool CanFillVehicle(Vehicle *v)
       
   743 {
       
   744 	TileIndex tile = v->tile;
       
   745 
       
   746 	if (IsTileType(tile, MP_STATION) ||
       
   747 			(v->type == VEH_SHIP && (
       
   748 				IsTileType(TILE_ADDXY(tile,  1,  0), MP_STATION) ||
       
   749 				IsTileType(TILE_ADDXY(tile, -1,  0), MP_STATION) ||
       
   750 				IsTileType(TILE_ADDXY(tile,  0,  1), MP_STATION) ||
       
   751 				IsTileType(TILE_ADDXY(tile,  0, -1), MP_STATION) ||
       
   752 				IsTileType(TILE_ADDXY(tile, -2,  0), MP_STATION)
       
   753 			))) {
       
   754 
       
   755 		/* If patch is active, use alternative CanFillVehicle-function */
       
   756 		if (_patches.full_load_any && v->current_order.flags & OF_FULL_LOAD) return CanFillVehicle_FullLoadAny(v);
       
   757 
       
   758 		do {
       
   759 			if (v->cargo_count != v->cargo_cap) return true;
       
   760 		} while ((v = v->next) != NULL);
       
   761 	}
       
   762 	return false;
       
   763 }
   712 }
   764 
   713 
   765 /** Check if a given engine type can be refitted to a given cargo
   714 /** Check if a given engine type can be refitted to a given cargo
   766  * @param engine_type Engine type to check
   715  * @param engine_type Engine type to check
   767  * @param cid_to check refit to this cargo-type
   716  * @param cid_to check refit to this cargo-type
  1436 {
  1385 {
  1437 	Vehicle *v;
  1386 	Vehicle *v;
  1438 
  1387 
  1439 	v = ForceAllocateSpecialVehicle();
  1388 	v = ForceAllocateSpecialVehicle();
  1440 	if (v != NULL) {
  1389 	if (v != NULL) {
  1441 		v->type = VEH_SPECIAL;
  1390 		v = new (v) SpecialVehicle();
  1442 		v->subtype = type;
  1391 		v->subtype = type;
  1443 		v->x_pos = x;
  1392 		v->x_pos = x;
  1444 		v->y_pos = y;
  1393 		v->y_pos = y;
  1445 		v->z_pos = z;
  1394 		v->z_pos = z;
  1446 		v->z_height = v->sprite_width = v->sprite_height = 1;
       
  1447 		v->x_offs = v->y_offs = 0;
       
  1448 		v->tile = 0;
  1395 		v->tile = 0;
       
  1396 		v->UpdateDeltaXY(INVALID_DIR);
  1449 		v->vehstatus = VS_UNCLICKABLE;
  1397 		v->vehstatus = VS_UNCLICKABLE;
  1450 
  1398 
  1451 		_effect_init_procs[type](v);
  1399 		_effect_init_procs[type](v);
  1452 
  1400 
  1453 		VehiclePositionChanged(v);
  1401 		VehiclePositionChanged(v);
  1481 
  1429 
  1482 	if ( (uint)(x -= vp->left) >= (uint)vp->width ||
  1430 	if ( (uint)(x -= vp->left) >= (uint)vp->width ||
  1483 			 (uint)(y -= vp->top) >= (uint)vp->height)
  1431 			 (uint)(y -= vp->top) >= (uint)vp->height)
  1484 				return NULL;
  1432 				return NULL;
  1485 
  1433 
  1486 	x = (x << vp->zoom) + vp->virtual_left;
  1434 	x = ScaleByZoom(x, vp->zoom) + vp->virtual_left;
  1487 	y = (y << vp->zoom) + vp->virtual_top;
  1435 	y = ScaleByZoom(y, vp->zoom) + vp->virtual_top;
  1488 
  1436 
  1489 	FOR_ALL_VEHICLES(v) {
  1437 	FOR_ALL_VEHICLES(v) {
  1490 		if ((v->vehstatus & (VS_HIDDEN|VS_UNCLICKABLE)) == 0 &&
  1438 		if ((v->vehstatus & (VS_HIDDEN|VS_UNCLICKABLE)) == 0 &&
  1491 				x >= v->left_coord && x <= v->right_coord &&
  1439 				x >= v->left_coord && x <= v->right_coord &&
  1492 				y >= v->top_coord && y <= v->bottom_coord) {
  1440 				y >= v->top_coord && y <= v->bottom_coord) {
  1622 	uint16 engine_list_length = 0;
  1570 	uint16 engine_list_length = 0;
  1623 	uint16 engine_count = 0;
  1571 	uint16 engine_count = 0;
  1624 	int32 return_value = CMD_ERROR;
  1572 	int32 return_value = CMD_ERROR;
  1625 	uint i;
  1573 	uint i;
  1626 	uint stop_command;
  1574 	uint stop_command;
  1627 	byte vehicle_type = GB(p2, 0, 5);
  1575 	VehicleType vehicle_type = (VehicleType)GB(p2, 0, 5);
  1628 	bool start_stop = HASBIT(p2, 5);
  1576 	bool start_stop = HASBIT(p2, 5);
  1629 	bool vehicle_list_window = HASBIT(p2, 6);
  1577 	bool vehicle_list_window = HASBIT(p2, 6);
  1630 
  1578 
  1631 	switch (vehicle_type) {
  1579 	switch (vehicle_type) {
  1632 		case VEH_TRAIN:    stop_command = CMD_START_STOP_TRAIN;    break;
  1580 		case VEH_TRAIN:    stop_command = CMD_START_STOP_TRAIN;    break;
  1689 	uint16 wagon_list_length = 0;
  1637 	uint16 wagon_list_length = 0;
  1690 	uint16 wagon_count = 0;
  1638 	uint16 wagon_count = 0;
  1691 
  1639 
  1692 	int32 cost = 0;
  1640 	int32 cost = 0;
  1693 	uint i, sell_command, total_number_vehicles;
  1641 	uint i, sell_command, total_number_vehicles;
  1694 	byte vehicle_type = GB(p1, 0, 8);
  1642 	VehicleType vehicle_type = (VehicleType)GB(p1, 0, 8);
  1695 
  1643 
  1696 	switch (vehicle_type) {
  1644 	switch (vehicle_type) {
  1697 		case VEH_TRAIN:    sell_command = CMD_SELL_RAIL_WAGON; break;
  1645 		case VEH_TRAIN:    sell_command = CMD_SELL_RAIL_WAGON; break;
  1698 		case VEH_ROAD:     sell_command = CMD_SELL_ROAD_VEH;   break;
  1646 		case VEH_ROAD:     sell_command = CMD_SELL_ROAD_VEH;   break;
  1699 		case VEH_SHIP:     sell_command = CMD_SELL_SHIP;       break;
  1647 		case VEH_SHIP:     sell_command = CMD_SELL_SHIP;       break;
  1738 	Vehicle **vl = NULL;
  1686 	Vehicle **vl = NULL;
  1739 	uint16 engine_list_length = 0;
  1687 	uint16 engine_list_length = 0;
  1740 	uint16 engine_count = 0;
  1688 	uint16 engine_count = 0;
  1741 	uint i, x = 0, y = 0, z = 0;
  1689 	uint i, x = 0, y = 0, z = 0;
  1742 	int32 cost = 0;
  1690 	int32 cost = 0;
  1743 	byte vehicle_type = GB(p1, 0, 8);
  1691 	VehicleType vehicle_type = (VehicleType)GB(p1, 0, 8);
  1744 
       
  1745 
  1692 
  1746 	if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
  1693 	if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
  1747 
  1694 
  1748 	/* Get the list of vehicles in the depot */
  1695 	/* Get the list of vehicles in the depot */
  1749 	BuildDepotVehicleList(vehicle_type, tile, &vl, &engine_list_length, &engine_count, NULL, NULL, NULL);
  1696 	BuildDepotVehicleList(vehicle_type, tile, &vl, &engine_list_length, &engine_count, NULL, NULL, NULL);
  1802  */
  1749  */
  1803 int32 CmdCloneVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1750 int32 CmdCloneVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1804 {
  1751 {
  1805 	Vehicle *v_front, *v;
  1752 	Vehicle *v_front, *v;
  1806 	Vehicle *w_front, *w, *w_rear;
  1753 	Vehicle *w_front, *w, *w_rear;
  1807 	int cost, total_cost = 0;
  1754 	int32 cost, total_cost = 0;
  1808 	uint32 build_argument = 2;
  1755 	uint32 build_argument = 2;
  1809 
  1756 
  1810 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1757 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1811 	v = GetVehicle(p1);
  1758 	v = GetVehicle(p1);
  1812 	v_front = v;
  1759 	v_front = v;
  1840 	}
  1787 	}
  1841 
  1788 
  1842 	v = v_front;
  1789 	v = v_front;
  1843 
  1790 
  1844 	do {
  1791 	do {
  1845 
       
  1846 		if (!(flags & DC_EXEC)) {
       
  1847 			/* Get the refit cost.
       
  1848 			 * This is only needed when estimating as when the command is executed, the cost from the refit command is used.
       
  1849 			 * This needs to be done for every single unit, so it should be done before checking if it's a multiheaded engine. */
       
  1850 			CargoID new_cargo_type = GetEngineCargoType(v->engine_type);
       
  1851 
       
  1852 			if (new_cargo_type != v->cargo_type && new_cargo_type != CT_INVALID) {
       
  1853 				total_cost += GetRefitCost(v->engine_type);
       
  1854 			}
       
  1855 		}
       
  1856 
       
  1857 		if (IsMultiheaded(v) && !IsTrainEngine(v)) {
  1792 		if (IsMultiheaded(v) && !IsTrainEngine(v)) {
  1858 			/* we build the rear ends of multiheaded trains with the front ones */
  1793 			/* we build the rear ends of multiheaded trains with the front ones */
  1859 			continue;
  1794 			continue;
  1860 		}
  1795 		}
  1861 
  1796 
  1866 
  1801 
  1867 		total_cost += cost;
  1802 		total_cost += cost;
  1868 
  1803 
  1869 		if (flags & DC_EXEC) {
  1804 		if (flags & DC_EXEC) {
  1870 			w = GetVehicle(_new_vehicle_id);
  1805 			w = GetVehicle(_new_vehicle_id);
  1871 
       
  1872 			Vehicle *w2 = w;
       
  1873 			Vehicle *v2 = v;
       
  1874 			do {
       
  1875 				if (v2->cargo_type != w2->cargo_type || v2->cargo_subtype != w2->cargo_subtype) {
       
  1876 					/* We can't pay for refitting because we can't estimate refitting costs for a vehicle before it's build.
       
  1877 					 * If we pay for it anyway, the cost and the estimated cost will not be the same and we will have an assert.
       
  1878 					 * We need to check the whole chain if it is a train because some newgrf articulated engines can refit some units only (and not the front) */
       
  1879 					total_cost += DoCommand(0, w->index, v2->cargo_type | (v2->cargo_subtype << 8), flags, GetCmdRefitVeh(v));
       
  1880 					break; // We learned that the engine in question needed a refit. No need to check anymore
       
  1881 				}
       
  1882 			} while (v->type == VEH_TRAIN && (w2 = w2->next) != NULL && (v2 = v2->next) != NULL);
       
  1883 
  1806 
  1884 			if (v->type == VEH_TRAIN && HASBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION)) {
  1807 			if (v->type == VEH_TRAIN && HASBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION)) {
  1885 				SETBIT(w->u.rail.flags, VRF_REVERSE_DIRECTION);
  1808 				SETBIT(w->u.rail.flags, VRF_REVERSE_DIRECTION);
  1886 			}
  1809 			}
  1887 
  1810 
  1900 	} while (v->type == VEH_TRAIN && (v = GetNextVehicle(v)) != NULL);
  1823 	} while (v->type == VEH_TRAIN && (v = GetNextVehicle(v)) != NULL);
  1901 
  1824 
  1902 	if (flags & DC_EXEC && v_front->type == VEH_TRAIN) {
  1825 	if (flags & DC_EXEC && v_front->type == VEH_TRAIN) {
  1903 		/* for trains this needs to be the front engine due to the callback function */
  1826 		/* for trains this needs to be the front engine due to the callback function */
  1904 		_new_vehicle_id = w_front->index;
  1827 		_new_vehicle_id = w_front->index;
       
  1828 	}
       
  1829 
       
  1830 	if (flags & DC_EXEC) {
       
  1831 		/* Cloned vehicles belong to the same group */
       
  1832 		DoCommand(0, v_front->group_id, w_front->index, flags, CMD_ADD_VEHICLE_GROUP);
       
  1833 	}
       
  1834 
       
  1835 
       
  1836 	/* Take care of refitting. */
       
  1837 	w = w_front;
       
  1838 	v = v_front;
       
  1839 
       
  1840 	/* Both building and refitting are influenced by newgrf callbacks, which
       
  1841 	 * makes it impossible to accurately estimate the cloning costs. In
       
  1842 	 * particular, it is possible for engines of the same type to be built with
       
  1843 	 * different numbers of articulated parts, so when refitting we have to
       
  1844 	 * loop over real vehicles first, and then the articulated parts of those
       
  1845 	 * vehicles in a different loop. */
       
  1846 	do {
       
  1847 		do {
       
  1848 			if (flags & DC_EXEC) {
       
  1849 				assert(w != NULL);
       
  1850 
       
  1851 				if (w->cargo_type != v->cargo_type || w->cargo_subtype != v->cargo_type) {
       
  1852 					cost = DoCommand(0, w->index, v->cargo_type | (v->cargo_subtype << 8) | 1U << 16 , flags, GetCmdRefitVeh(v));
       
  1853 					if (!CmdFailed(cost)) total_cost += cost;
       
  1854 				}
       
  1855 
       
  1856 				if (w->type == VEH_TRAIN && EngineHasArticPart(w)) {
       
  1857 					w = GetNextArticPart(w);
       
  1858 				} else {
       
  1859 					break;
       
  1860 				}
       
  1861 			} else {
       
  1862 				CargoID initial_cargo = GetEngineCargoType(v->engine_type);
       
  1863 
       
  1864 				if (v->cargo_type != initial_cargo && initial_cargo != CT_INVALID) {
       
  1865 					total_cost += GetRefitCost(v->engine_type);
       
  1866 				}
       
  1867 			}
       
  1868 		} while (v->type == VEH_TRAIN && EngineHasArticPart(v) && (v = GetNextArticPart(v)) != NULL);
       
  1869 
       
  1870 		if (flags & DC_EXEC) w = GetNextVehicle(w);
       
  1871 	} while (v->type == VEH_TRAIN && (v = GetNextVehicle(v)) != NULL);
       
  1872 
       
  1873 	/* Since we can't estimate the cost of cloning a vehicle accurately we must
       
  1874 	 * check whether the player has enough money manually. */
       
  1875 	if (!CheckPlayerHasMoney(total_cost)) {
       
  1876 		if (flags & DC_EXEC) {
       
  1877 			/* The vehicle has already been bought, so now it must be sold again. */
       
  1878 			DoCommand(w_front->tile, w_front->index, 1, flags, GetCmdSellVeh(w_front));
       
  1879 		}
       
  1880 		return CMD_ERROR;
  1905 	}
  1881 	}
  1906 
  1882 
  1907 	/* Set the expense type last as refitting will make the cost go towards
  1883 	/* Set the expense type last as refitting will make the cost go towards
  1908 	 * running costs... */
  1884 	 * running costs... */
  1909 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
  1885 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
  1928  * @param *engine_count The number of engines stored in the list
  1904  * @param *engine_count The number of engines stored in the list
  1929  * @param ***wagon_list Pointer to a pointer to an array of free wagons in the depot (old list is freed and a new one is malloced)
  1905  * @param ***wagon_list Pointer to a pointer to an array of free wagons in the depot (old list is freed and a new one is malloced)
  1930  * @param *wagon_list_length Allocated size of wagon_list. Needs to be set to 0 when wagon_list points to a NULL array
  1906  * @param *wagon_list_length Allocated size of wagon_list. Needs to be set to 0 when wagon_list points to a NULL array
  1931  * @param *wagon_count The number of engines stored in the list
  1907  * @param *wagon_count The number of engines stored in the list
  1932  */
  1908  */
  1933 void BuildDepotVehicleList(byte type, TileIndex tile, Vehicle ***engine_list, uint16 *engine_list_length, uint16 *engine_count, Vehicle ***wagon_list, uint16 *wagon_list_length, uint16 *wagon_count)
  1909 void BuildDepotVehicleList(VehicleType type, TileIndex tile, Vehicle ***engine_list, uint16 *engine_list_length, uint16 *engine_count, Vehicle ***wagon_list, uint16 *wagon_list_length, uint16 *wagon_count)
  1934 {
  1910 {
  1935 	Vehicle *v;
  1911 	Vehicle *v;
  1936 
  1912 
  1937 	/* This function should never be called without an array to store results */
  1913 	/* This function should never be called without an array to store results */
  1938 	assert(!(engine_list == NULL && type != VEH_TRAIN));
  1914 	assert(!(engine_list == NULL && type != VEH_TRAIN));
  2007     <ul>
  1983     <ul>
  2008       <li>VLW_STATION_LIST:  index of station to generate a list for</li>
  1984       <li>VLW_STATION_LIST:  index of station to generate a list for</li>
  2009       <li>VLW_SHARED_ORDERS: index of order to generate a list for<li>
  1985       <li>VLW_SHARED_ORDERS: index of order to generate a list for<li>
  2010       <li>VLW_STANDARD: not used<li>
  1986       <li>VLW_STANDARD: not used<li>
  2011       <li>VLW_DEPOT_LIST: TileIndex of the depot/hangar to make the list for</li>
  1987       <li>VLW_DEPOT_LIST: TileIndex of the depot/hangar to make the list for</li>
       
  1988       <li>VLW_GROUP_LIST: index of group to generate a list for</li>
  2012     </ul>
  1989     </ul>
  2013 * @param window_type tells what kind of window the list is for. Use the VLW flags in vehicle_gui.h
  1990 * @param window_type tells what kind of window the list is for. Use the VLW flags in vehicle_gui.h
  2014 * @return the number of vehicles added to the list
  1991 * @return the number of vehicles added to the list
  2015 */
  1992 */
  2016 uint GenerateVehicleSortList(const Vehicle ***sort_list, uint16 *length_of_array, byte type, PlayerID owner, uint32 index, uint16 window_type)
  1993 uint GenerateVehicleSortList(const Vehicle ***sort_list, uint16 *length_of_array, VehicleType type, PlayerID owner, uint32 index, uint16 window_type)
  2017 {
  1994 {
  2018 	const byte subtype = (type != VEH_AIRCRAFT) ? (byte)Train_Front : (byte)AIR_AIRCRAFT;
  1995 	const byte subtype = (type != VEH_AIRCRAFT) ? (byte)Train_Front : (byte)AIR_AIRCRAFT;
  2019 	uint n = 0;
  1996 	uint n = 0;
  2020 	const Vehicle *v;
  1997 	const Vehicle *v;
  2021 
  1998 
  2085 				}
  2062 				}
  2086 			}
  2063 			}
  2087 			break;
  2064 			break;
  2088 		}
  2065 		}
  2089 
  2066 
       
  2067  		case VLW_GROUP_LIST:
       
  2068 			FOR_ALL_VEHICLES(v) {
       
  2069 				if (v->type == type && (
       
  2070 							(type == VEH_TRAIN && IsFrontEngine(v)) ||
       
  2071 							(type != VEH_TRAIN && v->subtype <= subtype)
       
  2072 						) && v->owner == owner && v->group_id == index) {
       
  2073 					if (n == *length_of_array) ExtendVehicleListSize(sort_list, length_of_array, GetNumVehicles() / 4);
       
  2074 
       
  2075 					(*sort_list)[n++] = v;
       
  2076 				}
       
  2077 			}
       
  2078 			break;
       
  2079 
  2090 		default: NOT_REACHED(); break;
  2080 		default: NOT_REACHED(); break;
  2091 	}
  2081 	}
  2092 
  2082 
  2093 	if ((n + 100) < *length_of_array) {
  2083 	if ((n + 100) < *length_of_array) {
  2094 		/* We allocated way too much for sort_list.
  2084 		/* We allocated way too much for sort_list.
  2108  * @param service should the vehicles only get service in the depots
  2098  * @param service should the vehicles only get service in the depots
  2109  * @param owner PlayerID of owner of the vehicles to send
  2099  * @param owner PlayerID of owner of the vehicles to send
  2110  * @param vlw_flag tells what kind of list requested the goto depot
  2100  * @param vlw_flag tells what kind of list requested the goto depot
  2111  * @return 0 for success and CMD_ERROR if no vehicle is able to go to depot
  2101  * @return 0 for success and CMD_ERROR if no vehicle is able to go to depot
  2112  */
  2102  */
  2113 int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id)
  2103 int32 SendAllVehiclesToDepot(VehicleType type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id)
  2114 {
  2104 {
  2115 	const Vehicle **sort_list = NULL;
  2105 	const Vehicle **sort_list = NULL;
  2116 	uint n, i;
  2106 	uint n, i;
  2117 	uint16 array_length = 0;
  2107 	uint16 array_length = 0;
  2118 
  2108 
  2219 			}
  2209 			}
  2220 		}
  2210 		}
  2221 
  2211 
  2222 		if (HASBIT(t.flags, OFB_PART_OF_ORDERS)) {
  2212 		if (HASBIT(t.flags, OFB_PART_OF_ORDERS)) {
  2223 			/* Part of orders */
  2213 			/* Part of orders */
  2224 			if (v->type == VEH_TRAIN) v->u.rail.days_since_order_progr = 0;
       
  2225 			v->cur_order_index++;
  2214 			v->cur_order_index++;
  2226 		} else if (HASBIT(t.flags, OFB_HALT_IN_DEPOT)) {
  2215 		} else if (HASBIT(t.flags, OFB_HALT_IN_DEPOT)) {
  2227 			/* Force depot visit */
  2216 			/* Force depot visit */
  2228 			v->vehstatus |= VS_STOPPED;
  2217 			v->vehstatus |= VS_STOPPED;
  2229 			if (v->owner == _local_player) {
  2218 			if (v->owner == _local_player) {
  2419 uint32 VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y)
  2408 uint32 VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y)
  2420 {
  2409 {
  2421 	return _tile_type_procs[GetTileType(tile)]->vehicle_enter_tile_proc(v, tile, x, y);
  2410 	return _tile_type_procs[GetTileType(tile)]->vehicle_enter_tile_proc(v, tile, x, y);
  2422 }
  2411 }
  2423 
  2412 
  2424 UnitID GetFreeUnitNumber(byte type)
  2413 UnitID GetFreeUnitNumber(VehicleType type)
  2425 {
  2414 {
  2426 	UnitID unit, max = 0;
  2415 	UnitID unit, max = 0;
  2427 	const Vehicle *u;
  2416 	const Vehicle *u;
  2428 	static bool *cache = NULL;
  2417 	static bool *cache = NULL;
  2429 	static UnitID gmax = 0;
  2418 	static UnitID gmax = 0;
  2465 	}
  2454 	}
  2466 
  2455 
  2467 	return unit;
  2456 	return unit;
  2468 }
  2457 }
  2469 
  2458 
  2470 static SpriteID GetEngineColourMap(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v)
  2459 
  2471 {
  2460 const Livery *GetEngineLivery(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v)
  2472 	SpriteID map = PAL_NONE;
  2461 {
  2473 	const Player *p = GetPlayer(player);
  2462 	const Player *p = GetPlayer(player);
  2474 	LiveryScheme scheme = LS_DEFAULT;
  2463 	LiveryScheme scheme = LS_DEFAULT;
  2475 	CargoID cargo_type = v == NULL ? (CargoID)CT_INVALID : v->cargo_type;
  2464 	CargoID cargo_type = v == NULL ? (CargoID)CT_INVALID : v->cargo_type;
       
  2465 
       
  2466 	/* The default livery is always available for use, but its in_use flag determines
       
  2467 	 * whether any _other_ liveries are in use. */
       
  2468 	if (p->livery[LS_DEFAULT].in_use && (_patches.liveries == 2 || (_patches.liveries == 1 && player == _local_player))) {
       
  2469 		/* Determine the livery scheme to use */
       
  2470 		switch (GetEngine(engine_type)->type) {
       
  2471 			default: NOT_REACHED();
       
  2472 			case VEH_TRAIN: {
       
  2473 				const RailVehicleInfo *rvi = RailVehInfo(engine_type);
       
  2474 
       
  2475 				switch (rvi->railtype) {
       
  2476 					default: NOT_REACHED();
       
  2477 					case RAILTYPE_RAIL:
       
  2478 					case RAILTYPE_ELECTRIC:
       
  2479 					{
       
  2480 						if (cargo_type == CT_INVALID) cargo_type = rvi->cargo_type;
       
  2481 						if (rvi->railveh_type == RAILVEH_WAGON) {
       
  2482 							if (!GetCargo(cargo_type)->is_freight) {
       
  2483 								if (parent_engine_type == INVALID_ENGINE) {
       
  2484 									scheme = LS_PASSENGER_WAGON_STEAM;
       
  2485 								} else {
       
  2486 									switch (RailVehInfo(parent_engine_type)->engclass) {
       
  2487 										default: NOT_REACHED();
       
  2488 										case EC_STEAM:    scheme = LS_PASSENGER_WAGON_STEAM;    break;
       
  2489 										case EC_DIESEL:   scheme = LS_PASSENGER_WAGON_DIESEL;   break;
       
  2490 										case EC_ELECTRIC: scheme = LS_PASSENGER_WAGON_ELECTRIC; break;
       
  2491 									}
       
  2492 								}
       
  2493 							} else {
       
  2494 								scheme = LS_FREIGHT_WAGON;
       
  2495 							}
       
  2496 						} else {
       
  2497 							bool is_mu = HASBIT(_engine_info[engine_type].misc_flags, EF_RAIL_IS_MU);
       
  2498 
       
  2499 							switch (rvi->engclass) {
       
  2500 								default: NOT_REACHED();
       
  2501 								case EC_STEAM:    scheme = LS_STEAM; break;
       
  2502 								case EC_DIESEL:   scheme = is_mu ? LS_DMU : LS_DIESEL;   break;
       
  2503 								case EC_ELECTRIC: scheme = is_mu ? LS_EMU : LS_ELECTRIC; break;
       
  2504 							}
       
  2505 						}
       
  2506 						break;
       
  2507 					}
       
  2508 
       
  2509 					case RAILTYPE_MONO: scheme = LS_MONORAIL; break;
       
  2510 					case RAILTYPE_MAGLEV: scheme = LS_MAGLEV; break;
       
  2511 				}
       
  2512 				break;
       
  2513 			}
       
  2514 
       
  2515 			case VEH_ROAD: {
       
  2516 				const RoadVehicleInfo *rvi = RoadVehInfo(engine_type);
       
  2517 				if (cargo_type == CT_INVALID) cargo_type = rvi->cargo_type;
       
  2518 				scheme = IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_BUS : LS_TRUCK;
       
  2519 				break;
       
  2520 			}
       
  2521 
       
  2522 			case VEH_SHIP: {
       
  2523 				const ShipVehicleInfo *svi = ShipVehInfo(engine_type);
       
  2524 				if (cargo_type == CT_INVALID) cargo_type = svi->cargo_type;
       
  2525 				scheme = IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_PASSENGER_SHIP : LS_FREIGHT_SHIP;
       
  2526 				break;
       
  2527 			}
       
  2528 
       
  2529 			case VEH_AIRCRAFT: {
       
  2530 				const AircraftVehicleInfo *avi = AircraftVehInfo(engine_type);
       
  2531 				if (cargo_type == CT_INVALID) cargo_type = CT_PASSENGERS;
       
  2532 				switch (avi->subtype) {
       
  2533 					case AIR_HELI: scheme = LS_HELICOPTER; break;
       
  2534 					case AIR_CTOL: scheme = LS_SMALL_PLANE; break;
       
  2535 					case AIR_CTOL | AIR_FAST: scheme = LS_LARGE_PLANE; break;
       
  2536 				}
       
  2537 				break;
       
  2538 			}
       
  2539 		}
       
  2540 
       
  2541 		/* Switch back to the default scheme if the resolved scheme is not in use */
       
  2542 		if (!p->livery[scheme].in_use) scheme = LS_DEFAULT;
       
  2543 	}
       
  2544 
       
  2545 	return &p->livery[scheme];
       
  2546 }
       
  2547 
       
  2548 
       
  2549 static SpriteID GetEngineColourMap(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v)
       
  2550 {
       
  2551 	SpriteID map = PAL_NONE;
  2476 
  2552 
  2477 	/* Check if we should use the colour map callback */
  2553 	/* Check if we should use the colour map callback */
  2478 	if (HASBIT(EngInfo(engine_type)->callbackmask, CBM_COLOUR_REMAP)) {
  2554 	if (HASBIT(EngInfo(engine_type)->callbackmask, CBM_COLOUR_REMAP)) {
  2479 		uint16 callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v);
  2555 		uint16 callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v);
  2480 		/* A return value of 0xC000 is stated to "use the default two-color
  2556 		/* A return value of 0xC000 is stated to "use the default two-color
  2485 			 * map else it's returned as-is. */
  2561 			 * map else it's returned as-is. */
  2486 			if (!HASBIT(callback, 14)) return map;
  2562 			if (!HASBIT(callback, 14)) return map;
  2487 		}
  2563 		}
  2488 	}
  2564 	}
  2489 
  2565 
  2490 	/* The default livery is always available for use, but its in_use flag determines
       
  2491 	 * whether any _other_ liveries are in use. */
       
  2492 	if (p->livery[LS_DEFAULT].in_use && (_patches.liveries == 2 || (_patches.liveries == 1 && player == _local_player))) {
       
  2493 		/* Determine the livery scheme to use */
       
  2494 		switch (GetEngine(engine_type)->type) {
       
  2495 			case VEH_TRAIN: {
       
  2496 				const RailVehicleInfo *rvi = RailVehInfo(engine_type);
       
  2497 
       
  2498 				switch (rvi->railtype) {
       
  2499 					default: NOT_REACHED();
       
  2500 					case RAILTYPE_RAIL:
       
  2501 					case RAILTYPE_ELECTRIC:
       
  2502 					{
       
  2503 						if (cargo_type == CT_INVALID) cargo_type = rvi->cargo_type;
       
  2504 						if (rvi->railveh_type == RAILVEH_WAGON) {
       
  2505 							if (cargo_type == CT_PASSENGERS || cargo_type == CT_MAIL || cargo_type == CT_VALUABLES) {
       
  2506 								if (parent_engine_type == INVALID_ENGINE) {
       
  2507 									scheme = LS_PASSENGER_WAGON_STEAM;
       
  2508 								} else {
       
  2509 									switch (RailVehInfo(parent_engine_type)->engclass) {
       
  2510 										case 0: scheme = LS_PASSENGER_WAGON_STEAM; break;
       
  2511 										case 1: scheme = LS_PASSENGER_WAGON_DIESEL; break;
       
  2512 										case 2: scheme = LS_PASSENGER_WAGON_ELECTRIC; break;
       
  2513 									}
       
  2514 								}
       
  2515 							} else {
       
  2516 								scheme = LS_FREIGHT_WAGON;
       
  2517 							}
       
  2518 						} else {
       
  2519 							bool is_mu = HASBIT(_engine_info[engine_type].misc_flags, EF_RAIL_IS_MU);
       
  2520 
       
  2521 							switch (rvi->engclass) {
       
  2522 								case 0: scheme = LS_STEAM; break;
       
  2523 								case 1: scheme = is_mu ? LS_DMU : LS_DIESEL; break;
       
  2524 								case 2: scheme = is_mu ? LS_EMU : LS_ELECTRIC; break;
       
  2525 							}
       
  2526 						}
       
  2527 						break;
       
  2528 					}
       
  2529 
       
  2530 					case RAILTYPE_MONO: scheme = LS_MONORAIL; break;
       
  2531 					case RAILTYPE_MAGLEV: scheme = LS_MAGLEV; break;
       
  2532 				}
       
  2533 				break;
       
  2534 			}
       
  2535 
       
  2536 			case VEH_ROAD: {
       
  2537 				const RoadVehicleInfo *rvi = RoadVehInfo(engine_type);
       
  2538 				if (cargo_type == CT_INVALID) cargo_type = rvi->cargo_type;
       
  2539 				scheme = IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_BUS : LS_TRUCK;
       
  2540 				break;
       
  2541 			}
       
  2542 
       
  2543 			case VEH_SHIP: {
       
  2544 				const ShipVehicleInfo *svi = ShipVehInfo(engine_type);
       
  2545 				if (cargo_type == CT_INVALID) cargo_type = svi->cargo_type;
       
  2546 				scheme = IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_PASSENGER_SHIP : LS_FREIGHT_SHIP;
       
  2547 				break;
       
  2548 			}
       
  2549 
       
  2550 			case VEH_AIRCRAFT: {
       
  2551 				const AircraftVehicleInfo *avi = AircraftVehInfo(engine_type);
       
  2552 				if (cargo_type == CT_INVALID) cargo_type = CT_PASSENGERS;
       
  2553 				switch (avi->subtype) {
       
  2554 					case AIR_HELI: scheme = LS_HELICOPTER; break;
       
  2555 					case AIR_CTOL: scheme = LS_SMALL_PLANE; break;
       
  2556 					case AIR_CTOL | AIR_FAST: scheme = LS_LARGE_PLANE; break;
       
  2557 				}
       
  2558 				break;
       
  2559 			}
       
  2560 		}
       
  2561 
       
  2562 		/* Switch back to the default scheme if the resolved scheme is not in use */
       
  2563 		if (!p->livery[scheme].in_use) scheme = LS_DEFAULT;
       
  2564 	}
       
  2565 
       
  2566 	bool twocc = HASBIT(EngInfo(engine_type)->misc_flags, EF_USES_2CC);
  2566 	bool twocc = HASBIT(EngInfo(engine_type)->misc_flags, EF_USES_2CC);
  2567 
  2567 
  2568 	if (map == PAL_NONE) map = twocc ? (SpriteID)SPR_2CCMAP_BASE : (SpriteID)PALETTE_RECOLOR_START;
  2568 	if (map == PAL_NONE) map = twocc ? (SpriteID)SPR_2CCMAP_BASE : (SpriteID)PALETTE_RECOLOR_START;
  2569 
  2569 
  2570 	map += p->livery[scheme].colour1;
  2570 	const Livery *livery = GetEngineLivery(engine_type, player, parent_engine_type, v);
  2571 	if (twocc) map += p->livery[scheme].colour2 * 16;
  2571 
       
  2572 	map += livery->colour1;
       
  2573 	if (twocc) map += livery->colour2 * 16;
  2572 
  2574 
  2573 	return map;
  2575 	return map;
  2574 }
  2576 }
  2575 
  2577 
  2576 SpriteID GetEnginePalette(EngineID engine_type, PlayerID player)
  2578 SpriteID GetEnginePalette(EngineID engine_type, PlayerID player)
  2609 	SLE_CONDVAR(Vehicle, y_pos,                SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
  2611 	SLE_CONDVAR(Vehicle, y_pos,                SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
  2610 	SLE_CONDVAR(Vehicle, y_pos,                SLE_UINT32,                  6, SL_MAX_VERSION),
  2612 	SLE_CONDVAR(Vehicle, y_pos,                SLE_UINT32,                  6, SL_MAX_VERSION),
  2611 	    SLE_VAR(Vehicle, z_pos,                SLE_UINT8),
  2613 	    SLE_VAR(Vehicle, z_pos,                SLE_UINT8),
  2612 	    SLE_VAR(Vehicle, direction,            SLE_UINT8),
  2614 	    SLE_VAR(Vehicle, direction,            SLE_UINT8),
  2613 
  2615 
  2614 	    SLE_VAR(Vehicle, cur_image,            SLE_UINT16),
  2616 	SLE_CONDNULL(2,                                                         0, 57),
  2615 	    SLE_VAR(Vehicle, spritenum,            SLE_UINT8),
  2617 	    SLE_VAR(Vehicle, spritenum,            SLE_UINT8),
  2616 	    SLE_VAR(Vehicle, sprite_width,         SLE_UINT8),
  2618 	SLE_CONDNULL(5,                                                         0, 57),
  2617 	    SLE_VAR(Vehicle, sprite_height,        SLE_UINT8),
       
  2618 	    SLE_VAR(Vehicle, z_height,             SLE_UINT8),
       
  2619 	    SLE_VAR(Vehicle, x_offs,               SLE_INT8),
       
  2620 	    SLE_VAR(Vehicle, y_offs,               SLE_INT8),
       
  2621 	    SLE_VAR(Vehicle, engine_type,          SLE_UINT16),
  2619 	    SLE_VAR(Vehicle, engine_type,          SLE_UINT16),
  2622 
  2620 
  2623 	    SLE_VAR(Vehicle, max_speed,            SLE_UINT16),
  2621 	    SLE_VAR(Vehicle, max_speed,            SLE_UINT16),
  2624 	    SLE_VAR(Vehicle, cur_speed,            SLE_UINT16),
  2622 	    SLE_VAR(Vehicle, cur_speed,            SLE_UINT16),
  2625 	    SLE_VAR(Vehicle, subspeed,             SLE_UINT8),
  2623 	    SLE_VAR(Vehicle, subspeed,             SLE_UINT8),
  2646 	    SLE_VAR(Vehicle, num_orders,           SLE_UINT8),
  2644 	    SLE_VAR(Vehicle, num_orders,           SLE_UINT8),
  2647 
  2645 
  2648 	/* This next line is for version 4 and prior compatibility.. it temporarily reads
  2646 	/* This next line is for version 4 and prior compatibility.. it temporarily reads
  2649 	    type and flags (which were both 4 bits) into type. Later on this is
  2647 	    type and flags (which were both 4 bits) into type. Later on this is
  2650 	    converted correctly */
  2648 	    converted correctly */
  2651 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, type), SLE_UINT8,                 0, 4),
  2649 	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type), SLE_UINT8,                 0, 4),
  2652 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
  2650 	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
  2653 
  2651 
  2654 	/* Orders for version 5 and on */
  2652 	/* Orders for version 5 and on */
  2655 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, type),  SLE_UINT8,  5, SL_MAX_VERSION),
  2653 	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type),  SLE_UINT8,  5, SL_MAX_VERSION),
  2656 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, flags), SLE_UINT8,  5, SL_MAX_VERSION),
  2654 	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, flags), SLE_UINT8,  5, SL_MAX_VERSION),
  2657 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest),  SLE_UINT16, 5, SL_MAX_VERSION),
  2655 	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest),  SLE_UINT16, 5, SL_MAX_VERSION),
  2658 
  2656 
  2659 	/* Refit in current order */
  2657 	/* Refit in current order */
  2660 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, refit_cargo),    SLE_UINT8, 36, SL_MAX_VERSION),
  2658 	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_cargo),    SLE_UINT8, 36, SL_MAX_VERSION),
  2661 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, refit_subtype),  SLE_UINT8, 36, SL_MAX_VERSION),
  2659 	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_subtype),  SLE_UINT8, 36, SL_MAX_VERSION),
  2662 
  2660 
  2663 	    SLE_REF(Vehicle, orders,               REF_ORDER),
  2661 	    SLE_REF(Vehicle, orders,               REF_ORDER),
  2664 
  2662 
  2665 	SLE_CONDVAR(Vehicle, age,                  SLE_FILE_U16 | SLE_VAR_I32,  0, 30),
  2663 	SLE_CONDVAR(Vehicle, age,                  SLE_FILE_U16 | SLE_VAR_I32,  0, 30),
  2666 	SLE_CONDVAR(Vehicle, age,                  SLE_INT32,                  31, SL_MAX_VERSION),
  2664 	SLE_CONDVAR(Vehicle, age,                  SLE_INT32,                  31, SL_MAX_VERSION),
  2693 	    SLE_VAR(Vehicle, waiting_triggers,     SLE_UINT8),
  2691 	    SLE_VAR(Vehicle, waiting_triggers,     SLE_UINT8),
  2694 
  2692 
  2695 	    SLE_REF(Vehicle, next_shared,          REF_VEHICLE),
  2693 	    SLE_REF(Vehicle, next_shared,          REF_VEHICLE),
  2696 	    SLE_REF(Vehicle, prev_shared,          REF_VEHICLE),
  2694 	    SLE_REF(Vehicle, prev_shared,          REF_VEHICLE),
  2697 
  2695 
       
  2696 	SLE_CONDVAR(Vehicle, group_id,             SLE_UINT16,                60, SL_MAX_VERSION),
       
  2697 
  2698 	/* reserve extra space in savegame here. (currently 10 bytes) */
  2698 	/* reserve extra space in savegame here. (currently 10 bytes) */
  2699 	SLE_CONDNULL(10,                                                       2, SL_MAX_VERSION),
  2699 	SLE_CONDNULL(10,                                                       2, SL_MAX_VERSION),
  2700 
  2700 
  2701 	SLE_END()
  2701 	SLE_END()
  2702 };
  2702 };
  2703 
  2703 
  2704 
  2704 
  2705 static const SaveLoad _train_desc[] = {
  2705 static const SaveLoad _train_desc[] = {
  2706 	SLE_WRITEBYTE(Vehicle, type, VEH_TRAIN, 0), // Train type. VEH_TRAIN in mem, 0 in file.
  2706 	SLE_WRITEBYTE(Vehicle, type, VEH_TRAIN, 0), // Train type. VEH_TRAIN in mem, 0 in file.
  2707 	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
  2707 	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
  2708 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, crash_anim_pos),         SLE_UINT16),
  2708 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, crash_anim_pos),         SLE_UINT16),
  2709 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, force_proceed),          SLE_UINT8),
  2709 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, force_proceed),          SLE_UINT8),
  2710 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, railtype),               SLE_UINT8),
  2710 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, railtype),               SLE_UINT8),
  2711 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, track),                  SLE_UINT8),
  2711 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, track),                  SLE_UINT8),
  2712 
  2712 
  2713 	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRail, flags),                  SLE_UINT8,  2, SL_MAX_VERSION),
  2713 	SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags),                  SLE_UINT8,  2, SL_MAX_VERSION),
  2714 	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRail, days_since_order_progr), SLE_UINT16, 2, SL_MAX_VERSION),
  2714 	SLE_CONDNULL(2, 2, 59),
  2715 
  2715 
  2716 	SLE_CONDNULL(2, 2, 19),
  2716 	SLE_CONDNULL(2, 2, 19),
  2717 	/* reserve extra space in savegame here. (currently 11 bytes) */
  2717 	/* reserve extra space in savegame here. (currently 11 bytes) */
  2718 	SLE_CONDNULL(11, 2, SL_MAX_VERSION),
  2718 	SLE_CONDNULL(11, 2, SL_MAX_VERSION),
  2719 
  2719 
  2721 };
  2721 };
  2722 
  2722 
  2723 static const SaveLoad _roadveh_desc[] = {
  2723 static const SaveLoad _roadveh_desc[] = {
  2724 	SLE_WRITEBYTE(Vehicle, type, VEH_ROAD, 1), // Road type. VEH_ROAD in mem, 1 in file.
  2724 	SLE_WRITEBYTE(Vehicle, type, VEH_ROAD, 1), // Road type. VEH_ROAD in mem, 1 in file.
  2725 	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
  2725 	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
  2726 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, state),          SLE_UINT8),
  2726 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, state),          SLE_UINT8),
  2727 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, frame),          SLE_UINT8),
  2727 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, frame),          SLE_UINT8),
  2728 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, blocked_ctr),    SLE_UINT16),
  2728 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, blocked_ctr),    SLE_UINT16),
  2729 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, overtaking),     SLE_UINT8),
  2729 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking),     SLE_UINT8),
  2730 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, overtaking_ctr), SLE_UINT8),
  2730 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking_ctr), SLE_UINT8),
  2731 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, crashed_ctr),    SLE_UINT16),
  2731 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, crashed_ctr),    SLE_UINT16),
  2732 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, reverse_ctr),    SLE_UINT8),
  2732 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, reverse_ctr),    SLE_UINT8),
  2733 
  2733 
  2734 	SLE_CONDREFX(offsetof(Vehicle, u) + offsetof(VehicleRoad, slot),     REF_ROADSTOPS, 6, SL_MAX_VERSION),
  2734 	SLE_CONDREFX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot),     REF_ROADSTOPS, 6, SL_MAX_VERSION),
  2735 	SLE_CONDNULL(1,                                                                     6, SL_MAX_VERSION),
  2735 	SLE_CONDNULL(1,                                                                     6, SL_MAX_VERSION),
  2736 	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, slot_age), SLE_UINT8,     6, SL_MAX_VERSION),
  2736 	SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot_age), SLE_UINT8,     6, SL_MAX_VERSION),
  2737 	/* reserve extra space in savegame here. (currently 16 bytes) */
  2737 	/* reserve extra space in savegame here. (currently 16 bytes) */
  2738 	SLE_CONDNULL(16,                                                                    2, SL_MAX_VERSION),
  2738 	SLE_CONDNULL(16,                                                                    2, SL_MAX_VERSION),
  2739 
  2739 
  2740 	SLE_END()
  2740 	SLE_END()
  2741 };
  2741 };
  2742 
  2742 
  2743 static const SaveLoad _ship_desc[] = {
  2743 static const SaveLoad _ship_desc[] = {
  2744 	SLE_WRITEBYTE(Vehicle, type, VEH_SHIP, 2), // Ship type. VEH_SHIP in mem, 2 in file.
  2744 	SLE_WRITEBYTE(Vehicle, type, VEH_SHIP, 2), // Ship type. VEH_SHIP in mem, 2 in file.
  2745 	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
  2745 	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
  2746 	SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleShip, state), SLE_UINT8),
  2746 	SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleShip, state), SLE_UINT8),
  2747 
  2747 
  2748 	/* reserve extra space in savegame here. (currently 16 bytes) */
  2748 	/* reserve extra space in savegame here. (currently 16 bytes) */
  2749 	SLE_CONDNULL(16, 2, SL_MAX_VERSION),
  2749 	SLE_CONDNULL(16, 2, SL_MAX_VERSION),
  2750 
  2750 
  2751 	SLE_END()
  2751 	SLE_END()
  2752 };
  2752 };
  2753 
  2753 
  2754 static const SaveLoad _aircraft_desc[] = {
  2754 static const SaveLoad _aircraft_desc[] = {
  2755 	SLE_WRITEBYTE(Vehicle, type, VEH_AIRCRAFT, 3), // Aircraft type. VEH_AIRCRAFT in mem, 3 in file.
  2755 	SLE_WRITEBYTE(Vehicle, type, VEH_AIRCRAFT, 3), // Aircraft type. VEH_AIRCRAFT in mem, 3 in file.
  2756 	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
  2756 	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
  2757 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleAir, crashed_counter), SLE_UINT16),
  2757 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, crashed_counter), SLE_UINT16),
  2758 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleAir, pos),             SLE_UINT8),
  2758 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, pos),             SLE_UINT8),
  2759 
  2759 
  2760 	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, targetairport),   SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
  2760 	SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport),   SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
  2761 	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, targetairport),   SLE_UINT16,                5, SL_MAX_VERSION),
  2761 	SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport),   SLE_UINT16,                5, SL_MAX_VERSION),
  2762 
  2762 
  2763 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleAir, state),           SLE_UINT8),
  2763 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, state),           SLE_UINT8),
  2764 
  2764 
  2765 	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, previous_pos),    SLE_UINT8,                 2, SL_MAX_VERSION),
  2765 	SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, previous_pos),    SLE_UINT8,                 2, SL_MAX_VERSION),
  2766 
  2766 
  2767 	/* reserve extra space in savegame here. (currently 15 bytes) */
  2767 	/* reserve extra space in savegame here. (currently 15 bytes) */
  2768 	SLE_CONDNULL(15,                                                                                      2, SL_MAX_VERSION),
  2768 	SLE_CONDNULL(15,                                                                                      2, SL_MAX_VERSION),
  2769 
  2769 
  2770 	SLE_END()
  2770 	SLE_END()
  2783 	SLE_CONDVAR(Vehicle, y_pos,         SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
  2783 	SLE_CONDVAR(Vehicle, y_pos,         SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
  2784 	SLE_CONDVAR(Vehicle, y_pos,         SLE_INT32,                  6, SL_MAX_VERSION),
  2784 	SLE_CONDVAR(Vehicle, y_pos,         SLE_INT32,                  6, SL_MAX_VERSION),
  2785 	    SLE_VAR(Vehicle, z_pos,         SLE_UINT8),
  2785 	    SLE_VAR(Vehicle, z_pos,         SLE_UINT8),
  2786 
  2786 
  2787 	    SLE_VAR(Vehicle, cur_image,     SLE_UINT16),
  2787 	    SLE_VAR(Vehicle, cur_image,     SLE_UINT16),
  2788 	    SLE_VAR(Vehicle, sprite_width,  SLE_UINT8),
  2788 	SLE_CONDNULL(5,                                                 0, 57),
  2789 	    SLE_VAR(Vehicle, sprite_height, SLE_UINT8),
       
  2790 	    SLE_VAR(Vehicle, z_height,      SLE_UINT8),
       
  2791 	    SLE_VAR(Vehicle, x_offs,        SLE_INT8),
       
  2792 	    SLE_VAR(Vehicle, y_offs,        SLE_INT8),
       
  2793 	    SLE_VAR(Vehicle, progress,      SLE_UINT8),
  2789 	    SLE_VAR(Vehicle, progress,      SLE_UINT8),
  2794 	    SLE_VAR(Vehicle, vehstatus,     SLE_UINT8),
  2790 	    SLE_VAR(Vehicle, vehstatus,     SLE_UINT8),
  2795 
  2791 
  2796 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleSpecial, unk0), SLE_UINT16),
  2792 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleSpecial, unk0), SLE_UINT16),
  2797 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleSpecial, unk2), SLE_UINT8),
  2793 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleSpecial, unk2), SLE_UINT8),
  2798 
  2794 
  2799 	/* reserve extra space in savegame here. (currently 16 bytes) */
  2795 	/* reserve extra space in savegame here. (currently 16 bytes) */
  2800 	SLE_CONDNULL(16, 2, SL_MAX_VERSION),
  2796 	SLE_CONDNULL(16, 2, SL_MAX_VERSION),
  2801 
  2797 
  2802 	SLE_END()
  2798 	SLE_END()
  2818 	SLE_CONDVAR(Vehicle, y_pos,         SLE_FILE_I16 | SLE_VAR_I32,  0, 5),
  2814 	SLE_CONDVAR(Vehicle, y_pos,         SLE_FILE_I16 | SLE_VAR_I32,  0, 5),
  2819 	SLE_CONDVAR(Vehicle, y_pos,         SLE_INT32,                   6, SL_MAX_VERSION),
  2815 	SLE_CONDVAR(Vehicle, y_pos,         SLE_INT32,                   6, SL_MAX_VERSION),
  2820 	    SLE_VAR(Vehicle, z_pos,         SLE_UINT8),
  2816 	    SLE_VAR(Vehicle, z_pos,         SLE_UINT8),
  2821 	    SLE_VAR(Vehicle, direction,     SLE_UINT8),
  2817 	    SLE_VAR(Vehicle, direction,     SLE_UINT8),
  2822 
  2818 
  2823 	    SLE_VAR(Vehicle, x_offs,        SLE_INT8),
  2819 	SLE_CONDNULL(5,                                                  0, 57),
  2824 	    SLE_VAR(Vehicle, y_offs,        SLE_INT8),
       
  2825 	    SLE_VAR(Vehicle, sprite_width,  SLE_UINT8),
       
  2826 	    SLE_VAR(Vehicle, sprite_height, SLE_UINT8),
       
  2827 	    SLE_VAR(Vehicle, z_height,      SLE_UINT8),
       
  2828 	    SLE_VAR(Vehicle, owner,         SLE_UINT8),
  2820 	    SLE_VAR(Vehicle, owner,         SLE_UINT8),
  2829 	    SLE_VAR(Vehicle, vehstatus,     SLE_UINT8),
  2821 	    SLE_VAR(Vehicle, vehstatus,     SLE_UINT8),
  2830 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
  2822 	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
  2831 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_UINT16,                5, SL_MAX_VERSION),
  2823 	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_UINT16,                5, SL_MAX_VERSION),
  2832 
  2824 
  2833 	    SLE_VAR(Vehicle, cur_image,     SLE_UINT16),
  2825 	    SLE_VAR(Vehicle, cur_image,     SLE_UINT16),
  2834 	SLE_CONDVAR(Vehicle, age,           SLE_FILE_U16 | SLE_VAR_I32,  0, 30),
  2826 	SLE_CONDVAR(Vehicle, age,           SLE_FILE_U16 | SLE_VAR_I32,  0, 30),
  2835 	SLE_CONDVAR(Vehicle, age,           SLE_INT32,                  31, SL_MAX_VERSION),
  2827 	SLE_CONDVAR(Vehicle, age,           SLE_INT32,                  31, SL_MAX_VERSION),
  2836 	    SLE_VAR(Vehicle, tick_counter,  SLE_UINT8),
  2828 	    SLE_VAR(Vehicle, tick_counter,  SLE_UINT8),
  2837 
  2829 
  2838 	   SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleDisaster, image_override), SLE_UINT16),
  2830 	   SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, image_override), SLE_UINT16),
  2839 	   SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleDisaster, unk2),           SLE_UINT16),
  2831 	   SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, unk2),           SLE_UINT16),
  2840 
  2832 
  2841 	/* reserve extra space in savegame here. (currently 16 bytes) */
  2833 	/* reserve extra space in savegame here. (currently 16 bytes) */
  2842 	SLE_CONDNULL(16,                                                 2, SL_MAX_VERSION),
  2834 	SLE_CONDNULL(16,                                                 2, SL_MAX_VERSION),
  2843 
  2835 
  2844 	SLE_END()
  2836 	SLE_END()
  2878 			error("Vehicles: failed loading savegame: too many vehicles");
  2870 			error("Vehicles: failed loading savegame: too many vehicles");
  2879 
  2871 
  2880 		v = GetVehicle(index);
  2872 		v = GetVehicle(index);
  2881 		SlObject(v, (SaveLoad*)_veh_descs[SlReadByte()]);
  2873 		SlObject(v, (SaveLoad*)_veh_descs[SlReadByte()]);
  2882 
  2874 
       
  2875 		switch (v->type) {
       
  2876 			case VEH_TRAIN:    v = new (v) Train();           break;
       
  2877 			case VEH_ROAD:     v = new (v) RoadVehicle();     break;
       
  2878 			case VEH_SHIP:     v = new (v) Ship();            break;
       
  2879 			case VEH_AIRCRAFT: v = new (v) Aircraft();        break;
       
  2880 			case VEH_SPECIAL:  v = new (v) SpecialVehicle();  break;
       
  2881 			case VEH_DISASTER: v = new (v) DisasterVehicle(); break;
       
  2882 			case VEH_INVALID:  v = new (v) InvalidVehicle();  break;
       
  2883 			default: NOT_REACHED();
       
  2884 		}
       
  2885 
  2883 		/* Old savegames used 'last_station_visited = 0xFF' */
  2886 		/* Old savegames used 'last_station_visited = 0xFF' */
  2884 		if (CheckSavegameVersion(5) && v->last_station_visited == 0xFF)
  2887 		if (CheckSavegameVersion(5) && v->last_station_visited == 0xFF)
  2885 			v->last_station_visited = INVALID_STATION;
  2888 			v->last_station_visited = INVALID_STATION;
  2886 
  2889 
  2887 		if (CheckSavegameVersion(5)) {
  2890 		if (CheckSavegameVersion(5)) {
  2888 			/* Convert the current_order.type (which is a mix of type and flags, because
  2891 			/* Convert the current_order.type (which is a mix of type and flags, because
  2889 			 *  in those versions, they both were 4 bits big) to type and flags */
  2892 			 *  in those versions, they both were 4 bits big) to type and flags */
  2890 			v->current_order.flags = (v->current_order.type & 0xF0) >> 4;
  2893 			v->current_order.flags = (v->current_order.type & 0xF0) >> 4;
  2891 			v->current_order.type.m_val &= 0x0F;
  2894 			v->current_order.type.m_val &= 0x0F;
  2892 		}
  2895 		}
       
  2896 
       
  2897 		/* Advanced vehicle lists got added */
       
  2898 		if (CheckSavegameVersion(60)) v->group_id = DEFAULT_GROUP;
  2893 	}
  2899 	}
  2894 
  2900 
  2895 	/* Check for shared order-lists (we now use pointers for that) */
  2901 	/* Check for shared order-lists (we now use pointers for that) */
  2896 	if (CheckSavegameVersionOldStyle(5, 2)) {
  2902 	if (CheckSavegameVersionOldStyle(5, 2)) {
  2897 		FOR_ALL_VEHICLES(v) {
  2903 		FOR_ALL_VEHICLES(v) {
  2915 };
  2921 };
  2916 
  2922 
  2917 void Vehicle::BeginLoading()
  2923 void Vehicle::BeginLoading()
  2918 {
  2924 {
  2919 	assert(IsTileType(tile, MP_STATION) || type == VEH_SHIP);
  2925 	assert(IsTileType(tile, MP_STATION) || type == VEH_SHIP);
       
  2926 
       
  2927 	if (this->current_order.type == OT_GOTO_STATION &&
       
  2928 			this->current_order.dest == this->last_station_visited) {
       
  2929 		/* Arriving at the ordered station.
       
  2930 		 * Keep the load/unload flags, as we (obviously) still need them. */
       
  2931 		this->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD | OF_TRANSFER;
       
  2932 
       
  2933 		/* Furthermore add the Non Stop flag to mark that this station
       
  2934 		 * is the actual destination of the vehicle, which is (for example)
       
  2935 		 * necessary to be known for HandleTrainLoading to determine
       
  2936 		 * whether the train is lost or not; not marking a train lost
       
  2937 		 * that arrives at random stations is bad. */
       
  2938 		this->current_order.flags |= OF_NON_STOP;
       
  2939 	} else {
       
  2940 		/* This is just an unordered intermediate stop */
       
  2941 		this->current_order.flags = 0;
       
  2942 	}
       
  2943 
  2920 	current_order.type = OT_LOADING;
  2944 	current_order.type = OT_LOADING;
  2921 	GetStation(this->last_station_visited)->loading_vehicles.push_back(this);
  2945 	GetStation(this->last_station_visited)->loading_vehicles.push_back(this);
       
  2946 
       
  2947 	SET_EXPENSES_TYPE(this->GetExpenseType(true));
       
  2948 	VehiclePayment(this);
       
  2949 
       
  2950 	InvalidateWindow(this->GetVehicleListWindowClass(), this->owner);
       
  2951 	InvalidateWindowWidget(WC_VEHICLE_VIEW, this->index, STATUS_BAR);
       
  2952 	InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
       
  2953 	InvalidateWindow(WC_STATION_VIEW, this->last_station_visited);
       
  2954 
       
  2955 	GetStation(this->last_station_visited)->MarkTilesDirty();
       
  2956 	this->MarkDirty();
  2922 }
  2957 }
  2923 
  2958 
  2924 void Vehicle::LeaveStation()
  2959 void Vehicle::LeaveStation()
  2925 {
  2960 {
  2926 	assert(IsTileType(tile, MP_STATION) || type == VEH_SHIP);
       
  2927 	assert(current_order.type == OT_LOADING);
  2961 	assert(current_order.type == OT_LOADING);
  2928 	current_order.type = OT_LEAVESTATION;
  2962 	current_order.type = OT_LEAVESTATION;
  2929 	current_order.flags = 0;
  2963 	current_order.flags = 0;
  2930 	GetStation(this->last_station_visited)->loading_vehicles.remove(this);
  2964 	GetStation(this->last_station_visited)->loading_vehicles.remove(this);
  2931 }
  2965 }
       
  2966 
       
  2967 
       
  2968 void Vehicle::HandleLoading(bool mode)
       
  2969 {
       
  2970 	switch (this->current_order.type) {
       
  2971 		case OT_LOADING: {
       
  2972 			/* Not the first call for this tick, or still loading */
       
  2973 			if (mode || !HASBIT(this->vehicle_flags, VF_LOADING_FINISHED)) return;
       
  2974 
       
  2975 			this->PlayLeaveStationSound();
       
  2976 
       
  2977 			Order b = this->current_order;
       
  2978 			this->LeaveStation();
       
  2979 
       
  2980 			/* If this was not the final order, don't remove it from the list. */
       
  2981 			if (!(b.flags & OF_NON_STOP)) return;
       
  2982 			break;
       
  2983 		}
       
  2984 
       
  2985 		case OT_DUMMY: break;
       
  2986 
       
  2987 		default: return;
       
  2988 	}
       
  2989 
       
  2990 	this->cur_order_index++;
       
  2991 	InvalidateVehicleOrder(this);
       
  2992 }
       
  2993 
       
  2994 
       
  2995 void SpecialVehicle::UpdateDeltaXY(Direction direction)
       
  2996 {
       
  2997 	this->x_offs        = 0;
       
  2998 	this->y_offs        = 0;
       
  2999 	this->sprite_width  = 1;
       
  3000 	this->sprite_height = 1;
       
  3001 	this->z_height      = 1;
       
  3002 }