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 } |
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); |
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. |
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 |
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; |