src/vehicle.cpp
branchNewGRF_ports
changeset 6871 5a9dc001e1ad
parent 6870 ca3fd1fbe311
child 6872 1c4a4a609f85
equal deleted inserted replaced
6870:ca3fd1fbe311 6871:5a9dc001e1ad
   115 		case VEH_AIRCRAFT: return STR_A015_AIRCRAFT_IN_THE_WAY;
   115 		case VEH_AIRCRAFT: return STR_A015_AIRCRAFT_IN_THE_WAY;
   116 		default:           return STR_980E_SHIP_IN_THE_WAY;
   116 		default:           return STR_980E_SHIP_IN_THE_WAY;
   117 	}
   117 	}
   118 }
   118 }
   119 
   119 
   120 static void *EnsureNoVehicleProc(Vehicle *v, void *data)
       
   121 {
       
   122 	if (v->tile != *(const TileIndex*)data || v->type == VEH_DISASTER)
       
   123 		return NULL;
       
   124 
       
   125 	_error_message = VehicleInTheWayErrMsg(v);
       
   126 	return v;
       
   127 }
       
   128 
       
   129 bool EnsureNoVehicle(TileIndex tile)
       
   130 {
       
   131 	return VehicleFromPos(tile, &tile, EnsureNoVehicleProc) == NULL;
       
   132 }
       
   133 
       
   134 static void *EnsureNoVehicleProcZ(Vehicle *v, void *data)
   120 static void *EnsureNoVehicleProcZ(Vehicle *v, void *data)
   135 {
   121 {
   136 	const TileInfo *ti = (const TileInfo*)data;
   122 	const TileInfo *ti = (const TileInfo*)data;
   137 
   123 
   138 	if (v->tile != ti->tile || v->type == VEH_DISASTER) return NULL;
   124 	if (v->tile != ti->tile || v->type == VEH_DISASTER || (v->type == VEH_AIRCRAFT && v->subtype == AIR_SHADOW)) return NULL;
   139 	if (v->z_pos > ti->z) return NULL;
   125 	if (v->z_pos > ti->z) return NULL;
   140 
   126 
   141 	_error_message = VehicleInTheWayErrMsg(v);
   127 	_error_message = VehicleInTheWayErrMsg(v);
   142 	return v;
   128 	return v;
   143 }
   129 }
   246 	}
   232 	}
   247 
   233 
   248 	FOR_ALL_VEHICLES(v) {
   234 	FOR_ALL_VEHICLES(v) {
   249 		switch (v->type) {
   235 		switch (v->type) {
   250 			case VEH_ROAD:
   236 			case VEH_ROAD:
   251 				v->u.road.roadtype = HASBIT(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
   237 				v->u.road.roadtype = HasBit(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
   252 				v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype);
   238 				v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype);
   253 				/* FALL THROUGH */
   239 				/* FALL THROUGH */
   254 			case VEH_TRAIN:
   240 			case VEH_TRAIN:
   255 			case VEH_SHIP:
   241 			case VEH_SHIP:
   256 				v->cur_image = v->GetImage(v->direction);
   242 				v->cur_image = v->GetImage(v->direction);
   286 	this->type               = VEH_INVALID;
   272 	this->type               = VEH_INVALID;
   287 	this->left_coord         = INVALID_COORD;
   273 	this->left_coord         = INVALID_COORD;
   288 	this->group_id           = DEFAULT_GROUP;
   274 	this->group_id           = DEFAULT_GROUP;
   289 	this->fill_percent_te_id = INVALID_TE_ID;
   275 	this->fill_percent_te_id = INVALID_TE_ID;
   290 	this->first              = this;
   276 	this->first              = this;
       
   277 	this->colormap           = PAL_NONE;
   291 }
   278 }
   292 
   279 
   293 /**
   280 /**
   294  * Get a value for a vehicle's random_bits.
   281  * Get a value for a vehicle's random_bits.
   295  * @return A random value from 0 to 255.
   282  * @return A random value from 0 to 255.
   469 	FOR_ALL_VEHICLES(v) { v->old_new_hash = NULL; }
   456 	FOR_ALL_VEHICLES(v) { v->old_new_hash = NULL; }
   470 	memset(_vehicle_position_hash, 0, sizeof(_vehicle_position_hash));
   457 	memset(_vehicle_position_hash, 0, sizeof(_vehicle_position_hash));
   471 	memset(_new_vehicle_position_hash, 0, sizeof(_new_vehicle_position_hash));
   458 	memset(_new_vehicle_position_hash, 0, sizeof(_new_vehicle_position_hash));
   472 }
   459 }
   473 
   460 
       
   461 void ResetVehicleColorMap()
       
   462 {
       
   463 	Vehicle *v;
       
   464 	FOR_ALL_VEHICLES(v) { v->colormap = PAL_NONE; }
       
   465 }
       
   466 
   474 void InitializeVehicles()
   467 void InitializeVehicles()
   475 {
   468 {
   476 	_Vehicle_pool.CleanPool();
   469 	_Vehicle_pool.CleanPool();
   477 	_Vehicle_pool.AddBlockToPool();
   470 	_Vehicle_pool.AddBlockToPool();
   478 
   471 
   541 	 *  destroy vehicle, which on his turn can remove any
   534 	 *  destroy vehicle, which on his turn can remove any
   542 	 *  other artic parts. */
   535 	 *  other artic parts. */
   543 	if ((this->type == VEH_TRAIN && EngineHasArticPart(this)) || (this->type == VEH_ROAD && RoadVehHasArticPart(this))) {
   536 	if ((this->type == VEH_TRAIN && EngineHasArticPart(this)) || (this->type == VEH_ROAD && RoadVehHasArticPart(this))) {
   544 		delete this->Next();
   537 		delete this->Next();
   545 	}
   538 	}
       
   539 
       
   540 	Window *w = FindWindowById(WC_VEHICLE_VIEW, this->index);
       
   541 	if (w != NULL && WP(w, vp_d).follow_vehicle == this->index) {
       
   542 		ScrollMainWindowTo(this->x_pos, this->y_pos); // lock the main view on the vehicle's last position
       
   543 		WP(w, vp_d).follow_vehicle = INVALID_VEHICLE;
       
   544 	}
   546 }
   545 }
   547 
   546 
   548 Vehicle::~Vehicle()
   547 Vehicle::~Vehicle()
   549 {
   548 {
   550 	DeleteName(this->string_id);
   549 	DeleteName(this->string_id);
   562 }
   561 }
   563 
   562 
   564 /**
   563 /**
   565  * Deletes all vehicles in a chain.
   564  * Deletes all vehicles in a chain.
   566  * @param v The first vehicle in the chain.
   565  * @param v The first vehicle in the chain.
   567  *
       
   568  * @warning This function is not valid for any vehicle containing articulated
       
   569  * parts.
       
   570  */
   566  */
   571 void DeleteVehicleChain(Vehicle *v)
   567 void DeleteVehicleChain(Vehicle *v)
   572 {
   568 {
   573 	assert(v->type != VEH_TRAIN && v->type != VEH_ROAD);
   569 	assert(v->First() == v);
   574 
   570 
   575 	do {
   571 	do {
   576 		Vehicle *u = v;
   572 		Vehicle *u = v;
   577 		v = v->Next();
   573 		v = v->Next();
   578 		delete u;
   574 		delete u;
   586  * @param *v vehicle to add
   582  * @param *v vehicle to add
   587  */
   583  */
   588 void VehicleEnteredDepotThisTick(Vehicle *v)
   584 void VehicleEnteredDepotThisTick(Vehicle *v)
   589 {
   585 {
   590 	/* we need to set v->leave_depot_instantly as we have no control of it's contents at this time */
   586 	/* we need to set v->leave_depot_instantly as we have no control of it's contents at this time */
   591 	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) {
   587 	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) {
   592 		/* we keep the vehicle in the depot since the user ordered it to stay */
   588 		/* we keep the vehicle in the depot since the user ordered it to stay */
   593 		v->leave_depot_instantly = false;
   589 		v->leave_depot_instantly = false;
   594 	} else {
   590 	} else {
   595 		/* the vehicle do not plan on stopping in the depot, so we stop it to ensure that it will not reserve the path
   591 		/* the vehicle do not plan on stopping in the depot, so we stop it to ensure that it will not reserve the path
   596 		 * out of the depot before we might autoreplace it to a different engine. The new engine would not own the reserved path
   592 		 * out of the depot before we might autoreplace it to a different engine. The new engine would not own the reserved path
   654  * @param cid_to check refit to this cargo-type
   650  * @param cid_to check refit to this cargo-type
   655  * @return true if it is possible, false otherwise
   651  * @return true if it is possible, false otherwise
   656  */
   652  */
   657 bool CanRefitTo(EngineID engine_type, CargoID cid_to)
   653 bool CanRefitTo(EngineID engine_type, CargoID cid_to)
   658 {
   654 {
   659 	return HASBIT(EngInfo(engine_type)->refit_mask, cid_to);
   655 	return HasBit(EngInfo(engine_type)->refit_mask, cid_to);
   660 }
   656 }
   661 
   657 
   662 /** Find the first cargo type that an engine can be refitted to.
   658 /** Find the first cargo type that an engine can be refitted to.
   663  * @param engine_type Which engine to find cargo for.
   659  * @param engine_type Which engine to find cargo for.
   664  * @return A climate dependent cargo type. CT_INVALID is returned if not refittable.
   660  * @return A climate dependent cargo type. CT_INVALID is returned if not refittable.
   667 {
   663 {
   668 	uint32 refit_mask = EngInfo(engine_type)->refit_mask;
   664 	uint32 refit_mask = EngInfo(engine_type)->refit_mask;
   669 
   665 
   670 	if (refit_mask != 0) {
   666 	if (refit_mask != 0) {
   671 		for (CargoID cid = 0; cid < NUM_CARGO; cid++) {
   667 		for (CargoID cid = 0; cid < NUM_CARGO; cid++) {
   672 			if (HASBIT(refit_mask, cid)) return cid;
   668 			if (HasBit(refit_mask, cid)) return cid;
   673 		}
   669 		}
   674 	}
   670 	}
   675 
   671 
   676 	return CT_INVALID;
   672 	return CT_INVALID;
   677 }
   673 }
  1266 		delete v;
  1262 		delete v;
  1267 		return;
  1263 		return;
  1268 	}
  1264 	}
  1269 
  1265 
  1270 	if (b->y == 4 && b->x == 1) {
  1266 	if (b->y == 4 && b->x == 1) {
  1271 		if (v->z_pos > 180 || CHANCE16I(1, 96, InteractiveRandom())) {
  1267 		if (v->z_pos > 180 || Chance16I(1, 96, InteractiveRandom())) {
  1272 			v->spritenum = 5;
  1268 			v->spritenum = 5;
  1273 			SndPlayVehicleFx(SND_2F_POP, v);
  1269 			SndPlayVehicleFx(SND_2F_POP, v);
  1274 		}
  1270 		}
  1275 		et = 0;
  1271 		et = 0;
  1276 	}
  1272 	}
  1351 	return v;
  1347 	return v;
  1352 }
  1348 }
  1353 
  1349 
  1354 Vehicle *CreateEffectVehicleAbove(int x, int y, int z, EffectVehicle type)
  1350 Vehicle *CreateEffectVehicleAbove(int x, int y, int z, EffectVehicle type)
  1355 {
  1351 {
  1356 	int safe_x = clamp(x, 0, MapMaxX() * TILE_SIZE);
  1352 	int safe_x = Clamp(x, 0, MapMaxX() * TILE_SIZE);
  1357 	int safe_y = clamp(y, 0, MapMaxY() * TILE_SIZE);
  1353 	int safe_y = Clamp(y, 0, MapMaxY() * TILE_SIZE);
  1358 	return CreateEffectVehicle(x, y, GetSlopeZ(safe_x, safe_y) + z, type);
  1354 	return CreateEffectVehicle(x, y, GetSlopeZ(safe_x, safe_y) + z, type);
  1359 }
  1355 }
  1360 
  1356 
  1361 Vehicle *CreateEffectVehicleRel(const Vehicle *v, int x, int y, int z, EffectVehicle type)
  1357 Vehicle *CreateEffectVehicleRel(const Vehicle *v, int x, int y, int z, EffectVehicle type)
  1362 {
  1358 {
  1384 		if ((v->vehstatus & (VS_HIDDEN|VS_UNCLICKABLE)) == 0 &&
  1380 		if ((v->vehstatus & (VS_HIDDEN|VS_UNCLICKABLE)) == 0 &&
  1385 				x >= v->left_coord && x <= v->right_coord &&
  1381 				x >= v->left_coord && x <= v->right_coord &&
  1386 				y >= v->top_coord && y <= v->bottom_coord) {
  1382 				y >= v->top_coord && y <= v->bottom_coord) {
  1387 
  1383 
  1388 			dist = max(
  1384 			dist = max(
  1389 				myabs( ((v->left_coord + v->right_coord)>>1) - x ),
  1385 				abs( ((v->left_coord + v->right_coord)>>1) - x ),
  1390 				myabs( ((v->top_coord + v->bottom_coord)>>1) - y )
  1386 				abs( ((v->top_coord + v->bottom_coord)>>1) - y )
  1391 			);
  1387 			);
  1392 
  1388 
  1393 			if (dist < best_dist) {
  1389 			if (dist < best_dist) {
  1394 				found = v;
  1390 				found = v;
  1395 				best_dist = dist;
  1391 				best_dist = dist;
  1398 	}
  1394 	}
  1399 
  1395 
  1400 	return found;
  1396 	return found;
  1401 }
  1397 }
  1402 
  1398 
       
  1399 void CheckVehicle32Day(Vehicle *v)
       
  1400 {
       
  1401 	if ((v->day_counter & 0x1F) != 0) return;
       
  1402 
       
  1403 	uint16 callback = GetVehicleCallback(CBID_VEHICLE_32DAY_CALLBACK, 0, 0, v->engine_type, v);
       
  1404 	if (callback == CALLBACK_FAILED) return;
       
  1405 	if (HasBit(callback, 0)) TriggerVehicle(v, VEHICLE_TRIGGER_CALLBACK_32); // Trigger vehicle trigger 10
       
  1406 	if (HasBit(callback, 1)) v->colormap = PAL_NONE;                         // Update colormap via callback 2D
       
  1407 }
  1403 
  1408 
  1404 void DecreaseVehicleValue(Vehicle *v)
  1409 void DecreaseVehicleValue(Vehicle *v)
  1405 {
  1410 {
  1406 	v->value -= v->value >> 8;
  1411 	v->value -= v->value >> 8;
  1407 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  1412 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  1436 
  1441 
  1437 	r = Random();
  1442 	r = Random();
  1438 
  1443 
  1439 	/* increase chance of failure */
  1444 	/* increase chance of failure */
  1440 	chance = v->breakdown_chance + 1;
  1445 	chance = v->breakdown_chance + 1;
  1441 	if (CHANCE16I(1,25,r)) chance += 25;
  1446 	if (Chance16I(1,25,r)) chance += 25;
  1442 	v->breakdown_chance = min(255, chance);
  1447 	v->breakdown_chance = min(255, chance);
  1443 
  1448 
  1444 	/* calculate reliability value to use in comparison */
  1449 	/* calculate reliability value to use in comparison */
  1445 	rel = v->reliability;
  1450 	rel = v->reliability;
  1446 	if (v->type == VEH_SHIP) rel += 0x6666;
  1451 	if (v->type == VEH_SHIP) rel += 0x6666;
  1513 	uint16 engine_count = 0;
  1518 	uint16 engine_count = 0;
  1514 	CommandCost return_value = CMD_ERROR;
  1519 	CommandCost return_value = CMD_ERROR;
  1515 	uint i;
  1520 	uint i;
  1516 	uint stop_command;
  1521 	uint stop_command;
  1517 	VehicleType vehicle_type = (VehicleType)GB(p2, 0, 5);
  1522 	VehicleType vehicle_type = (VehicleType)GB(p2, 0, 5);
  1518 	bool start_stop = HASBIT(p2, 5);
  1523 	bool start_stop = HasBit(p2, 5);
  1519 	bool vehicle_list_window = HASBIT(p2, 6);
  1524 	bool vehicle_list_window = HasBit(p2, 6);
  1520 
  1525 
  1521 	switch (vehicle_type) {
  1526 	switch (vehicle_type) {
  1522 		case VEH_TRAIN:    stop_command = CMD_START_STOP_TRAIN;    break;
  1527 		case VEH_TRAIN:    stop_command = CMD_START_STOP_TRAIN;    break;
  1523 		case VEH_ROAD:     stop_command = CMD_START_STOP_ROADVEH;  break;
  1528 		case VEH_ROAD:     stop_command = CMD_START_STOP_ROADVEH;  break;
  1524 		case VEH_SHIP:     stop_command = CMD_START_STOP_SHIP;     break;
  1529 		case VEH_SHIP:     stop_command = CMD_START_STOP_SHIP;     break;
  1744 		total_cost.AddCost(cost);
  1749 		total_cost.AddCost(cost);
  1745 
  1750 
  1746 		if (flags & DC_EXEC) {
  1751 		if (flags & DC_EXEC) {
  1747 			w = GetVehicle(_new_vehicle_id);
  1752 			w = GetVehicle(_new_vehicle_id);
  1748 
  1753 
  1749 			if (v->type == VEH_TRAIN && HASBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION)) {
  1754 			if (v->type == VEH_TRAIN && HasBit(v->u.rail.flags, VRF_REVERSE_DIRECTION)) {
  1750 				SETBIT(w->u.rail.flags, VRF_REVERSE_DIRECTION);
  1755 				SetBit(w->u.rail.flags, VRF_REVERSE_DIRECTION);
  1751 			}
  1756 			}
  1752 
  1757 
  1753 			if (v->type == VEH_TRAIN && !IsFrontEngine(v)) {
  1758 			if (v->type == VEH_TRAIN && !IsFrontEngine(v)) {
  1754 				/* this s a train car
  1759 				/* this s a train car
  1755 				 * add this unit to the end of the train */
  1760 				 * add this unit to the end of the train */
  1760 					DoCommand(w_front->tile, w_front->index, 1, flags, GetCmdSellVeh(w_front));
  1765 					DoCommand(w_front->tile, w_front->index, 1, flags, GetCmdSellVeh(w_front));
  1761 					DoCommand(w_front->tile, w->index,       1, flags, GetCmdSellVeh(w));
  1766 					DoCommand(w_front->tile, w->index,       1, flags, GetCmdSellVeh(w));
  1762 					return result; // return error and the message returned from CMD_MOVE_RAIL_VEHICLE
  1767 					return result; // return error and the message returned from CMD_MOVE_RAIL_VEHICLE
  1763 				}
  1768 				}
  1764 			} else {
  1769 			} else {
  1765 				/* this is a front engine or not a train. It need orders */
  1770 				/* this is a front engine or not a train. */
  1766 				w_front = w;
  1771 				w_front = w;
  1767 				w->service_interval = v->service_interval;
  1772 				w->service_interval = v->service_interval;
  1768 				DoCommand(0, (v->index << 16) | w->index, p2 & 1 ? CO_SHARE : CO_COPY, flags, CMD_CLONE_ORDER);
       
  1769 			}
  1773 			}
  1770 			w_rear = w; // trains needs to know the last car in the train, so they can add more in next loop
  1774 			w_rear = w; // trains needs to know the last car in the train, so they can add more in next loop
  1771 		}
  1775 		}
  1772 	} while (v->type == VEH_TRAIN && (v = GetNextVehicle(v)) != NULL);
  1776 	} while (v->type == VEH_TRAIN && (v = GetNextVehicle(v)) != NULL);
  1773 
  1777 
  1795 	do {
  1799 	do {
  1796 		do {
  1800 		do {
  1797 			if (flags & DC_EXEC) {
  1801 			if (flags & DC_EXEC) {
  1798 				assert(w != NULL);
  1802 				assert(w != NULL);
  1799 
  1803 
  1800 				if (w->cargo_type != v->cargo_type || w->cargo_subtype != v->cargo_type) {
  1804 				if (w->cargo_type != v->cargo_type || w->cargo_subtype != v->cargo_subtype) {
  1801 					cost = DoCommand(0, w->index, v->cargo_type | (v->cargo_subtype << 8) | 1U << 16 , flags, GetCmdRefitVeh(v));
  1805 					cost = DoCommand(0, w->index, v->cargo_type | (v->cargo_subtype << 8) | 1U << 16 , flags, GetCmdRefitVeh(v));
  1802 					if (CmdSucceeded(cost)) total_cost.AddCost(cost);
  1806 					if (CmdSucceeded(cost)) total_cost.AddCost(cost);
  1803 				}
  1807 				}
  1804 
  1808 
  1805 				if (w->type == VEH_TRAIN && EngineHasArticPart(w)) {
  1809 				if (w->type == VEH_TRAIN && EngineHasArticPart(w)) {
  1826 			}
  1830 			}
  1827 		} while (v != NULL);
  1831 		} while (v != NULL);
  1828 
  1832 
  1829 		if ((flags & DC_EXEC) && v->type == VEH_TRAIN) w = GetNextVehicle(w);
  1833 		if ((flags & DC_EXEC) && v->type == VEH_TRAIN) w = GetNextVehicle(w);
  1830 	} while (v->type == VEH_TRAIN && (v = GetNextVehicle(v)) != NULL);
  1834 	} while (v->type == VEH_TRAIN && (v = GetNextVehicle(v)) != NULL);
       
  1835 
       
  1836 	if (flags & DC_EXEC) {
       
  1837 		/*
       
  1838 		 * Set the orders of the vehicle. Cannot do it earlier as we need
       
  1839 		 * the vehicle refitted before doing this, otherwise the moved
       
  1840 		 * cargo types might not match (passenger vs non-passenger)
       
  1841 		 */
       
  1842 		DoCommand(0, (v_front->index << 16) | w_front->index, p2 & 1 ? CO_SHARE : CO_COPY, flags, CMD_CLONE_ORDER);
       
  1843 	}
  1831 
  1844 
  1832 	/* Since we can't estimate the cost of cloning a vehicle accurately we must
  1845 	/* Since we can't estimate the cost of cloning a vehicle accurately we must
  1833 	 * check whether the player has enough money manually. */
  1846 	 * check whether the player has enough money manually. */
  1834 	if (!CheckPlayerHasMoney(total_cost)) {
  1847 	if (!CheckPlayerHasMoney(total_cost)) {
  1835 		if (flags & DC_EXEC) {
  1848 		if (flags & DC_EXEC) {
  2099 	/* Count up max and used */
  2112 	/* Count up max and used */
  2100 	for (; v != NULL; v = v->Next()) {
  2113 	for (; v != NULL; v = v->Next()) {
  2101 		count += v->cargo.Count();
  2114 		count += v->cargo.Count();
  2102 		max += v->cargo_cap;
  2115 		max += v->cargo_cap;
  2103 		if (v->cargo_cap != 0) {
  2116 		if (v->cargo_cap != 0) {
  2104 			unloading += HASBIT(v->vehicle_flags, VF_CARGO_UNLOADING) ? 1 : 0;
  2117 			unloading += HasBit(v->vehicle_flags, VF_CARGO_UNLOADING) ? 1 : 0;
  2105 			loading |= (u->current_order.flags & OF_UNLOAD) == 0 && st->goods[v->cargo_type].days_since_pickup != 255;
  2118 			loading |= (u->current_order.flags & OF_UNLOAD) == 0 && st->goods[v->cargo_type].days_since_pickup != 255;
  2106 			cars++;
  2119 			cars++;
  2107 		}
  2120 		}
  2108 	}
  2121 	}
  2109 
  2122 
  2186 			} else if (v->owner == _local_player && cost.GetCost() != 0) {
  2199 			} else if (v->owner == _local_player && cost.GetCost() != 0) {
  2187 				ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost());
  2200 				ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost());
  2188 			}
  2201 			}
  2189 		}
  2202 		}
  2190 
  2203 
  2191 		if (HASBIT(t.flags, OFB_PART_OF_ORDERS)) {
  2204 		if (HasBit(t.flags, OFB_PART_OF_ORDERS)) {
  2192 			/* Part of orders */
  2205 			/* Part of orders */
  2193 			UpdateVehicleTimetable(v, true);
  2206 			UpdateVehicleTimetable(v, true);
  2194 			v->cur_order_index++;
  2207 			v->cur_order_index++;
  2195 		} else if (HASBIT(t.flags, OFB_HALT_IN_DEPOT)) {
  2208 		} else if (HasBit(t.flags, OFB_HALT_IN_DEPOT)) {
  2196 			/* Force depot visit */
  2209 			/* Force depot visit */
  2197 			v->vehstatus |= VS_STOPPED;
  2210 			v->vehstatus |= VS_STOPPED;
  2198 			if (v->owner == _local_player) {
  2211 			if (v->owner == _local_player) {
  2199 				StringID string;
  2212 				StringID string;
  2200 
  2213 
  2502 	if (max > 0) {
  2515 	if (max > 0) {
  2503 
  2516 
  2504 		/* Can we actually build the vehicle type? */
  2517 		/* Can we actually build the vehicle type? */
  2505 		EngineID e;
  2518 		EngineID e;
  2506 		FOR_ALL_ENGINEIDS_OF_TYPE(e, type) {
  2519 		FOR_ALL_ENGINEIDS_OF_TYPE(e, type) {
  2507 			if (HASBIT(GetEngine(e)->player_avail, _local_player)) return true;
  2520 			if (HasBit(GetEngine(e)->player_avail, _local_player)) return true;
  2508 		}
  2521 		}
  2509 		return false;
  2522 		return false;
  2510 	}
  2523 	}
  2511 
  2524 
  2512 	/* We should be able to build infrastructure when we have the actual vehicle type */
  2525 	/* We should be able to build infrastructure when we have the actual vehicle type */
  2554 								}
  2567 								}
  2555 							} else {
  2568 							} else {
  2556 								scheme = LS_FREIGHT_WAGON;
  2569 								scheme = LS_FREIGHT_WAGON;
  2557 							}
  2570 							}
  2558 						} else {
  2571 						} else {
  2559 							bool is_mu = HASBIT(EngInfo(engine_type)->misc_flags, EF_RAIL_IS_MU);
  2572 							bool is_mu = HasBit(EngInfo(engine_type)->misc_flags, EF_RAIL_IS_MU);
  2560 
  2573 
  2561 							switch (rvi->engclass) {
  2574 							switch (rvi->engclass) {
  2562 								default: NOT_REACHED();
  2575 								default: NOT_REACHED();
  2563 								case EC_STEAM:    scheme = LS_STEAM; break;
  2576 								case EC_STEAM:    scheme = LS_STEAM; break;
  2564 								case EC_DIESEL:   scheme = is_mu ? LS_DMU : LS_DIESEL;   break;
  2577 								case EC_DIESEL:   scheme = is_mu ? LS_DMU : LS_DIESEL;   break;
  2575 			}
  2588 			}
  2576 
  2589 
  2577 			case VEH_ROAD: {
  2590 			case VEH_ROAD: {
  2578 				const RoadVehicleInfo *rvi = RoadVehInfo(engine_type);
  2591 				const RoadVehicleInfo *rvi = RoadVehInfo(engine_type);
  2579 				if (cargo_type == CT_INVALID) cargo_type = rvi->cargo_type;
  2592 				if (cargo_type == CT_INVALID) cargo_type = rvi->cargo_type;
  2580 				if (HASBIT(EngInfo(engine_type)->misc_flags, EF_ROAD_TRAM)) {
  2593 				if (HasBit(EngInfo(engine_type)->misc_flags, EF_ROAD_TRAM)) {
  2581 					/* Tram */
  2594 					/* Tram */
  2582 					scheme = IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_PASSENGER_TRAM : LS_FREIGHT_TRAM;
  2595 					scheme = IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_PASSENGER_TRAM : LS_FREIGHT_TRAM;
  2583 				} else {
  2596 				} else {
  2584 					/* Bus or truck */
  2597 					/* Bus or truck */
  2585 					scheme = IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_BUS : LS_TRUCK;
  2598 					scheme = IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_BUS : LS_TRUCK;
  2614 }
  2627 }
  2615 
  2628 
  2616 
  2629 
  2617 static SpriteID GetEngineColourMap(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v)
  2630 static SpriteID GetEngineColourMap(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v)
  2618 {
  2631 {
  2619 	SpriteID map = PAL_NONE;
  2632 	SpriteID map = (v != NULL) ? v->colormap : PAL_NONE;
       
  2633 
       
  2634 	/* Return cached value if any */
       
  2635 	if (map != PAL_NONE) return map;
  2620 
  2636 
  2621 	/* Check if we should use the colour map callback */
  2637 	/* Check if we should use the colour map callback */
  2622 	if (HASBIT(EngInfo(engine_type)->callbackmask, CBM_VEHICLE_COLOUR_REMAP)) {
  2638 	if (HasBit(EngInfo(engine_type)->callbackmask, CBM_VEHICLE_COLOUR_REMAP)) {
  2623 		uint16 callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v);
  2639 		uint16 callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v);
  2624 		/* A return value of 0xC000 is stated to "use the default two-color
  2640 		/* A return value of 0xC000 is stated to "use the default two-color
  2625 		 * maps" which happens to be the failure action too... */
  2641 		 * maps" which happens to be the failure action too... */
  2626 		if (callback != CALLBACK_FAILED && callback != 0xC000) {
  2642 		if (callback != CALLBACK_FAILED && callback != 0xC000) {
  2627 			map = GB(callback, 0, 14);
  2643 			map = GB(callback, 0, 14);
  2628 			/* If bit 14 is set, then the company colours are applied to the
  2644 			/* If bit 14 is set, then the company colours are applied to the
  2629 			 * map else it's returned as-is. */
  2645 			 * map else it's returned as-is. */
  2630 			if (!HASBIT(callback, 14)) return map;
  2646 			if (!HasBit(callback, 14)) {
  2631 		}
  2647 				/* Update cache */
  2632 	}
  2648 				if (v != NULL) ((Vehicle*)v)->colormap = map;
  2633 
  2649 				return map;
  2634 	bool twocc = HASBIT(EngInfo(engine_type)->misc_flags, EF_USES_2CC);
  2650 			}
       
  2651 		}
       
  2652 	}
       
  2653 
       
  2654 	bool twocc = HasBit(EngInfo(engine_type)->misc_flags, EF_USES_2CC);
  2635 
  2655 
  2636 	if (map == PAL_NONE) map = twocc ? (SpriteID)SPR_2CCMAP_BASE : (SpriteID)PALETTE_RECOLOR_START;
  2656 	if (map == PAL_NONE) map = twocc ? (SpriteID)SPR_2CCMAP_BASE : (SpriteID)PALETTE_RECOLOR_START;
  2637 
  2657 
  2638 	const Livery *livery = GetEngineLivery(engine_type, player, parent_engine_type, v);
  2658 	const Livery *livery = GetEngineLivery(engine_type, player, parent_engine_type, v);
  2639 
  2659 
  2640 	map += livery->colour1;
  2660 	map += livery->colour1;
  2641 	if (twocc) map += livery->colour2 * 16;
  2661 	if (twocc) map += livery->colour2 * 16;
  2642 
  2662 
       
  2663 	/* Update cache */
       
  2664 	if (v != NULL) ((Vehicle*)v)->colormap = map;
  2643 	return map;
  2665 	return map;
  2644 }
  2666 }
  2645 
  2667 
  2646 SpriteID GetEnginePalette(EngineID engine_type, PlayerID player)
  2668 SpriteID GetEnginePalette(EngineID engine_type, PlayerID player)
  2647 {
  2669 {
  3090 	switch (this->current_order.type) {
  3112 	switch (this->current_order.type) {
  3091 		case OT_LOADING: {
  3113 		case OT_LOADING: {
  3092 			uint wait_time = max(this->current_order.wait_time - this->lateness_counter, 0);
  3114 			uint wait_time = max(this->current_order.wait_time - this->lateness_counter, 0);
  3093 
  3115 
  3094 			/* Not the first call for this tick, or still loading */
  3116 			/* Not the first call for this tick, or still loading */
  3095 			if (mode || !HASBIT(this->vehicle_flags, VF_LOADING_FINISHED) ||
  3117 			if (mode || !HasBit(this->vehicle_flags, VF_LOADING_FINISHED) ||
  3096 					(_patches.timetabling && this->current_order_time < wait_time)) return;
  3118 					(_patches.timetabling && this->current_order_time < wait_time)) return;
  3097 
  3119 
  3098 			this->PlayLeaveStationSound();
  3120 			this->PlayLeaveStationSound();
  3099 
  3121 
  3100 			Order b = this->current_order;
  3122 			Order b = this->current_order;