Changeset - r14021:1aae6a0ffa3b
[Not reviewed]
master
0 3 0
rubidium - 14 years ago 2009-12-20 16:19:47
rubidium@openttd.org
(svn r18574) -Fix [FS#3392] (r18481): manually sending trains and RVs to depots didn't quite work
3 files changed with 14 insertions and 9 deletions:
0 comments (0 inline, 0 general)
src/roadveh_cmd.cpp
Show inline comments
 
@@ -340,50 +340,50 @@ CommandCost CmdSellRoadVeh(TileIndex til
 
{
 
	RoadVehicle *v = RoadVehicle::GetIfValid(p1);
 
	if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (v->vehstatus & VS_CRASHED) return_cmd_error(STR_ERROR_CAN_T_SELL_DESTROYED_VEHICLE);
 

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

	
 
	CommandCost ret(EXPENSES_NEW_VEHICLES, -v->value);
 

	
 
	if (flags & DC_EXEC) {
 
		delete v;
 
	}
 

	
 
	return ret;
 
}
 

	
 
static FindDepotData FindClosestRoadDepot(const RoadVehicle *v, int max_distance)
 
{
 
	if (IsRoadDepotTile(v->tile)) return FindDepotData(v->tile, 0);
 

	
 
	switch (_settings_game.pf.pathfinder_for_roadvehs) {
 
		case VPF_NPF: return NPFRoadVehicleFindNearestDepot(v, _settings_game.pf.npf.maximum_go_to_depot_penalty);
 
		case VPF_YAPF: return YapfRoadVehicleFindNearestDepot(v, _settings_game.pf.yapf.maximum_go_to_depot_penalty);
 
		case VPF_NPF: return NPFRoadVehicleFindNearestDepot(v, max_distance);
 
		case VPF_YAPF: return YapfRoadVehicleFindNearestDepot(v, max_distance);
 

	
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
bool RoadVehicle::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)
 
{
 
	FindDepotData rfdd = FindClosestRoadDepot(this, 0);
 
	if (rfdd.best_length == UINT_MAX) return false;
 

	
 
	if (location    != NULL) *location    = rfdd.tile;
 
	if (destination != NULL) *destination = GetDepotIndex(rfdd.tile);
 

	
 
	return true;
 
}
 

	
 
/** Send a road vehicle to the depot.
 
 * @param tile unused
 
 * @param flags operation to perform
 
 * @param p1 vehicle ID to send to the depot
 
 * @param p2 various bitmasked elements
 
 * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
 
 * - p2 bit 8-10 - VLW flag (for mass goto depot)
 
 * @param text unused
src/ship_cmd.cpp
Show inline comments
 
@@ -76,88 +76,93 @@ void DrawShipEngine(int left, int right,
 
 * @param height The height of the sprite
 
 */
 
void GetShipSpriteSize(EngineID engine, uint &width, uint &height)
 
{
 
	const Sprite *spr = GetSprite(GetShipIcon(engine), ST_NORMAL);
 

	
 
	width  = spr->width;
 
	height = spr->height;
 
}
 

	
 
SpriteID Ship::GetImage(Direction direction) const
 
{
 
	uint8 spritenum = this->spritenum;
 

	
 
	if (is_custom_sprite(spritenum)) {
 
		SpriteID sprite = GetCustomVehicleSprite(this, direction);
 
		if (sprite != 0) return sprite;
 

	
 
		spritenum = Engine::Get(this->engine_type)->original_image_index;
 
	}
 

	
 
	return _ship_sprites[spritenum] + direction;
 
}
 

	
 
static const Depot *FindClosestShipDepot(const Vehicle *v)
 
static const Depot *FindClosestShipDepot(const Vehicle *v, uint max_distance)
 
{
 
	/* Find the closest depot */
 
	const Depot *depot;
 
	const Depot *best_depot = NULL;
 
	uint best_dist = UINT_MAX;
 
	/* If we don't have a maximum distance, i.e. distance = 0,
 
	 * we want to find any depot so the best distance of no
 
	 * depot must be more than any correct distance. On the
 
	 * other hand if we have set a maximum distance, any depot
 
	 * further away than max_distance can safely be ignored. */
 
	uint best_dist = max_distance == 0 ? UINT_MAX : max_distance + 1;
 

	
 
	FOR_ALL_DEPOTS(depot) {
 
		TileIndex tile = depot->xy;
 
		if (IsShipDepotTile(tile) && IsTileOwner(tile, v->owner)) {
 
			uint dist = DistanceManhattan(tile, v->tile);
 
			if (dist < best_dist) {
 
				best_dist = dist;
 
				best_depot = depot;
 
			}
 
		}
 
	}
 

	
 
	return best_depot;
 
}
 

	
 
static void CheckIfShipNeedsService(Vehicle *v)
 
{
 
	if (Company::Get(v->owner)->settings.vehicle.servint_ships == 0 || !v->NeedsAutomaticServicing()) return;
 
	if (v->IsInDepot()) {
 
		VehicleServiceInDepot(v);
 
		return;
 
	}
 

	
 
	uint max_distance;
 
	switch (_settings_game.pf.pathfinder_for_ships) {
 
		case VPF_OPF:  max_distance = 12; break;
 
		case VPF_NPF:  max_distance = _settings_game.pf.npf.maximum_go_to_depot_penalty  / NPF_TILE_LENGTH;  break;
 
		case VPF_YAPF: max_distance = _settings_game.pf.yapf.maximum_go_to_depot_penalty / YAPF_TILE_LENGTH; break;
 
		default: NOT_REACHED();
 
	}
 

	
 
	const Depot *depot = FindClosestShipDepot(v);
 
	const Depot *depot = FindClosestShipDepot(v, max_distance);
 

	
 
	if (depot == NULL || DistanceManhattan(v->tile, depot->xy) > max_distance) {
 
	if (depot == NULL) {
 
		if (v->current_order.IsType(OT_GOTO_DEPOT)) {
 
			v->current_order.MakeDummy();
 
			SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		}
 
		return;
 
	}
 

	
 
	v->current_order.MakeGoToDepot(depot->index, ODTFB_SERVICE);
 
	v->dest_tile = depot->xy;
 
	SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
}
 

	
 
Money Ship::GetRunningCost() const
 
{
 
	const Engine *e = Engine::Get(this->engine_type);
 
	uint cost_factor = GetVehicleProperty(this, PROP_SHIP_RUNNING_COST_FACTOR, e->u.ship.running_cost);
 
	return GetPrice(PR_RUNNING_SHIP, cost_factor, e->grffile);
 
}
 

	
 
void Ship::OnNewDay()
 
{
 
	if ((++this->day_counter & 7) == 0)
 
		DecreaseVehicleValue(this);
 

	
 
@@ -703,49 +708,49 @@ CommandCost CmdBuildShip(TileIndex tile,
 
 * @return the cost of this operation or an error
 
 */
 
CommandCost CmdSellShip(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
{
 
	Ship *v = Ship::GetIfValid(p1);
 
	if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (v->vehstatus & VS_CRASHED) return_cmd_error(STR_ERROR_CAN_T_SELL_DESTROYED_VEHICLE);
 

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

	
 
	CommandCost ret(EXPENSES_NEW_VEHICLES, -v->value);
 

	
 
	if (flags & DC_EXEC) {
 
		delete v;
 
	}
 

	
 
	return ret;
 
}
 

	
 
bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)
 
{
 
	const Depot *depot = FindClosestShipDepot(this);
 
	const Depot *depot = FindClosestShipDepot(this, 0);
 

	
 
	if (depot == NULL) return false;
 

	
 
	if (location    != NULL) *location    = depot->xy;
 
	if (destination != NULL) *destination = depot->index;
 

	
 
	return true;
 
}
 

	
 
/** Send a ship to the depot.
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 vehicle ID to send to the depot
 
 * @param p2 various bitmasked elements
 
 * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
 
 * - p2 bit 8-10 - VLW flag (for mass goto depot)
 
 * @param text unused
 
 * @return the cost of this operation or an error
 
 */
 
CommandCost CmdSendShipToDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
{
 
	if (p2 & DEPOT_MASS_SEND) {
 
		/* Mass goto depot requested */
 
		if (!ValidVLWFlags(p2 & VLW_MASK)) return CMD_ERROR;
src/train_cmd.cpp
Show inline comments
 
@@ -2086,50 +2086,50 @@ CommandCost CmdRefitRailVehicle(TileInde
 
		Train *front = v->First();
 
		TrainConsistChanged(front, false);
 
		SetWindowDirty(WC_VEHICLE_DETAILS, front->index);
 
		SetWindowDirty(WC_VEHICLE_DEPOT, front->tile);
 
		InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
 
	} else {
 
		v->InvalidateNewGRFCacheOfChain(); // always invalidate; querycost might have filled it
 
	}
 

	
 
	return cost;
 
}
 

	
 
/** returns the tile of a depot to goto to. The given vehicle must not be
 
 * crashed! */
 
static FindDepotData FindClosestTrainDepot(Train *v, int max_distance)
 
{
 
	assert(!(v->vehstatus & VS_CRASHED));
 

	
 
	if (IsRailDepotTile(v->tile)) return FindDepotData(v->tile, 0);
 

	
 
	PBSTileInfo origin = FollowTrainReservation(v);
 
	if (IsRailDepotTile(origin.tile)) return FindDepotData(origin.tile, 0);
 

	
 
	switch (_settings_game.pf.pathfinder_for_trains) {
 
		case VPF_NPF: return NPFTrainFindNearestDepot(v, _settings_game.pf.npf.maximum_go_to_depot_penalty);
 
		case VPF_YAPF: return YapfTrainFindNearestDepot(v, _settings_game.pf.yapf.maximum_go_to_depot_penalty);
 
		case VPF_NPF: return NPFTrainFindNearestDepot(v, max_distance);
 
		case VPF_YAPF: return YapfTrainFindNearestDepot(v, max_distance);
 

	
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
bool Train::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)
 
{
 
	FindDepotData tfdd = FindClosestTrainDepot(this, 0);
 
	if (tfdd.best_length == UINT_MAX) return false;
 

	
 
	if (location    != NULL) *location    = tfdd.tile;
 
	if (destination != NULL) *destination = GetDepotIndex(tfdd.tile);
 
	if (reverse     != NULL) *reverse     = tfdd.reverse;
 

	
 
	return true;
 
}
 

	
 
/** Send a train to a depot
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 train to send to the depot
 
 * @param p2 various bitmasked elements
 
 * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
 
 * - p2 bit 8-10 - VLW flag (for mass goto depot)
0 comments (0 inline, 0 general)