589 void RoadVeh_Tick(Vehicle *v); |
589 void RoadVeh_Tick(Vehicle *v); |
590 void Ship_Tick(Vehicle *v); |
590 void Ship_Tick(Vehicle *v); |
591 void Train_Tick(Vehicle *v); |
591 void Train_Tick(Vehicle *v); |
592 static void EffectVehicle_Tick(Vehicle *v); |
592 static void EffectVehicle_Tick(Vehicle *v); |
593 void DisasterVehicle_Tick(Vehicle *v); |
593 void DisasterVehicle_Tick(Vehicle *v); |
594 static int32 MaybeReplaceVehicle(Vehicle **original_vehicle, bool check, bool display_costs); |
594 static int32 MaybeReplaceVehicle(Vehicle *v, bool check, bool display_costs); |
595 |
595 |
596 // head of the linked list to tell what vehicles that visited a depot in a tick |
596 // head of the linked list to tell what vehicles that visited a depot in a tick |
597 static Vehicle* _first_veh_in_depot_list; |
597 static Vehicle* _first_veh_in_depot_list; |
598 |
598 |
599 /** Adds a vehicle to the list of vehicles, that visited a depot this tick |
599 /** Adds a vehicle to the list of vehicles, that visited a depot this tick |
669 // now we handle all the vehicles that entered a depot this tick |
669 // now we handle all the vehicles that entered a depot this tick |
670 v = _first_veh_in_depot_list; |
670 v = _first_veh_in_depot_list; |
671 while (v != NULL) { |
671 while (v != NULL) { |
672 Vehicle *w = v->depot_list; |
672 Vehicle *w = v->depot_list; |
673 v->depot_list = NULL; // it should always be NULL at the end of each tick |
673 v->depot_list = NULL; // it should always be NULL at the end of each tick |
674 MaybeReplaceVehicle(&v, false, true); |
674 MaybeReplaceVehicle(v, false, true); |
675 v = w; |
675 v = w; |
676 } |
676 } |
677 } |
677 } |
678 |
678 |
679 static bool CanFillVehicle_FullLoadAny(Vehicle *v) |
679 static bool CanFillVehicle_FullLoadAny(Vehicle *v) |
1727 if ((vehicle_type == VEH_Train && !CheckTrainInDepot(v, false)) || |
1727 if ((vehicle_type == VEH_Train && !CheckTrainInDepot(v, false)) || |
1728 (vehicle_type == VEH_Road && !IsRoadVehInDepot(v) ) || |
1728 (vehicle_type == VEH_Road && !IsRoadVehInDepot(v) ) || |
1729 (vehicle_type == VEH_Ship && !IsShipInDepot(v) ) || |
1729 (vehicle_type == VEH_Ship && !IsShipInDepot(v) ) || |
1730 (vehicle_type == VEH_Aircraft && !IsAircraftInHangar(v)) ) continue; |
1730 (vehicle_type == VEH_Aircraft && !IsAircraftInHangar(v)) ) continue; |
1731 |
1731 |
1732 if (stopped) v->vehstatus |= VS_STOPPED; // Stop the vehicle |
1732 x = v->x_pos; |
1733 ret = MaybeReplaceVehicle(&v, !(flags & DC_EXEC), false); |
1733 y = v->y_pos; |
1734 if (stopped) v->vehstatus &= ~VS_STOPPED; // restart the vehicle if we stopped it for being replaced |
1734 z = v->z_pos; |
|
1735 |
|
1736 if (stopped) { |
|
1737 v->vehstatus |= VS_STOPPED; // Stop the vehicle |
|
1738 v->leave_depot_instantly = true; |
|
1739 } |
|
1740 ret = MaybeReplaceVehicle(v, !(flags & DC_EXEC), false); |
1735 |
1741 |
1736 if (!CmdFailed(ret)) { |
1742 if (!CmdFailed(ret)) { |
1737 cost += ret; |
1743 cost += ret; |
1738 if (!(flags & DC_EXEC)) break; |
1744 if (!(flags & DC_EXEC)) break; |
1739 x = v->x_pos; |
|
1740 y = v->y_pos; |
|
1741 z = v->z_pos; |
|
1742 /* There is a problem with autoreplace and newgrf |
1745 /* There is a problem with autoreplace and newgrf |
1743 * It's impossible to tell the length of a train after it's being replaced before it's actually done |
1746 * It's impossible to tell the length of a train after it's being replaced before it's actually done |
1744 * Because of this, we can't estimate costs due to wagon removal and we will have to always return 0 and pay manually |
1747 * Because of this, we can't estimate costs due to wagon removal and we will have to always return 0 and pay manually |
1745 * Since we pay after each vehicle is replaced and MaybeReplaceVehicle() check if the player got enough money |
1748 * Since we pay after each vehicle is replaced and MaybeReplaceVehicle() check if the player got enough money |
1746 * we should never reach a condition where the player will end up with negative money from doing this */ |
1749 * we should never reach a condition where the player will end up with negative money from doing this */ |
2067 * if the vehicle is a train, v needs to be the front engine |
2070 * if the vehicle is a train, v needs to be the front engine |
2068 * @param check Checks if the replace is valid. No action is done at all |
2071 * @param check Checks if the replace is valid. No action is done at all |
2069 * @param display_costs If set, a cost animation is shown (only if check is false) |
2072 * @param display_costs If set, a cost animation is shown (only if check is false) |
2070 * @return CMD_ERROR if something went wrong. Otherwise the price of the replace |
2073 * @return CMD_ERROR if something went wrong. Otherwise the price of the replace |
2071 */ |
2074 */ |
2072 static int32 MaybeReplaceVehicle(Vehicle **original_vehicle, bool check, bool display_costs) |
2075 static int32 MaybeReplaceVehicle(Vehicle *v, bool check, bool display_costs) |
2073 { |
2076 { |
2074 Vehicle *v = *original_vehicle; |
|
2075 Vehicle *w; |
2077 Vehicle *w; |
2076 const Player *p = GetPlayer(v->owner); |
2078 const Player *p = GetPlayer(v->owner); |
2077 byte flags = 0; |
2079 byte flags = 0; |
2078 int32 cost, temp_cost = 0; |
2080 int32 cost, temp_cost = 0; |
2079 bool stopped = false; |
2081 bool stopped = false; |
2148 } |
2150 } |
2149 |
2151 |
2150 AddNewsItem(message, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0); |
2152 AddNewsItem(message, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0); |
2151 } |
2153 } |
2152 if (stopped) v->vehstatus &= ~VS_STOPPED; |
2154 if (stopped) v->vehstatus &= ~VS_STOPPED; |
2153 _current_player = OWNER_NONE; |
2155 if (display_costs) _current_player = OWNER_NONE; |
2154 return CMD_ERROR; |
2156 return CMD_ERROR; |
2155 } |
2157 } |
2156 |
2158 |
2157 if (flags & DC_EXEC) { |
2159 if (flags & DC_EXEC) { |
2158 break; // we are done replacing since the loop ran once with DC_EXEC |
2160 break; // we are done replacing since the loop ran once with DC_EXEC |
2186 DoCommand(0, (INVALID_VEHICLE << 16) | temp->index, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE); |
2188 DoCommand(0, (INVALID_VEHICLE << 16) | temp->index, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE); |
2187 MoveVehicleCargo(v, temp); |
2189 MoveVehicleCargo(v, temp); |
2188 cost += DoCommand(0, temp->index, 0, DC_EXEC, CMD_SELL_RAIL_WAGON); |
2190 cost += DoCommand(0, temp->index, 0, DC_EXEC, CMD_SELL_RAIL_WAGON); |
2189 } |
2191 } |
2190 } |
2192 } |
2191 |
|
2192 original_vehicle = &v; |
|
2193 |
2193 |
2194 if (stopped) v->vehstatus &= ~VS_STOPPED; |
2194 if (stopped) v->vehstatus &= ~VS_STOPPED; |
2195 if (display_costs) { |
2195 if (display_costs) { |
2196 if (IsLocalPlayer()) ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost); |
2196 if (IsLocalPlayer()) ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost); |
2197 _current_player = OWNER_NONE; |
2197 _current_player = OWNER_NONE; |