1
0
Fork 0

Change: Ships may reverse on find closest depot order

Ships may be allowed to reverse when:
- manually ordered to find the closest ship depot.
- executing an updated order to find the closest ship depot after departing from a station.
pull/10544/head
SamuXarick 2024-12-21 10:33:17 +00:00
parent 7df9426000
commit 8031d68d01
14 changed files with 27 additions and 23 deletions

View File

@ -110,7 +110,7 @@ struct Aircraft final : public SpecializedVehicle<Aircraft, VEH_AIRCRAFT> {
uint Crash(bool flooded = false) override; uint Crash(bool flooded = false) override;
TileIndex GetOrderStationLocation(StationID station) override; TileIndex GetOrderStationLocation(StationID station) override;
TileIndex GetCargoTile() const override { return this->First()->tile; } TileIndex GetCargoTile() const override { return this->First()->tile; }
ClosestDepot FindClosestDepot() override; ClosestDepot FindClosestDepot(bool may_reverse = false) override;
/** /**
* Check if the aircraft type is a normal flying device; eg * Check if the aircraft type is a normal flying device; eg

View File

@ -396,7 +396,7 @@ CommandCost CmdBuildAircraft(DoCommandFlags flags, TileIndex tile, const Engine
} }
ClosestDepot Aircraft::FindClosestDepot() ClosestDepot Aircraft::FindClosestDepot([[maybe_unused]] bool may_reverse)
{ {
const Station *st = GetTargetAirportIfValid(this); const Station *st = GetTargetAirportIfValid(this);
/* If the station is not a valid airport or if it has no hangars */ /* If the station is not a valid airport or if it has no hangars */

View File

@ -1896,10 +1896,11 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v)
* Update the vehicle's destination tile from an order. * Update the vehicle's destination tile from an order.
* @param order the order the vehicle currently has * @param order the order the vehicle currently has
* @param v the vehicle to update * @param v the vehicle to update
* @param may_reverse Whether the vehicle is allowed to reverse when executing the updated order.
* @param conditional_depth the depth (amount of steps) to go with conditional orders. This to prevent infinite loops. * @param conditional_depth the depth (amount of steps) to go with conditional orders. This to prevent infinite loops.
* @param pbs_look_ahead Whether we are forecasting orders for pbs reservations in advance. If true, the order indices must not be modified. * @param pbs_look_ahead Whether we are forecasting orders for pbs reservations in advance. If true, the order indices must not be modified.
*/ */
bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool pbs_look_ahead) bool UpdateOrderDest(Vehicle *v, const Order *order, bool may_reverse, int conditional_depth, bool pbs_look_ahead)
{ {
if (conditional_depth > v->GetNumOrders()) { if (conditional_depth > v->GetNumOrders()) {
v->current_order.Free(); v->current_order.Free();
@ -1926,7 +1927,7 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool
if (v->dest_tile == 0 && TimerGameEconomy::date_fract != (v->index % Ticks::DAY_TICKS)) break; if (v->dest_tile == 0 && TimerGameEconomy::date_fract != (v->index % Ticks::DAY_TICKS)) break;
/* We need to search for the nearest depot (hangar). */ /* We need to search for the nearest depot (hangar). */
ClosestDepot closest_depot = v->FindClosestDepot(); ClosestDepot closest_depot = v->FindClosestDepot(may_reverse);
if (closest_depot.found) { if (closest_depot.found) {
/* PBS reservations cannot reverse */ /* PBS reservations cannot reverse */
@ -2018,7 +2019,7 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool
} }
v->current_order = *order; v->current_order = *order;
return UpdateOrderDest(v, order, conditional_depth + 1, pbs_look_ahead); return UpdateOrderDest(v, order, may_reverse, conditional_depth + 1, pbs_look_ahead);
} }
/** /**
@ -2116,7 +2117,7 @@ bool ProcessOrders(Vehicle *v)
break; break;
} }
return UpdateOrderDest(v, order) && may_reverse; return UpdateOrderDest(v, order, may_reverse) && may_reverse;
} }
/** /**

View File

@ -20,7 +20,7 @@ void InvalidateVehicleOrder(const Vehicle *v, int data);
void CheckOrders(const Vehicle*); void CheckOrders(const Vehicle*);
void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist = false, bool reset_order_indices = true); void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist = false, bool reset_order_indices = true);
bool ProcessOrders(Vehicle *v); bool ProcessOrders(Vehicle *v);
bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth = 0, bool pbs_look_ahead = false); bool UpdateOrderDest(Vehicle *v, const Order *order, bool may_reverse = false, int conditional_depth = 0, bool pbs_look_ahead = false);
VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v); VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v);
uint GetOrderDistance(VehicleOrderID prev, VehicleOrderID cur, const Vehicle *v, int conditional_depth = 0); uint GetOrderDistance(VehicleOrderID prev, VehicleOrderID cur, const Vehicle *v, int conditional_depth = 0);

View File

@ -40,9 +40,10 @@ bool YapfShipCheckReverse(const Ship *v, Trackdir *trackdir);
* @param max_penalty max distance (in pathfinder penalty) from the current ship position * @param max_penalty max distance (in pathfinder penalty) from the current ship position
* (used also as optimization - the pathfinder can stop path finding if max_penalty * (used also as optimization - the pathfinder can stop path finding if max_penalty
* was reached and no depot was seen) * was reached and no depot was seen)
* @param may_reverse whether the ship is allowed to reverse
* @return the data about the depot * @return the data about the depot
*/ */
FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_penalty); FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_penalty, bool may_reverse);
/** /**
* Finds the best path for given road vehicle using YAPF. * Finds the best path for given road vehicle using YAPF.

View File

@ -369,9 +369,10 @@ public:
* Find the best depot for a ship. * Find the best depot for a ship.
* @param v Ship * @param v Ship
* @param max_penalty maximum pathfinder cost. * @param max_penalty maximum pathfinder cost.
* @param may_reverse whether the ship is allowed to reverse.
* @return FindDepotData with the best depot tile, cost and whether to reverse. * @return FindDepotData with the best depot tile, cost and whether to reverse.
*/ */
static inline FindDepotData FindNearestDepot(const Ship *v, int max_penalty) static inline FindDepotData FindNearestDepot(const Ship *v, int max_penalty, bool may_reverse)
{ {
FindDepotData depot; FindDepotData depot;
@ -379,7 +380,7 @@ public:
ShipPathCache dummy_cache; ShipPathCache dummy_cache;
TileIndex tile = INVALID_TILE; TileIndex tile = INVALID_TILE;
Trackdir best_origin_dir = INVALID_TRACKDIR; Trackdir best_origin_dir = INVALID_TRACKDIR;
const bool search_both_ways = max_penalty == 0; const bool search_both_ways = may_reverse && max_penalty == 0;
const Trackdir forward_dir = v->GetVehicleTrackdir(); const Trackdir forward_dir = v->GetVehicleTrackdir();
const Trackdir reverse_dir = ReverseTrackdir(forward_dir); const Trackdir reverse_dir = ReverseTrackdir(forward_dir);
const TrackdirBits forward_dirs = TrackdirToTrackdirBits(forward_dir); const TrackdirBits forward_dirs = TrackdirToTrackdirBits(forward_dir);
@ -515,7 +516,7 @@ bool YapfShipCheckReverse(const Ship *v, Trackdir *trackdir)
return CYapfShip::CheckShipReverse(v, trackdir); return CYapfShip::CheckShipReverse(v, trackdir);
} }
FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_penalty) FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_penalty, bool may_reverse)
{ {
return CYapfShip::FindNearestDepot(v, max_penalty); return CYapfShip::FindNearestDepot(v, max_penalty, may_reverse);
} }

