Changeset - r7490:4e86e893fa7f
[Not reviewed]
master
0 12 0
rubidium - 17 years ago 2007-08-29 21:49:08
rubidium@openttd.org
(svn r11001) -Codechange: unify the way to determine whether a vehicle is in a depot.
12 files changed with 55 insertions and 105 deletions:
0 comments (0 inline, 0 general)
src/ai/default/default.cpp
Show inline comments
 
@@ -335,13 +335,13 @@ static void AiHandleReplaceTrain(Player 
 
static void AiHandleReplaceRoadVeh(Player *p)
 
{
 
	const Vehicle* v = p->ai.cur_veh;
 
	BackuppedOrders orderbak[1];
 
	EngineID veh;
 

	
 
	if (!IsRoadVehInDepotStopped(v)) {
 
	if (!v->IsStoppedInDepot()) {
 
		AiHandleGotoDepot(p, CMD_SEND_ROADVEH_TO_DEPOT);
 
		return;
 
	}
 

	
 
	veh = AiChooseRoadVehToReplaceWith(p, v);
 
	if (veh != INVALID_ENGINE) {
 
@@ -364,13 +364,13 @@ static void AiHandleReplaceRoadVeh(Playe
 
static void AiHandleReplaceAircraft(Player *p)
 
{
 
	const Vehicle* v = p->ai.cur_veh;
 
	BackuppedOrders orderbak[1];
 
	EngineID veh;
 

	
 
	if (!IsAircraftInHangarStopped(v)) {
 
	if (!v->IsStoppedInDepot()) {
 
		AiHandleGotoDepot(p, CMD_SEND_AIRCRAFT_TO_HANGAR);
 
		return;
 
	}
 

	
 
	veh = AiChooseAircraftToReplaceWith(p, v);
 
	if (veh != INVALID_ENGINE) {
 
@@ -3575,21 +3575,21 @@ static void AiStateSellVeh(Player *p)
 
			}
 

	
 
			// Sell whole train
 
			DoCommand(v->tile, v->index, 1, DC_EXEC, CMD_SELL_RAIL_WAGON);
 

	
 
		} else if (v->type == VEH_ROAD) {
 
			if (!IsRoadVehInDepotStopped(v)) {
 
			if (!v->IsStoppedInDepot()) {
 
				if (v->current_order.type != OT_GOTO_DEPOT)
 
					DoCommand(0, v->index, 0, DC_EXEC, CMD_SEND_ROADVEH_TO_DEPOT);
 
				goto going_to_depot;
 
			}
 

	
 
			DoCommand(0, v->index, 0, DC_EXEC, CMD_SELL_ROAD_VEH);
 
		} else if (v->type == VEH_AIRCRAFT) {
 
			if (!IsAircraftInHangarStopped(v)) {
 
			if (!v->IsStoppedInDepot()) {
 
				if (v->current_order.type != OT_GOTO_DEPOT)
 
					DoCommand(0, v->index, 0, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR);
 
				goto going_to_depot;
 
			}
 

	
 
			DoCommand(0, v->index, 0, DC_EXEC, CMD_SELL_AIRCRAFT);
src/aircraft.h
Show inline comments
 
@@ -30,31 +30,12 @@ static inline bool IsNormalAircraft(cons
 
	/* To be fully correct the commented out functionality is the proper one,
 
	 * but since value can only be 0 or 2, it is sufficient to only check <= 2
 
	 * return (v->subtype == AIR_HELICOPTER) || (v->subtype == AIR_AIRCRAFT); */
 
	return v->subtype <= AIR_AIRCRAFT;
 
}
 

	
 
/** Check if this aircraft is in a hangar
 
 * @param v vehicle to check
 
 * @return true if in hangar
 
 */
 
static inline bool IsAircraftInHangar(const Vehicle *v)
 
{
 
	assert(v->type == VEH_AIRCRAFT);
 
	return v->vehstatus & VS_HIDDEN && IsHangarTile(v->tile);
 
}
 

	
 
/** Check if this aircraft is in a hangar and stopped
 
 * @param v vehicle to check
 
 * @return true if in hangar and stopped
 
 */
 
static inline bool IsAircraftInHangarStopped(const Vehicle *v)
 
{
 
	return IsAircraftInHangar(v) && v->vehstatus & VS_STOPPED;
 
}
 

	
 
/** Checks if an aircraft is buildable at the tile in question
 
 * @param engine The engine to test
 
 * @param tile The tile where the hangar is
 
 * @return true if the aircraft can be build
 
 */
 
static inline bool IsAircraftBuildableAtStation(EngineID engine, TileIndex tile)
 
@@ -130,10 +111,11 @@ struct Aircraft : public Vehicle {
 
	WindowClass GetVehicleListWindowClass() const { return WC_AIRCRAFT_LIST; }
 
	bool IsPrimaryVehicle() const { return IsNormalAircraft(this); }
 
	int GetImage(Direction direction) const;
 
	int GetDisplaySpeed() const { return this->cur_speed * 10 / 16; }
 
	int GetDisplayMaxSpeed() const { return this->max_speed * 10 / 16; }
 
	Money GetRunningCost() const { return AircraftVehInfo(this->engine_type)->running_cost * _price.aircraft_running; }
 
	bool IsInDepot() const { return (this->vehstatus & VS_HIDDEN) != 0 && IsHangarTile(this->tile); }
 
	void Tick();
 
};
 

	
 
#endif /* AIRCRAFT_H */
src/aircraft_cmd.cpp
Show inline comments
 
@@ -482,13 +482,13 @@ CommandCost CmdSellAircraft(TileIndex ti
 
{
 
	if (!IsValidVehicleID(p1)) return CMD_ERROR;
 

	
 
	Vehicle *v = GetVehicle(p1);
 

	
 
	if (v->type != VEH_AIRCRAFT || !CheckOwnership(v->owner)) return CMD_ERROR;
 
	if (!IsAircraftInHangarStopped(v)) return_cmd_error(STR_A01B_AIRCRAFT_MUST_BE_STOPPED);
 
	if (!v->IsStoppedInDepot()) return_cmd_error(STR_A01B_AIRCRAFT_MUST_BE_STOPPED);
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 

	
 
	if (flags & DC_EXEC) {
 
		// Invalidate depot
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
@@ -523,13 +523,13 @@ CommandCost CmdStartStopAircraft(TileInd
 
	if (callback != CALLBACK_FAILED && callback != 0xFF) {
 
		StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
 
		return_cmd_error(error);
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		if (IsAircraftInHangarStopped(v)) {
 
		if (v->IsStoppedInDepot()) {
 
			DeleteVehicleNews(p1, STR_A014_AIRCRAFT_IS_WAITING_IN);
 
		}
 

	
 
		v->vehstatus ^= VS_STOPPED;
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
@@ -557,13 +557,13 @@ CommandCost CmdSendAircraftToHangar(Tile
 
	}
 

	
 
	if (!IsValidVehicleID(p1)) return CMD_ERROR;
 

	
 
	Vehicle *v = GetVehicle(p1);
 

	
 
	if (v->type != VEH_AIRCRAFT || !CheckOwnership(v->owner) || IsAircraftInHangar(v)) return CMD_ERROR;
 
	if (v->type != VEH_AIRCRAFT || !CheckOwnership(v->owner) || v->IsInDepot()) return CMD_ERROR;
 

	
 
	if (v->current_order.type == OT_GOTO_DEPOT && !(p2 & DEPOT_LOCATE_HANGAR)) {
 
		if (!!(p2 & DEPOT_SERVICE) == HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT)) {
 
			/* We called with a different DEPOT_SERVICE setting.
 
			 * Now we change the setting to apply the new one and let the vehicle head for the same hangar.
 
			 * Note: the if is (true for requesting service == true for ordered to stop in hangar) */
 
@@ -631,13 +631,13 @@ CommandCost CmdRefitAircraft(TileIndex t
 

	
 
	if (!IsValidVehicleID(p1)) return CMD_ERROR;
 

	
 
	Vehicle *v = GetVehicle(p1);
 

	
 
	if (v->type != VEH_AIRCRAFT || !CheckOwnership(v->owner)) return CMD_ERROR;
 
	if (!IsAircraftInHangarStopped(v)) return_cmd_error(STR_A01B_AIRCRAFT_MUST_BE_STOPPED);
 
	if (!v->IsStoppedInDepot()) return_cmd_error(STR_A01B_AIRCRAFT_MUST_BE_STOPPED);
 

	
 
	/* Check cargo */
 
	CargoID new_cid = GB(p2, 0, 8);
 
	if (new_cid >= NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_RUN);
 
@@ -703,13 +703,13 @@ static void CheckIfAircraftNeedsService(
 
	if (v->current_order.type == OT_GOTO_DEPOT &&
 
			v->current_order.flags & OF_HALT_IN_DEPOT)
 
		return;
 

	
 
	if (_patches.gotodepot && VehicleHasDepotOrders(v)) return;
 

	
 
	if (IsAircraftInHangar(v)) {
 
		if (v->IsInDepot()) {
 
		VehicleServiceInDepot(v);
 
		return;
 
	}
 

	
 
	const Station *st = GetStation(v->current_order.dest);
 
	/* only goto depot if the target airport has terminals (eg. it is airport) */
src/group_gui.cpp
Show inline comments
 
@@ -455,13 +455,13 @@ static void GroupWndProc(Window *w, Wind
 
				assert(v->type == gv->vehicle_type && v->owner == owner);
 

	
 
				DrawVehicleImage(v, x + 19, y2 + 6, w->hscroll.cap, 0, gv->vehicle_sel);
 
				DrawVehicleProfitButton(v, x, y2 + 13);
 

	
 
				SetDParam(0, v->unitnumber);
 
				DrawString(x, y2 + 2, IsVehicleInDepot(v) ? STR_021F : (v->age > v->max_age - 366 ? STR_00E3 : STR_00E2), 0);
 
				DrawString(x, y2 + 2, v->IsInDepot() ? STR_021F : (v->age > v->max_age - 366 ? STR_00E3 : STR_00E2), 0);
 

	
 
				if (w->resize.step_height == PLY_WND_PRC__SIZE_OF_ROW_BIG2) DrawSmallOrderList(v, x + 138, y2);
 

	
 
				SetDParam(0, v->profit_this_year);
 
				SetDParam(1, v->profit_last_year);
 
				DrawString(x + 19, y2 + w->resize.step_height - 8, STR_0198_PROFIT_THIS_YEAR_LAST_YEAR, 0);
src/roadveh.h
Show inline comments
 
@@ -42,23 +42,12 @@ static inline bool RoadVehHasArticPart(c
 
{
 
	assert(v->type == VEH_ROAD);
 
	return v->next != NULL && IsRoadVehArticPart(v->next);
 
}
 

	
 

	
 
static inline bool IsRoadVehInDepot(const Vehicle *v)
 
{
 
	assert(v->type == VEH_ROAD);
 
	return v->u.road.state == 254;
 
}
 

	
 
static inline bool IsRoadVehInDepotStopped(const Vehicle *v)
 
{
 
	return IsRoadVehInDepot(v) && v->vehstatus & VS_STOPPED;
 
}
 

	
 
void CcBuildRoadVeh(bool success, TileIndex tile, uint32 p1, uint32 p2);
 

	
 

	
 
/**
 
 * This class 'wraps' Vehicle; you do not actually instantiate this class.
 
 * You create a Vehicle using AllocateVehicle, so it is added to the pool
 
@@ -82,12 +71,13 @@ struct RoadVehicle : public Vehicle {
 
	bool IsPrimaryVehicle() const { return IsRoadVehFront(this); }
 
	bool HasFront() const { return true; }
 
	int GetImage(Direction direction) const;
 
	int GetDisplaySpeed() const { return this->cur_speed * 10 / 32; }
 
	int GetDisplayMaxSpeed() const { return this->max_speed * 10 / 32; }
 
	Money GetRunningCost() const { return RoadVehInfo(this->engine_type)->running_cost * _price.roadveh_running; }
 
	bool IsInDepot() const { return this->u.road.state == RVSB_IN_DEPOT; }
 
	void Tick();
 
};
 

	
 
byte GetRoadVehLength(const Vehicle *v);
 

	
 
void RoadVehUpdateCache(Vehicle *v);
src/roadveh_cmd.cpp
Show inline comments
 
@@ -301,13 +301,13 @@ CommandCost CmdStartStopRoadVeh(TileInde
 
	if (callback != CALLBACK_FAILED && callback != 0xFF) {
 
		StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
 
		return_cmd_error(error);
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		if (IsRoadVehInDepotStopped(v)) {
 
		if (v->IsStoppedInDepot()) {
 
			DeleteVehicleNews(p1, STR_9016_ROAD_VEHICLE_IS_WAITING);
 
		}
 

	
 
		v->vehstatus ^= VS_STOPPED;
 
		v->cur_speed = 0;
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 
@@ -466,13 +466,13 @@ CommandCost CmdSendRoadVehToDepot(TileIn
 
	v = GetVehicle(p1);
 

	
 
	if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
 

	
 
	if (IsRoadVehInDepot(v)) return CMD_ERROR;
 
	if (v->IsInDepot()) return CMD_ERROR;
 

	
 
	/* If the current orders are already goto-depot */
 
	if (v->current_order.type == OT_GOTO_DEPOT) {
 
		if (!!(p2 & DEPOT_SERVICE) == HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT)) {
 
			/* We called with a different DEPOT_SERVICE setting.
 
			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
 
@@ -535,13 +535,13 @@ CommandCost CmdTurnRoadVeh(TileIndex til
 

	
 
	if (v->vehstatus & VS_STOPPED ||
 
			v->vehstatus & VS_CRASHED ||
 
			v->breakdown_ctr != 0 ||
 
			v->u.road.overtaking != 0 ||
 
			v->u.road.state == RVSB_WORMHOLE ||
 
			IsRoadVehInDepot(v) ||
 
			v->IsInDepot() ||
 
			v->cur_speed < 5) {
 
		return CMD_ERROR;
 
	}
 

	
 
	if (IsTileType(v->tile, MP_ROAD) && GetRoadTileType(v->tile) == ROAD_TILE_NORMAL && GetDisallowedRoadDirections(v->tile) != DRD_NONE) return CMD_ERROR;
 

	
 
@@ -862,13 +862,13 @@ static void* EnumCheckRoadVehClose(Vehic
 

	
 
	short x_diff = v->x_pos - rvf->x;
 
	short y_diff = v->y_pos - rvf->y;
 

	
 
	return
 
		v->type == VEH_ROAD &&
 
		!IsRoadVehInDepot(v) &&
 
		!v->IsInDepot() &&
 
		myabs(v->z_pos - rvf->veh->z_pos) < 6 &&
 
		v->direction == rvf->dir &&
 
		GetFirstVehicleInChain(rvf->veh) != GetFirstVehicleInChain(v) &&
 
		(dist_x[v->direction] >= 0 || (x_diff > dist_x[v->direction] && x_diff <= 0)) &&
 
		(dist_x[v->direction] <= 0 || (x_diff < dist_x[v->direction] && x_diff >= 0)) &&
 
		(dist_y[v->direction] >= 0 || (y_diff > dist_y[v->direction] && y_diff <= 0)) &&
 
@@ -1436,13 +1436,13 @@ static bool IndividualRoadVehicleControl
 
			}
 
	}
 

	
 
	/* If this vehicle is in a depot and we've reached this point it must be
 
	 * one of the articulated parts. It will stay in the depot until activated
 
	 * by the previous vehicle in the chain when it gets to the right place. */
 
	if (IsRoadVehInDepot(v)) return true;
 
	if (v->IsInDepot()) return true;
 

	
 
	/* Save old vehicle position to use at end of move to set viewport area dirty */
 
	BeginVehicleMove(v);
 

	
 
	if (v->u.road.state == RVSB_WORMHOLE) {
 
		/* Vehicle is entering a depot or is on a bridge or in a tunnel */
 
@@ -1814,13 +1814,13 @@ static void RoadVehController(Vehicle *v
 

	
 
	ProcessRoadVehOrder(v);
 
	v->HandleLoading();
 

	
 
	if (v->current_order.type == OT_LOADING) return;
 

	
 
	if (IsRoadVehInDepot(v) && RoadVehLeaveDepot(v, true)) return;
 
	if (v->IsInDepot() && RoadVehLeaveDepot(v, true)) return;
 

	
 
	/* Check if vehicle needs to proceed, return if it doesn't */
 
	if (!RoadVehAccelerate(v)) return;
 

	
 
	for (Vehicle *prev = NULL; v != NULL; prev = v, v = v->next) {
 
		if (!IndividualRoadVehicleController(v, prev)) break;
 
@@ -1855,13 +1855,13 @@ static void CheckIfRoadVehNeedsService(V
 
			(v->current_order.flags & (OF_HALT_IN_DEPOT | OF_PART_OF_ORDERS)) != 0)
 
		return;
 

	
 
	/* If we already got a slot at a stop, use that FIRST, and go to a depot later */
 
	if (v->u.road.slot != NULL) return;
 

	
 
	if (IsRoadVehInDepot(v)) {
 
	if (v->IsInDepot()) {
 
		VehicleServiceInDepot(v);
 
		return;
 
	}
 

	
 
	/* XXX If we already have a depot order, WHY do we search over and over? */
 
	depot = FindClosestRoadDepot(v);
src/ship.h
Show inline comments
 
@@ -10,24 +10,12 @@
 
#include "variables.h"
 

	
 
void CcBuildShip(bool success, TileIndex tile, uint32 p1, uint32 p2);
 
void RecalcShipStuff(Vehicle *v);
 
void GetShipSpriteSize(EngineID engine, uint &width, uint &height);
 

	
 
static inline bool IsShipInDepot(const Vehicle *v)
 
{
 
	assert(v->type == VEH_SHIP);
 
	return v->u.ship.state == 0x80;
 
}
 

	
 
static inline bool IsShipInDepotStopped(const Vehicle *v)
 
{
 
	return IsShipInDepot(v) && v->vehstatus & VS_STOPPED;
 
}
 

	
 

	
 
/**
 
 * This class 'wraps' Vehicle; you do not actually instantiate this class.
 
 * You create a Vehicle using AllocateVehicle, so it is added to the pool
 
 * and you reinitialize that to a Train using:
 
 *   v = new (v) Ship();
 
 *
 
@@ -48,10 +36,11 @@ struct Ship: public Vehicle {
 
	void PlayLeaveStationSound() const;
 
	bool IsPrimaryVehicle() const { return true; }
 
	int GetImage(Direction direction) const;
 
	int GetDisplaySpeed() const { return this->cur_speed * 10 / 32; }
 
	int GetDisplayMaxSpeed() const { return this->max_speed * 10 / 32; }
 
	Money GetRunningCost() const { return ShipVehInfo(this->engine_type)->running_cost * _price.ship_running; }
 
	bool IsInDepot() const { return this->u.ship.state == 0x80; }
 
	void Tick();
 
};
 

	
 
#endif /* SHIP_H */
src/ship_cmd.cpp
Show inline comments
 
@@ -149,13 +149,13 @@ static void CheckIfShipNeedsService(Vehi
 
	if (v->current_order.type == OT_GOTO_DEPOT &&
 
			v->current_order.flags & OF_HALT_IN_DEPOT)
 
		return;
 

	
 
	if (_patches.gotodepot && VehicleHasDepotOrders(v)) return;
 

	
 
	if (IsShipInDepot(v)) {
 
	if (v->IsInDepot()) {
 
		VehicleServiceInDepot(v);
 
		return;
 
	}
 

	
 
	depot = FindClosestShipDepot(v);
 

	
 
@@ -352,13 +352,13 @@ static const TileIndexDiffC _ship_leave_
 
static void CheckShipLeaveDepot(Vehicle *v)
 
{
 
	TileIndex tile;
 
	Axis axis;
 
	uint m;
 

	
 
	if (!IsShipInDepot(v)) return;
 
	if (!v->IsInDepot()) return;
 

	
 
	tile = v->tile;
 
	axis = GetShipDepotAxis(tile);
 

	
 
	/* Check first side */
 
	if (_ship_sometracks[axis] & GetTileShipTrackStatus(TILE_ADD(tile, ToTileIndexDiff(_ship_leave_depot_offs[axis])))) {
 
@@ -675,13 +675,13 @@ static void ShipController(Vehicle *v)
 

	
 
	BeginVehicleMove(v);
 

	
 
	GetNewVehiclePosResult gp = GetNewVehiclePos(v);
 
	if (gp.old_tile == gp.new_tile) {
 
		/* Staying in tile */
 
		if (IsShipInDepot(v)) {
 
		if (v->IsInDepot()) {
 
			gp.x = v->x_pos;
 
			gp.y = v->y_pos;
 
		} else {
 
			/* Not inside depot */
 
			r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
 
			if (HASBIT(r, VETS_CANNOT_ENTER)) goto reverse_direction;
 
@@ -922,13 +922,13 @@ CommandCost CmdSellShip(TileIndex tile, 
 
	v = GetVehicle(p1);
 

	
 
	if (v->type != VEH_SHIP || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 

	
 
	if (!IsShipInDepotStopped(v)) {
 
	if (!v->IsStoppedInDepot()) {
 
		return_cmd_error(STR_980B_SHIP_MUST_BE_STOPPED_IN);
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
		RebuildVehicleLists();
 
@@ -964,13 +964,13 @@ CommandCost CmdStartStopShip(TileIndex t
 
	if (callback != CALLBACK_FAILED && callback != 0xFF) {
 
		StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
 
		return_cmd_error(error);
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		if (IsShipInDepotStopped(v)) {
 
		if (v->IsStoppedInDepot()) {
 
			DeleteVehicleNews(p1, STR_981C_SHIP_IS_WAITING_IN_DEPOT);
 
		}
 

	
 
		v->vehstatus ^= VS_STOPPED;
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
@@ -1004,13 +1004,13 @@ CommandCost CmdSendShipToDepot(TileIndex
 
	v = GetVehicle(p1);
 

	
 
	if (v->type != VEH_SHIP || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
 

	
 
	if (IsShipInDepot(v)) return CMD_ERROR;
 
	if (v->IsInDepot()) return CMD_ERROR;
 

	
 
	/* If the current orders are already goto-depot */
 
	if (v->current_order.type == OT_GOTO_DEPOT) {
 
		if (!!(p2 & DEPOT_SERVICE) == HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT)) {
 
			/* We called with a different DEPOT_SERVICE setting.
 
			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
 
@@ -1076,13 +1076,13 @@ CommandCost CmdRefitShip(TileIndex tile,
 
	if (!IsValidVehicleID(p1)) return CMD_ERROR;
 

	
 
	v = GetVehicle(p1);
 

	
 
	if (v->type != VEH_SHIP || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (!IsShipInDepotStopped(v)) {
 
	if (!v->IsStoppedInDepot()) {
 
		return_cmd_error(STR_980B_SHIP_MUST_BE_STOPPED_IN);
 
	}
 

	
 
	/* Check cargo */
 
	if (!ShipVehInfo(v->engine_type)->refittable) return CMD_ERROR;
 
	if (new_cid >= NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR;
src/train.h
Show inline comments
 
@@ -245,12 +245,15 @@ uint CountArticulatedParts(EngineID engi
 
int CheckTrainInDepot(const Vehicle *v, bool needs_to_be_stopped);
 
void CcBuildLoco(bool success, TileIndex tile, uint32 p1, uint32 p2);
 
void CcBuildWagon(bool success, TileIndex tile, uint32 p1, uint32 p2);
 

	
 
byte FreightWagonMult(CargoID cargo);
 

	
 
int CheckTrainInDepot(const Vehicle *v, bool needs_to_be_stopped);
 
int CheckTrainStoppedInDepot(const Vehicle *v);
 

	
 
/**
 
 * This class 'wraps' Vehicle; you do not actually instantiate this class.
 
 * You create a Vehicle using AllocateVehicle, so it is added to the pool
 
 * and you reinitialize that to a Train using:
 
 *   v = new (v) Train();
 
 *
 
@@ -272,10 +275,12 @@ struct Train : public Vehicle {
 
	bool IsPrimaryVehicle() const { return IsFrontEngine(this); }
 
	bool HasFront() const { return true; }
 
	int GetImage(Direction direction) const;
 
	int GetDisplaySpeed() const { return this->cur_speed * 10 / 16; }
 
	int GetDisplayMaxSpeed() const { return this->u.rail.cached_max_speed * 10 / 16; }
 
	Money GetRunningCost() const;
 
	bool IsInDepot() const { return CheckTrainInDepot(this, false) != -1; }
 
	bool IsStoppedInDepot() const { return CheckTrainStoppedInDepot(this) >= 0; }
 
	void Tick();
 
};
 

	
 
#endif /* TRAIN_H */
src/vehicle.cpp
Show inline comments
 
@@ -1697,13 +1697,13 @@ CommandCost CmdDepotMassAutoReplace(Tile
 
	for (i = 0; i < engine_count; i++) {
 
		Vehicle *v = vl[i];
 
		bool stopped = !(v->vehstatus & VS_STOPPED);
 
		CommandCost ret;
 

	
 
		/* Ensure that the vehicle completely in the depot */
 
		if (!IsVehicleInDepot(v)) continue;
 
		if (!v->IsInDepot()) continue;
 

	
 
		x = v->x_pos;
 
		y = v->y_pos;
 
		z = v->z_pos;
 

	
 
		if (stopped) {
 
@@ -1955,33 +1955,33 @@ void BuildDepotVehicleList(VehicleType t
 
				}
 
			}
 
			break;
 

	
 
		case VEH_ROAD:
 
			FOR_ALL_VEHICLES(v) {
 
				if (v->tile == tile && v->type == VEH_ROAD && IsRoadVehInDepot(v) && IsRoadVehFront(v)) {
 
				if (v->tile == tile && v->type == VEH_ROAD && v->IsInDepot() && IsRoadVehFront(v)) {
 
					if (*engine_count == *engine_list_length) ExtendVehicleListSize((const Vehicle***)engine_list, engine_list_length, 25);
 
					(*engine_list)[(*engine_count)++] = v;
 
				}
 
			}
 
			break;
 

	
 
		case VEH_SHIP:
 
			FOR_ALL_VEHICLES(v) {
 
				if (v->tile == tile && v->type == VEH_SHIP && IsShipInDepot(v)) {
 
				if (v->tile == tile && v->type == VEH_SHIP && v->IsInDepot()) {
 
					if (*engine_count == *engine_list_length) ExtendVehicleListSize((const Vehicle***)engine_list, engine_list_length, 25);
 
					(*engine_list)[(*engine_count)++] = v;
 
				}
 
			}
 
			break;
 

	
 
		case VEH_AIRCRAFT:
 
			FOR_ALL_VEHICLES(v) {
 
				if (v->tile == tile &&
 
						v->type == VEH_AIRCRAFT && IsNormalAircraft(v) &&
 
						v->vehstatus & VS_HIDDEN) {
 
						v->IsInDepot()) {
 
					if (*engine_count == *engine_list_length) ExtendVehicleListSize((const Vehicle***)engine_list, engine_list_length, 25);
 
					(*engine_list)[(*engine_count)++] = v;
 
				}
 
			}
 
			break;
 

	
 
@@ -2130,36 +2130,12 @@ CommandCost SendAllVehiclesToDepot(Vehic
 
	}
 

	
 
	free((void*)sort_list);
 
	return (flags & DC_EXEC) ? CommandCost() : CMD_ERROR;
 
}
 

	
 
bool IsVehicleInDepot(const Vehicle *v)
 
{
 
	switch (v->type) {
 
		case VEH_TRAIN:    return CheckTrainInDepot(v, false) != -1;
 
		case VEH_ROAD:     return IsRoadVehInDepot(v);
 
		case VEH_SHIP:     return IsShipInDepot(v);
 
		case VEH_AIRCRAFT: return IsAircraftInHangar(v);
 
		default: NOT_REACHED();
 
	}
 
	return false;
 
}
 

	
 
bool IsVehicleInDepotStopped(const Vehicle *v)
 
{
 
	switch (v->type) {
 
		case VEH_TRAIN:    return CheckTrainStoppedInDepot(v) >= 0;
 
		case VEH_ROAD:     return IsRoadVehInDepotStopped(v);
 
		case VEH_SHIP:     return IsShipInDepotStopped(v);
 
		case VEH_AIRCRAFT: return IsAircraftInHangarStopped(v);
 
		default: NOT_REACHED();
 
	}
 
	return false;
 
}
 

	
 
/**
 
 * Calculates how full a vehicle is.
 
 * @param v The Vehicle to check. For trains, use the first engine.
 
 * @param color The string to show depending on if we are unloading or loading
 
 * @return A percentage of how full the Vehicle is.
 
 */
 
@@ -2469,20 +2445,20 @@ Trackdir GetVehicleTrackdir(const Vehicl
 
			if (v->u.rail.track == TRACK_BIT_WORMHOLE) // train in tunnel, so just use his direction and assume a diagonal track
 
				return DiagdirToDiagTrackdir(DirToDiagDir(v->direction));
 

	
 
			return TrackDirectionToTrackdir(FindFirstTrack(v->u.rail.track), v->direction);
 

	
 
		case VEH_SHIP:
 
			if (IsShipInDepot(v))
 
			if (v->IsInDepot())
 
				// We'll assume the ship is facing outwards
 
				return DiagdirToDiagTrackdir(GetShipDepotDirection(v->tile));
 

	
 
			return TrackDirectionToTrackdir(FindFirstTrack(v->u.ship.state), v->direction);
 

	
 
		case VEH_ROAD:
 
			if (IsRoadVehInDepot(v)) // We'll assume the road vehicle is facing outwards
 
			if (v->IsInDepot()) // We'll assume the road vehicle is facing outwards
 
				return DiagdirToDiagTrackdir(GetRoadDepotDirection(v->tile));
 

	
 
			if (IsStandardRoadStopTile(v->tile)) // We'll assume the road vehicle is facing outwards
 
				return DiagdirToDiagTrackdir(GetRoadStopDir(v->tile)); // Road vehicle in a station
 

	
 
			if (IsDriveThroughStopTile(v->tile)) return DiagdirToDiagTrackdir(DirToDiagDir(v->direction));
src/vehicle.h
Show inline comments
 
@@ -430,12 +430,24 @@ struct Vehicle : PoolItem<Vehicle, Vehic
 
	 * Gets the running cost of a vehicle
 
	 * @return the vehicle's running cost
 
	 */
 
	virtual Money GetRunningCost() const { return 0; }
 

	
 
	/**
 
	 * Check whether the vehicle is in the depot.
 
	 * @return true if and only if the vehicle is in the depot.
 
	 */
 
	virtual bool IsInDepot() const { return false; }
 

	
 
	/**
 
	 * Check whether the vehicle is in the depot *and* stopped.
 
	 * @return true if and only if the vehicle is in the depot and stopped.
 
	 */
 
	virtual bool IsStoppedInDepot() const { return this->IsInDepot() && (this->vehstatus & VS_STOPPED) != 0; }
 

	
 
	/**
 
	 * Calls the tick handler of the vehicle
 
	 */
 
	virtual void Tick() {};
 

	
 
	/**
 
	 * Gets the running cost of a vehicle  that can be sent into SetDParam for string processing.
 
@@ -570,21 +582,17 @@ void EndVehicleMove(Vehicle *v);
 
UnitID GetFreeUnitNumber(VehicleType type);
 

	
 
void TrainConsistChanged(Vehicle *v);
 
void TrainPowerChanged(Vehicle *v);
 
Money GetTrainRunningCost(const Vehicle *v);
 

	
 
int CheckTrainStoppedInDepot(const Vehicle *v);
 

	
 
bool VehicleNeedsService(const Vehicle *v);
 

	
 
uint GenerateVehicleSortList(const Vehicle*** sort_list, uint16 *length_of_array, VehicleType type, PlayerID owner, uint32 index, uint16 window_type);
 
void BuildDepotVehicleList(VehicleType type, TileIndex tile, Vehicle ***engine_list, uint16 *engine_list_length, uint16 *engine_count, Vehicle ***wagon_list, uint16 *wagon_list_length, uint16 *wagon_count);
 
CommandCost SendAllVehiclesToDepot(VehicleType type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id);
 
bool IsVehicleInDepot(const Vehicle *v);
 
bool IsVehicleInDepotStopped(const Vehicle *v);
 
void VehicleEnterDepot(Vehicle *v);
 

	
 
void InvalidateAutoreplaceWindow(EngineID e, GroupID id_g);
 

	
 
CommandCost MaybeReplaceVehicle(Vehicle *v, bool check, bool display_costs);
 
bool CanBuildVehicleInfrastructure(VehicleType type);
src/vehicle_gui.cpp
Show inline comments
 
@@ -1018,13 +1018,13 @@ static void DrawVehicleListWindow(Window
 
			SetDParam(0, v->index);
 
			DrawString(x + 19, y, STR_01AB, 0);
 
		}
 

	
 
		if (w->resize.step_height == PLY_WND_PRC__SIZE_OF_ROW_BIG) DrawSmallOrderList(v, x + 138, y);
 

	
 
		if (IsVehicleInDepot(v)) {
 
		if (v->IsInDepot()) {
 
			str = STR_021F;
 
		} else {
 
			str = (v->age > v->max_age - 366) ? STR_00E3 : STR_00E2;
 
		}
 

	
 
		SetDParam(0, v->unitnumber);
 
@@ -1543,15 +1543,15 @@ static bool IsVehicleRefitable(const Veh
 
{
 
	/* Why is this so different for different vehicles?
 
	 * Does maybe work one solution for all?
 
	 */
 
	switch (v->type) {
 
		case VEH_TRAIN:    return false;
 
		case VEH_ROAD:     return EngInfo(v->engine_type)->refit_mask != 0 && IsVehicleInDepotStopped(v);
 
		case VEH_SHIP:     return ShipVehInfo(v->engine_type)->refittable && IsVehicleInDepotStopped(v);
 
		case VEH_AIRCRAFT: return IsVehicleInDepotStopped(v);
 
		case VEH_ROAD:     return EngInfo(v->engine_type)->refit_mask != 0 && v->IsStoppedInDepot();
 
		case VEH_SHIP:     return ShipVehInfo(v->engine_type)->refittable && v->IsStoppedInDepot();
 
		case VEH_AIRCRAFT: return v->IsStoppedInDepot();
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
/** Message strings for heading to depot indexed by vehicle type. */
 
static const StringID _heading_for_depot_strings[] = {
 
@@ -1787,13 +1787,13 @@ static void VehicleViewWndProc(Window *w
 
			DeleteWindowById(WC_VEHICLE_DETAILS, w->window_number);
 
			DeleteWindowById(WC_VEHICLE_TIMETABLE, w->window_number);
 
			break;
 

	
 
		case WE_MOUSELOOP: {
 
			const Vehicle *v = GetVehicle(w->window_number);
 
			bool veh_stopped = IsVehicleInDepotStopped(v);
 
			bool veh_stopped = v->IsStoppedInDepot();
 

	
 
			/* Widget VVW_WIDGET_GOTO_DEPOT must be hidden if the vehicle is already
 
			 * stopped in depot.
 
			 * Widget VVW_WIDGET_CLONE_VEH should then be shown, since cloning is
 
			 * allowed only while in depot and stopped.
 
			 * This sytem allows to have two buttons, on top of each other.
0 comments (0 inline, 0 general)