vehicle.c
changeset 4676 e58dba0b7093
parent 4675 61585e778cc8
child 4678 073e56e25e83
equal deleted inserted replaced
4675:61585e778cc8 4676:e58dba0b7093
   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;