View File

@ -132,7 +132,7 @@ struct RoadVehicle final : public GroundVehicle<RoadVehicle, VEH_ROAD> {
uint Crash(bool flooded = false) override; uint Crash(bool flooded = false) override;
Trackdir GetVehicleTrackdir() const override; Trackdir GetVehicleTrackdir() const override;
TileIndex GetOrderStationLocation(StationID station) override; TileIndex GetOrderStationLocation(StationID station) override;
ClosestDepot FindClosestDepot() override; ClosestDepot FindClosestDepot(bool may_reverse = false) override;
bool IsBus() const; bool IsBus() const;

View File

@ -346,7 +346,7 @@ static FindDepotData FindClosestRoadDepot(const RoadVehicle *v, int max_distance
return YapfRoadVehicleFindNearestDepot(v, max_distance); return YapfRoadVehicleFindNearestDepot(v, max_distance);
} }
ClosestDepot RoadVehicle::FindClosestDepot() ClosestDepot RoadVehicle::FindClosestDepot([[maybe_unused]] bool may_reverse)
{ {
FindDepotData rfdd = FindClosestRoadDepot(this, 0); FindDepotData rfdd = FindClosestRoadDepot(this, 0);
if (rfdd.best_length == UINT_MAX) return ClosestDepot(); if (rfdd.best_length == UINT_MAX) return ClosestDepot();

View File

@ -57,7 +57,7 @@ struct Ship final : public SpecializedVehicle<Ship, VEH_SHIP> {
void OnNewEconomyDay() override; void OnNewEconomyDay() override;
Trackdir GetVehicleTrackdir() const override; Trackdir GetVehicleTrackdir() const override;
TileIndex GetOrderStationLocation(StationID station) override; TileIndex GetOrderStationLocation(StationID station) override;
ClosestDepot FindClosestDepot() override; ClosestDepot FindClosestDepot(bool may_reverse = false) override;
void UpdateCache(); void UpdateCache();
void SetDestTile(TileIndex tile) override; void SetDestTile(TileIndex tile) override;
}; };

View File

@ -142,12 +142,12 @@ void Ship::GetImage(Direction direction, EngineImageType image_type, VehicleSpri
result->Set(_ship_sprites[spritenum] + direction); result->Set(_ship_sprites[spritenum] + direction);
} }
static const Depot *FindClosestShipDepot(const Vehicle *v, uint max_distance) static const Depot *FindClosestShipDepot(const Vehicle *v, uint max_distance, bool may_reverse = false)
{ {
const TileIndex tile = v->tile; const TileIndex tile = v->tile;
if (IsShipDepotTile(tile) && IsTileOwner(tile, v->owner)) return Depot::GetByTile(tile); if (IsShipDepotTile(tile) && IsTileOwner(tile, v->owner)) return Depot::GetByTile(tile);
FindDepotData sfdd = YapfShipFindNearestDepot(Ship::From(v), max_distance); FindDepotData sfdd = YapfShipFindNearestDepot(Ship::From(v), max_distance, may_reverse);
if (sfdd.tile == INVALID_TILE) return nullptr; if (sfdd.tile == INVALID_TILE) return nullptr;
return Depot::GetByTile(sfdd.tile); return Depot::GetByTile(sfdd.tile);
@ -906,9 +906,9 @@ CommandCost CmdBuildShip(DoCommandFlags flags, TileIndex tile, const Engine *e,
return CommandCost(); return CommandCost();
} }
ClosestDepot Ship::FindClosestDepot() ClosestDepot Ship::FindClosestDepot(bool may_reverse)
{ {
const Depot *depot = FindClosestShipDepot(this, 0); const Depot *depot = FindClosestShipDepot(this, 0, may_reverse);
if (depot == nullptr) return ClosestDepot(); if (depot == nullptr) return ClosestDepot();
return ClosestDepot(depot->xy, depot->index); return ClosestDepot(depot->xy, depot->index);

View File

@ -129,7 +129,7 @@ struct Train final : public GroundVehicle<Train, VEH_TRAIN> {
uint Crash(bool flooded = false) override; uint Crash(bool flooded = false) override;
Trackdir GetVehicleTrackdir() const override; Trackdir GetVehicleTrackdir() const override;
TileIndex GetOrderStationLocation(StationID station) override; TileIndex GetOrderStationLocation(StationID station) override;
ClosestDepot FindClosestDepot() override; ClosestDepot FindClosestDepot(bool may_reverse = false) override;
void ReserveTrackUnderConsist() const; void ReserveTrackUnderConsist() const;

View File

@ -2176,7 +2176,7 @@ static FindDepotData FindClosestTrainDepot(Train *v, int max_distance)
return YapfTrainFindNearestDepot(v, max_distance); return YapfTrainFindNearestDepot(v, max_distance);
} }
ClosestDepot Train::FindClosestDepot() ClosestDepot Train::FindClosestDepot([[maybe_unused]] bool may_reverse)
{ {
FindDepotData tfdd = FindClosestTrainDepot(this, 0); FindDepotData tfdd = FindClosestTrainDepot(this, 0);
if (tfdd.best_length == UINT_MAX) return ClosestDepot(); if (tfdd.best_length == UINT_MAX) return ClosestDepot();

View File

@ -2583,7 +2583,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlags flags, DepotCommandFlags command
return CommandCost(); return CommandCost();
} }
ClosestDepot closest_depot = this->FindClosestDepot(); ClosestDepot closest_depot = this->FindClosestDepot(true);
static const StringID no_depot[] = {STR_ERROR_UNABLE_TO_FIND_ROUTE_TO, STR_ERROR_UNABLE_TO_FIND_LOCAL_DEPOT, STR_ERROR_UNABLE_TO_FIND_LOCAL_DEPOT, STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR}; static const StringID no_depot[] = {STR_ERROR_UNABLE_TO_FIND_ROUTE_TO, STR_ERROR_UNABLE_TO_FIND_LOCAL_DEPOT, STR_ERROR_UNABLE_TO_FIND_LOCAL_DEPOT, STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR};
if (!closest_depot.found) return CommandCost(no_depot[this->type]); if (!closest_depot.found) return CommandCost(no_depot[this->type]);

View File

@ -792,9 +792,10 @@ public:
/** /**
* Find the closest depot for this vehicle and tell us the location, * Find the closest depot for this vehicle and tell us the location,
* DestinationID and whether we should reverse. * DestinationID and whether we should reverse.
* @param may_reverse Whether the vehicle is allowed to reverse.
* @return A structure with information about the closest depot, if found. * @return A structure with information about the closest depot, if found.
*/ */
virtual ClosestDepot FindClosestDepot() { return {}; } virtual ClosestDepot FindClosestDepot([[maybe_unused]] bool may_reverse = false) { return {}; }
virtual void SetDestTile(TileIndex tile) { this->dest_tile = tile; } virtual void SetDestTile(TileIndex tile) { this->dest_tile = tile; }