src/vehicle.cpp
changeset 5584 1111b4d36e35
parent 5574 2cb543714009
child 5587 167d9a91ef02
equal deleted inserted replaced
5583:136d8764c7e6 5584:1111b4d36e35
       
     1 /* $Id$ */
       
     2 
       
     3 #include "stdafx.h"
       
     4 #include "openttd.h"
       
     5 #include "road_map.h"
       
     6 #include "roadveh.h"
       
     7 #include "ship.h"
       
     8 #include "spritecache.h"
       
     9 #include "table/sprites.h"
       
    10 #include "table/strings.h"
       
    11 #include "functions.h"
       
    12 #include "map.h"
       
    13 #include "tile.h"
       
    14 #include "vehicle.h"
       
    15 #include "gfx.h"
       
    16 #include "viewport.h"
       
    17 #include "news.h"
       
    18 #include "command.h"
       
    19 #include "saveload.h"
       
    20 #include "player.h"
       
    21 #include "engine.h"
       
    22 #include "sound.h"
       
    23 #include "debug.h"
       
    24 #include "vehicle_gui.h"
       
    25 #include "depot.h"
       
    26 #include "station.h"
       
    27 #include "rail.h"
       
    28 #include "train.h"
       
    29 #include "aircraft.h"
       
    30 #include "industry_map.h"
       
    31 #include "station_map.h"
       
    32 #include "water_map.h"
       
    33 #include "network/network.h"
       
    34 #include "yapf/yapf.h"
       
    35 #include "date.h"
       
    36 #include "newgrf_engine.h"
       
    37 #include "newgrf_sound.h"
       
    38 
       
    39 #define INVALID_COORD (-0x8000)
       
    40 #define GEN_HASH(x, y) ((GB((y), 6, 6) << 6) + GB((x), 7, 6))
       
    41 
       
    42 /*
       
    43  * These command macros are used to call vehicle type specific commands with non type specific commands
       
    44  * it should be used like: DoCommandP(x, y, p1, p2, flags, CMD_STARTSTOP_VEH(v->type))
       
    45  * that line will start/stop a vehicle nomatter what type it is
       
    46  * VEH_Train is used as an offset because the vehicle type values doesn't start with 0
       
    47  */
       
    48 
       
    49 #define CMD_BUILD_VEH(x) _veh_build_proc_table[ x - VEH_Train]
       
    50 #define CMD_SELL_VEH(x)  _veh_sell_proc_table [ x - VEH_Train]
       
    51 #define CMD_REFIT_VEH(x) _veh_refit_proc_table[ x - VEH_Train]
       
    52 
       
    53 static const uint32 _veh_build_proc_table[] = {
       
    54 	CMD_BUILD_RAIL_VEHICLE,
       
    55 	CMD_BUILD_ROAD_VEH,
       
    56 	CMD_BUILD_SHIP,
       
    57 	CMD_BUILD_AIRCRAFT,
       
    58 };
       
    59 static const uint32 _veh_sell_proc_table[] = {
       
    60 	CMD_SELL_RAIL_WAGON,
       
    61 	CMD_SELL_ROAD_VEH,
       
    62 	CMD_SELL_SHIP,
       
    63 	CMD_SELL_AIRCRAFT,
       
    64 };
       
    65 
       
    66 static const uint32 _veh_refit_proc_table[] = {
       
    67 	CMD_REFIT_RAIL_VEHICLE,
       
    68 	CMD_REFIT_ROAD_VEH,
       
    69 	CMD_REFIT_SHIP,
       
    70 	CMD_REFIT_AIRCRAFT,
       
    71 };
       
    72 
       
    73 const uint32 _send_to_depot_proc_table[] = {
       
    74 	CMD_SEND_TRAIN_TO_DEPOT,
       
    75 	CMD_SEND_ROADVEH_TO_DEPOT,
       
    76 	CMD_SEND_SHIP_TO_DEPOT,
       
    77 	CMD_SEND_AIRCRAFT_TO_HANGAR,
       
    78 };
       
    79 
       
    80 
       
    81 enum {
       
    82 	BLOCKS_FOR_SPECIAL_VEHICLES   = 2, ///< Blocks needed for special vehicles
       
    83 };
       
    84 
       
    85 /**
       
    86  * Called if a new block is added to the vehicle-pool
       
    87  */
       
    88 static void VehiclePoolNewBlock(uint start_item)
       
    89 {
       
    90 	Vehicle *v;
       
    91 
       
    92 	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
       
    93 	 * TODO - This is just a temporary stage, this will be removed. */
       
    94 	for (v = GetVehicle(start_item); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) v->index = start_item++;
       
    95 }
       
    96 
       
    97 /* Initialize the vehicle-pool */
       
    98 DEFINE_OLD_POOL(Vehicle, Vehicle, VehiclePoolNewBlock, NULL)
       
    99 
       
   100 void VehicleServiceInDepot(Vehicle *v)
       
   101 {
       
   102 	v->date_of_last_service = _date;
       
   103 	v->breakdowns_since_last_service = 0;
       
   104 	v->reliability = GetEngine(v->engine_type)->reliability;
       
   105 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index); // ensure that last service date and reliability are updated
       
   106 }
       
   107 
       
   108 bool VehicleNeedsService(const Vehicle *v)
       
   109 {
       
   110 	if (v->vehstatus & VS_CRASHED)
       
   111 		return false; /* Crashed vehicles don't need service anymore */
       
   112 
       
   113 	if (_patches.no_servicing_if_no_breakdowns && _opt.diff.vehicle_breakdowns == 0) {
       
   114 		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 	}
       
   116 
       
   117 	return _patches.servint_ispercent ?
       
   118 		(v->reliability < GetEngine(v->engine_type)->reliability * (100 - v->service_interval) / 100) :
       
   119 		(v->date_of_last_service + v->service_interval < _date);
       
   120 }
       
   121 
       
   122 StringID VehicleInTheWayErrMsg(const Vehicle* v)
       
   123 {
       
   124 	switch (v->type) {
       
   125 		case VEH_Train:    return STR_8803_TRAIN_IN_THE_WAY;
       
   126 		case VEH_Road:     return STR_9000_ROAD_VEHICLE_IN_THE_WAY;
       
   127 		case VEH_Aircraft: return STR_A015_AIRCRAFT_IN_THE_WAY;
       
   128 		default:           return STR_980E_SHIP_IN_THE_WAY;
       
   129 	}
       
   130 }
       
   131 
       
   132 static void *EnsureNoVehicleProc(Vehicle *v, void *data)
       
   133 {
       
   134 	if (v->tile != *(const TileIndex*)data || v->type == VEH_Disaster)
       
   135 		return NULL;
       
   136 
       
   137 	_error_message = VehicleInTheWayErrMsg(v);
       
   138 	return v;
       
   139 }
       
   140 
       
   141 bool EnsureNoVehicle(TileIndex tile)
       
   142 {
       
   143 	return VehicleFromPos(tile, &tile, EnsureNoVehicleProc) == NULL;
       
   144 }
       
   145 
       
   146 static void *EnsureNoVehicleProcZ(Vehicle *v, void *data)
       
   147 {
       
   148 	const TileInfo *ti = data;
       
   149 
       
   150 	if (v->tile != ti->tile || v->type == VEH_Disaster) return NULL;
       
   151 	if (v->z_pos > ti->z) return NULL;
       
   152 
       
   153 	_error_message = VehicleInTheWayErrMsg(v);
       
   154 	return v;
       
   155 }
       
   156 
       
   157 
       
   158 bool EnsureNoVehicleOnGround(TileIndex tile)
       
   159 {
       
   160 	TileInfo ti;
       
   161 
       
   162 	ti.tile = tile;
       
   163 	ti.z = GetTileMaxZ(tile);
       
   164 	return VehicleFromPos(tile, &ti, EnsureNoVehicleProcZ) == NULL;
       
   165 }
       
   166 
       
   167 Vehicle *FindVehicleOnTileZ(TileIndex tile, byte z)
       
   168 {
       
   169 	TileInfo ti;
       
   170 
       
   171 	ti.tile = tile;
       
   172 	ti.z = z;
       
   173 
       
   174 	return VehicleFromPos(tile, &ti, EnsureNoVehicleProcZ);
       
   175 }
       
   176 
       
   177 Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z)
       
   178 {
       
   179 	int x1 = TileX(from);
       
   180 	int y1 = TileY(from);
       
   181 	int x2 = TileX(to);
       
   182 	int y2 = TileY(to);
       
   183 	Vehicle *veh;
       
   184 
       
   185 	/* Make sure x1 < x2 or y1 < y2 */
       
   186 	if (x1 > x2 || y1 > y2) {
       
   187 		intswap(x1,x2);
       
   188 		intswap(y1,y2);
       
   189 	}
       
   190 	FOR_ALL_VEHICLES(veh) {
       
   191 		if ((veh->type == VEH_Train || veh->type == VEH_Road) && (z==0xFF || veh->z_pos == z)) {
       
   192 			if ((veh->x_pos>>4) >= x1 && (veh->x_pos>>4) <= x2 &&
       
   193 					(veh->y_pos>>4) >= y1 && (veh->y_pos>>4) <= y2) {
       
   194 				return veh;
       
   195 			}
       
   196 		}
       
   197 	}
       
   198 	return NULL;
       
   199 }
       
   200 
       
   201 
       
   202 static void UpdateVehiclePosHash(Vehicle* v, int x, int y);
       
   203 
       
   204 void VehiclePositionChanged(Vehicle *v)
       
   205 {
       
   206 	int img = v->cur_image;
       
   207 	Point pt = RemapCoords(v->x_pos + v->x_offs, v->y_pos + v->y_offs, v->z_pos);
       
   208 	const Sprite* spr = GetSprite(img);
       
   209 
       
   210 	pt.x += spr->x_offs;
       
   211 	pt.y += spr->y_offs;
       
   212 
       
   213 	UpdateVehiclePosHash(v, pt.x, pt.y);
       
   214 
       
   215 	v->left_coord = pt.x;
       
   216 	v->top_coord = pt.y;
       
   217 	v->right_coord = pt.x + spr->width + 2;
       
   218 	v->bottom_coord = pt.y + spr->height + 2;
       
   219 }
       
   220 
       
   221 // Called after load to update coordinates
       
   222 void AfterLoadVehicles(void)
       
   223 {
       
   224 	Vehicle *v;
       
   225 
       
   226 	FOR_ALL_VEHICLES(v) {
       
   227 		v->first = NULL;
       
   228 		if (v->type == VEH_Train) v->u.rail.first_engine = INVALID_ENGINE;
       
   229 	}
       
   230 
       
   231 	FOR_ALL_VEHICLES(v) {
       
   232 		if (v->type == VEH_Train && (IsFrontEngine(v) || IsFreeWagon(v)))
       
   233 			TrainConsistChanged(v);
       
   234 	}
       
   235 
       
   236 	FOR_ALL_VEHICLES(v) {
       
   237 		switch (v->type) {
       
   238 			case VEH_Train: v->cur_image = GetTrainImage(v, v->direction); break;
       
   239 			case VEH_Road: v->cur_image = GetRoadVehImage(v, v->direction); break;
       
   240 			case VEH_Ship: v->cur_image = GetShipImage(v, v->direction); break;
       
   241 			case VEH_Aircraft:
       
   242 				if (v->subtype == 0 || v->subtype == 2) {
       
   243 					v->cur_image = GetAircraftImage(v, v->direction);
       
   244 					if (v->next != NULL) v->next->cur_image = v->cur_image;
       
   245 				}
       
   246 				break;
       
   247 			default: break;
       
   248 		}
       
   249 
       
   250 		v->left_coord = INVALID_COORD;
       
   251 		VehiclePositionChanged(v);
       
   252 	}
       
   253 }
       
   254 
       
   255 static Vehicle *InitializeVehicle(Vehicle *v)
       
   256 {
       
   257 	VehicleID index = v->index;
       
   258 	memset(v, 0, sizeof(Vehicle));
       
   259 	v->index = index;
       
   260 
       
   261 	assert(v->orders == NULL);
       
   262 
       
   263 	v->left_coord = INVALID_COORD;
       
   264 	v->first = NULL;
       
   265 	v->next = NULL;
       
   266 	v->next_hash = NULL;
       
   267 	v->string_id = 0;
       
   268 	v->next_shared = NULL;
       
   269 	v->prev_shared = NULL;
       
   270 	v->depot_list  = NULL;
       
   271 	v->random_bits = 0;
       
   272 	return v;
       
   273 }
       
   274 
       
   275 /**
       
   276  * Get a value for a vehicle's random_bits.
       
   277  * @return A random value from 0 to 255.
       
   278  */
       
   279 byte VehicleRandomBits(void)
       
   280 {
       
   281 	return GB(Random(), 0, 8);
       
   282 }
       
   283 
       
   284 Vehicle *ForceAllocateSpecialVehicle(void)
       
   285 {
       
   286 	/* This stays a strange story.. there should always be room for special
       
   287 	 * vehicles (special effects all over the map), but with 65k of vehicles
       
   288 	 * is this realistic to double-check for that? For now we just reserve
       
   289 	 * BLOCKS_FOR_SPECIAL_VEHICLES times block_size vehicles that may only
       
   290 	 * be used for special vehicles.. should work nicely :) */
       
   291 
       
   292 	Vehicle *v;
       
   293 
       
   294 	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
       
   295 	 * TODO - This is just a temporary stage, this will be removed. */
       
   296 	for (v = GetVehicle(0); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) {
       
   297 		/* No more room for the special vehicles, return NULL */
       
   298 		if (v->index >= (1 << Vehicle_POOL_BLOCK_SIZE_BITS) * BLOCKS_FOR_SPECIAL_VEHICLES)
       
   299 			return NULL;
       
   300 
       
   301 		if (!IsValidVehicle(v)) return InitializeVehicle(v);
       
   302 	}
       
   303 
       
   304 	return NULL;
       
   305 }
       
   306 
       
   307 /*
       
   308  * finds a free vehicle in the memory or allocates a new one
       
   309  * returns a pointer to the first free vehicle or NULL if all vehicles are in use
       
   310  * *skip_vehicles is an offset to where in the array we should begin looking
       
   311  * this is to avoid looping though the same vehicles more than once after we learned that they are not free
       
   312  * this feature is used by AllocateVehicles() since it need to allocate more than one and when
       
   313  * another block is added to _Vehicle_pool, since we only do that when we know it's already full
       
   314  */
       
   315 static Vehicle *AllocateSingleVehicle(VehicleID *skip_vehicles)
       
   316 {
       
   317 	/* See note by ForceAllocateSpecialVehicle() why we skip the
       
   318 	 * first blocks */
       
   319 	Vehicle *v;
       
   320 	const int offset = (1 << Vehicle_POOL_BLOCK_SIZE_BITS) * BLOCKS_FOR_SPECIAL_VEHICLES;
       
   321 
       
   322 	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
       
   323 	 * TODO - This is just a temporary stage, this will be removed. */
       
   324 	if (*skip_vehicles < (_Vehicle_pool.total_items - offset)) { // make sure the offset in the array is not larger than the array itself
       
   325 		for (v = GetVehicle(offset + *skip_vehicles); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) {
       
   326 			(*skip_vehicles)++;
       
   327 			if (!IsValidVehicle(v)) return InitializeVehicle(v);
       
   328 		}
       
   329 	}
       
   330 
       
   331 	/* Check if we can add a block to the pool */
       
   332 	if (AddBlockToPool(&_Vehicle_pool))
       
   333 		return AllocateSingleVehicle(skip_vehicles);
       
   334 
       
   335 	return NULL;
       
   336 }
       
   337 
       
   338 
       
   339 Vehicle *AllocateVehicle(void)
       
   340 {
       
   341 	VehicleID counter = 0;
       
   342 	return AllocateSingleVehicle(&counter);
       
   343 }
       
   344 
       
   345 
       
   346 /** Allocates a lot of vehicles and frees them again
       
   347  * @param vl pointer to an array of vehicles to get allocated. Can be NULL if the vehicles aren't needed (makes it test only)
       
   348  * @param num number of vehicles to allocate room for
       
   349  * @return true if there is room to allocate all the vehicles
       
   350  */
       
   351 bool AllocateVehicles(Vehicle **vl, int num)
       
   352 {
       
   353 	int i;
       
   354 	Vehicle *v;
       
   355 	VehicleID counter = 0;
       
   356 
       
   357 	for (i = 0; i != num; i++) {
       
   358 		v = AllocateSingleVehicle(&counter);
       
   359 		if (v == NULL) {
       
   360 			return false;
       
   361 		}
       
   362 		if (vl != NULL) {
       
   363 			vl[i] = v;
       
   364 		}
       
   365 	}
       
   366 
       
   367 	return true;
       
   368 }
       
   369 
       
   370 
       
   371 static Vehicle *_vehicle_position_hash[0x1000];
       
   372 
       
   373 void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
       
   374 {
       
   375 	Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, 0);
       
   376 
       
   377 	// The hash area to scan
       
   378 	const int xl = GB(pt.x - 174, 7, 6);
       
   379 	const int xu = GB(pt.x + 104, 7, 6);
       
   380 	const int yl = GB(pt.y - 294, 6, 6) << 6;
       
   381 	const int yu = GB(pt.y +  56, 6, 6) << 6;
       
   382 
       
   383 	int x;
       
   384 	int y;
       
   385 
       
   386 	for (y = yl;; y = (y + (1 << 6)) & (0x3F << 6)) {
       
   387 		for (x = xl;; x = (x + 1) & 0x3F) {
       
   388 			Vehicle *v = _vehicle_position_hash[(x + y) & 0xFFFF];
       
   389 
       
   390 			while (v != NULL) {
       
   391 				void* a = proc(v, data);
       
   392 
       
   393 				if (a != NULL) return a;
       
   394 				v = v->next_hash;
       
   395 			}
       
   396 
       
   397 			if (x == xu) break;
       
   398 		}
       
   399 
       
   400 		if (y == yu) break;
       
   401 	}
       
   402 	return NULL;
       
   403 }
       
   404 
       
   405 
       
   406 static void UpdateVehiclePosHash(Vehicle* v, int x, int y)
       
   407 {
       
   408 	Vehicle **old_hash, **new_hash;
       
   409 	int old_x = v->left_coord;
       
   410 	int old_y = v->top_coord;
       
   411 
       
   412 	new_hash = (x == INVALID_COORD) ? NULL : &_vehicle_position_hash[GEN_HASH(x,y)];
       
   413 	old_hash = (old_x == INVALID_COORD) ? NULL : &_vehicle_position_hash[GEN_HASH(old_x, old_y)];
       
   414 
       
   415 	if (old_hash == new_hash) return;
       
   416 
       
   417 	/* remove from hash table? */
       
   418 	if (old_hash != NULL) {
       
   419 		Vehicle *last = NULL;
       
   420 		Vehicle *u = *old_hash;
       
   421 		while (u != v) {
       
   422 			last = u;
       
   423 			u = u->next_hash;
       
   424 			assert(u != NULL);
       
   425 		}
       
   426 
       
   427 		if (last == NULL) {
       
   428 			*old_hash = v->next_hash;
       
   429 		} else {
       
   430 			last->next_hash = v->next_hash;
       
   431 		}
       
   432 	}
       
   433 
       
   434 	/* insert into hash table? */
       
   435 	if (new_hash != NULL) {
       
   436 		v->next_hash = *new_hash;
       
   437 		*new_hash = v;
       
   438 	}
       
   439 }
       
   440 
       
   441 void ResetVehiclePosHash(void)
       
   442 {
       
   443 	memset(_vehicle_position_hash, 0, sizeof(_vehicle_position_hash));
       
   444 }
       
   445 
       
   446 void InitializeVehicles(void)
       
   447 {
       
   448 	uint i;
       
   449 
       
   450 	/* Clean the vehicle pool, and reserve enough blocks
       
   451 	 *  for the special vehicles, plus one for all the other
       
   452 	 *  vehicles (which is increased on-the-fly) */
       
   453 	CleanPool(&_Vehicle_pool);
       
   454 	AddBlockToPool(&_Vehicle_pool);
       
   455 	for (i = 0; i < BLOCKS_FOR_SPECIAL_VEHICLES; i++) {
       
   456 		AddBlockToPool(&_Vehicle_pool);
       
   457 	}
       
   458 
       
   459 	ResetVehiclePosHash();
       
   460 }
       
   461 
       
   462 Vehicle *GetLastVehicleInChain(Vehicle *v)
       
   463 {
       
   464 	while (v->next != NULL) v = v->next;
       
   465 	return v;
       
   466 }
       
   467 
       
   468 /** Finds the previous vehicle in a chain, by a brute force search.
       
   469  * This old function is REALLY slow because it searches through all vehicles to
       
   470  * find the previous vehicle, but if v->first has not been set, then this function
       
   471  * will need to be used to find the previous one. This function should never be
       
   472  * called by anything but GetFirstVehicleInChain
       
   473  */
       
   474 static Vehicle *GetPrevVehicleInChain_bruteforce(const Vehicle *v)
       
   475 {
       
   476 	Vehicle *u;
       
   477 
       
   478 	FOR_ALL_VEHICLES(u) if (u->type == VEH_Train && u->next == v) return u;
       
   479 
       
   480 	return NULL;
       
   481 }
       
   482 
       
   483 /** Find the previous vehicle in a chain, by using the v->first cache.
       
   484  * While this function is fast, it cannot be used in the GetFirstVehicleInChain
       
   485  * function, otherwise you'll end up in an infinite loop call
       
   486  */
       
   487 Vehicle *GetPrevVehicleInChain(const Vehicle *v)
       
   488 {
       
   489 	Vehicle *u;
       
   490 	assert(v != NULL);
       
   491 
       
   492 	u = GetFirstVehicleInChain(v);
       
   493 
       
   494 	// Check to see if this is the first
       
   495 	if (v == u) return NULL;
       
   496 
       
   497 	for (; u->next != v; u = u->next) assert(u->next != NULL);
       
   498 
       
   499 	return u;
       
   500 }
       
   501 
       
   502 /** Finds the first vehicle in a chain.
       
   503  * This function reads out the v->first cache. Should the cache be dirty,
       
   504  * it determines the first vehicle in a chain, and updates the cache.
       
   505  */
       
   506 Vehicle *GetFirstVehicleInChain(const Vehicle *v)
       
   507 {
       
   508 	Vehicle* u;
       
   509 
       
   510 	assert(v != NULL);
       
   511 
       
   512 	if (v->first != NULL) {
       
   513 		if (IsFrontEngine(v->first) || IsFreeWagon(v->first)) return v->first;
       
   514 
       
   515 		DEBUG(misc, 0, "v->first cache faulty. We shouldn't be here, rebuilding cache!");
       
   516 	}
       
   517 
       
   518 	/* It is the fact (currently) that newly built vehicles do not have
       
   519 	 * their ->first pointer set. When this is the case, go up to the
       
   520 	 * first engine and set the pointers correctly. Also the first pointer
       
   521 	 * is not saved in a savegame, so this has to be fixed up after loading */
       
   522 
       
   523 	/* Find the 'locomotive' or the first wagon in a chain */
       
   524 	while ((u = GetPrevVehicleInChain_bruteforce(v)) != NULL) v = u;
       
   525 
       
   526 	/* Set the first pointer of all vehicles in that chain to the first wagon */
       
   527 	if (IsFrontEngine(v) || IsFreeWagon(v))
       
   528 		for (u = (Vehicle *)v; u != NULL; u = u->next) u->first = (Vehicle *)v;
       
   529 
       
   530 	return (Vehicle*)v;
       
   531 }
       
   532 
       
   533 uint CountVehiclesInChain(const Vehicle* v)
       
   534 {
       
   535 	uint count = 0;
       
   536 	do count++; while ((v = v->next) != NULL);
       
   537 	return count;
       
   538 }
       
   539 
       
   540 /** Check if a vehicle is counted in num_engines in each player struct
       
   541  * @param *v Vehicle to test
       
   542  * @return true if the vehicle is counted in num_engines
       
   543  */
       
   544 bool IsEngineCountable(const Vehicle *v)
       
   545 {
       
   546 	switch (v->type) {
       
   547 		case VEH_Aircraft: return (v->subtype <= 2); // don't count plane shadows and helicopter rotors
       
   548 		case VEH_Train:
       
   549 			return !IsArticulatedPart(v) && // tenders and other articulated parts
       
   550 			(!IsMultiheaded(v) || IsTrainEngine(v)); // rear parts of multiheaded engines
       
   551 		case VEH_Road:
       
   552 		case VEH_Ship:
       
   553 			return true;
       
   554 		default: return false; // Only count player buildable vehicles
       
   555 	}
       
   556 }
       
   557 
       
   558 void DestroyVehicle(Vehicle *v)
       
   559 {
       
   560 	if (IsEngineCountable(v)) GetPlayer(v->owner)->num_engines[v->engine_type]--;
       
   561 
       
   562 	DeleteVehicleNews(v->index, INVALID_STRING_ID);
       
   563 
       
   564 	DeleteName(v->string_id);
       
   565 	if (v->type == VEH_Road) ClearSlot(v);
       
   566 
       
   567 	if (v->type != VEH_Train || (v->type == VEH_Train && (IsFrontEngine(v) || IsFreeWagon(v)))) {
       
   568 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
       
   569 	}
       
   570 
       
   571 	UpdateVehiclePosHash(v, INVALID_COORD, 0);
       
   572 	v->next_hash = NULL;
       
   573 	if (v->orders != NULL) DeleteVehicleOrders(v);
       
   574 
       
   575 	/* Now remove any artic part. This will trigger an other
       
   576 	 *  destroy vehicle, which on his turn can remove any
       
   577 	 *  other artic parts. */
       
   578 	if (EngineHasArticPart(v)) DeleteVehicle(v->next);
       
   579 }
       
   580 
       
   581 void DeleteVehicleChain(Vehicle *v)
       
   582 {
       
   583 	do {
       
   584 		Vehicle *u = v;
       
   585 		v = GetNextVehicle(v);
       
   586 		DeleteVehicle(u);
       
   587 	} while (v != NULL);
       
   588 }
       
   589 
       
   590 
       
   591 void Aircraft_Tick(Vehicle *v);
       
   592 void RoadVeh_Tick(Vehicle *v);
       
   593 void Ship_Tick(Vehicle *v);
       
   594 void Train_Tick(Vehicle *v);
       
   595 static void EffectVehicle_Tick(Vehicle *v);
       
   596 void DisasterVehicle_Tick(Vehicle *v);
       
   597 static int32 MaybeReplaceVehicle(Vehicle *v, bool check, bool display_costs);
       
   598 
       
   599 // head of the linked list to tell what vehicles that visited a depot in a tick
       
   600 static Vehicle* _first_veh_in_depot_list;
       
   601 
       
   602 /** Adds a vehicle to the list of vehicles, that visited a depot this tick
       
   603  * @param *v vehicle to add
       
   604  */
       
   605 void VehicleEnteredDepotThisTick(Vehicle *v)
       
   606 {
       
   607 	// we need to set v->leave_depot_instantly as we have no control of it's contents at this time
       
   608 	if (HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT) && !HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS) && v->current_order.type == OT_GOTO_DEPOT) {
       
   609 		// we keep the vehicle in the depot since the user ordered it to stay
       
   610 		v->leave_depot_instantly = false;
       
   611 	} else {
       
   612 		// the vehicle do not plan on stopping in the depot, so we stop it to ensure that it will not reserve the path
       
   613 		// out of the depot before we might autoreplace it to a different engine. The new engine would not own the reserved path
       
   614 		// we store that we stopped the vehicle, so autoreplace can start it again
       
   615 		v->vehstatus |= VS_STOPPED;
       
   616 		v->leave_depot_instantly = true;
       
   617 	}
       
   618 
       
   619 	if (_first_veh_in_depot_list == NULL) {
       
   620 		_first_veh_in_depot_list = v;
       
   621 	} else {
       
   622 		Vehicle *w = _first_veh_in_depot_list;
       
   623 		while (w->depot_list != NULL) w = w->depot_list;
       
   624 		w->depot_list = v;
       
   625 	}
       
   626 }
       
   627 
       
   628 typedef void VehicleTickProc(Vehicle*);
       
   629 static VehicleTickProc* _vehicle_tick_procs[] = {
       
   630 	Train_Tick,
       
   631 	RoadVeh_Tick,
       
   632 	Ship_Tick,
       
   633 	Aircraft_Tick,
       
   634 	EffectVehicle_Tick,
       
   635 	DisasterVehicle_Tick,
       
   636 };
       
   637 
       
   638 void CallVehicleTicks(void)
       
   639 {
       
   640 	Vehicle *v;
       
   641 
       
   642 #ifdef ENABLE_NETWORK
       
   643 	// hotfix for desync problem:
       
   644 	//  for MP games invalidate the YAPF cache every tick to keep it exactly the same on the server and all clients
       
   645 	if (_networking) {
       
   646 		YapfNotifyTrackLayoutChange(0, 0);
       
   647 	}
       
   648 #endif //ENABLE_NETWORK
       
   649 
       
   650 	_first_veh_in_depot_list = NULL; // now we are sure it's initialized at the start of each tick
       
   651 
       
   652 	FOR_ALL_VEHICLES(v) {
       
   653 		_vehicle_tick_procs[v->type - 0x10](v);
       
   654 
       
   655 		switch (v->type) {
       
   656 			case VEH_Train:
       
   657 			case VEH_Road:
       
   658 			case VEH_Aircraft:
       
   659 			case VEH_Ship:
       
   660 				if (v->type == VEH_Train && IsTrainWagon(v)) continue;
       
   661 				if (v->type == VEH_Aircraft && v->subtype > 0) continue;
       
   662 
       
   663 				v->motion_counter += (v->direction & 1) ? (v->cur_speed * 3) / 4 : v->cur_speed;
       
   664 				/* Play a running sound if the motion counter passes 256 (Do we not skip sounds?) */
       
   665 				if (GB(v->motion_counter, 0, 8) < v->cur_speed) PlayVehicleSound(v, VSE_RUNNING);
       
   666 
       
   667 				/* Play an alterate running sound every 16 ticks */
       
   668 				if (GB(v->tick_counter, 0, 4) == 0) PlayVehicleSound(v, v->cur_speed > 0 ? VSE_RUNNING_16 : VSE_STOPPED_16);
       
   669 		}
       
   670 	}
       
   671 
       
   672 	// now we handle all the vehicles that entered a depot this tick
       
   673 	v = _first_veh_in_depot_list;
       
   674 	while (v != NULL) {
       
   675 		Vehicle *w = v->depot_list;
       
   676 		v->depot_list = NULL; // it should always be NULL at the end of each tick
       
   677 		MaybeReplaceVehicle(v, false, true);
       
   678 		v = w;
       
   679 	}
       
   680 }
       
   681 
       
   682 static bool CanFillVehicle_FullLoadAny(Vehicle *v)
       
   683 {
       
   684 	uint32 full = 0, not_full = 0;
       
   685 	bool keep_loading = false;
       
   686 	const GoodsEntry *ge = GetStation(v->last_station_visited)->goods;
       
   687 
       
   688 	//special handling of aircraft
       
   689 
       
   690 	//if the aircraft carries passengers and is NOT full, then
       
   691 	//continue loading, no matter how much mail is in
       
   692 	if (v->type == VEH_Aircraft &&
       
   693 			v->cargo_type == CT_PASSENGERS &&
       
   694 			v->cargo_cap != v->cargo_count) {
       
   695 		return true;
       
   696 	}
       
   697 
       
   698 	// patch should return "true" to continue loading, i.e. when there is no cargo type that is fully loaded.
       
   699 	do {
       
   700 		//Should never happen, but just in case future additions change this
       
   701 		assert(v->cargo_type<32);
       
   702 
       
   703 		if (v->cargo_cap != 0) {
       
   704 			uint32 mask = 1 << v->cargo_type;
       
   705 
       
   706 			if (v->cargo_cap == v->cargo_count) {
       
   707 				full |= mask;
       
   708 			} else if (GB(ge[v->cargo_type].waiting_acceptance, 0, 12) > 0 ||
       
   709 					(HASBIT(v->load_status, LS_CARGO_UNLOADING) && (ge[v->cargo_type].waiting_acceptance & 0x8000))) {
       
   710 				/* If there is any cargo waiting, or this vehicle is still unloading
       
   711 				 * and the station accepts the cargo, don't leave the station. */
       
   712 				keep_loading = true;
       
   713 			} else {
       
   714 				not_full |= mask;
       
   715 			}
       
   716 		}
       
   717 	} while ((v = v->next) != NULL);
       
   718 
       
   719 	// continue loading if there is a non full cargo type and no cargo type that is full
       
   720 	return keep_loading || (not_full && (full & ~not_full) == 0);
       
   721 }
       
   722 
       
   723 bool CanFillVehicle(Vehicle *v)
       
   724 {
       
   725 	TileIndex tile = v->tile;
       
   726 
       
   727 	if (IsTileType(tile, MP_STATION) ||
       
   728 			(v->type == VEH_Ship && (
       
   729 				IsTileType(TILE_ADDXY(tile,  1,  0), MP_STATION) ||
       
   730 				IsTileType(TILE_ADDXY(tile, -1,  0), MP_STATION) ||
       
   731 				IsTileType(TILE_ADDXY(tile,  0,  1), MP_STATION) ||
       
   732 				IsTileType(TILE_ADDXY(tile,  0, -1), MP_STATION) ||
       
   733 				IsTileType(TILE_ADDXY(tile, -2,  0), MP_STATION)
       
   734 			))) {
       
   735 
       
   736 		// If patch is active, use alternative CanFillVehicle-function
       
   737 		if (_patches.full_load_any && v->current_order.flags & OF_FULL_LOAD) return CanFillVehicle_FullLoadAny(v);
       
   738 
       
   739 		do {
       
   740 			if (v->cargo_count != v->cargo_cap) return true;
       
   741 		} while ((v = v->next) != NULL);
       
   742 	}
       
   743 	return false;
       
   744 }
       
   745 
       
   746 /** Check if a given engine type can be refitted to a given cargo
       
   747  * @param engine_type Engine type to check
       
   748  * @param cid_to check refit to this cargo-type
       
   749  * @return true if it is possible, false otherwise
       
   750  */
       
   751 bool CanRefitTo(EngineID engine_type, CargoID cid_to)
       
   752 {
       
   753 	CargoID cid = _global_cargo_id[_opt_ptr->landscape][cid_to];
       
   754 	return HASBIT(EngInfo(engine_type)->refit_mask, cid);
       
   755 }
       
   756 
       
   757 /** Find the first cargo type that an engine can be refitted to.
       
   758  * @param engine Which engine to find cargo for.
       
   759  * @return A climate dependent cargo type. CT_INVALID is returned if not refittable.
       
   760  */
       
   761 CargoID FindFirstRefittableCargo(EngineID engine_type)
       
   762 {
       
   763 	CargoID cid;
       
   764 	uint32 refit_mask = EngInfo(engine_type)->refit_mask;
       
   765 
       
   766 	if (refit_mask != 0) {
       
   767 		for (cid = CT_PASSENGERS; cid < NUM_CARGO; cid++) {
       
   768 			if (HASBIT(refit_mask, _global_cargo_id[_opt_ptr->landscape][cid])) return cid;
       
   769 		}
       
   770 	}
       
   771 
       
   772 	return CT_INVALID;
       
   773 }
       
   774 
       
   775 /** Learn the price of refitting a certain engine
       
   776 * @param engine Which engine to refit
       
   777 * @return Price for refitting
       
   778 */
       
   779 int32 GetRefitCost(EngineID engine_type)
       
   780 {
       
   781 	int32 base_cost = 0;
       
   782 
       
   783 	switch (GetEngine(engine_type)->type) {
       
   784 		case VEH_Ship: base_cost = _price.ship_base; break;
       
   785 		case VEH_Road: base_cost = _price.roadveh_base; break;
       
   786 		case VEH_Aircraft: base_cost = _price.aircraft_base; break;
       
   787 		case VEH_Train:
       
   788 			base_cost = 2 * ((RailVehInfo(engine_type)->flags & RVI_WAGON) ?
       
   789 							 _price.build_railwagon : _price.build_railvehicle);
       
   790 			break;
       
   791 		default: NOT_REACHED(); break;
       
   792 	}
       
   793 	return (EngInfo(engine_type)->refit_cost * base_cost) >> 10;
       
   794 }
       
   795 
       
   796 static void DoDrawVehicle(const Vehicle *v)
       
   797 {
       
   798 	uint32 image = v->cur_image;
       
   799 
       
   800 	if (v->vehstatus & VS_SHADOW) {
       
   801 		MAKE_TRANSPARENT(image);
       
   802 	} else if (v->vehstatus & VS_DEFPAL) {
       
   803 		image |= (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
       
   804 	}
       
   805 
       
   806 	AddSortableSpriteToDraw(image, v->x_pos + v->x_offs, v->y_pos + v->y_offs,
       
   807 		v->sprite_width, v->sprite_height, v->z_height, v->z_pos);
       
   808 }
       
   809 
       
   810 void ViewportAddVehicles(DrawPixelInfo *dpi)
       
   811 {
       
   812 	// The bounding rectangle
       
   813 	const int l = dpi->left;
       
   814 	const int r = dpi->left + dpi->width;
       
   815 	const int t = dpi->top;
       
   816 	const int b = dpi->top + dpi->height;
       
   817 
       
   818 	// The hash area to scan
       
   819 	const int xl = GB(l - 70, 7, 6);
       
   820 	const int xu = GB(r,      7, 6);
       
   821 	const int yl = GB(t - 70, 6, 6) << 6;
       
   822 	const int yu = GB(b,      6, 6) << 6;
       
   823 
       
   824 	int x;
       
   825 	int y;
       
   826 
       
   827 	for (y = yl;; y = (y + (1 << 6)) & (0x3F << 6)) {
       
   828 		for (x = xl;; x = (x + 1) & 0x3F) {
       
   829 			const Vehicle *v = _vehicle_position_hash[(x + y) & 0xFFFF];
       
   830 
       
   831 			while (v != NULL) {
       
   832 				if (!(v->vehstatus & VS_HIDDEN) &&
       
   833 						l <= v->right_coord &&
       
   834 						t <= v->bottom_coord &&
       
   835 						r >= v->left_coord &&
       
   836 						b >= v->top_coord) {
       
   837 					DoDrawVehicle(v);
       
   838 				}
       
   839 				v = v->next_hash;
       
   840 			}
       
   841 
       
   842 			if (x == xu) break;
       
   843 		}
       
   844 
       
   845 		if (y == yu) break;
       
   846 	}
       
   847 }
       
   848 
       
   849 static void ChimneySmokeInit(Vehicle *v)
       
   850 {
       
   851 	uint32 r = Random();
       
   852 	v->cur_image = SPR_CHIMNEY_SMOKE_0 + GB(r, 0, 3);
       
   853 	v->progress = GB(r, 16, 3);
       
   854 }
       
   855 
       
   856 static void ChimneySmokeTick(Vehicle *v)
       
   857 {
       
   858 	if (v->progress > 0) {
       
   859 		v->progress--;
       
   860 	} else {
       
   861 		TileIndex tile;
       
   862 
       
   863 		BeginVehicleMove(v);
       
   864 
       
   865 		tile = TileVirtXY(v->x_pos, v->y_pos);
       
   866 		if (!IsTileType(tile, MP_INDUSTRY)) {
       
   867 			EndVehicleMove(v);
       
   868 			DeleteVehicle(v);
       
   869 			return;
       
   870 		}
       
   871 
       
   872 		if (v->cur_image != SPR_CHIMNEY_SMOKE_7) {
       
   873 			v->cur_image++;
       
   874 		} else {
       
   875 			v->cur_image = SPR_CHIMNEY_SMOKE_0;
       
   876 		}
       
   877 		v->progress = 7;
       
   878 		VehiclePositionChanged(v);
       
   879 		EndVehicleMove(v);
       
   880 	}
       
   881 }
       
   882 
       
   883 static void SteamSmokeInit(Vehicle *v)
       
   884 {
       
   885 	v->cur_image = SPR_STEAM_SMOKE_0;
       
   886 	v->progress = 12;
       
   887 }
       
   888 
       
   889 static void SteamSmokeTick(Vehicle *v)
       
   890 {
       
   891 	bool moved = false;
       
   892 
       
   893 	BeginVehicleMove(v);
       
   894 
       
   895 	v->progress++;
       
   896 
       
   897 	if ((v->progress & 7) == 0) {
       
   898 		v->z_pos++;
       
   899 		moved = true;
       
   900 	}
       
   901 
       
   902 	if ((v->progress & 0xF) == 4) {
       
   903 		if (v->cur_image != SPR_STEAM_SMOKE_4) {
       
   904 			v->cur_image++;
       
   905 		} else {
       
   906 			EndVehicleMove(v);
       
   907 			DeleteVehicle(v);
       
   908 			return;
       
   909 		}
       
   910 		moved = true;
       
   911 	}
       
   912 
       
   913 	if (moved) {
       
   914 		VehiclePositionChanged(v);
       
   915 		EndVehicleMove(v);
       
   916 	}
       
   917 }
       
   918 
       
   919 static void DieselSmokeInit(Vehicle *v)
       
   920 {
       
   921 	v->cur_image = SPR_DIESEL_SMOKE_0;
       
   922 	v->progress = 0;
       
   923 }
       
   924 
       
   925 static void DieselSmokeTick(Vehicle *v)
       
   926 {
       
   927 	v->progress++;
       
   928 
       
   929 	if ((v->progress & 3) == 0) {
       
   930 		BeginVehicleMove(v);
       
   931 		v->z_pos++;
       
   932 		VehiclePositionChanged(v);
       
   933 		EndVehicleMove(v);
       
   934 	} else if ((v->progress & 7) == 1) {
       
   935 		BeginVehicleMove(v);
       
   936 		if (v->cur_image != SPR_DIESEL_SMOKE_5) {
       
   937 			v->cur_image++;
       
   938 			VehiclePositionChanged(v);
       
   939 			EndVehicleMove(v);
       
   940 		} else {
       
   941 			EndVehicleMove(v);
       
   942 			DeleteVehicle(v);
       
   943 		}
       
   944 	}
       
   945 }
       
   946 
       
   947 static void ElectricSparkInit(Vehicle *v)
       
   948 {
       
   949 	v->cur_image = SPR_ELECTRIC_SPARK_0;
       
   950 	v->progress = 1;
       
   951 }
       
   952 
       
   953 static void ElectricSparkTick(Vehicle *v)
       
   954 {
       
   955 	if (v->progress < 2) {
       
   956 		v->progress++;
       
   957 	} else {
       
   958 		v->progress = 0;
       
   959 		BeginVehicleMove(v);
       
   960 		if (v->cur_image != SPR_ELECTRIC_SPARK_5) {
       
   961 			v->cur_image++;
       
   962 			VehiclePositionChanged(v);
       
   963 			EndVehicleMove(v);
       
   964 		} else {
       
   965 			EndVehicleMove(v);
       
   966 			DeleteVehicle(v);
       
   967 		}
       
   968 	}
       
   969 }
       
   970 
       
   971 static void SmokeInit(Vehicle *v)
       
   972 {
       
   973 	v->cur_image = SPR_SMOKE_0;
       
   974 	v->progress = 12;
       
   975 }
       
   976 
       
   977 static void SmokeTick(Vehicle *v)
       
   978 {
       
   979 	bool moved = false;
       
   980 
       
   981 	BeginVehicleMove(v);
       
   982 
       
   983 	v->progress++;
       
   984 
       
   985 	if ((v->progress & 3) == 0) {
       
   986 		v->z_pos++;
       
   987 		moved = true;
       
   988 	}
       
   989 
       
   990 	if ((v->progress & 0xF) == 4) {
       
   991 		if (v->cur_image != SPR_SMOKE_4) {
       
   992 			v->cur_image++;
       
   993 		} else {
       
   994 			EndVehicleMove(v);
       
   995 			DeleteVehicle(v);
       
   996 			return;
       
   997 		}
       
   998 		moved = true;
       
   999 	}
       
  1000 
       
  1001 	if (moved) {
       
  1002 		VehiclePositionChanged(v);
       
  1003 		EndVehicleMove(v);
       
  1004 	}
       
  1005 }
       
  1006 
       
  1007 static void ExplosionLargeInit(Vehicle *v)
       
  1008 {
       
  1009 	v->cur_image = SPR_EXPLOSION_LARGE_0;
       
  1010 	v->progress = 0;
       
  1011 }
       
  1012 
       
  1013 static void ExplosionLargeTick(Vehicle *v)
       
  1014 {
       
  1015 	v->progress++;
       
  1016 	if ((v->progress & 3) == 0) {
       
  1017 		BeginVehicleMove(v);
       
  1018 		if (v->cur_image != SPR_EXPLOSION_LARGE_F) {
       
  1019 			v->cur_image++;
       
  1020 			VehiclePositionChanged(v);
       
  1021 			EndVehicleMove(v);
       
  1022 		} else {
       
  1023 			EndVehicleMove(v);
       
  1024 			DeleteVehicle(v);
       
  1025 		}
       
  1026 	}
       
  1027 }
       
  1028 
       
  1029 static void BreakdownSmokeInit(Vehicle *v)
       
  1030 {
       
  1031 	v->cur_image = SPR_BREAKDOWN_SMOKE_0;
       
  1032 	v->progress = 0;
       
  1033 }
       
  1034 
       
  1035 static void BreakdownSmokeTick(Vehicle *v)
       
  1036 {
       
  1037 	v->progress++;
       
  1038 	if ((v->progress & 7) == 0) {
       
  1039 		BeginVehicleMove(v);
       
  1040 		if (v->cur_image != SPR_BREAKDOWN_SMOKE_3) {
       
  1041 			v->cur_image++;
       
  1042 		} else {
       
  1043 			v->cur_image = SPR_BREAKDOWN_SMOKE_0;
       
  1044 		}
       
  1045 		VehiclePositionChanged(v);
       
  1046 		EndVehicleMove(v);
       
  1047 	}
       
  1048 
       
  1049 	v->u.special.unk0--;
       
  1050 	if (v->u.special.unk0 == 0) {
       
  1051 		BeginVehicleMove(v);
       
  1052 		EndVehicleMove(v);
       
  1053 		DeleteVehicle(v);
       
  1054 	}
       
  1055 }
       
  1056 
       
  1057 static void ExplosionSmallInit(Vehicle *v)
       
  1058 {
       
  1059 	v->cur_image = SPR_EXPLOSION_SMALL_0;
       
  1060 	v->progress = 0;
       
  1061 }
       
  1062 
       
  1063 static void ExplosionSmallTick(Vehicle *v)
       
  1064 {
       
  1065 	v->progress++;
       
  1066 	if ((v->progress & 3) == 0) {
       
  1067 		BeginVehicleMove(v);
       
  1068 		if (v->cur_image != SPR_EXPLOSION_SMALL_B) {
       
  1069 			v->cur_image++;
       
  1070 			VehiclePositionChanged(v);
       
  1071 			EndVehicleMove(v);
       
  1072 		} else {
       
  1073 			EndVehicleMove(v);
       
  1074 			DeleteVehicle(v);
       
  1075 		}
       
  1076 	}
       
  1077 }
       
  1078 
       
  1079 static void BulldozerInit(Vehicle *v)
       
  1080 {
       
  1081 	v->cur_image = SPR_BULLDOZER_NE;
       
  1082 	v->progress = 0;
       
  1083 	v->u.special.unk0 = 0;
       
  1084 	v->u.special.unk2 = 0;
       
  1085 }
       
  1086 
       
  1087 typedef struct BulldozerMovement {
       
  1088 	byte direction:2;
       
  1089 	byte image:2;
       
  1090 	byte duration:3;
       
  1091 } BulldozerMovement;
       
  1092 
       
  1093 static const BulldozerMovement _bulldozer_movement[] = {
       
  1094 	{ 0, 0, 4 },
       
  1095 	{ 3, 3, 4 },
       
  1096 	{ 2, 2, 7 },
       
  1097 	{ 0, 2, 7 },
       
  1098 	{ 1, 1, 3 },
       
  1099 	{ 2, 2, 7 },
       
  1100 	{ 0, 2, 7 },
       
  1101 	{ 1, 1, 3 },
       
  1102 	{ 2, 2, 7 },
       
  1103 	{ 0, 2, 7 },
       
  1104 	{ 3, 3, 6 },
       
  1105 	{ 2, 2, 6 },
       
  1106 	{ 1, 1, 7 },
       
  1107 	{ 3, 1, 7 },
       
  1108 	{ 0, 0, 3 },
       
  1109 	{ 1, 1, 7 },
       
  1110 	{ 3, 1, 7 },
       
  1111 	{ 0, 0, 3 },
       
  1112 	{ 1, 1, 7 },
       
  1113 	{ 3, 1, 7 }
       
  1114 };
       
  1115 
       
  1116 static const struct {
       
  1117 	int8 x;
       
  1118 	int8 y;
       
  1119 } _inc_by_dir[] = {
       
  1120 	{ -1,  0 },
       
  1121 	{  0,  1 },
       
  1122 	{  1,  0 },
       
  1123 	{  0, -1 }
       
  1124 };
       
  1125 
       
  1126 static void BulldozerTick(Vehicle *v)
       
  1127 {
       
  1128 	v->progress++;
       
  1129 	if ((v->progress & 7) == 0) {
       
  1130 		const BulldozerMovement* b = &_bulldozer_movement[v->u.special.unk0];
       
  1131 
       
  1132 		BeginVehicleMove(v);
       
  1133 
       
  1134 		v->cur_image = SPR_BULLDOZER_NE + b->image;
       
  1135 
       
  1136 		v->x_pos += _inc_by_dir[b->direction].x;
       
  1137 		v->y_pos += _inc_by_dir[b->direction].y;
       
  1138 
       
  1139 		v->u.special.unk2++;
       
  1140 		if (v->u.special.unk2 >= b->duration) {
       
  1141 			v->u.special.unk2 = 0;
       
  1142 			v->u.special.unk0++;
       
  1143 			if (v->u.special.unk0 == lengthof(_bulldozer_movement)) {
       
  1144 				EndVehicleMove(v);
       
  1145 				DeleteVehicle(v);
       
  1146 				return;
       
  1147 			}
       
  1148 		}
       
  1149 		VehiclePositionChanged(v);
       
  1150 		EndVehicleMove(v);
       
  1151 	}
       
  1152 }
       
  1153 
       
  1154 static void BubbleInit(Vehicle *v)
       
  1155 {
       
  1156 	v->cur_image = SPR_BUBBLE_GENERATE_0;
       
  1157 	v->spritenum = 0;
       
  1158 	v->progress = 0;
       
  1159 }
       
  1160 
       
  1161 typedef struct BubbleMovement {
       
  1162 	int8 x:4;
       
  1163 	int8 y:4;
       
  1164 	int8 z:4;
       
  1165 	byte image:4;
       
  1166 } BubbleMovement;
       
  1167 
       
  1168 #define MK(x, y, z, i) { x, y, z, i }
       
  1169 #define ME(i) { i, 4, 0, 0 }
       
  1170 
       
  1171 static const BubbleMovement _bubble_float_sw[] = {
       
  1172 	MK(0, 0, 1, 0),
       
  1173 	MK(1, 0, 1, 1),
       
  1174 	MK(0, 0, 1, 0),
       
  1175 	MK(1, 0, 1, 2),
       
  1176 	ME(1)
       
  1177 };
       
  1178 
       
  1179 
       
  1180 static const BubbleMovement _bubble_float_ne[] = {
       
  1181 	MK( 0, 0, 1, 0),
       
  1182 	MK(-1, 0, 1, 1),
       
  1183 	MK( 0, 0, 1, 0),
       
  1184 	MK(-1, 0, 1, 2),
       
  1185 	ME(1)
       
  1186 };
       
  1187 
       
  1188 static const BubbleMovement _bubble_float_se[] = {
       
  1189 	MK(0, 0, 1, 0),
       
  1190 	MK(0, 1, 1, 1),
       
  1191 	MK(0, 0, 1, 0),
       
  1192 	MK(0, 1, 1, 2),
       
  1193 	ME(1)
       
  1194 };
       
  1195 
       
  1196 static const BubbleMovement _bubble_float_nw[] = {
       
  1197 	MK(0,  0, 1, 0),
       
  1198 	MK(0, -1, 1, 1),
       
  1199 	MK(0,  0, 1, 0),
       
  1200 	MK(0, -1, 1, 2),
       
  1201 	ME(1)
       
  1202 };
       
  1203 
       
  1204 static const BubbleMovement _bubble_burst[] = {
       
  1205 	MK(0, 0, 1, 2),
       
  1206 	MK(0, 0, 1, 7),
       
  1207 	MK(0, 0, 1, 8),
       
  1208 	MK(0, 0, 1, 9),
       
  1209 	ME(0)
       
  1210 };
       
  1211 
       
  1212 static const BubbleMovement _bubble_absorb[] = {
       
  1213 	MK(0, 0, 1, 0),
       
  1214 	MK(0, 0, 1, 1),
       
  1215 	MK(0, 0, 1, 0),
       
  1216 	MK(0, 0, 1, 2),
       
  1217 	MK(0, 0, 1, 0),
       
  1218 	MK(0, 0, 1, 1),
       
  1219 	MK(0, 0, 1, 0),
       
  1220 	MK(0, 0, 1, 2),
       
  1221 	MK(0, 0, 1, 0),
       
  1222 	MK(0, 0, 1, 1),
       
  1223 	MK(0, 0, 1, 0),
       
  1224 	MK(0, 0, 1, 2),
       
  1225 	MK(0, 0, 1, 0),
       
  1226 	MK(0, 0, 1, 1),
       
  1227 	MK(0, 0, 1, 0),
       
  1228 	MK(0, 0, 1, 2),
       
  1229 	MK(0, 0, 1, 0),
       
  1230 	MK(0, 0, 1, 1),
       
  1231 	MK(0, 0, 1, 0),
       
  1232 	MK(0, 0, 1, 2),
       
  1233 	MK(0, 0, 1, 0),
       
  1234 	MK(0, 0, 1, 1),
       
  1235 	MK(0, 0, 1, 0),
       
  1236 	MK(0, 0, 1, 2),
       
  1237 	MK(0, 0, 1, 0),
       
  1238 	MK(0, 0, 1, 1),
       
  1239 	MK(0, 0, 1, 0),
       
  1240 	MK(0, 0, 1, 2),
       
  1241 	MK(0, 0, 1, 0),
       
  1242 	MK(0, 0, 1, 1),
       
  1243 	MK(0, 0, 1, 0),
       
  1244 	MK(0, 0, 1, 2),
       
  1245 	MK(0, 0, 1, 0),
       
  1246 	MK(0, 0, 1, 1),
       
  1247 	MK(0, 0, 1, 0),
       
  1248 	MK(0, 0, 1, 2),
       
  1249 	MK(0, 0, 1, 0),
       
  1250 	MK(0, 0, 1, 1),
       
  1251 	MK(0, 0, 1, 0),
       
  1252 	MK(0, 0, 1, 2),
       
  1253 	MK(0, 0, 1, 0),
       
  1254 	MK(0, 0, 1, 1),
       
  1255 	MK(0, 0, 1, 0),
       
  1256 	MK(0, 0, 1, 2),
       
  1257 	MK(0, 0, 1, 0),
       
  1258 	MK(0, 0, 1, 1),
       
  1259 	MK(0, 0, 1, 0),
       
  1260 	MK(0, 0, 1, 2),
       
  1261 	MK(0, 0, 1, 0),
       
  1262 	MK(0, 0, 1, 1),
       
  1263 	MK(0, 0, 1, 0),
       
  1264 	MK(0, 0, 1, 2),
       
  1265 	MK(0, 0, 1, 0),
       
  1266 	MK(0, 0, 1, 1),
       
  1267 	MK(0, 0, 1, 0),
       
  1268 	MK(0, 0, 1, 2),
       
  1269 	MK(0, 0, 1, 0),
       
  1270 	MK(0, 0, 1, 1),
       
  1271 	MK(0, 0, 1, 0),
       
  1272 	MK(0, 0, 1, 2),
       
  1273 	MK(0, 0, 1, 0),
       
  1274 	MK(0, 0, 1, 1),
       
  1275 	MK(2, 1, 3, 0),
       
  1276 	MK(1, 1, 3, 1),
       
  1277 	MK(2, 1, 3, 0),
       
  1278 	MK(1, 1, 3, 2),
       
  1279 	MK(2, 1, 3, 0),
       
  1280 	MK(1, 1, 3, 1),
       
  1281 	MK(2, 1, 3, 0),
       
  1282 	MK(1, 0, 1, 2),
       
  1283 	MK(0, 0, 1, 0),
       
  1284 	MK(1, 0, 1, 1),
       
  1285 	MK(0, 0, 1, 0),
       
  1286 	MK(1, 0, 1, 2),
       
  1287 	MK(0, 0, 1, 0),
       
  1288 	MK(1, 0, 1, 1),
       
  1289 	MK(0, 0, 1, 0),
       
  1290 	MK(1, 0, 1, 2),
       
  1291 	ME(2),
       
  1292 	MK(0, 0, 0, 0xA),
       
  1293 	MK(0, 0, 0, 0xB),
       
  1294 	MK(0, 0, 0, 0xC),
       
  1295 	MK(0, 0, 0, 0xD),
       
  1296 	MK(0, 0, 0, 0xE),
       
  1297 	ME(0)
       
  1298 };
       
  1299 #undef ME
       
  1300 #undef MK
       
  1301 
       
  1302 static const BubbleMovement * const _bubble_movement[] = {
       
  1303 	_bubble_float_sw,
       
  1304 	_bubble_float_ne,
       
  1305 	_bubble_float_se,
       
  1306 	_bubble_float_nw,
       
  1307 	_bubble_burst,
       
  1308 	_bubble_absorb,
       
  1309 };
       
  1310 
       
  1311 static void BubbleTick(Vehicle *v)
       
  1312 {
       
  1313 	/*
       
  1314 	 * Warning: those effects can NOT use Random(), and have to use
       
  1315 	 *  InteractiveRandom(), because somehow someone forgot to save
       
  1316 	 *  spritenum to the savegame, and so it will cause desyncs in
       
  1317 	 *  multiplayer!! (that is: in ToyLand)
       
  1318 	 */
       
  1319 	uint et;
       
  1320 	const BubbleMovement *b;
       
  1321 
       
  1322 	v->progress++;
       
  1323 	if ((v->progress & 3) != 0)
       
  1324 		return;
       
  1325 
       
  1326 	BeginVehicleMove(v);
       
  1327 
       
  1328 	if (v->spritenum == 0) {
       
  1329 		v->cur_image++;
       
  1330 		if (v->cur_image < SPR_BUBBLE_GENERATE_3) {
       
  1331 			VehiclePositionChanged(v);
       
  1332 			EndVehicleMove(v);
       
  1333 			return;
       
  1334 		}
       
  1335 		if (v->u.special.unk2 != 0) {
       
  1336 			v->spritenum = GB(InteractiveRandom(), 0, 2) + 1;
       
  1337 		} else {
       
  1338 			v->spritenum = 6;
       
  1339 		}
       
  1340 		et = 0;
       
  1341 	} else {
       
  1342 		et = v->engine_type + 1;
       
  1343 	}
       
  1344 
       
  1345 	b = &_bubble_movement[v->spritenum - 1][et];
       
  1346 
       
  1347 	if (b->y == 4 && b->x == 0) {
       
  1348 		EndVehicleMove(v);
       
  1349 		DeleteVehicle(v);
       
  1350 		return;
       
  1351 	}
       
  1352 
       
  1353 	if (b->y == 4 && b->x == 1) {
       
  1354 		if (v->z_pos > 180 || CHANCE16I(1, 96, InteractiveRandom())) {
       
  1355 			v->spritenum = 5;
       
  1356 			SndPlayVehicleFx(SND_2F_POP, v);
       
  1357 		}
       
  1358 		et = 0;
       
  1359 	}
       
  1360 
       
  1361 	if (b->y == 4 && b->x == 2) {
       
  1362 		TileIndex tile;
       
  1363 
       
  1364 		et++;
       
  1365 		SndPlayVehicleFx(SND_31_EXTRACT, v);
       
  1366 
       
  1367 		tile = TileVirtXY(v->x_pos, v->y_pos);
       
  1368 		if (IsTileType(tile, MP_INDUSTRY) && GetIndustryGfx(tile) == 0xA2) AddAnimatedTile(tile);
       
  1369 	}
       
  1370 
       
  1371 	v->engine_type = et;
       
  1372 	b = &_bubble_movement[v->spritenum - 1][et];
       
  1373 
       
  1374 	v->x_pos += b->x;
       
  1375 	v->y_pos += b->y;
       
  1376 	v->z_pos += b->z;
       
  1377 	v->cur_image = SPR_BUBBLE_0 + b->image;
       
  1378 
       
  1379 	VehiclePositionChanged(v);
       
  1380 	EndVehicleMove(v);
       
  1381 }
       
  1382 
       
  1383 
       
  1384 typedef void EffectInitProc(Vehicle *v);
       
  1385 typedef void EffectTickProc(Vehicle *v);
       
  1386 
       
  1387 static EffectInitProc * const _effect_init_procs[] = {
       
  1388 	ChimneySmokeInit,
       
  1389 	SteamSmokeInit,
       
  1390 	DieselSmokeInit,
       
  1391 	ElectricSparkInit,
       
  1392 	SmokeInit,
       
  1393 	ExplosionLargeInit,
       
  1394 	BreakdownSmokeInit,
       
  1395 	ExplosionSmallInit,
       
  1396 	BulldozerInit,
       
  1397 	BubbleInit,
       
  1398 };
       
  1399 
       
  1400 static EffectTickProc * const _effect_tick_procs[] = {
       
  1401 	ChimneySmokeTick,
       
  1402 	SteamSmokeTick,
       
  1403 	DieselSmokeTick,
       
  1404 	ElectricSparkTick,
       
  1405 	SmokeTick,
       
  1406 	ExplosionLargeTick,
       
  1407 	BreakdownSmokeTick,
       
  1408 	ExplosionSmallTick,
       
  1409 	BulldozerTick,
       
  1410 	BubbleTick,
       
  1411 };
       
  1412 
       
  1413 
       
  1414 Vehicle *CreateEffectVehicle(int x, int y, int z, EffectVehicle type)
       
  1415 {
       
  1416 	Vehicle *v;
       
  1417 
       
  1418 	v = ForceAllocateSpecialVehicle();
       
  1419 	if (v != NULL) {
       
  1420 		v->type = VEH_Special;
       
  1421 		v->subtype = type;
       
  1422 		v->x_pos = x;
       
  1423 		v->y_pos = y;
       
  1424 		v->z_pos = z;
       
  1425 		v->z_height = v->sprite_width = v->sprite_height = 1;
       
  1426 		v->x_offs = v->y_offs = 0;
       
  1427 		v->tile = 0;
       
  1428 		v->vehstatus = VS_UNCLICKABLE;
       
  1429 
       
  1430 		_effect_init_procs[type](v);
       
  1431 
       
  1432 		VehiclePositionChanged(v);
       
  1433 		BeginVehicleMove(v);
       
  1434 		EndVehicleMove(v);
       
  1435 	}
       
  1436 	return v;
       
  1437 }
       
  1438 
       
  1439 Vehicle *CreateEffectVehicleAbove(int x, int y, int z, EffectVehicle type)
       
  1440 {
       
  1441 	int safe_x = clamp(x, 0, MapMaxX() * TILE_SIZE);
       
  1442 	int safe_y = clamp(y, 0, MapMaxY() * TILE_SIZE);
       
  1443 	return CreateEffectVehicle(x, y, GetSlopeZ(safe_x, safe_y) + z, type);
       
  1444 }
       
  1445 
       
  1446 Vehicle *CreateEffectVehicleRel(const Vehicle *v, int x, int y, int z, EffectVehicle type)
       
  1447 {
       
  1448 	return CreateEffectVehicle(v->x_pos + x, v->y_pos + y, v->z_pos + z, type);
       
  1449 }
       
  1450 
       
  1451 static void EffectVehicle_Tick(Vehicle *v)
       
  1452 {
       
  1453 	_effect_tick_procs[v->subtype](v);
       
  1454 }
       
  1455 
       
  1456 Vehicle *CheckClickOnVehicle(const ViewPort *vp, int x, int y)
       
  1457 {
       
  1458 	Vehicle *found = NULL, *v;
       
  1459 	uint dist, best_dist = (uint)-1;
       
  1460 
       
  1461 	if ( (uint)(x -= vp->left) >= (uint)vp->width ||
       
  1462 			 (uint)(y -= vp->top) >= (uint)vp->height)
       
  1463 				return NULL;
       
  1464 
       
  1465 	x = (x << vp->zoom) + vp->virtual_left;
       
  1466 	y = (y << vp->zoom) + vp->virtual_top;
       
  1467 
       
  1468 	FOR_ALL_VEHICLES(v) {
       
  1469 		if ((v->vehstatus & (VS_HIDDEN|VS_UNCLICKABLE)) == 0 &&
       
  1470 				x >= v->left_coord && x <= v->right_coord &&
       
  1471 				y >= v->top_coord && y <= v->bottom_coord) {
       
  1472 
       
  1473 			dist = max(
       
  1474 				myabs( ((v->left_coord + v->right_coord)>>1) - x ),
       
  1475 				myabs( ((v->top_coord + v->bottom_coord)>>1) - y )
       
  1476 			);
       
  1477 
       
  1478 			if (dist < best_dist) {
       
  1479 				found = v;
       
  1480 				best_dist = dist;
       
  1481 			}
       
  1482 		}
       
  1483 	}
       
  1484 
       
  1485 	return found;
       
  1486 }
       
  1487 
       
  1488 
       
  1489 void DecreaseVehicleValue(Vehicle *v)
       
  1490 {
       
  1491 	v->value -= v->value >> 8;
       
  1492 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
       
  1493 }
       
  1494 
       
  1495 static const byte _breakdown_chance[64] = {
       
  1496 	  3,   3,   3,   3,   3,   3,   3,   3,
       
  1497 	  4,   4,   5,   5,   6,   6,   7,   7,
       
  1498 	  8,   8,   9,   9,  10,  10,  11,  11,
       
  1499 	 12,  13,  13,  13,  13,  14,  15,  16,
       
  1500 	 17,  19,  21,  25,  28,  31,  34,  37,
       
  1501 	 40,  44,  48,  52,  56,  60,  64,  68,
       
  1502 	 72,  80,  90, 100, 110, 120, 130, 140,
       
  1503 	150, 170, 190, 210, 230, 250, 250, 250,
       
  1504 };
       
  1505 
       
  1506 void CheckVehicleBreakdown(Vehicle *v)
       
  1507 {
       
  1508 	int rel, rel_old;
       
  1509 	uint32 r;
       
  1510 	int chance;
       
  1511 
       
  1512 	/* decrease reliability */
       
  1513 	v->reliability = rel = max((rel_old = v->reliability) - v->reliability_spd_dec, 0);
       
  1514 	if ((rel_old >> 8) != (rel >> 8))
       
  1515 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
       
  1516 
       
  1517 	if (v->breakdown_ctr != 0 || v->vehstatus & VS_STOPPED ||
       
  1518 			v->cur_speed < 5 || _game_mode == GM_MENU) {
       
  1519 		return;
       
  1520 	}
       
  1521 
       
  1522 	r = Random();
       
  1523 
       
  1524 	/* increase chance of failure */
       
  1525 	chance = v->breakdown_chance + 1;
       
  1526 	if (CHANCE16I(1,25,r)) chance += 25;
       
  1527 	v->breakdown_chance = min(255, chance);
       
  1528 
       
  1529 	/* calculate reliability value to use in comparison */
       
  1530 	rel = v->reliability;
       
  1531 	if (v->type == VEH_Ship) rel += 0x6666;
       
  1532 
       
  1533 	/* disabled breakdowns? */
       
  1534 	if (_opt.diff.vehicle_breakdowns < 1) return;
       
  1535 
       
  1536 	/* reduced breakdowns? */
       
  1537 	if (_opt.diff.vehicle_breakdowns == 1) rel += 0x6666;
       
  1538 
       
  1539 	/* check if to break down */
       
  1540 	if (_breakdown_chance[(uint)min(rel, 0xffff) >> 10] <= v->breakdown_chance) {
       
  1541 		v->breakdown_ctr    = GB(r, 16, 6) + 0x3F;
       
  1542 		v->breakdown_delay  = GB(r, 24, 7) + 0x80;
       
  1543 		v->breakdown_chance = 0;
       
  1544 	}
       
  1545 }
       
  1546 
       
  1547 static const StringID _vehicle_type_names[4] = {
       
  1548 	STR_019F_TRAIN,
       
  1549 	STR_019C_ROAD_VEHICLE,
       
  1550 	STR_019E_SHIP,
       
  1551 	STR_019D_AIRCRAFT,
       
  1552 };
       
  1553 
       
  1554 static void ShowVehicleGettingOld(Vehicle *v, StringID msg)
       
  1555 {
       
  1556 	if (v->owner != _local_player) return;
       
  1557 
       
  1558 	// Do not show getting-old message if autorenew is active
       
  1559 	if (GetPlayer(v->owner)->engine_renew) return;
       
  1560 
       
  1561 	SetDParam(0, _vehicle_type_names[v->type - 0x10]);
       
  1562 	SetDParam(1, v->unitnumber);
       
  1563 	AddNewsItem(msg, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
       
  1564 }
       
  1565 
       
  1566 void AgeVehicle(Vehicle *v)
       
  1567 {
       
  1568 	int age;
       
  1569 
       
  1570 	if (v->age < 65535)
       
  1571 		v->age++;
       
  1572 
       
  1573 	age = v->age - v->max_age;
       
  1574 	if (age == 366*0 || age == 366*1 || age == 366*2 || age == 366*3 || age == 366*4)
       
  1575 		v->reliability_spd_dec <<= 1;
       
  1576 
       
  1577 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
       
  1578 
       
  1579 	if (age == -366) {
       
  1580 		ShowVehicleGettingOld(v, STR_01A0_IS_GETTING_OLD);
       
  1581 	} else if (age == 0) {
       
  1582 		ShowVehicleGettingOld(v, STR_01A1_IS_GETTING_VERY_OLD);
       
  1583 	} else if (age == 366*1 || age == 366*2 || age == 366*3 || age == 366*4 || age == 366*5) {
       
  1584 		ShowVehicleGettingOld(v, STR_01A2_IS_GETTING_VERY_OLD_AND);
       
  1585 	}
       
  1586 }
       
  1587 
       
  1588 /** Starts or stops a lot of vehicles
       
  1589  * @param tile Tile of the depot where the vehicles are started/stopped (only used for depots)
       
  1590  * @param p1 Station/Order/Depot ID (only used for vehicle list windows)
       
  1591  * @param p2 bitmask
       
  1592  *   - bit 0-4 Vehicle type
       
  1593  *   - bit 5 false = start vehicles, true = stop vehicles
       
  1594  *   - bit 6 if set, then it's a vehicle list window, not a depot and Tile is ignored in this case
       
  1595  *   - bit 8-11 Vehicle List Window type (ignored unless bit 1 is set)
       
  1596  */
       
  1597 int32 CmdMassStartStopVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
  1598 {
       
  1599 	Vehicle **vl = NULL;
       
  1600 	uint16 engine_list_length = 0;
       
  1601 	uint16 engine_count = 0;
       
  1602 	int32 return_value = CMD_ERROR;
       
  1603 	uint i;
       
  1604 	uint stop_command;
       
  1605 	byte vehicle_type = GB(p2, 0, 5);
       
  1606 	bool start_stop = HASBIT(p2, 5);
       
  1607 	bool vehicle_list_window = HASBIT(p2, 6);
       
  1608 
       
  1609 	switch (vehicle_type) {
       
  1610 		case VEH_Train:    stop_command = CMD_START_STOP_TRAIN;    break;
       
  1611 		case VEH_Road:     stop_command = CMD_START_STOP_ROADVEH;  break;
       
  1612 		case VEH_Ship:     stop_command = CMD_START_STOP_SHIP;     break;
       
  1613 		case VEH_Aircraft: stop_command = CMD_START_STOP_AIRCRAFT; break;
       
  1614 		default: return CMD_ERROR;
       
  1615 	}
       
  1616 
       
  1617 	if (vehicle_list_window) {
       
  1618 		uint16 id = GB(p1, 0, 16);
       
  1619 		uint16 window_type = p2 & VLW_MASK;
       
  1620 
       
  1621 		engine_count = GenerateVehicleSortList((const Vehicle***)&vl, &engine_list_length, vehicle_type, _current_player, id, id, id, window_type);
       
  1622 	} else {
       
  1623 		/* Get the list of vehicles in the depot */
       
  1624 		BuildDepotVehicleList(vehicle_type, tile, &vl, &engine_list_length, &engine_count, NULL, NULL, NULL);
       
  1625 	}
       
  1626 
       
  1627 	for (i = 0; i < engine_count; i++) {
       
  1628 		const Vehicle *v = vl[i];
       
  1629 		int32 ret;
       
  1630 
       
  1631 		if (!!(v->vehstatus & VS_STOPPED) != start_stop) continue;
       
  1632 
       
  1633 		if (!vehicle_list_window) {
       
  1634 			if (vehicle_type == VEH_Train) {
       
  1635 				if (CheckTrainInDepot(v, false) == -1) continue;
       
  1636 			} else {
       
  1637 				if (!(v->vehstatus & VS_HIDDEN)) continue;
       
  1638 			}
       
  1639 		}
       
  1640 
       
  1641 		ret = DoCommand(tile, v->index, 0, flags, stop_command);
       
  1642 
       
  1643 		if (!CmdFailed(ret)) {
       
  1644 			return_value = 0;
       
  1645 			/* We know that the command is valid for at least one vehicle.
       
  1646 			 * If we haven't set DC_EXEC, then there is no point in continueing because it will be valid */
       
  1647 			if (!(flags & DC_EXEC)) break;
       
  1648 		}
       
  1649 	}
       
  1650 
       
  1651 	free(vl);
       
  1652 	return return_value;
       
  1653 }
       
  1654 
       
  1655 /** Sells all vehicles in a depot
       
  1656 * @param tile Tile of the depot where the depot is
       
  1657 * @param p1 Vehicle type
       
  1658 * @param p2 unused
       
  1659 */
       
  1660 int32 CmdDepotSellAllVehicles(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
  1661 {
       
  1662 	Vehicle **engines = NULL;
       
  1663 	Vehicle **wagons = NULL;
       
  1664 	uint16 engine_list_length = 0;
       
  1665 	uint16 engine_count = 0;
       
  1666 	uint16 wagon_list_length = 0;
       
  1667 	uint16 wagon_count = 0;
       
  1668 
       
  1669 	int32 cost = 0;
       
  1670 	uint i, sell_command, total_number_vehicles;
       
  1671 	byte vehicle_type = GB(p1, 0, 8);
       
  1672 
       
  1673 	switch (vehicle_type) {
       
  1674 		case VEH_Train:    sell_command = CMD_SELL_RAIL_WAGON; break;
       
  1675 		case VEH_Road:     sell_command = CMD_SELL_ROAD_VEH;   break;
       
  1676 		case VEH_Ship:     sell_command = CMD_SELL_SHIP;       break;
       
  1677 		case VEH_Aircraft: sell_command = CMD_SELL_AIRCRAFT;   break;
       
  1678 		default: return CMD_ERROR;
       
  1679 	}
       
  1680 
       
  1681 	/* Get the list of vehicles in the depot */
       
  1682 	BuildDepotVehicleList(vehicle_type, tile, &engines, &engine_list_length, &engine_count,
       
  1683 						                      &wagons,  &wagon_list_length,  &wagon_count);
       
  1684 
       
  1685 	total_number_vehicles = engine_count + wagon_count;
       
  1686 	for (i = 0; i < total_number_vehicles; i++) {
       
  1687 		const Vehicle *v;
       
  1688 		int32 ret;
       
  1689 
       
  1690 		if (i < engine_count) {
       
  1691 			v = engines[i];
       
  1692 		} else {
       
  1693 			v = wagons[i - engine_count];
       
  1694 		}
       
  1695 
       
  1696 		ret = DoCommand(tile, v->index, 1, flags, sell_command);
       
  1697 
       
  1698 		if (!CmdFailed(ret)) cost += ret;
       
  1699 	}
       
  1700 
       
  1701 	free(engines);
       
  1702 	free(wagons);
       
  1703 	if (cost == 0) return CMD_ERROR; // no vehicles to sell
       
  1704 	return cost;
       
  1705 }
       
  1706 
       
  1707 /** Autoreplace all vehicles in the depot
       
  1708 * @param tile Tile of the depot where the vehicles are
       
  1709 * @param p1 Type of vehicle
       
  1710 * @param p2 Unused
       
  1711 */
       
  1712 int32 CmdDepotMassAutoReplace(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
  1713 {
       
  1714 	Vehicle **vl = NULL;
       
  1715 	uint16 engine_list_length = 0;
       
  1716 	uint16 engine_count = 0;
       
  1717 	uint i, x = 0, y = 0, z = 0;
       
  1718 	int32 cost = 0;
       
  1719 	byte vehicle_type = GB(p1, 0, 8);
       
  1720 
       
  1721 
       
  1722 	if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
       
  1723 
       
  1724 	/* Get the list of vehicles in the depot */
       
  1725 	BuildDepotVehicleList(vehicle_type, tile, &vl, &engine_list_length, &engine_count, NULL, NULL, NULL);
       
  1726 
       
  1727 
       
  1728 	for (i = 0; i < engine_count; i++) {
       
  1729 		Vehicle *v = vl[i];
       
  1730 		bool stopped = !(v->vehstatus & VS_STOPPED);
       
  1731 		int32 ret;
       
  1732 
       
  1733 		/* Ensure that the vehicle completely in the depot */
       
  1734 		if (!IsVehicleInDepot(v)) continue;
       
  1735 
       
  1736 		x = v->x_pos;
       
  1737 		y = v->y_pos;
       
  1738 		z = v->z_pos;
       
  1739 
       
  1740 		if (stopped) {
       
  1741 			v->vehstatus |= VS_STOPPED; // Stop the vehicle
       
  1742 			v->leave_depot_instantly = true;
       
  1743 		}
       
  1744 		ret = MaybeReplaceVehicle(v, !(flags & DC_EXEC), false);
       
  1745 
       
  1746 		if (!CmdFailed(ret)) {
       
  1747 			cost += ret;
       
  1748 			if (!(flags & DC_EXEC)) break;
       
  1749 			/* There is a problem with autoreplace and newgrf
       
  1750 			 * It's impossible to tell the length of a train after it's being replaced before it's actually done
       
  1751 			 * Because of this, we can't estimate costs due to wagon removal and we will have to always return 0 and pay manually
       
  1752 			 * Since we pay after each vehicle is replaced and MaybeReplaceVehicle() check if the player got enough money
       
  1753 			 * we should never reach a condition where the player will end up with negative money from doing this */
       
  1754 			SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
       
  1755 			SubtractMoneyFromPlayer(ret);
       
  1756 		}
       
  1757 	}
       
  1758 
       
  1759 	if (cost == 0) {
       
  1760 		cost = CMD_ERROR;
       
  1761 	} else {
       
  1762 		if (flags & DC_EXEC) {
       
  1763 			/* Display the cost animation now that DoCommandP() can't do it for us (see previous comments) */
       
  1764 			if (IsLocalPlayer()) ShowCostOrIncomeAnimation(x, y, z, cost);
       
  1765 		}
       
  1766 		cost = 0;
       
  1767 	}
       
  1768 
       
  1769 	free(vl);
       
  1770 	return cost;
       
  1771 }
       
  1772 
       
  1773 /** Clone a vehicle. If it is a train, it will clone all the cars too
       
  1774  * @param tile tile of the depot where the cloned vehicle is build
       
  1775  * @param p1 the original vehicle's index
       
  1776  * @param p2 1 = shared orders, else copied orders
       
  1777  */
       
  1778 int32 CmdCloneVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
  1779 {
       
  1780 	Vehicle *v_front, *v;
       
  1781 	Vehicle *w_front, *w, *w_rear;
       
  1782 	int cost, total_cost = 0;
       
  1783 	uint32 build_argument = 2;
       
  1784 
       
  1785 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
       
  1786 	v = GetVehicle(p1);
       
  1787 	v_front = v;
       
  1788 	w = NULL;
       
  1789 	w_front = NULL;
       
  1790 	w_rear = NULL;
       
  1791 
       
  1792 
       
  1793 	/*
       
  1794 	 * v_front is the front engine in the original vehicle
       
  1795 	 * v is the car/vehicle of the original vehicle, that is currently being copied
       
  1796 	 * w_front is the front engine of the cloned vehicle
       
  1797 	 * w is the car/vehicle currently being cloned
       
  1798 	 * w_rear is the rear end of the cloned train. It's used to add more cars and is only used by trains
       
  1799 	 */
       
  1800 
       
  1801 	if (!CheckOwnership(v->owner)) return CMD_ERROR;
       
  1802 
       
  1803 	if (v->type == VEH_Train && (!IsFrontEngine(v) || v->u.rail.crash_anim_pos >= 4400)) return CMD_ERROR;
       
  1804 
       
  1805 	// check that we can allocate enough vehicles
       
  1806 	if (!(flags & DC_EXEC)) {
       
  1807 		int veh_counter = 0;
       
  1808 		do {
       
  1809 			veh_counter++;
       
  1810 		} while ((v = v->next) != NULL);
       
  1811 
       
  1812 		if (!AllocateVehicles(NULL, veh_counter)) {
       
  1813 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
       
  1814 		}
       
  1815 	}
       
  1816 
       
  1817 	v = v_front;
       
  1818 
       
  1819 	do {
       
  1820 
       
  1821 		if (IsMultiheaded(v) && !IsTrainEngine(v)) {
       
  1822 			/* we build the rear ends of multiheaded trains with the front ones */
       
  1823 			continue;
       
  1824 		}
       
  1825 
       
  1826 		cost = DoCommand(tile, v->engine_type, build_argument, flags, CMD_BUILD_VEH(v->type));
       
  1827 		build_argument = 3; // ensure that we only assign a number to the first engine
       
  1828 
       
  1829 		if (CmdFailed(cost)) return cost;
       
  1830 
       
  1831 		total_cost += cost;
       
  1832 
       
  1833 		if (flags & DC_EXEC) {
       
  1834 			w = GetVehicle(_new_vehicle_id);
       
  1835 
       
  1836 			if (v->cargo_type != w->cargo_type || v->cargo_subtype != w->cargo_subtype) {
       
  1837 				// we can't pay for refitting because we can't estimate refitting costs for a vehicle before it's build
       
  1838 				// if we pay for it anyway, the cost and the estimated cost will not be the same and we will have an assert
       
  1839 				DoCommand(0, w->index, v->cargo_type | (v->cargo_subtype << 8), flags, CMD_REFIT_VEH(v->type));
       
  1840 			}
       
  1841 			if (v->type == VEH_Train && HASBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION)) {
       
  1842 				SETBIT(w->u.rail.flags, VRF_REVERSE_DIRECTION);
       
  1843 			}
       
  1844 
       
  1845 			if (v->type == VEH_Train && !IsFrontEngine(v)) {
       
  1846 				// this s a train car
       
  1847 				// add this unit to the end of the train
       
  1848 				DoCommand(0, (w_rear->index << 16) | w->index, 1, flags, CMD_MOVE_RAIL_VEHICLE);
       
  1849 			} else {
       
  1850 				// this is a front engine or not a train. It need orders
       
  1851 				w_front = w;
       
  1852 				w->service_interval = v->service_interval;
       
  1853 				DoCommand(0, (v->index << 16) | w->index, p2 & 1 ? CO_SHARE : CO_COPY, flags, CMD_CLONE_ORDER);
       
  1854 			}
       
  1855 			w_rear = w; // trains needs to know the last car in the train, so they can add more in next loop
       
  1856 		}
       
  1857 	} while (v->type == VEH_Train && (v = GetNextVehicle(v)) != NULL);
       
  1858 
       
  1859 	if (flags & DC_EXEC && v_front->type == VEH_Train) {
       
  1860 		// for trains this needs to be the front engine due to the callback function
       
  1861 		_new_vehicle_id = w_front->index;
       
  1862 	}
       
  1863 
       
  1864 	/* Set the expense type last as refitting will make the cost go towards
       
  1865 	 * running costs... */
       
  1866 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
       
  1867 	return total_cost;
       
  1868 }
       
  1869 
       
  1870 /*
       
  1871  * move the cargo from one engine to another if possible
       
  1872  */
       
  1873 static void MoveVehicleCargo(Vehicle *dest, Vehicle *source)
       
  1874 {
       
  1875 	Vehicle *v = dest;
       
  1876 	int units_moved;
       
  1877 
       
  1878 	do {
       
  1879 		do {
       
  1880 			if (source->cargo_type != dest->cargo_type)
       
  1881 				continue; // cargo not compatible
       
  1882 
       
  1883 			if (dest->cargo_count == dest->cargo_cap)
       
  1884 				continue; // the destination vehicle is already full
       
  1885 
       
  1886 			units_moved = min(source->cargo_count, dest->cargo_cap - dest->cargo_count);
       
  1887 			source->cargo_count -= units_moved;
       
  1888 			dest->cargo_count   += units_moved;
       
  1889 			dest->cargo_source   = source->cargo_source;
       
  1890 
       
  1891 			// copy the age of the cargo
       
  1892 			dest->cargo_days   = source->cargo_days;
       
  1893 			dest->day_counter  = source->day_counter;
       
  1894 			dest->tick_counter = source->tick_counter;
       
  1895 
       
  1896 		} while (source->cargo_count > 0 && (dest = dest->next) != NULL);
       
  1897 		dest = v;
       
  1898 	} while ((source = source->next) != NULL);
       
  1899 }
       
  1900 
       
  1901 static bool VerifyAutoreplaceRefitForOrders(const Vehicle *v, const EngineID engine_type)
       
  1902 {
       
  1903 	const Order *o;
       
  1904 	const Vehicle *u;
       
  1905 
       
  1906 	if (v->type == VEH_Train) {
       
  1907 		u = GetFirstVehicleInChain(v);
       
  1908 	} else {
       
  1909 		u = v;
       
  1910 	}
       
  1911 
       
  1912 	FOR_VEHICLE_ORDERS(u, o) {
       
  1913 		if (!(o->refit_cargo < NUM_CARGO)) continue;
       
  1914 		if (!CanRefitTo(v->engine_type, o->refit_cargo)) continue;
       
  1915 		if (!CanRefitTo(engine_type, o->refit_cargo)) return false;
       
  1916 	}
       
  1917 
       
  1918 	return true;
       
  1919 }
       
  1920 
       
  1921 /**
       
  1922  * Function to find what type of cargo to refit to when autoreplacing
       
  1923  * @param *v Original vehicle, that is being replaced
       
  1924  * @param engine_type The EngineID of the vehicle that is being replaced to
       
  1925  * @return The cargo type to replace to
       
  1926  *    CT_NO_REFIT is returned if no refit is needed
       
  1927  *    CT_INVALID is returned when both old and new vehicle got cargo capacity and refitting the new one to the old one's cargo type isn't possible
       
  1928  */
       
  1929 static CargoID GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type)
       
  1930 {
       
  1931 	bool new_cargo_capacity = true;
       
  1932 	CargoID new_cargo_type = CT_INVALID;
       
  1933 
       
  1934 	switch (v->type) {
       
  1935 		case VEH_Train:
       
  1936 			new_cargo_capacity = (RailVehInfo(engine_type)->capacity > 0);
       
  1937 			new_cargo_type     = RailVehInfo(engine_type)->cargo_type;
       
  1938 			break;
       
  1939 
       
  1940 		case VEH_Road:
       
  1941 			new_cargo_capacity = (RoadVehInfo(engine_type)->capacity > 0);
       
  1942 			new_cargo_type     = RoadVehInfo(engine_type)->cargo_type;
       
  1943 			break;
       
  1944 		case VEH_Ship:
       
  1945 			new_cargo_capacity = (ShipVehInfo(engine_type)->capacity > 0);
       
  1946 			new_cargo_type     = ShipVehInfo(engine_type)->cargo_type;
       
  1947 			break;
       
  1948 
       
  1949 		case VEH_Aircraft:
       
  1950 			/* all aircraft starts as passenger planes with cargo capacity
       
  1951 			 * new_cargo_capacity is always true for aircraft, which is the init value. No need to set it here */
       
  1952 			new_cargo_type     = CT_PASSENGERS;
       
  1953 			break;
       
  1954 
       
  1955 		default: NOT_REACHED(); break;
       
  1956 	}
       
  1957 
       
  1958 	if (!new_cargo_capacity) return CT_NO_REFIT; // Don't try to refit an engine with no cargo capacity
       
  1959 
       
  1960 	if (v->cargo_type == new_cargo_type || CanRefitTo(engine_type, v->cargo_type)) {
       
  1961 		if (VerifyAutoreplaceRefitForOrders(v, engine_type)) {
       
  1962 			return v->cargo_type == new_cargo_type ? CT_NO_REFIT : v->cargo_type;
       
  1963 		} else {
       
  1964 			return CT_INVALID;
       
  1965 		}
       
  1966 	}
       
  1967 	if (v->type != VEH_Train) return CT_INVALID; // We can't refit the vehicle to carry the cargo we want
       
  1968 
       
  1969 	/* Below this line it's safe to assume that the vehicle in question is a train */
       
  1970 
       
  1971 	if (v->cargo_cap != 0) return CT_INVALID; // trying to replace a vehicle with cargo capacity into another one with incompatible cargo type
       
  1972 
       
  1973 	/* the old engine didn't have cargo capacity, but the new one does
       
  1974 	 * now we will figure out what cargo the train is carrying and refit to fit this */
       
  1975 	v = GetFirstVehicleInChain(v);
       
  1976 	do {
       
  1977 		if (v->cargo_cap == 0) continue;
       
  1978 		/* Now we found a cargo type being carried on the train and we will see if it is possible to carry to this one */
       
  1979 		if (v->cargo_type == new_cargo_type) return CT_NO_REFIT;
       
  1980 		if (CanRefitTo(engine_type, v->cargo_type)) return v->cargo_type;
       
  1981 	} while ((v=v->next) != NULL);
       
  1982 	return CT_NO_REFIT; // We failed to find a cargo type on the old vehicle and we will not refit the new one
       
  1983 }
       
  1984 
       
  1985 /* Replaces a vehicle (used to be called autorenew)
       
  1986  * This function is only called from MaybeReplaceVehicle()
       
  1987  * Must be called with _current_player set to the owner of the vehicle
       
  1988  * @param w Vehicle to replace
       
  1989  * @param flags is the flags to use when calling DoCommand(). Mainly DC_EXEC counts
       
  1990  * @return value is cost of the replacement or CMD_ERROR
       
  1991  */
       
  1992 static int32 ReplaceVehicle(Vehicle **w, byte flags, int32 total_cost)
       
  1993 {
       
  1994 	int32 cost;
       
  1995 	int32 sell_value;
       
  1996 	Vehicle *old_v = *w;
       
  1997 	const Player *p = GetPlayer(old_v->owner);
       
  1998 	EngineID new_engine_type;
       
  1999 	const UnitID cached_unitnumber = old_v->unitnumber;
       
  2000 	bool new_front = false;
       
  2001 	Vehicle *new_v = NULL;
       
  2002 	char vehicle_name[32];
       
  2003 	CargoID replacement_cargo_type;
       
  2004 
       
  2005 	new_engine_type = EngineReplacementForPlayer(p, old_v->engine_type);
       
  2006 	if (new_engine_type == INVALID_ENGINE) new_engine_type = old_v->engine_type;
       
  2007 
       
  2008 	replacement_cargo_type = GetNewCargoTypeForReplace(old_v, new_engine_type);
       
  2009 
       
  2010 	/* check if we can't refit to the needed type, so no replace takes place to prevent the vehicle from altering cargo type */
       
  2011 	if (replacement_cargo_type == CT_INVALID) return 0;
       
  2012 
       
  2013 	sell_value = DoCommand(0, old_v->index, 0, DC_QUERY_COST, CMD_SELL_VEH(old_v->type));
       
  2014 
       
  2015 	/* We give the player a loan of the same amount as the sell value.
       
  2016 	 * This is needed in case he needs the income from the sale to build the new vehicle.
       
  2017 	 * We take it back if building fails or when we really sell the old engine */
       
  2018 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
       
  2019 	SubtractMoneyFromPlayer(sell_value);
       
  2020 
       
  2021 	cost = DoCommand(old_v->tile, new_engine_type, 3, flags, CMD_BUILD_VEH(old_v->type));
       
  2022 	if (CmdFailed(cost)) {
       
  2023 		SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
       
  2024 		SubtractMoneyFromPlayer(-sell_value); // Take back the money we just gave the player
       
  2025 		return cost;
       
  2026 	}
       
  2027 
       
  2028 	if (replacement_cargo_type != CT_NO_REFIT) cost += GetRefitCost(new_engine_type); // add refit cost
       
  2029 
       
  2030 	if (flags & DC_EXEC) {
       
  2031 		new_v = GetVehicle(_new_vehicle_id);
       
  2032 		*w = new_v; //we changed the vehicle, so MaybeReplaceVehicle needs to work on the new one. Now we tell it what the new one is
       
  2033 
       
  2034 		/* refit if needed */
       
  2035 		if (replacement_cargo_type != CT_NO_REFIT) {
       
  2036 			if (CmdFailed(DoCommand(0, new_v->index, replacement_cargo_type, DC_EXEC, CMD_REFIT_VEH(new_v->type)))) {
       
  2037 				/* Being here shows a failure, which most likely is in GetNewCargoTypeForReplace() or incorrect estimation costs */
       
  2038 				error("Autoreplace failed to refit. Replace engine %d to %d and refit to cargo %d", old_v->engine_type, new_v->engine_type, replacement_cargo_type);
       
  2039 			}
       
  2040 		}
       
  2041 
       
  2042 		if (new_v->type == VEH_Train && HASBIT(old_v->u.rail.flags, VRF_REVERSE_DIRECTION) && !IsMultiheaded(new_v) && !(new_v->next != NULL && IsArticulatedPart(new_v->next))) {
       
  2043 			// we are autorenewing to a single engine, so we will turn it as the old one was turned as well
       
  2044 			SETBIT(new_v->u.rail.flags, VRF_REVERSE_DIRECTION);
       
  2045 		}
       
  2046 
       
  2047 		if (old_v->type == VEH_Train && !IsFrontEngine(old_v)) {
       
  2048 			/* this is a railcar. We need to move the car into the train
       
  2049 			 * We add the new engine after the old one instead of replacing it. It will give the same result anyway when we
       
  2050 			 * sell the old engine in a moment
       
  2051 			 */
       
  2052 			DoCommand(0, (GetPrevVehicleInChain(old_v)->index << 16) | new_v->index, 1, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
       
  2053 			/* Now we move the old one out of the train */
       
  2054 			DoCommand(0, (INVALID_VEHICLE << 16) | old_v->index, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
       
  2055 		} else {
       
  2056 			// copy/clone the orders
       
  2057 			DoCommand(0, (old_v->index << 16) | new_v->index, IsOrderListShared(old_v) ? CO_SHARE : CO_COPY, DC_EXEC, CMD_CLONE_ORDER);
       
  2058 			new_v->cur_order_index = old_v->cur_order_index;
       
  2059 			ChangeVehicleViewWindow(old_v, new_v);
       
  2060 			new_v->profit_this_year = old_v->profit_this_year;
       
  2061 			new_v->profit_last_year = old_v->profit_last_year;
       
  2062 			new_v->service_interval = old_v->service_interval;
       
  2063 			new_front = true;
       
  2064 			new_v->unitnumber = old_v->unitnumber; // use the same unit number
       
  2065 
       
  2066 			new_v->current_order = old_v->current_order;
       
  2067 			if (old_v->type == VEH_Train && GetNextVehicle(old_v) != NULL){
       
  2068 				Vehicle *temp_v = GetNextVehicle(old_v);
       
  2069 
       
  2070 				// move the entire train to the new engine, excluding the old engine
       
  2071 				if (IsMultiheaded(old_v) && temp_v == old_v->u.rail.other_multiheaded_part) {
       
  2072 					// we got front and rear of a multiheaded engine right after each other. We should work with the next in line instead
       
  2073 					temp_v = GetNextVehicle(temp_v);
       
  2074 				}
       
  2075 
       
  2076 				if (temp_v != NULL) {
       
  2077 					DoCommand(0, (new_v->index << 16) | temp_v->index, 1, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
       
  2078 				}
       
  2079 			}
       
  2080 		}
       
  2081 		/* We are done setting up the new vehicle. Now we move the cargo from the old one to the new one */
       
  2082 		MoveVehicleCargo(new_v->type == VEH_Train ? GetFirstVehicleInChain(new_v) : new_v, old_v);
       
  2083 
       
  2084 		// Get the name of the old vehicle if it has a custom name.
       
  2085 		if (!IsCustomName(old_v->string_id)) {
       
  2086 			vehicle_name[0] = '\0';
       
  2087 		} else {
       
  2088 			GetName(vehicle_name, old_v->string_id & 0x7FF, lastof(vehicle_name));
       
  2089 		}
       
  2090 	} else { // flags & DC_EXEC not set
       
  2091 		/* Ensure that the player will not end up having negative money while autoreplacing
       
  2092 		 * This is needed because the only other check is done after the income from selling the old vehicle is substracted from the cost */
       
  2093 		if (p->money64 < (cost + total_cost)) {
       
  2094 			SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
       
  2095 			SubtractMoneyFromPlayer(-sell_value); // Pay back the loan
       
  2096 			return CMD_ERROR;
       
  2097 		}
       
  2098 	}
       
  2099 
       
  2100 	/* Take back the money we just gave the player just before building the vehicle
       
  2101 	 * The player will get the same amount now that the sale actually takes place */
       
  2102 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
       
  2103 	SubtractMoneyFromPlayer(-sell_value);
       
  2104 
       
  2105 	/* sell the engine/ find out how much you get for the old engine (income is returned as negative cost) */
       
  2106 	cost += DoCommand(0, old_v->index, 0, flags, CMD_SELL_VEH(old_v->type));
       
  2107 
       
  2108 	if (new_front) {
       
  2109 		/* now we assign the old unitnumber to the new vehicle */
       
  2110 		new_v->unitnumber = cached_unitnumber;
       
  2111 	}
       
  2112 
       
  2113 	/* Transfer the name of the old vehicle */
       
  2114 	if ((flags & DC_EXEC) && vehicle_name[0] != '\0') {
       
  2115 		_cmd_text = vehicle_name;
       
  2116 		DoCommand(0, new_v->index, 0, DC_EXEC, CMD_NAME_VEHICLE);
       
  2117 	}
       
  2118 
       
  2119 	return cost;
       
  2120 }
       
  2121 
       
  2122 /** replaces a vehicle if it's set for autoreplace or is too old
       
  2123  * (used to be called autorenew)
       
  2124  * @param v The vehicle to replace
       
  2125  * if the vehicle is a train, v needs to be the front engine
       
  2126  * @param check Checks if the replace is valid. No action is done at all
       
  2127  * @param display_costs If set, a cost animation is shown (only if check is false)
       
  2128  * @return CMD_ERROR if something went wrong. Otherwise the price of the replace
       
  2129  */
       
  2130 static int32 MaybeReplaceVehicle(Vehicle *v, bool check, bool display_costs)
       
  2131 {
       
  2132 	Vehicle *w;
       
  2133 	const Player *p = GetPlayer(v->owner);
       
  2134 	byte flags = 0;
       
  2135 	int32 cost, temp_cost = 0;
       
  2136 	bool stopped = false;
       
  2137 
       
  2138 	/* Remember the length in case we need to trim train later on
       
  2139 	 * If it's not a train, the value is unused
       
  2140 	 * round up to the length of the tiles used for the train instead of the train length instead
       
  2141 	 * Useful when newGRF uses custom length */
       
  2142 	uint16 old_total_length = (v->type == VEH_Train ?
       
  2143 		(v->u.rail.cached_total_length + TILE_SIZE - 1) / TILE_SIZE * TILE_SIZE :
       
  2144 		-1
       
  2145 	);
       
  2146 
       
  2147 
       
  2148 	_current_player = v->owner;
       
  2149 
       
  2150 	assert(v->type == VEH_Train || v->type == VEH_Road || v->type == VEH_Ship || v->type == VEH_Aircraft);
       
  2151 
       
  2152 	assert(v->vehstatus & VS_STOPPED); // the vehicle should have been stopped in VehicleEnteredDepotThisTick() if needed
       
  2153 
       
  2154 	if (v->leave_depot_instantly) {
       
  2155 		// we stopped the vehicle to do this, so we have to remember to start it again when we are done
       
  2156 		// we need to store this info as the engine might be replaced and lose this info
       
  2157 		stopped = true;
       
  2158 	}
       
  2159 
       
  2160 	for (;;) {
       
  2161 		cost = 0;
       
  2162 		w = v;
       
  2163 		do {
       
  2164 			if (w->type == VEH_Train && IsMultiheaded(w) && !IsTrainEngine(w)) {
       
  2165 				/* we build the rear ends of multiheaded trains with the front ones */
       
  2166 				continue;
       
  2167 			}
       
  2168 
       
  2169 			// check if the vehicle should be replaced
       
  2170 			if (!p->engine_renew ||
       
  2171 					w->age - w->max_age < (p->engine_renew_months * 30) || // replace if engine is too old
       
  2172 					w->max_age == 0) { // rail cars got a max age of 0
       
  2173 				if (!EngineHasReplacementForPlayer(p, w->engine_type)) // updates to a new model
       
  2174 					continue;
       
  2175 			}
       
  2176 
       
  2177 			/* Now replace the vehicle */
       
  2178 			temp_cost = ReplaceVehicle(&w, flags, cost);
       
  2179 
       
  2180 			if (flags & DC_EXEC &&
       
  2181 					(w->type != VEH_Train || w->u.rail.first_engine == INVALID_ENGINE)) {
       
  2182 				/* now we bought a new engine and sold the old one. We need to fix the
       
  2183 				 * pointers in order to avoid pointing to the old one for trains: these
       
  2184 				 * pointers should point to the front engine and not the cars
       
  2185 				 */
       
  2186 				v = w;
       
  2187 			}
       
  2188 
       
  2189 			if (!CmdFailed(temp_cost)) {
       
  2190 				cost += temp_cost;
       
  2191 			}
       
  2192 		} while (w->type == VEH_Train && (w = GetNextVehicle(w)) != NULL);
       
  2193 
       
  2194 		if (!(flags & DC_EXEC) && (p->money64 < (int32)(cost + p->engine_renew_money) || cost == 0)) {
       
  2195 			if (!check && p->money64 < (int32)(cost + p->engine_renew_money) && ( _local_player == v->owner ) && cost != 0) {
       
  2196 				StringID message;
       
  2197 				SetDParam(0, v->unitnumber);
       
  2198 				switch (v->type) {
       
  2199 					case VEH_Train:    message = STR_TRAIN_AUTORENEW_FAILED;       break;
       
  2200 					case VEH_Road:     message = STR_ROADVEHICLE_AUTORENEW_FAILED; break;
       
  2201 					case VEH_Ship:     message = STR_SHIP_AUTORENEW_FAILED;        break;
       
  2202 					case VEH_Aircraft: message = STR_AIRCRAFT_AUTORENEW_FAILED;    break;
       
  2203 						// This should never happen
       
  2204 					default: NOT_REACHED(); message = 0; break;
       
  2205 				}
       
  2206 
       
  2207 				AddNewsItem(message, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
       
  2208 			}
       
  2209 			if (stopped) v->vehstatus &= ~VS_STOPPED;
       
  2210 			if (display_costs) _current_player = OWNER_NONE;
       
  2211 			return CMD_ERROR;
       
  2212 		}
       
  2213 
       
  2214 		if (flags & DC_EXEC) {
       
  2215 			break; // we are done replacing since the loop ran once with DC_EXEC
       
  2216 		} else if (check) {
       
  2217 			/* It's a test only and we know that we can do this
       
  2218 			 * NOTE: payment for wagon removal is NOT included in this price */
       
  2219 			return cost;
       
  2220 		}
       
  2221 		// now we redo the loop, but this time we actually do stuff since we know that we can do it
       
  2222 		flags |= DC_EXEC;
       
  2223 	}
       
  2224 
       
  2225 	/* If setting is on to try not to exceed the old length of the train with the replacement */
       
  2226 	if (v->type == VEH_Train && p->renew_keep_length) {
       
  2227 		Vehicle *temp;
       
  2228 		w = v;
       
  2229 
       
  2230 		while (v->u.rail.cached_total_length > old_total_length) {
       
  2231 			// the train is too long. We will remove cars one by one from the start of the train until it's short enough
       
  2232 			while (w != NULL && !(RailVehInfo(w->engine_type)->flags&RVI_WAGON) ) {
       
  2233 				w = GetNextVehicle(w);
       
  2234 			}
       
  2235 			if (w == NULL) {
       
  2236 				// we failed to make the train short enough
       
  2237 				SetDParam(0, v->unitnumber);
       
  2238 				AddNewsItem(STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
       
  2239 				break;
       
  2240 			}
       
  2241 			temp = w;
       
  2242 			w = GetNextVehicle(w);
       
  2243 			DoCommand(0, (INVALID_VEHICLE << 16) | temp->index, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
       
  2244 			MoveVehicleCargo(v, temp);
       
  2245 			cost += DoCommand(0, temp->index, 0, DC_EXEC, CMD_SELL_RAIL_WAGON);
       
  2246 		}
       
  2247 	}
       
  2248 
       
  2249 	if (stopped) v->vehstatus &= ~VS_STOPPED;
       
  2250 	if (display_costs) {
       
  2251 		if (IsLocalPlayer()) ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost);
       
  2252 		_current_player = OWNER_NONE;
       
  2253 	}
       
  2254 	return cost;
       
  2255 }
       
  2256 
       
  2257 /* Extend the list size for BuildDepotVehicleList() */
       
  2258 static inline void ExtendVehicleListSize(const Vehicle ***engine_list, uint16 *engine_list_length, uint16 step_size)
       
  2259 {
       
  2260 	*engine_list_length = min(*engine_list_length + step_size, GetMaxVehicleIndex() + 1);
       
  2261 	*engine_list = realloc((void*)*engine_list, (*engine_list_length) * sizeof((*engine_list)[0]));
       
  2262 }
       
  2263 
       
  2264 /** Generates a list of vehicles inside a depot
       
  2265  * Will enlarge allocated space for the list if they are too small, so it's ok to call with (pointer to NULL array, pointer to uninitised uint16, pointer to 0)
       
  2266  * If one of the lists is not needed (say wagons when finding ships), all the pointers regarding that list should be set to NULL
       
  2267  * @param Type type of vehicle
       
  2268  * @param tile The tile the depot is located in
       
  2269  * @param ***engine_list Pointer to a pointer to an array of vehicles in the depot (old list is freed and a new one is malloced)
       
  2270  * @param *engine_list_length Allocated size of engine_list. Needs to be set to 0 when engine_list points to a NULL array
       
  2271  * @param *engine_count The number of engines stored in the list
       
  2272  * @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)
       
  2273  * @param *wagon_list_length Allocated size of wagon_list. Needs to be set to 0 when wagon_list points to a NULL array
       
  2274  * @param *wagon_count The number of engines stored in the list
       
  2275  */
       
  2276 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)
       
  2277 {
       
  2278 	Vehicle *v;
       
  2279 
       
  2280 	/* This function should never be called without an array to store results */
       
  2281 	assert(!(engine_list == NULL && type != VEH_Train));
       
  2282 	assert(!(type == VEH_Train && engine_list == NULL && wagon_list == NULL));
       
  2283 
       
  2284 	/* Both array and the length should either be NULL to disable the list or both should not be NULL */
       
  2285 	assert((engine_list == NULL && engine_list_length == NULL) || (engine_list != NULL && engine_list_length != NULL));
       
  2286 	assert((wagon_list == NULL && wagon_list_length == NULL) || (wagon_list != NULL && wagon_list_length != NULL));
       
  2287 
       
  2288 	assert(!(engine_list != NULL && engine_count == NULL));
       
  2289 	assert(!(wagon_list != NULL && wagon_count == NULL));
       
  2290 
       
  2291 	if (engine_count != NULL) *engine_count = 0;
       
  2292 	if (wagon_count != NULL) *wagon_count = 0;
       
  2293 
       
  2294 	switch (type) {
       
  2295 		case VEH_Train:
       
  2296 			FOR_ALL_VEHICLES(v) {
       
  2297 				if (v->tile == tile && v->type == VEH_Train && v->u.rail.track == 0x80) {
       
  2298 					if (IsFrontEngine(v)) {
       
  2299 						if (engine_list == NULL) continue;
       
  2300 						if (*engine_count == *engine_list_length) ExtendVehicleListSize((const Vehicle***)engine_list, engine_list_length, 25);
       
  2301 						(*engine_list)[(*engine_count)++] = v;
       
  2302 					} else if (IsFreeWagon(v)) {
       
  2303 						if (wagon_list == NULL) continue;
       
  2304 						if (*wagon_count == *wagon_list_length) ExtendVehicleListSize((const Vehicle***)wagon_list, wagon_list_length, 25);
       
  2305 						(*wagon_list)[(*wagon_count)++] = v;
       
  2306 					}
       
  2307 				}
       
  2308 			}
       
  2309 			break;
       
  2310 
       
  2311 		case VEH_Road:
       
  2312 			FOR_ALL_VEHICLES(v) {
       
  2313 				if (v->tile == tile && v->type == VEH_Road && IsRoadVehInDepot(v)) {
       
  2314 					if (*engine_count == *engine_list_length) ExtendVehicleListSize((const Vehicle***)engine_list, engine_list_length, 25);
       
  2315 					(*engine_list)[(*engine_count)++] = v;
       
  2316 				}
       
  2317 			}
       
  2318 			break;
       
  2319 
       
  2320 		case VEH_Ship:
       
  2321 			FOR_ALL_VEHICLES(v) {
       
  2322 				if (v->tile == tile && v->type == VEH_Ship && IsShipInDepot(v)) {
       
  2323 					if (*engine_count == *engine_list_length) ExtendVehicleListSize((const Vehicle***)engine_list, engine_list_length, 25);
       
  2324 					(*engine_list)[(*engine_count)++] = v;
       
  2325 				}
       
  2326 			}
       
  2327 			break;
       
  2328 
       
  2329 		case VEH_Aircraft:
       
  2330 			FOR_ALL_VEHICLES(v) {
       
  2331 				if (v->tile == tile &&
       
  2332 						v->type == VEH_Aircraft &&
       
  2333 						v->subtype <= 2 &&
       
  2334 						v->vehstatus & VS_HIDDEN) {
       
  2335 					if (*engine_count == *engine_list_length) ExtendVehicleListSize((const Vehicle***)engine_list, engine_list_length, 25);
       
  2336 					(*engine_list)[(*engine_count)++] = v;
       
  2337 				}
       
  2338 			}
       
  2339 			break;
       
  2340 
       
  2341 		default: NOT_REACHED();
       
  2342 	}
       
  2343 }
       
  2344 
       
  2345 /**
       
  2346 * @param sort_list list to store the list in. Either NULL or the length length_of_array tells
       
  2347 * @param length_of_array informs the length allocated for sort_list. This is not the same as the number of vehicles in the list. Needs to be 0 when sort_list is NULL
       
  2348 * @param type type of vehicle
       
  2349 * @param owner PlayerID of owner to generate a list for
       
  2350 * @param station index of station to generate a list for. INVALID_STATION when not used
       
  2351 * @param order index of oder to generate a list for. INVALID_ORDER when not used
       
  2352 * @param window_type tells what kind of window the list is for. Use the VLW flags in vehicle_gui.h
       
  2353 * @return the number of vehicles added to the list
       
  2354 */
       
  2355 uint GenerateVehicleSortList(const Vehicle ***sort_list, uint16 *length_of_array, byte type, PlayerID owner, StationID station, OrderID order, uint16 depot_airport_index, uint16 window_type)
       
  2356 {
       
  2357 	const uint subtype = (type != VEH_Aircraft) ? Train_Front : 2;
       
  2358 	uint n = 0;
       
  2359 	const Vehicle *v;
       
  2360 
       
  2361 	switch (window_type) {
       
  2362 		case VLW_STATION_LIST: {
       
  2363 			FOR_ALL_VEHICLES(v) {
       
  2364 				if (v->type == type && (
       
  2365 					(type == VEH_Train && IsFrontEngine(v)) ||
       
  2366 					(type != VEH_Train && v->subtype <= subtype))) {
       
  2367 					const Order *order;
       
  2368 
       
  2369 					FOR_VEHICLE_ORDERS(v, order) {
       
  2370 						if (order->type == OT_GOTO_STATION && order->dest == station) {
       
  2371 							if (n == *length_of_array) ExtendVehicleListSize(sort_list, length_of_array, 50);
       
  2372 							(*sort_list)[n++] = v;
       
  2373 							break;
       
  2374 						}
       
  2375 					}
       
  2376 				}
       
  2377 			}
       
  2378 			break;
       
  2379 		}
       
  2380 
       
  2381 		case VLW_SHARED_ORDERS: {
       
  2382 			FOR_ALL_VEHICLES(v) {
       
  2383 				/* Find a vehicle with the order in question */
       
  2384 				if (v->orders != NULL && v->orders->index == order) break;
       
  2385 			}
       
  2386 
       
  2387 			if (v != NULL && v->orders != NULL && v->orders->index == order) {
       
  2388 				/* Only try to make the list if we found a vehicle using the order in question */
       
  2389 				for (v = GetFirstVehicleFromSharedList(v); v != NULL; v = v->next_shared) {
       
  2390 					if (n == *length_of_array) ExtendVehicleListSize(sort_list, length_of_array, 25);
       
  2391 					(*sort_list)[n++] = v;
       
  2392 				}
       
  2393 			}
       
  2394 			break;
       
  2395 		}
       
  2396 
       
  2397 		case VLW_STANDARD: {
       
  2398 			FOR_ALL_VEHICLES(v) {
       
  2399 				if (v->type == type && v->owner == owner && (
       
  2400 					(type == VEH_Train && IsFrontEngine(v)) ||
       
  2401 					(type != VEH_Train && v->subtype <= subtype))) {
       
  2402 					/* TODO find a better estimate on the total number of vehicles for current player */
       
  2403 					if (n == *length_of_array) ExtendVehicleListSize(sort_list, length_of_array, GetNumVehicles()/4);
       
  2404 					(*sort_list)[n++] = v;
       
  2405 				}
       
  2406 			}
       
  2407 			break;
       
  2408 		}
       
  2409 
       
  2410 		case VLW_DEPOT_LIST: {
       
  2411 			FOR_ALL_VEHICLES(v) {
       
  2412 				if (v->type == type && (
       
  2413 					(type == VEH_Train && IsFrontEngine(v)) ||
       
  2414 					(type != VEH_Train && v->subtype <= subtype))) {
       
  2415 					const Order *order;
       
  2416 
       
  2417 					FOR_VEHICLE_ORDERS(v, order) {
       
  2418 						if (order->type == OT_GOTO_DEPOT && order->dest == depot_airport_index) {
       
  2419 							if (n == *length_of_array) ExtendVehicleListSize(sort_list, length_of_array, 25);
       
  2420 							(*sort_list)[n++] = v;
       
  2421 							break;
       
  2422 						}
       
  2423 					}
       
  2424 				}
       
  2425 			}
       
  2426 			break;
       
  2427 		}
       
  2428 
       
  2429 		default: NOT_REACHED(); break;
       
  2430 	}
       
  2431 
       
  2432 	if ((n + 100) < *length_of_array) {
       
  2433 		/* We allocated way too much for sort_list.
       
  2434 		 * Now we will reduce how much we allocated.
       
  2435 		 * We will still make it have room for 50 extra vehicles to prevent having
       
  2436 		 * to move the whole array if just one vehicle is added later */
       
  2437 		*length_of_array = n + 50;
       
  2438 		*sort_list = realloc((void*)*sort_list, (*length_of_array) * sizeof((*sort_list)[0]));
       
  2439 	}
       
  2440 
       
  2441 	return n;
       
  2442 }
       
  2443 
       
  2444 /** send all vehicles of type to depots
       
  2445  * @param type type of vehicle
       
  2446  * @param flags the flags used for DoCommand()
       
  2447  * @param service should the vehicles only get service in the depots
       
  2448  * @param owner PlayerID of owner of the vehicles to send
       
  2449  * @param VLW_flag tells what kind of list requested the goto depot
       
  2450  * @return 0 for success and CMD_ERROR if no vehicle is able to go to depot
       
  2451  */
       
  2452 int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id)
       
  2453 {
       
  2454 	const Vehicle **sort_list = NULL;
       
  2455 	uint n, i;
       
  2456 	uint16 array_length = 0;
       
  2457 
       
  2458 	n = GenerateVehicleSortList(&sort_list, &array_length, type, owner, id, id, id, vlw_flag);
       
  2459 
       
  2460 	/* Send all the vehicles to a depot */
       
  2461 	for (i = 0; i < n; i++) {
       
  2462 		const Vehicle *v = sort_list[i];
       
  2463 		int32 ret = DoCommand(v->tile, v->index, service | DEPOT_DONT_CANCEL, flags, CMD_SEND_TO_DEPOT(type));
       
  2464 
       
  2465 		/* Return 0 if DC_EXEC is not set this is a valid goto depot command)
       
  2466 			* In this case we know that at least one vehicle can be sent to a depot
       
  2467 			* and we will issue the command. We can now safely quit the loop, knowing
       
  2468 			* it will succeed at least once. With DC_EXEC we really need to send them to the depot */
       
  2469 		if (!CmdFailed(ret) && !(flags & DC_EXEC)) {
       
  2470 			free((void*)sort_list);
       
  2471 			return 0;
       
  2472 		}
       
  2473 	}
       
  2474 
       
  2475 	free((void*)sort_list);
       
  2476 	return (flags & DC_EXEC) ? 0 : CMD_ERROR;
       
  2477 }
       
  2478 
       
  2479 bool IsVehicleInDepot(const Vehicle *v)
       
  2480 {
       
  2481 	switch (v->type) {
       
  2482 		case VEH_Train:    return CheckTrainInDepot(v, false) != -1;
       
  2483 		case VEH_Road:     return IsRoadVehInDepot(v);
       
  2484 		case VEH_Ship:     return IsShipInDepot(v);
       
  2485 		case VEH_Aircraft: return IsAircraftInHangar(v);
       
  2486 		default: NOT_REACHED();
       
  2487 	}
       
  2488 	return false;
       
  2489 }
       
  2490 
       
  2491 void VehicleEnterDepot(Vehicle *v)
       
  2492 {
       
  2493 	switch (v->type) {
       
  2494 		case VEH_Train:
       
  2495 			InvalidateWindowClasses(WC_TRAINS_LIST);
       
  2496 			if (!IsFrontEngine(v)) v = GetFirstVehicleInChain(v);
       
  2497 			UpdateSignalsOnSegment(v->tile, GetRailDepotDirection(v->tile));
       
  2498 			v->load_unload_time_rem = 0;
       
  2499 			break;
       
  2500 
       
  2501 		case VEH_Road:
       
  2502 			InvalidateWindowClasses(WC_ROADVEH_LIST);
       
  2503 			v->u.road.state = 254;
       
  2504 			break;
       
  2505 
       
  2506 		case VEH_Ship:
       
  2507 			InvalidateWindowClasses(WC_SHIPS_LIST);
       
  2508 			v->u.ship.state = 0x80;
       
  2509 			RecalcShipStuff(v);
       
  2510 			break;
       
  2511 
       
  2512 		case VEH_Aircraft:
       
  2513 			InvalidateWindowClasses(WC_AIRCRAFT_LIST);
       
  2514 			HandleAircraftEnterHangar(v);
       
  2515 			break;
       
  2516 		default: NOT_REACHED();
       
  2517 	}
       
  2518 
       
  2519 	if (v->type != VEH_Train) {
       
  2520 		/* Trains update the vehicle list when the first unit enters the depot and calls VehicleEnterDepot() when the last unit enters.
       
  2521 		 * We only increase the number of vehicles when the first one enters, so we will not need to search for more vehicles in the depot */
       
  2522 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
       
  2523 	}
       
  2524 	InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
       
  2525 
       
  2526 	v->vehstatus |= VS_HIDDEN;
       
  2527 	v->cur_speed = 0;
       
  2528 
       
  2529 	VehicleServiceInDepot(v);
       
  2530 
       
  2531 	TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
       
  2532 
       
  2533 	if (v->current_order.type == OT_GOTO_DEPOT) {
       
  2534 		Order t;
       
  2535 
       
  2536 		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
       
  2537 
       
  2538 		t = v->current_order;
       
  2539 		v->current_order.type = OT_DUMMY;
       
  2540 		v->current_order.flags = 0;
       
  2541 
       
  2542 		if (t.refit_cargo < NUM_CARGO) {
       
  2543 			int32 cost;
       
  2544 
       
  2545 			_current_player = v->owner;
       
  2546 			cost = DoCommand(v->tile, v->index, t.refit_cargo | t.refit_subtype << 8, DC_EXEC, CMD_REFIT_VEH(v->type));
       
  2547 
       
  2548 			if (CmdFailed(cost)) {
       
  2549 				v->leave_depot_instantly = false; // We ensure that the vehicle stays in the depot
       
  2550 				if (v->owner == _local_player) {
       
  2551 					/* Notify the user that we stopped the vehicle */
       
  2552 					SetDParam(0, _vehicle_type_names[v->type - 0x10]);
       
  2553 					SetDParam(1, v->unitnumber);
       
  2554 					AddNewsItem(STR_ORDER_REFIT_FAILED, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
       
  2555 				}
       
  2556 			} else if (v->owner == _local_player && cost != 0) {
       
  2557 				ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost);
       
  2558 			}
       
  2559 		}
       
  2560 
       
  2561 		if (HASBIT(t.flags, OFB_PART_OF_ORDERS)) {
       
  2562 			/* Part of orders */
       
  2563 			if (v->type == VEH_Train) v->u.rail.days_since_order_progr = 0;
       
  2564 			v->cur_order_index++;
       
  2565 		} else if (HASBIT(t.flags, OFB_HALT_IN_DEPOT)) {
       
  2566 			/* Force depot visit */
       
  2567 			v->vehstatus |= VS_STOPPED;
       
  2568 			if (v->owner == _local_player) {
       
  2569 				StringID string;
       
  2570 
       
  2571 				switch (v->type) {
       
  2572 					case VEH_Train:    string = STR_8814_TRAIN_IS_WAITING_IN_DEPOT; break;
       
  2573 					case VEH_Road:     string = STR_9016_ROAD_VEHICLE_IS_WAITING;   break;
       
  2574 					case VEH_Ship:     string = STR_981C_SHIP_IS_WAITING_IN_DEPOT;  break;
       
  2575 					case VEH_Aircraft: string = STR_A014_AIRCRAFT_IS_WAITING_IN;    break;
       
  2576 					default: NOT_REACHED(); string = STR_EMPTY; // Set the string to something to avoid a compiler warning
       
  2577 				}
       
  2578 
       
  2579 				SetDParam(0, v->unitnumber);
       
  2580 				AddNewsItem(string, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0),	v->index, 0);
       
  2581 			}
       
  2582 		}
       
  2583 	}
       
  2584 }
       
  2585 
       
  2586 /** Give a custom name to your vehicle
       
  2587  * @param tile unused
       
  2588  * @param p1 vehicle ID to name
       
  2589  * @param p2 unused
       
  2590  */
       
  2591 int32 CmdNameVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
  2592 {
       
  2593 	Vehicle *v;
       
  2594 	StringID str;
       
  2595 
       
  2596 	if (!IsValidVehicleID(p1) || _cmd_text[0] == '\0') return CMD_ERROR;
       
  2597 
       
  2598 	v = GetVehicle(p1);
       
  2599 
       
  2600 	if (!CheckOwnership(v->owner)) return CMD_ERROR;
       
  2601 
       
  2602 	str = AllocateNameUnique(_cmd_text, 2);
       
  2603 	if (str == 0) return CMD_ERROR;
       
  2604 
       
  2605 	if (flags & DC_EXEC) {
       
  2606 		StringID old_str = v->string_id;
       
  2607 		v->string_id = str;
       
  2608 		DeleteName(old_str);
       
  2609 		ResortVehicleLists();
       
  2610 		MarkWholeScreenDirty();
       
  2611 	} else {
       
  2612 		DeleteName(str);
       
  2613 	}
       
  2614 
       
  2615 	return 0;
       
  2616 }
       
  2617 
       
  2618 
       
  2619 /** Change the service interval of a vehicle
       
  2620  * @param tile unused
       
  2621  * @param p1 vehicle ID that is being service-interval-changed
       
  2622  * @param p2 new service interval
       
  2623  */
       
  2624 int32 CmdChangeServiceInt(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
  2625 {
       
  2626 	Vehicle* v;
       
  2627 	uint16 serv_int = GetServiceIntervalClamped(p2); /* Double check the service interval from the user-input */
       
  2628 
       
  2629 	if (serv_int != p2 || !IsValidVehicleID(p1)) return CMD_ERROR;
       
  2630 
       
  2631 	v = GetVehicle(p1);
       
  2632 
       
  2633 	if (!CheckOwnership(v->owner)) return CMD_ERROR;
       
  2634 
       
  2635 	if (flags & DC_EXEC) {
       
  2636 		v->service_interval = serv_int;
       
  2637 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
       
  2638 	}
       
  2639 
       
  2640 	return 0;
       
  2641 }
       
  2642 
       
  2643 
       
  2644 static Rect _old_vehicle_coords;
       
  2645 
       
  2646 void BeginVehicleMove(Vehicle *v) {
       
  2647 	_old_vehicle_coords.left = v->left_coord;
       
  2648 	_old_vehicle_coords.top = v->top_coord;
       
  2649 	_old_vehicle_coords.right = v->right_coord;
       
  2650 	_old_vehicle_coords.bottom = v->bottom_coord;
       
  2651 }
       
  2652 
       
  2653 void EndVehicleMove(Vehicle *v)
       
  2654 {
       
  2655 	MarkAllViewportsDirty(
       
  2656 		min(_old_vehicle_coords.left,v->left_coord),
       
  2657 		min(_old_vehicle_coords.top,v->top_coord),
       
  2658 		max(_old_vehicle_coords.right,v->right_coord)+1,
       
  2659 		max(_old_vehicle_coords.bottom,v->bottom_coord)+1
       
  2660 	);
       
  2661 }
       
  2662 
       
  2663 /* returns true if staying in the same tile */
       
  2664 bool GetNewVehiclePos(const Vehicle *v, GetNewVehiclePosResult *gp)
       
  2665 {
       
  2666 	static const int8 _delta_coord[16] = {
       
  2667 		-1,-1,-1, 0, 1, 1, 1, 0, /* x */
       
  2668 		-1, 0, 1, 1, 1, 0,-1,-1, /* y */
       
  2669 	};
       
  2670 
       
  2671 	int x = v->x_pos + _delta_coord[v->direction];
       
  2672 	int y = v->y_pos + _delta_coord[v->direction + 8];
       
  2673 
       
  2674 	gp->x = x;
       
  2675 	gp->y = y;
       
  2676 	gp->old_tile = v->tile;
       
  2677 	gp->new_tile = TileVirtXY(x, y);
       
  2678 	return gp->old_tile == gp->new_tile;
       
  2679 }
       
  2680 
       
  2681 static const Direction _new_direction_table[] = {
       
  2682 	DIR_N , DIR_NW, DIR_W ,
       
  2683 	DIR_NE, DIR_SE, DIR_SW,
       
  2684 	DIR_E , DIR_SE, DIR_S
       
  2685 };
       
  2686 
       
  2687 Direction GetDirectionTowards(const Vehicle* v, int x, int y)
       
  2688 {
       
  2689 	Direction dir;
       
  2690 	DirDiff dirdiff;
       
  2691 	int i = 0;
       
  2692 
       
  2693 	if (y >= v->y_pos) {
       
  2694 		if (y != v->y_pos) i+=3;
       
  2695 		i+=3;
       
  2696 	}
       
  2697 
       
  2698 	if (x >= v->x_pos) {
       
  2699 		if (x != v->x_pos) i++;
       
  2700 		i++;
       
  2701 	}
       
  2702 
       
  2703 	dir = v->direction;
       
  2704 
       
  2705 	dirdiff = DirDifference(_new_direction_table[i], dir);
       
  2706 	if (dirdiff == DIRDIFF_SAME) return dir;
       
  2707 	return ChangeDir(dir, dirdiff > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
       
  2708 }
       
  2709 
       
  2710 Trackdir GetVehicleTrackdir(const Vehicle* v)
       
  2711 {
       
  2712 	if (v->vehstatus & VS_CRASHED) return 0xFF;
       
  2713 
       
  2714 	switch (v->type) {
       
  2715 		case VEH_Train:
       
  2716 			if (v->u.rail.track == 0x80) /* We'll assume the train is facing outwards */
       
  2717 				return DiagdirToDiagTrackdir(GetRailDepotDirection(v->tile)); /* Train in depot */
       
  2718 
       
  2719 			if (v->u.rail.track == 0x40) /* train in tunnel, so just use his direction and assume a diagonal track */
       
  2720 				return DiagdirToDiagTrackdir(DirToDiagDir(v->direction));
       
  2721 
       
  2722 			return TrackDirectionToTrackdir(FIND_FIRST_BIT(v->u.rail.track),v->direction);
       
  2723 
       
  2724 		case VEH_Ship:
       
  2725 			if (IsShipInDepot(v))
       
  2726 				/* We'll assume the ship is facing outwards */
       
  2727 				return DiagdirToDiagTrackdir(GetShipDepotDirection(v->tile));
       
  2728 
       
  2729 			return TrackDirectionToTrackdir(FIND_FIRST_BIT(v->u.ship.state),v->direction);
       
  2730 
       
  2731 		case VEH_Road:
       
  2732 			if (IsRoadVehInDepot(v)) /* We'll assume the road vehicle is facing outwards */
       
  2733 				return DiagdirToDiagTrackdir(GetRoadDepotDirection(v->tile));
       
  2734 
       
  2735 			if (IsRoadStopTile(v->tile)) /* We'll assume the road vehicle is facing outwards */
       
  2736 				return DiagdirToDiagTrackdir(GetRoadStopDir(v->tile)); /* Road vehicle in a station */
       
  2737 
       
  2738 			/* If vehicle's state is a valid track direction (vehicle is not turning around) return it */
       
  2739 			if ((v->u.road.state & 7) < 6) return v->u.road.state;
       
  2740 
       
  2741 			/* Vehicle is turning around, get the direction from vehicle's direction */
       
  2742 			return DiagdirToDiagTrackdir(DirToDiagDir(v->direction));
       
  2743 
       
  2744 		/* case VEH_Aircraft: case VEH_Special: case VEH_Disaster: */
       
  2745 		default: return 0xFF;
       
  2746 	}
       
  2747 }
       
  2748 /* Return value has bit 0x2 set, when the vehicle enters a station. Then,
       
  2749  * result << 8 contains the id of the station entered. If the return value has
       
  2750  * bit 0x8 set, the vehicle could not and did not enter the tile. Are there
       
  2751  * other bits that can be set? */
       
  2752 uint32 VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y)
       
  2753 {
       
  2754 	return _tile_type_procs[GetTileType(tile)]->vehicle_enter_tile_proc(v, tile, x, y);
       
  2755 }
       
  2756 
       
  2757 UnitID GetFreeUnitNumber(byte type)
       
  2758 {
       
  2759 	UnitID unit, max = 0;
       
  2760 	const Vehicle *u;
       
  2761 	static bool *cache = NULL;
       
  2762 	static UnitID gmax = 0;
       
  2763 
       
  2764 	switch (type) {
       
  2765 		case VEH_Train:    max = _patches.max_trains; break;
       
  2766 		case VEH_Road:     max = _patches.max_roadveh; break;
       
  2767 		case VEH_Ship:     max = _patches.max_ships; break;
       
  2768 		case VEH_Aircraft: max = _patches.max_aircraft; break;
       
  2769 		default: NOT_REACHED();
       
  2770 	}
       
  2771 
       
  2772 	if (max == 0) {
       
  2773 		/* we can't build any of this kind of vehicle, so we just return 1 instead of looking for a free number
       
  2774 		 * a max of 0 will cause the following code to write to a NULL pointer
       
  2775 		 * We know that 1 is bigger than the max allowed vehicle number, so it's the same as returning something, that is too big
       
  2776 		 */
       
  2777 		return 1;
       
  2778 	}
       
  2779 
       
  2780 	if (max > gmax) {
       
  2781 		gmax = max;
       
  2782 		free(cache);
       
  2783 		cache = malloc((max + 1) * sizeof(*cache));
       
  2784 	}
       
  2785 
       
  2786 	// Clear the cache
       
  2787 	memset(cache, 0, (max + 1) * sizeof(*cache));
       
  2788 
       
  2789 	// Fill the cache
       
  2790 	FOR_ALL_VEHICLES(u) {
       
  2791 		if (u->type == type && u->owner == _current_player && u->unitnumber != 0 && u->unitnumber <= max)
       
  2792 			cache[u->unitnumber] = true;
       
  2793 	}
       
  2794 
       
  2795 	// Find the first unused unit number
       
  2796 	for (unit = 1; unit <= max; unit++) {
       
  2797 		if (!cache[unit]) break;
       
  2798 	}
       
  2799 
       
  2800 	return unit;
       
  2801 }
       
  2802 
       
  2803 static PalSpriteID GetEngineColourMap(EngineID engine_type, PlayerID player, EngineID parent_engine_type, CargoID cargo_type)
       
  2804 {
       
  2805 	SpriteID map;
       
  2806 	const Player *p = GetPlayer(player);
       
  2807 	LiveryScheme scheme = LS_DEFAULT;
       
  2808 
       
  2809 	/* The default livery is always available for use, but its in_use flag determines
       
  2810 	 * whether any _other_ liveries are in use. */
       
  2811 	if (p->livery[LS_DEFAULT].in_use && (_patches.liveries == 2 || (_patches.liveries == 1 && player == _local_player))) {
       
  2812 		/* Determine the livery scheme to use */
       
  2813 		switch (GetEngine(engine_type)->type) {
       
  2814 			case VEH_Train: {
       
  2815 				switch (_engine_info[engine_type].railtype) {
       
  2816 					case RAILTYPE_RAIL:
       
  2817 					case RAILTYPE_ELECTRIC:
       
  2818 					{
       
  2819 						const RailVehicleInfo *rvi = RailVehInfo(engine_type);
       
  2820 
       
  2821 						if (cargo_type == CT_INVALID) cargo_type = rvi->cargo_type;
       
  2822 						if (rvi->flags & RVI_WAGON) {
       
  2823 							if (cargo_type == CT_PASSENGERS || cargo_type == CT_MAIL || cargo_type == CT_VALUABLES) {
       
  2824 								if (parent_engine_type == INVALID_ENGINE) {
       
  2825 									scheme = LS_PASSENGER_WAGON_STEAM;
       
  2826 								} else {
       
  2827 									switch (RailVehInfo(parent_engine_type)->engclass) {
       
  2828 										case 0: scheme = LS_PASSENGER_WAGON_STEAM; break;
       
  2829 										case 1: scheme = LS_PASSENGER_WAGON_DIESEL; break;
       
  2830 										case 2: scheme = LS_PASSENGER_WAGON_ELECTRIC; break;
       
  2831 									}
       
  2832 								}
       
  2833 							} else {
       
  2834 								scheme = LS_FREIGHT_WAGON;
       
  2835 							}
       
  2836 						} else {
       
  2837 							bool is_mu = HASBIT(_engine_info[engine_type].misc_flags, EF_RAIL_IS_MU);
       
  2838 
       
  2839 							switch (rvi->engclass) {
       
  2840 								case 0: scheme = LS_STEAM; break;
       
  2841 								case 1: scheme = is_mu ? LS_DMU : LS_DIESEL; break;
       
  2842 								case 2: scheme = is_mu ? LS_EMU : LS_ELECTRIC; break;
       
  2843 							}
       
  2844 						}
       
  2845 						break;
       
  2846 					}
       
  2847 
       
  2848 					case RAILTYPE_MONO: scheme = LS_MONORAIL; break;
       
  2849 					case RAILTYPE_MAGLEV: scheme = LS_MAGLEV; break;
       
  2850 				}
       
  2851 				break;
       
  2852 			}
       
  2853 
       
  2854 			case VEH_Road: {
       
  2855 				const RoadVehicleInfo *rvi = RoadVehInfo(engine_type);
       
  2856 				if (cargo_type == CT_INVALID) cargo_type = rvi->cargo_type;
       
  2857 				scheme = (cargo_type == CT_PASSENGERS) ? LS_BUS : LS_TRUCK;
       
  2858 				break;
       
  2859 			}
       
  2860 
       
  2861 			case VEH_Ship: {
       
  2862 				const ShipVehicleInfo *svi = ShipVehInfo(engine_type);
       
  2863 				if (cargo_type == CT_INVALID) cargo_type = svi->cargo_type;
       
  2864 				scheme = (cargo_type == CT_PASSENGERS) ? LS_PASSENGER_SHIP : LS_FREIGHT_SHIP;
       
  2865 				break;
       
  2866 			}
       
  2867 
       
  2868 			case VEH_Aircraft: {
       
  2869 				const AircraftVehicleInfo *avi = AircraftVehInfo(engine_type);
       
  2870 				if (cargo_type == CT_INVALID) cargo_type = CT_PASSENGERS;
       
  2871 				switch (avi->subtype) {
       
  2872 					case 0: scheme = LS_HELICOPTER; break;
       
  2873 					case 1: scheme = LS_SMALL_PLANE; break;
       
  2874 					case 3: scheme = LS_LARGE_PLANE; break;
       
  2875 				}
       
  2876 				break;
       
  2877 			}
       
  2878 		}
       
  2879 
       
  2880 		/* Switch back to the default scheme if the resolved scheme is not in use */
       
  2881 		if (!p->livery[scheme].in_use) scheme = LS_DEFAULT;
       
  2882 	}
       
  2883 
       
  2884 	map = HASBIT(EngInfo(engine_type)->misc_flags, EF_USES_2CC) ?
       
  2885 		(SPR_2CCMAP_BASE + p->livery[scheme].colour1 + p->livery[scheme].colour2 * 16) :
       
  2886 		(PALETTE_RECOLOR_START + p->livery[scheme].colour1);
       
  2887 
       
  2888 	return SPRITE_PALETTE(map << PALETTE_SPRITE_START);
       
  2889 }
       
  2890 
       
  2891 PalSpriteID GetEnginePalette(EngineID engine_type, PlayerID player)
       
  2892 {
       
  2893 	return GetEngineColourMap(engine_type, player, INVALID_ENGINE, CT_INVALID);
       
  2894 }
       
  2895 
       
  2896 PalSpriteID GetVehiclePalette(const Vehicle *v)
       
  2897 {
       
  2898 	if (v->type == VEH_Train) {
       
  2899 		return GetEngineColourMap(
       
  2900 			(v->u.rail.first_engine != INVALID_ENGINE && (IsArticulatedPart(v) || UsesWagonOverride(v))) ?
       
  2901 				v->u.rail.first_engine : v->engine_type,
       
  2902 			v->owner,
       
  2903 			v->u.rail.first_engine,
       
  2904 			v->cargo_type);
       
  2905 	}
       
  2906 
       
  2907 	return GetEngineColourMap(v->engine_type, v->owner, INVALID_ENGINE, v->cargo_type);
       
  2908 }
       
  2909 
       
  2910 // Save and load of vehicles
       
  2911 const SaveLoad _common_veh_desc[] = {
       
  2912 	    SLE_VAR(Vehicle, subtype,              SLE_UINT8),
       
  2913 
       
  2914 	    SLE_REF(Vehicle, next,                 REF_VEHICLE_OLD),
       
  2915 	    SLE_VAR(Vehicle, string_id,            SLE_STRINGID),
       
  2916 	SLE_CONDVAR(Vehicle, unitnumber,           SLE_FILE_U8  | SLE_VAR_U16,  0, 7),
       
  2917 	SLE_CONDVAR(Vehicle, unitnumber,           SLE_UINT16,                  8, SL_MAX_VERSION),
       
  2918 	    SLE_VAR(Vehicle, owner,                SLE_UINT8),
       
  2919 	SLE_CONDVAR(Vehicle, tile,                 SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
       
  2920 	SLE_CONDVAR(Vehicle, tile,                 SLE_UINT32,                  6, SL_MAX_VERSION),
       
  2921 	SLE_CONDVAR(Vehicle, dest_tile,            SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
       
  2922 	SLE_CONDVAR(Vehicle, dest_tile,            SLE_UINT32,                  6, SL_MAX_VERSION),
       
  2923 
       
  2924 	SLE_CONDVAR(Vehicle, x_pos,                SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
       
  2925 	SLE_CONDVAR(Vehicle, x_pos,                SLE_UINT32,                  6, SL_MAX_VERSION),
       
  2926 	SLE_CONDVAR(Vehicle, y_pos,                SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
       
  2927 	SLE_CONDVAR(Vehicle, y_pos,                SLE_UINT32,                  6, SL_MAX_VERSION),
       
  2928 	    SLE_VAR(Vehicle, z_pos,                SLE_UINT8),
       
  2929 	    SLE_VAR(Vehicle, direction,            SLE_UINT8),
       
  2930 
       
  2931 	    SLE_VAR(Vehicle, cur_image,            SLE_UINT16),
       
  2932 	    SLE_VAR(Vehicle, spritenum,            SLE_UINT8),
       
  2933 	    SLE_VAR(Vehicle, sprite_width,         SLE_UINT8),
       
  2934 	    SLE_VAR(Vehicle, sprite_height,        SLE_UINT8),
       
  2935 	    SLE_VAR(Vehicle, z_height,             SLE_UINT8),
       
  2936 	    SLE_VAR(Vehicle, x_offs,               SLE_INT8),
       
  2937 	    SLE_VAR(Vehicle, y_offs,               SLE_INT8),
       
  2938 	    SLE_VAR(Vehicle, engine_type,          SLE_UINT16),
       
  2939 
       
  2940 	    SLE_VAR(Vehicle, max_speed,            SLE_UINT16),
       
  2941 	    SLE_VAR(Vehicle, cur_speed,            SLE_UINT16),
       
  2942 	    SLE_VAR(Vehicle, subspeed,             SLE_UINT8),
       
  2943 	    SLE_VAR(Vehicle, acceleration,         SLE_UINT8),
       
  2944 	    SLE_VAR(Vehicle, progress,             SLE_UINT8),
       
  2945 
       
  2946 	    SLE_VAR(Vehicle, vehstatus,            SLE_UINT8),
       
  2947 	SLE_CONDVAR(Vehicle, last_station_visited, SLE_FILE_U8  | SLE_VAR_U16,  0, 4),
       
  2948 	SLE_CONDVAR(Vehicle, last_station_visited, SLE_UINT16,                  5, SL_MAX_VERSION),
       
  2949 
       
  2950 	    SLE_VAR(Vehicle, cargo_type,           SLE_UINT8),
       
  2951 	SLE_CONDVAR(Vehicle, cargo_subtype,        SLE_UINT8,                  35, SL_MAX_VERSION),
       
  2952 	    SLE_VAR(Vehicle, cargo_days,           SLE_UINT8),
       
  2953 	SLE_CONDVAR(Vehicle, cargo_source,         SLE_FILE_U8  | SLE_VAR_U16,  0, 6),
       
  2954 	SLE_CONDVAR(Vehicle, cargo_source,         SLE_UINT16,                  7, SL_MAX_VERSION),
       
  2955 	    SLE_VAR(Vehicle, cargo_cap,            SLE_UINT16),
       
  2956 	    SLE_VAR(Vehicle, cargo_count,          SLE_UINT16),
       
  2957 
       
  2958 	    SLE_VAR(Vehicle, day_counter,          SLE_UINT8),
       
  2959 	    SLE_VAR(Vehicle, tick_counter,         SLE_UINT8),
       
  2960 
       
  2961 	    SLE_VAR(Vehicle, cur_order_index,      SLE_UINT8),
       
  2962 	    SLE_VAR(Vehicle, num_orders,           SLE_UINT8),
       
  2963 
       
  2964 	/* This next line is for version 4 and prior compatibility.. it temporarily reads
       
  2965 	    type and flags (which were both 4 bits) into type. Later on this is
       
  2966 	    converted correctly */
       
  2967 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, type), SLE_UINT8,                 0, 4),
       
  2968 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
       
  2969 
       
  2970 	/* Orders for version 5 and on */
       
  2971 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, type),  SLE_UINT8,  5, SL_MAX_VERSION),
       
  2972 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, flags), SLE_UINT8,  5, SL_MAX_VERSION),
       
  2973 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest),  SLE_UINT16, 5, SL_MAX_VERSION),
       
  2974 
       
  2975 	/* Refit in current order */
       
  2976 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, refit_cargo),    SLE_UINT8, 36, SL_MAX_VERSION),
       
  2977 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, refit_subtype),  SLE_UINT8, 36, SL_MAX_VERSION),
       
  2978 
       
  2979 	    SLE_REF(Vehicle, orders,               REF_ORDER),
       
  2980 
       
  2981 	SLE_CONDVAR(Vehicle, age,                  SLE_FILE_U16 | SLE_VAR_I32,  0, 30),
       
  2982 	SLE_CONDVAR(Vehicle, age,                  SLE_INT32,                  31, SL_MAX_VERSION),
       
  2983 	SLE_CONDVAR(Vehicle, max_age,              SLE_FILE_U16 | SLE_VAR_I32,  0, 30),
       
  2984 	SLE_CONDVAR(Vehicle, max_age,              SLE_INT32,                  31, SL_MAX_VERSION),
       
  2985 	SLE_CONDVAR(Vehicle, date_of_last_service, SLE_FILE_U16 | SLE_VAR_I32,  0, 30),
       
  2986 	SLE_CONDVAR(Vehicle, date_of_last_service, SLE_INT32,                  31, SL_MAX_VERSION),
       
  2987 	SLE_CONDVAR(Vehicle, service_interval,     SLE_FILE_U16 | SLE_VAR_I32,  0, 30),
       
  2988 	SLE_CONDVAR(Vehicle, service_interval,     SLE_INT32,                  31, SL_MAX_VERSION),
       
  2989 	    SLE_VAR(Vehicle, reliability,          SLE_UINT16),
       
  2990 	    SLE_VAR(Vehicle, reliability_spd_dec,  SLE_UINT16),
       
  2991 	    SLE_VAR(Vehicle, breakdown_ctr,        SLE_UINT8),
       
  2992 	    SLE_VAR(Vehicle, breakdown_delay,      SLE_UINT8),
       
  2993 	    SLE_VAR(Vehicle, breakdowns_since_last_service, SLE_UINT8),
       
  2994 	    SLE_VAR(Vehicle, breakdown_chance,     SLE_UINT8),
       
  2995 	SLE_CONDVAR(Vehicle, build_year,           SLE_FILE_U8 | SLE_VAR_I32,  0, 30),
       
  2996 	SLE_CONDVAR(Vehicle, build_year,           SLE_INT32,                 31, SL_MAX_VERSION),
       
  2997 
       
  2998 	    SLE_VAR(Vehicle, load_unload_time_rem, SLE_UINT16),
       
  2999 	SLE_CONDVAR(Vehicle, load_status,          SLE_UINT8,                 40, SL_MAX_VERSION),
       
  3000 
       
  3001 	    SLE_VAR(Vehicle, profit_this_year,     SLE_INT32),
       
  3002 	    SLE_VAR(Vehicle, profit_last_year,     SLE_INT32),
       
  3003 	    SLE_VAR(Vehicle, value,                SLE_UINT32),
       
  3004 
       
  3005 	    SLE_VAR(Vehicle, random_bits,          SLE_UINT8),
       
  3006 	    SLE_VAR(Vehicle, waiting_triggers,     SLE_UINT8),
       
  3007 
       
  3008 	    SLE_REF(Vehicle, next_shared,          REF_VEHICLE),
       
  3009 	    SLE_REF(Vehicle, prev_shared,          REF_VEHICLE),
       
  3010 
       
  3011 	// reserve extra space in savegame here. (currently 10 bytes)
       
  3012 	SLE_CONDNULL(10,                                                       2, SL_MAX_VERSION),
       
  3013 
       
  3014 	SLE_END()
       
  3015 };
       
  3016 
       
  3017 
       
  3018 static const SaveLoad _train_desc[] = {
       
  3019 	SLE_WRITEBYTE(Vehicle, type, VEH_Train, 0), // Train type. VEH_Train in mem, 0 in file.
       
  3020 	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
       
  3021 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, crash_anim_pos),         SLE_UINT16),
       
  3022 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, force_proceed),          SLE_UINT8),
       
  3023 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, railtype),               SLE_UINT8),
       
  3024 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, track),                  SLE_UINT8),
       
  3025 
       
  3026 	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRail, flags),                  SLE_UINT8,  2, SL_MAX_VERSION),
       
  3027 	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRail, days_since_order_progr), SLE_UINT16, 2, SL_MAX_VERSION),
       
  3028 
       
  3029 	SLE_CONDNULL(2, 2, 19),
       
  3030 	// reserve extra space in savegame here. (currently 11 bytes)
       
  3031 	SLE_CONDNULL(11, 2, SL_MAX_VERSION),
       
  3032 
       
  3033 	SLE_END()
       
  3034 };
       
  3035 
       
  3036 static const SaveLoad _roadveh_desc[] = {
       
  3037 	SLE_WRITEBYTE(Vehicle, type, VEH_Road, 1), // Road type. VEH_Road in mem, 1 in file.
       
  3038 	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
       
  3039 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, state),          SLE_UINT8),
       
  3040 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, frame),          SLE_UINT8),
       
  3041 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, blocked_ctr),    SLE_UINT16),
       
  3042 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, overtaking),     SLE_UINT8),
       
  3043 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, overtaking_ctr), SLE_UINT8),
       
  3044 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, crashed_ctr),    SLE_UINT16),
       
  3045 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, reverse_ctr),    SLE_UINT8),
       
  3046 
       
  3047 	SLE_CONDREFX(offsetof(Vehicle, u) + offsetof(VehicleRoad, slot),     REF_ROADSTOPS, 6, SL_MAX_VERSION),
       
  3048 	SLE_CONDNULL(1,                                                                     6, SL_MAX_VERSION),
       
  3049 	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, slot_age), SLE_UINT8,     6, SL_MAX_VERSION),
       
  3050 	// reserve extra space in savegame here. (currently 16 bytes)
       
  3051 	SLE_CONDNULL(16,                                                                    2, SL_MAX_VERSION),
       
  3052 
       
  3053 	SLE_END()
       
  3054 };
       
  3055 
       
  3056 static const SaveLoad _ship_desc[] = {
       
  3057 	SLE_WRITEBYTE(Vehicle, type, VEH_Ship, 2), // Ship type. VEH_Ship in mem, 2 in file.
       
  3058 	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
       
  3059 	SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleShip, state), SLE_UINT8),
       
  3060 
       
  3061 	// reserve extra space in savegame here. (currently 16 bytes)
       
  3062 	SLE_CONDNULL(16, 2, SL_MAX_VERSION),
       
  3063 
       
  3064 	SLE_END()
       
  3065 };
       
  3066 
       
  3067 static const SaveLoad _aircraft_desc[] = {
       
  3068 	SLE_WRITEBYTE(Vehicle, type, VEH_Aircraft, 3), // Aircraft type. VEH_Aircraft in mem, 3 in file.
       
  3069 	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
       
  3070 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleAir, crashed_counter), SLE_UINT16),
       
  3071 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleAir, pos),             SLE_UINT8),
       
  3072 
       
  3073 	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, targetairport),   SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
       
  3074 	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, targetairport),   SLE_UINT16,                5, SL_MAX_VERSION),
       
  3075 
       
  3076 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleAir, state),           SLE_UINT8),
       
  3077 
       
  3078 	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, previous_pos),    SLE_UINT8,                 2, SL_MAX_VERSION),
       
  3079 
       
  3080 	// reserve extra space in savegame here. (currently 15 bytes)
       
  3081 	SLE_CONDNULL(15,                                                                                      2, SL_MAX_VERSION),
       
  3082 
       
  3083 	SLE_END()
       
  3084 };
       
  3085 
       
  3086 static const SaveLoad _special_desc[] = {
       
  3087 	SLE_WRITEBYTE(Vehicle,type,VEH_Special, 4),
       
  3088 
       
  3089 	    SLE_VAR(Vehicle, subtype,       SLE_UINT8),
       
  3090 
       
  3091 	SLE_CONDVAR(Vehicle, tile,          SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
       
  3092 	SLE_CONDVAR(Vehicle, tile,          SLE_UINT32,                 6, SL_MAX_VERSION),
       
  3093 
       
  3094 	SLE_CONDVAR(Vehicle, x_pos,         SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
       
  3095 	SLE_CONDVAR(Vehicle, x_pos,         SLE_INT32,                  6, SL_MAX_VERSION),
       
  3096 	SLE_CONDVAR(Vehicle, y_pos,         SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
       
  3097 	SLE_CONDVAR(Vehicle, y_pos,         SLE_INT32,                  6, SL_MAX_VERSION),
       
  3098 	    SLE_VAR(Vehicle, z_pos,         SLE_UINT8),
       
  3099 
       
  3100 	    SLE_VAR(Vehicle, cur_image,     SLE_UINT16),
       
  3101 	    SLE_VAR(Vehicle, sprite_width,  SLE_UINT8),
       
  3102 	    SLE_VAR(Vehicle, sprite_height, SLE_UINT8),
       
  3103 	    SLE_VAR(Vehicle, z_height,      SLE_UINT8),
       
  3104 	    SLE_VAR(Vehicle, x_offs,        SLE_INT8),
       
  3105 	    SLE_VAR(Vehicle, y_offs,        SLE_INT8),
       
  3106 	    SLE_VAR(Vehicle, progress,      SLE_UINT8),
       
  3107 	    SLE_VAR(Vehicle, vehstatus,     SLE_UINT8),
       
  3108 
       
  3109 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleSpecial, unk0), SLE_UINT16),
       
  3110 	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleSpecial, unk2), SLE_UINT8),
       
  3111 
       
  3112 	// reserve extra space in savegame here. (currently 16 bytes)
       
  3113 	SLE_CONDNULL(16, 2, SL_MAX_VERSION),
       
  3114 
       
  3115 	SLE_END()
       
  3116 };
       
  3117 
       
  3118 static const SaveLoad _disaster_desc[] = {
       
  3119 	SLE_WRITEBYTE(Vehicle, type, VEH_Disaster, 5),
       
  3120 
       
  3121 	    SLE_REF(Vehicle, next,          REF_VEHICLE_OLD),
       
  3122 
       
  3123 	    SLE_VAR(Vehicle, subtype,       SLE_UINT8),
       
  3124 	SLE_CONDVAR(Vehicle, tile,          SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
       
  3125 	SLE_CONDVAR(Vehicle, tile,          SLE_UINT32,                  6, SL_MAX_VERSION),
       
  3126 	SLE_CONDVAR(Vehicle, dest_tile,     SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
       
  3127 	SLE_CONDVAR(Vehicle, dest_tile,     SLE_UINT32,                  6, SL_MAX_VERSION),
       
  3128 
       
  3129 	SLE_CONDVAR(Vehicle, x_pos,         SLE_FILE_I16 | SLE_VAR_I32,  0, 5),
       
  3130 	SLE_CONDVAR(Vehicle, x_pos,         SLE_INT32,                   6, SL_MAX_VERSION),
       
  3131 	SLE_CONDVAR(Vehicle, y_pos,         SLE_FILE_I16 | SLE_VAR_I32,  0, 5),
       
  3132 	SLE_CONDVAR(Vehicle, y_pos,         SLE_INT32,                   6, SL_MAX_VERSION),
       
  3133 	    SLE_VAR(Vehicle, z_pos,         SLE_UINT8),
       
  3134 	    SLE_VAR(Vehicle, direction,     SLE_UINT8),
       
  3135 
       
  3136 	    SLE_VAR(Vehicle, x_offs,        SLE_INT8),
       
  3137 	    SLE_VAR(Vehicle, y_offs,        SLE_INT8),
       
  3138 	    SLE_VAR(Vehicle, sprite_width,  SLE_UINT8),
       
  3139 	    SLE_VAR(Vehicle, sprite_height, SLE_UINT8),
       
  3140 	    SLE_VAR(Vehicle, z_height,      SLE_UINT8),
       
  3141 	    SLE_VAR(Vehicle, owner,         SLE_UINT8),
       
  3142 	    SLE_VAR(Vehicle, vehstatus,     SLE_UINT8),
       
  3143 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
       
  3144 	SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_UINT16,                5, SL_MAX_VERSION),
       
  3145 
       
  3146 	    SLE_VAR(Vehicle, cur_image,     SLE_UINT16),
       
  3147 	SLE_CONDVAR(Vehicle, age,           SLE_FILE_U16 | SLE_VAR_I32,  0, 30),
       
  3148 	SLE_CONDVAR(Vehicle, age,           SLE_INT32,                  31, SL_MAX_VERSION),
       
  3149 	    SLE_VAR(Vehicle, tick_counter,  SLE_UINT8),
       
  3150 
       
  3151 	   SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleDisaster, image_override), SLE_UINT16),
       
  3152 	   SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleDisaster, unk2),           SLE_UINT16),
       
  3153 
       
  3154 	// reserve extra space in savegame here. (currently 16 bytes)
       
  3155 	SLE_CONDNULL(16,                                                 2, SL_MAX_VERSION),
       
  3156 
       
  3157 	SLE_END()
       
  3158 };
       
  3159 
       
  3160 
       
  3161 static const void *_veh_descs[] = {
       
  3162 	_train_desc,
       
  3163 	_roadveh_desc,
       
  3164 	_ship_desc,
       
  3165 	_aircraft_desc,
       
  3166 	_special_desc,
       
  3167 	_disaster_desc,
       
  3168 };
       
  3169 
       
  3170 // Will be called when the vehicles need to be saved.
       
  3171 static void Save_VEHS(void)
       
  3172 {
       
  3173 	Vehicle *v;
       
  3174 	// Write the vehicles
       
  3175 	FOR_ALL_VEHICLES(v) {
       
  3176 		SlSetArrayIndex(v->index);
       
  3177 		SlObject(v, _veh_descs[v->type - 0x10]);
       
  3178 	}
       
  3179 }
       
  3180 
       
  3181 // Will be called when vehicles need to be loaded.
       
  3182 static void Load_VEHS(void)
       
  3183 {
       
  3184 	int index;
       
  3185 	Vehicle *v;
       
  3186 
       
  3187 	while ((index = SlIterateArray()) != -1) {
       
  3188 		Vehicle *v;
       
  3189 
       
  3190 		if (!AddBlockIfNeeded(&_Vehicle_pool, index))
       
  3191 			error("Vehicles: failed loading savegame: too many vehicles");
       
  3192 
       
  3193 		v = GetVehicle(index);
       
  3194 		SlObject(v, _veh_descs[SlReadByte()]);
       
  3195 
       
  3196 		/* Old savegames used 'last_station_visited = 0xFF' */
       
  3197 		if (CheckSavegameVersion(5) && v->last_station_visited == 0xFF)
       
  3198 			v->last_station_visited = INVALID_STATION;
       
  3199 
       
  3200 		if (CheckSavegameVersion(5)) {
       
  3201 			/* Convert the current_order.type (which is a mix of type and flags, because
       
  3202 			 *  in those versions, they both were 4 bits big) to type and flags */
       
  3203 			v->current_order.flags = (v->current_order.type & 0xF0) >> 4;
       
  3204 			v->current_order.type  =  v->current_order.type & 0x0F;
       
  3205 		}
       
  3206 	}
       
  3207 
       
  3208 	/* Check for shared order-lists (we now use pointers for that) */
       
  3209 	if (CheckSavegameVersionOldStyle(5, 2)) {
       
  3210 		FOR_ALL_VEHICLES(v) {
       
  3211 			Vehicle *u;
       
  3212 
       
  3213 			FOR_ALL_VEHICLES_FROM(u, v->index + 1) {
       
  3214 				/* If a vehicle has the same orders, add the link to eachother
       
  3215 				 *  in both vehicles */
       
  3216 				if (v->orders == u->orders) {
       
  3217 					v->next_shared = u;
       
  3218 					u->prev_shared = v;
       
  3219 					break;
       
  3220 				}
       
  3221 			}
       
  3222 		}
       
  3223 	}
       
  3224 }
       
  3225 
       
  3226 const ChunkHandler _veh_chunk_handlers[] = {
       
  3227 	{ 'VEHS', Save_VEHS, Load_VEHS, CH_SPARSE_ARRAY | CH_LAST},
       
  3228 };