1
0
Fork 0

Remove: Settings for NPF & YAPF

pull/10623/head
Charles Pigott 2023-04-10 10:31:51 +01:00
parent 4cd46e54aa
commit 00c314d5e9
17 changed files with 133 additions and 492 deletions

View File

@ -49,7 +49,7 @@ void AyStar::CheckTile(AyStarNode *current, PathNode *parent)
assert(new_g >= 0); assert(new_g >= 0);
/* Add the parent g-value to the new g-value */ /* Add the parent g-value to the new g-value */
new_g += parent->cost; new_g += parent->cost;
if (this->max_path_cost != 0 && new_g > this->max_path_cost) return; if (new_g > AYSTAR_MAX_SEARCH_NODES) return;
/* Calculate the h-value */ /* Calculate the h-value */
int new_h = this->CalculateH(this, current, parent); int new_h = this->CalculateH(this, current, parent);
@ -85,7 +85,7 @@ void AyStar::CheckTile(AyStarNode *current, PathNode *parent)
* its neighbour items. If they are valid, they are added to be checked too. * its neighbour items. If they are valid, they are added to be checked too.
* @return Possible values: * @return Possible values:
* - #AYSTAR_EMPTY_OPENLIST : indicates all items are tested, and no path has been found. * - #AYSTAR_EMPTY_OPENLIST : indicates all items are tested, and no path has been found.
* - #AYSTAR_LIMIT_REACHED : Indicates that the max_search_nodes limit has been reached. * - #AYSTAR_LIMIT_REACHED : Indicates that the #AYSTAR_MAX_SEARCH_NODES limit has been reached.
* - #AYSTAR_FOUND_END_NODE : indicates we found the end. Path_found now is true, and in path is the path found. * - #AYSTAR_FOUND_END_NODE : indicates we found the end. Path_found now is true, and in path is the path found.
* - #AYSTAR_STILL_BUSY : indicates we have done this tile, did not found the path yet, and have items left to try. * - #AYSTAR_STILL_BUSY : indicates we have done this tile, did not found the path yet, and have items left to try.
*/ */
@ -116,7 +116,7 @@ int AyStar::Loop()
this->CheckTile(&neighbour, current); this->CheckTile(&neighbour, current);
} }
if (this->max_search_nodes != 0 && this->nodes.ClosedCount() >= this->max_search_nodes) { if (this->nodes.ClosedCount() >= AYSTAR_MAX_SEARCH_NODES) {
/* We've expanded enough nodes */ /* We've expanded enough nodes */
return AYSTAR_LIMIT_REACHED; return AYSTAR_LIMIT_REACHED;
} else { } else {

View File

@ -33,12 +33,14 @@ enum AystarStatus {
AYSTAR_EMPTY_OPENLIST, ///< All items are tested, and no path has been found. AYSTAR_EMPTY_OPENLIST, ///< All items are tested, and no path has been found.
AYSTAR_STILL_BUSY, ///< Some checking was done, but no path found yet, and there are still items left to try. AYSTAR_STILL_BUSY, ///< Some checking was done, but no path found yet, and there are still items left to try.
AYSTAR_NO_PATH, ///< No path to the goal was found. AYSTAR_NO_PATH, ///< No path to the goal was found.
AYSTAR_LIMIT_REACHED, ///< The #AyStar::max_search_nodes limit has been reached, aborting search. AYSTAR_LIMIT_REACHED, ///< The #AYSTAR_MAX_SEARCH_NODES limit has been reached, aborting search.
AYSTAR_DONE, ///< Not an end-tile, or wrong direction. AYSTAR_DONE, ///< Not an end-tile, or wrong direction.
}; };
static const int AYSTAR_INVALID_NODE = -1; ///< Item is not valid (for example, not walkable). static const int AYSTAR_INVALID_NODE = -1; ///< Item is not valid (for example, not walkable).
static const int AYSTAR_MAX_SEARCH_NODES = 10000; ///< The maximum number of nodes that will be expanded.
using AyStarNode = CYapfNodeKeyTrackDir; using AyStarNode = CYapfNodeKeyTrackDir;
struct PathNode : CYapfNodeT<AyStarNode, PathNode> { struct PathNode : CYapfNodeT<AyStarNode, PathNode> {
@ -122,8 +124,6 @@ struct AyStar {
void *user_data; void *user_data;
uint8_t loops_per_tick; ///< How many loops are there called before Main() gives control back to the caller. 0 = until done. uint8_t loops_per_tick; ///< How many loops are there called before Main() gives control back to the caller. 0 = until done.
int max_path_cost; ///< If the g-value goes over this number, it stops searching, 0 = infinite.
int max_search_nodes = AYSTAR_DEF_MAX_SEARCH_NODES; ///< The maximum number of nodes that will be expanded, 0 = infinite.
/* These should be filled with the neighbours of a tile by GetNeighbours */ /* These should be filled with the neighbours of a tile by GetNeighbours */
std::vector<AyStarNode> neighbours; std::vector<AyStarNode> neighbours;

View File

@ -62,22 +62,16 @@ Track YapfTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdi
/** /**
* Used when user sends road vehicle to the nearest depot or if road vehicle needs servicing using YAPF. * Used when user sends road vehicle to the nearest depot or if road vehicle needs servicing using YAPF.
* @param v vehicle that needs to go to some depot * @param v vehicle that needs to go to some depot
* @param max_penalty max distance (in pathfinder penalty) from the current vehicle position
* (used also as optimization - the pathfinder can stop path finding if max_penalty
* was reached and no depot was seen)
* @return the data about the depot * @return the data about the depot
*/ */
FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_penalty); FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v);
/** /**
* Used when user sends train to the nearest depot or if train needs servicing using YAPF. * Used when user sends train to the nearest depot or if train needs servicing using YAPF.
* @param v train that needs to go to some depot * @param v train that needs to go to some depot
* @param max_distance max distance (int pathfinder penalty) from the current train position
* (used also as optimization - the pathfinder can stop path finding if max_penalty
* was reached and no depot was seen)
* @return the data about the depot * @return the data about the depot
*/ */
FindDepotData YapfTrainFindNearestDepot(const Train *v, int max_distance); FindDepotData YapfTrainFindNearestDepot(const Train *v);
/** /**
* Returns true if it is better to reverse the train before leaving station using YAPF. * Returns true if it is better to reverse the train before leaving station using YAPF.

View File

@ -59,10 +59,10 @@ public:
NodeList nodes; ///< node list multi-container NodeList nodes; ///< node list multi-container
protected: protected:
static const int MAX_SEARCH_NODES = 10000; ///< stop path-finding when this number of nodes visited
Node *best_dest_node = nullptr; ///< pointer to the destination node found at last round Node *best_dest_node = nullptr; ///< pointer to the destination node found at last round
Node *best_intermediate_node = nullptr; ///< here should be node closest to the destination if path not found Node *best_intermediate_node = nullptr; ///< here should be node closest to the destination if path not found
const YAPFSettings *settings; ///< current settings (_settings_game.yapf)
int max_search_nodes; ///< maximum number of nodes we are allowed to visit before we give up
const VehicleType *vehicle = nullptr; ///< vehicle that we are trying to drive const VehicleType *vehicle = nullptr; ///< vehicle that we are trying to drive
int stats_cost_calcs = 0; ///< stats - how many node's costs were calculated int stats_cost_calcs = 0; ///< stats - how many node's costs were calculated
@ -73,7 +73,7 @@ public:
public: public:
/** default constructor */ /** default constructor */
inline CYapfBaseT() : settings(&_settings_game.pf.yapf), max_search_nodes(PfGetSettings().max_search_nodes) {} inline CYapfBaseT() {}
/** default destructor */ /** default destructor */
~CYapfBaseT() {} ~CYapfBaseT() {}
@ -86,19 +86,13 @@ protected:
} }
public: public:
/** return current settings (can be custom - company based - but later) */
inline const YAPFSettings &PfGetSettings() const
{
return *this->settings;
}
/** /**
* Main pathfinder routine: * Main pathfinder routine:
* - set startup node(s) * - set startup node(s)
* - main loop that stops if: * - main loop that stops if:
* - the destination was found * - the destination was found
* - or the open list is empty (no route to destination). * - or the open list is empty (no route to destination).
* - or the maximum amount of loops reached - max_search_nodes (default = 10000) * - or the maximum amount of loops reached - MAX_SEARCH_NODES
* @return true if the path was found * @return true if the path was found
*/ */
inline bool FindPath(const VehicleType *v) inline bool FindPath(const VehicleType *v)
@ -118,7 +112,7 @@ public:
} }
Yapf().PfFollowNode(*best_open_node); Yapf().PfFollowNode(*best_open_node);
if (this->max_search_nodes != 0 && this->nodes.ClosedCount() >= this->max_search_nodes) break; if (this->nodes.ClosedCount() >= MAX_SEARCH_NODES) break;
this->nodes.PopOpenNode(best_open_node->GetKey()); this->nodes.PopOpenNode(best_open_node->GetKey());
this->nodes.InsertClosedNode(*best_open_node); this->nodes.InsertClosedNode(*best_open_node);
@ -227,7 +221,7 @@ public:
/* The new node can be set as the best intermediate node only once we're /* The new node can be set as the best intermediate node only once we're
* certain it will be finalized by being inserted into the open list. */ * certain it will be finalized by being inserted into the open list. */
bool set_intermediate = this->max_search_nodes > 0 && (this->best_intermediate_node == nullptr || (this->best_intermediate_node->GetCostEstimate() - this->best_intermediate_node->GetCost()) > (n.GetCostEstimate() - n.GetCost())); bool set_intermediate = this->best_intermediate_node == nullptr || (this->best_intermediate_node->GetCostEstimate() - this->best_intermediate_node->GetCost()) > (n.GetCostEstimate() - n.GetCost());
/* check new node against open list */ /* check new node against open list */
Node *open_node = this->nodes.FindOpenNode(n.GetKey()); Node *open_node = this->nodes.FindOpenNode(n.GetKey());

View File

@ -111,7 +111,7 @@ public:
/** return true if first two-way signal should be treated as dead end */ /** return true if first two-way signal should be treated as dead end */
inline bool TreatFirstRedTwoWaySignalAsEOL() inline bool TreatFirstRedTwoWaySignalAsEOL()
{ {
return Yapf().PfGetSettings().rail_firstred_twoway_eol && this->treat_first_red_two_way_signal_as_eol; return this->treat_first_red_two_way_signal_as_eol;
} }
}; };

View File

@ -17,6 +17,25 @@
#include "yapf_type.hpp" #include "yapf_type.hpp"
#include "yapf_costbase.hpp" #include "yapf_costbase.hpp"
static const uint YAPF_RAIL_FIRSTRED_PENALTY = 10 * YAPF_TILE_LENGTH; ///< penalty for first red signal
static const uint YAPF_RAIL_FIRSTRED_EXIT_PENALTY = 100 * YAPF_TILE_LENGTH; ///< penalty for first red exit signal
static const uint YAPF_RAIL_LASTRED_PENALTY = 10 * YAPF_TILE_LENGTH; ///< penalty for last red signal
static const uint YAPF_RAIL_LASTRED_EXIT_PENALTY = 100 * YAPF_TILE_LENGTH; ///< penalty for last red exit signal
static const uint YAPF_RAIL_STATION_PENALTY = 10 * YAPF_TILE_LENGTH; ///< penalty for non-target station tile
static const uint YAPF_RAIL_SLOPE_PENALTY = 2 * YAPF_TILE_LENGTH; ///< penalty for up-hill slope
static const uint YAPF_RAIL_CURVE45_PENALTY = 1 * YAPF_TILE_LENGTH; ///< penalty for curve
static const uint YAPF_RAIL_CURVE90_PENALTY = 6 * YAPF_TILE_LENGTH; ///< penalty for 90-deg curve
static const uint YAPF_RAIL_DEPOT_REVERSE_PENALTY = 50 * YAPF_TILE_LENGTH; ///< penalty for reversing in the depot
static const uint YAPF_RAIL_CROSSING_PENALTY = 3 * YAPF_TILE_LENGTH; ///< penalty for level crossing
static const uint YAPF_RAIL_PBS_CROSS_PENALTY = 3 * YAPF_TILE_LENGTH; ///< penalty for crossing a reserved tile
static const uint YAPF_RAIL_PBS_STATION_PENALTY = 8 * YAPF_TILE_LENGTH; ///< penalty for crossing a reserved station tile
static const uint YAPF_RAIL_PBS_SIGNAL_BACK_PENALTY = 15 * YAPF_TILE_LENGTH; ///< penalty for passing a pbs signal from the backside
static const uint YAPF_RAIL_DOUBLESLIP_PENALTY = 1 * YAPF_TILE_LENGTH; ///< penalty for passing a double slip switch
static const uint YAPF_RAIL_LONGER_PLATFORM_PENALTY = 8 * YAPF_TILE_LENGTH; ///< penalty for longer station platform than train
static const uint YAPF_RAIL_LONGER_PLATFORM_PER_TILE_PENALTY = 0 * YAPF_TILE_LENGTH; ///< penalty for longer station platform than train (per tile)
static const uint YAPF_RAIL_SHORTER_PLATFORM_PENALTY = 8 * YAPF_TILE_LENGTH; ///< penalty for shorter station platform than train
static const uint YAPF_RAIL_SHORTER_PLATFORM_PER_TILE_PENALTY = 0 * YAPF_TILE_LENGTH; ///< penalty for shorter station platform than train (per tile)
template <class Types> template <class Types>
class CYapfCostRailT : public CYapfCostBase { class CYapfCostRailT : public CYapfCostBase {
public: public:
@ -47,7 +66,24 @@ protected:
*/ */
int max_cost; int max_cost;
bool disable_cache; bool disable_cache;
std::vector<int> sig_look_ahead_costs;
static const int LOOK_AHEAD_MAX_SIGNALS = 10; ///< max. number of signals taken into consideration in look-ahead load balancer
static const int LOOK_AHEAD_SIGNAL_P0 = 500; ///< constant in polynomial penalty function
static const int LOOK_AHEAD_SIGNAL_P1 = -100; ///< constant in polynomial penalty function
static const int LOOK_AHEAD_SIGNAL_P2 = 5; ///< constant in polynomial penalty function
/** Pre-computes look-ahead penalties into array */
static constexpr std::array<int, LOOK_AHEAD_MAX_SIGNALS> init_lookahead_costs()
{
std::array<int, LOOK_AHEAD_MAX_SIGNALS> costs{};
for (int i = 0; i < LOOK_AHEAD_MAX_SIGNALS; i++) {
costs[i] = LOOK_AHEAD_SIGNAL_P0 + i * (LOOK_AHEAD_SIGNAL_P1 + i * LOOK_AHEAD_SIGNAL_P2);
}
return costs;
}
static constexpr auto sig_look_ahead_costs = init_lookahead_costs();
public: public:
bool stopped_on_first_two_way_signal; bool stopped_on_first_two_way_signal;
@ -56,17 +92,7 @@ protected:
static constexpr int MAX_SEGMENT_COST = 10000; static constexpr int MAX_SEGMENT_COST = 10000;
CYapfCostRailT() : max_cost(0), disable_cache(false), stopped_on_first_two_way_signal(false) CYapfCostRailT() : max_cost(0), disable_cache(false), stopped_on_first_two_way_signal(false)
{ {}
/* pre-compute look-ahead penalties into array */
int p0 = Yapf().PfGetSettings().rail_look_ahead_signal_p0;
int p1 = Yapf().PfGetSettings().rail_look_ahead_signal_p1;
int p2 = Yapf().PfGetSettings().rail_look_ahead_signal_p2;
this->sig_look_ahead_costs.clear();
this->sig_look_ahead_costs.reserve(Yapf().PfGetSettings().rail_look_ahead_max_signals);
for (uint i = 0; i < Yapf().PfGetSettings().rail_look_ahead_max_signals; i++) {
this->sig_look_ahead_costs.push_back(p0 + i * (p1 + i * p2));
}
}
/** to access inherited path finder */ /** to access inherited path finder */
Tpf &Yapf() Tpf &Yapf()
@ -78,7 +104,7 @@ public:
inline int SlopeCost(TileIndex tile, Trackdir td) inline int SlopeCost(TileIndex tile, Trackdir td)
{ {
if (!stSlopeCost(tile, td)) return 0; if (!stSlopeCost(tile, td)) return 0;
return Yapf().PfGetSettings().rail_slope_penalty; return YAPF_RAIL_SLOPE_PENALTY;
} }
inline int CurveCost(Trackdir td1, Trackdir td2) inline int CurveCost(Trackdir td1, Trackdir td2)
@ -89,10 +115,10 @@ public:
if (TrackFollower::Allow90degTurns() if (TrackFollower::Allow90degTurns()
&& HasTrackdir(TrackdirCrossesTrackdirs(td1), td2)) { && HasTrackdir(TrackdirCrossesTrackdirs(td1), td2)) {
/* 90-deg curve penalty */ /* 90-deg curve penalty */
cost += Yapf().PfGetSettings().rail_curve90_penalty; cost += YAPF_RAIL_CURVE90_PENALTY;
} else if (td2 != NextTrackdir(td1)) { } else if (td2 != NextTrackdir(td1)) {
/* 45-deg curve penalty */ /* 45-deg curve penalty */
cost += Yapf().PfGetSettings().rail_curve45_penalty; cost += YAPF_RAIL_CURVE45_PENALTY;
} }
return cost; return cost;
} }
@ -102,7 +128,7 @@ public:
if (IsPlainRailTile(tile1) && IsPlainRailTile(tile2)) { if (IsPlainRailTile(tile1) && IsPlainRailTile(tile2)) {
bool t1 = KillFirstBit(GetTrackBits(tile1) & DiagdirReachesTracks(ReverseDiagDir(exitdir))) != TRACK_BIT_NONE; bool t1 = KillFirstBit(GetTrackBits(tile1) & DiagdirReachesTracks(ReverseDiagDir(exitdir))) != TRACK_BIT_NONE;
bool t2 = KillFirstBit(GetTrackBits(tile2) & DiagdirReachesTracks(exitdir)) != TRACK_BIT_NONE; bool t2 = KillFirstBit(GetTrackBits(tile2) & DiagdirReachesTracks(exitdir)) != TRACK_BIT_NONE;
if (t1 && t2) return Yapf().PfGetSettings().rail_doubleslip_penalty; if (t1 && t2) return YAPF_RAIL_DOUBLESLIP_PENALTY;
} }
return 0; return 0;
} }
@ -118,7 +144,7 @@ public:
case MP_ROAD: case MP_ROAD:
/* Increase the cost for level crossings */ /* Increase the cost for level crossings */
if (IsLevelCrossing(tile)) { if (IsLevelCrossing(tile)) {
cost += Yapf().PfGetSettings().rail_crossing_penalty; cost += YAPF_RAIL_CROSSING_PENALTY;
} }
break; break;
@ -149,9 +175,9 @@ public:
if (!IsPbsSignal(n.last_signal_type)) return 0; if (!IsPbsSignal(n.last_signal_type)) return 0;
if (IsRailStationTile(tile) && IsAnyStationTileReserved(tile, trackdir, skipped)) { if (IsRailStationTile(tile) && IsAnyStationTileReserved(tile, trackdir, skipped)) {
return Yapf().PfGetSettings().rail_pbs_station_penalty * (skipped + 1); return YAPF_RAIL_PBS_STATION_PENALTY * (skipped + 1);
} else if (TrackOverlapsTracks(GetReservedTrackbits(tile), TrackdirToTrack(trackdir))) { } else if (TrackOverlapsTracks(GetReservedTrackbits(tile), TrackdirToTrack(trackdir))) {
int cost = Yapf().PfGetSettings().rail_pbs_cross_penalty; int cost = YAPF_RAIL_PBS_CROSS_PENALTY;
if (!IsDiagonalTrackdir(trackdir)) cost = (cost * YAPF_TILE_CORNER_LENGTH) / YAPF_TILE_LENGTH; if (!IsDiagonalTrackdir(trackdir)) cost = (cost * YAPF_TILE_CORNER_LENGTH) / YAPF_TILE_LENGTH;
return cost * (skipped + 1); return cost * (skipped + 1);
} }
@ -208,9 +234,9 @@ public:
if (n.num_signals_passed == 0) { if (n.num_signals_passed == 0) {
switch (sig_type) { switch (sig_type) {
case SIGTYPE_COMBO: case SIGTYPE_COMBO:
case SIGTYPE_EXIT: cost += Yapf().PfGetSettings().rail_firstred_exit_penalty; break; // first signal is red pre-signal-exit case SIGTYPE_EXIT: cost += YAPF_RAIL_FIRSTRED_EXIT_PENALTY; break; // first signal is red pre-signal-exit
case SIGTYPE_BLOCK: case SIGTYPE_BLOCK:
case SIGTYPE_ENTRY: cost += Yapf().PfGetSettings().rail_firstred_penalty; break; case SIGTYPE_ENTRY: cost += YAPF_RAIL_FIRSTRED_PENALTY; break;
default: break; default: break;
} }
} }
@ -222,7 +248,7 @@ public:
} }
if (has_signal_against && IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) { if (has_signal_against && IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) {
cost += n.num_signals_passed < Yapf().PfGetSettings().rail_look_ahead_max_signals ? Yapf().PfGetSettings().rail_pbs_signal_back_penalty : 0; cost += n.num_signals_passed < LOOK_AHEAD_MAX_SIGNALS ? YAPF_RAIL_PBS_SIGNAL_BACK_PENALTY : 0;
} }
} }
} }
@ -239,10 +265,10 @@ public:
int missing_platform_length = CeilDiv(v->gcache.cached_total_length, TILE_SIZE) - platform_length; int missing_platform_length = CeilDiv(v->gcache.cached_total_length, TILE_SIZE) - platform_length;
if (missing_platform_length < 0) { if (missing_platform_length < 0) {
/* apply penalty for longer platform than needed */ /* apply penalty for longer platform than needed */
cost += Yapf().PfGetSettings().rail_longer_platform_penalty + Yapf().PfGetSettings().rail_longer_platform_per_tile_penalty * -missing_platform_length; cost += YAPF_RAIL_LONGER_PLATFORM_PENALTY + YAPF_RAIL_LONGER_PLATFORM_PER_TILE_PENALTY * -missing_platform_length;
} else if (missing_platform_length > 0) { } else if (missing_platform_length > 0) {
/* apply penalty for shorter platform than needed */ /* apply penalty for shorter platform than needed */
cost += Yapf().PfGetSettings().rail_shorter_platform_penalty + Yapf().PfGetSettings().rail_shorter_platform_per_tile_penalty * missing_platform_length; cost += YAPF_RAIL_SHORTER_PLATFORM_PENALTY + YAPF_RAIL_SHORTER_PLATFORM_PER_TILE_PENALTY * missing_platform_length;
} }
return cost; return cost;
} }
@ -382,7 +408,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
if (cur.tile == prev.tile) { if (cur.tile == prev.tile) {
/* Penalty for reversing in a depot. */ /* Penalty for reversing in a depot. */
assert(IsRailDepot(cur.tile)); assert(IsRailDepot(cur.tile));
segment_cost += Yapf().PfGetSettings().rail_depot_reverse_penalty; segment_cost += YAPF_RAIL_DEPOT_REVERSE_PENALTY;
} else if (IsRailDepotTile(cur.tile)) { } else if (IsRailDepotTile(cur.tile)) {
/* We will end in this pass (depot is possible target) */ /* We will end in this pass (depot is possible target) */
@ -426,7 +452,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
if (td == INVALID_TRACKDIR || if (td == INVALID_TRACKDIR ||
!IsSafeWaitingPosition(v, t, td, true, _settings_game.pf.forbid_90_deg) || !IsSafeWaitingPosition(v, t, td, true, _settings_game.pf.forbid_90_deg) ||
!IsWaitingPositionFree(v, t, td, _settings_game.pf.forbid_90_deg)) { !IsWaitingPositionFree(v, t, td, _settings_game.pf.forbid_90_deg)) {
extra_cost += Yapf().PfGetSettings().rail_lastred_penalty; extra_cost += YAPF_RAIL_LASTRED_PENALTY;
} }
} }
/* Waypoint is also a good reason to finish. */ /* Waypoint is also a good reason to finish. */
@ -437,7 +463,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
uint platform_length = tf->tiles_skipped + 1; uint platform_length = tf->tiles_skipped + 1;
/* We don't know yet if the station is our target or not. Act like /* We don't know yet if the station is our target or not. Act like
* if it is pass-through station (not our destination). */ * if it is pass-through station (not our destination). */
segment_cost += Yapf().PfGetSettings().rail_station_penalty * platform_length; segment_cost += YAPF_RAIL_STATION_PENALTY * platform_length;
/* We will end in this pass (station is possible target) */ /* We will end in this pass (station is possible target) */
end_segment_reason |= ESRB_STATION; end_segment_reason |= ESRB_STATION;
@ -505,7 +531,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
} else if (HasSignalOnTrackdir(next.tile, ReverseTrackdir(next.td)) && GetSignalType(next.tile, TrackdirToTrack(next.td)) == SIGTYPE_PBS_ONEWAY) { } else if (HasSignalOnTrackdir(next.tile, ReverseTrackdir(next.td)) && GetSignalType(next.tile, TrackdirToTrack(next.td)) == SIGTYPE_PBS_ONEWAY) {
/* Possible safe tile, but not so good as it's the back of a signal... */ /* Possible safe tile, but not so good as it's the back of a signal... */
end_segment_reason |= ESRB_SAFE_TILE | ESRB_DEAD_END; end_segment_reason |= ESRB_SAFE_TILE | ESRB_DEAD_END;
extra_cost += Yapf().PfGetSettings().rail_lastred_exit_penalty; extra_cost += YAPF_RAIL_LASTRED_EXIT_PENALTY;
} }
} }
@ -576,10 +602,10 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
if (n.flags_u.flags_s.last_signal_was_red) { if (n.flags_u.flags_s.last_signal_was_red) {
if (n.last_red_signal_type == SIGTYPE_EXIT) { if (n.last_red_signal_type == SIGTYPE_EXIT) {
/* last signal was red pre-signal-exit */ /* last signal was red pre-signal-exit */
extra_cost += Yapf().PfGetSettings().rail_lastred_exit_penalty; extra_cost += YAPF_RAIL_LASTRED_EXIT_PENALTY;
} else if (!IsPbsSignal(n.last_red_signal_type)) { } else if (!IsPbsSignal(n.last_red_signal_type)) {
/* Last signal was red, but not exit or path signal. */ /* Last signal was red, but not exit or path signal. */
extra_cost += Yapf().PfGetSettings().rail_lastred_penalty; extra_cost += YAPF_RAIL_LASTRED_PENALTY;
} }
} }
@ -589,7 +615,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
assert(st != nullptr); assert(st != nullptr);
uint platform_length = st->GetPlatformLength(n.GetLastTile(), ReverseDiagDir(TrackdirToExitdir(n.GetLastTrackdir()))); uint platform_length = st->GetPlatformLength(n.GetLastTile(), ReverseDiagDir(TrackdirToExitdir(n.GetLastTrackdir())));
/* Reduce the extra cost caused by passing-station penalty (each station receives it in the segment cost). */ /* Reduce the extra cost caused by passing-station penalty (each station receives it in the segment cost). */
extra_cost -= Yapf().PfGetSettings().rail_station_penalty * platform_length; extra_cost -= YAPF_RAIL_STATION_PENALTY * platform_length;
/* Add penalty for the inappropriate platform length. */ /* Add penalty for the inappropriate platform length. */
extra_cost += PlatformLengthPenalty(platform_length); extra_cost += PlatformLengthPenalty(platform_length);
} }

View File

@ -235,7 +235,7 @@ public:
return 't'; return 't';
} }
static FindDepotData stFindNearestDepotTwoWay(const Train *v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2, int max_penalty, int reverse_penalty) static FindDepotData stFindNearestDepotTwoWay(const Train *v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2, int reverse_penalty)
{ {
Tpf pf1; Tpf pf1;
/* /*
@ -247,13 +247,13 @@ public:
* so it will only impact performance when you do not manually set * so it will only impact performance when you do not manually set
* depot orders and you do not disable automatic servicing. * depot orders and you do not disable automatic servicing.
*/ */
if (max_penalty != 0) pf1.DisableCache(true); pf1.DisableCache(true);
FindDepotData result1 = pf1.FindNearestDepotTwoWay(v, t1, td1, t2, td2, max_penalty, reverse_penalty); FindDepotData result1 = pf1.FindNearestDepotTwoWay(v, t1, td1, t2, td2, reverse_penalty);
if (_debug_desync_level >= 2) { if (_debug_desync_level >= 2) {
Tpf pf2; Tpf pf2;
pf2.DisableCache(true); pf2.DisableCache(true);
FindDepotData result2 = pf2.FindNearestDepotTwoWay(v, t1, td1, t2, td2, max_penalty, reverse_penalty); FindDepotData result2 = pf2.FindNearestDepotTwoWay(v, t1, td1, t2, td2, reverse_penalty);
if (result1.tile != result2.tile || (result1.reverse != result2.reverse)) { if (result1.tile != result2.tile || (result1.reverse != result2.reverse)) {
Debug(desync, 2, "warning: FindNearestDepotTwoWay cache mismatch: {} vs {}", Debug(desync, 2, "warning: FindNearestDepotTwoWay cache mismatch: {} vs {}",
result1.tile != INVALID_TILE ? "T" : "F", result1.tile != INVALID_TILE ? "T" : "F",
@ -265,12 +265,12 @@ public:
return result1; return result1;
} }
inline FindDepotData FindNearestDepotTwoWay(const Train *v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2, int max_penalty, int reverse_penalty) inline FindDepotData FindNearestDepotTwoWay(const Train *v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2, int reverse_penalty)
{ {
/* set origin and destination nodes */ /* set origin and destination nodes */
Yapf().SetOrigin(t1, td1, t2, td2, reverse_penalty, true); Yapf().SetOrigin(t1, td1, t2, td2, reverse_penalty, true);
Yapf().SetDestination(v); Yapf().SetDestination(v);
Yapf().SetMaxCost(max_penalty); Yapf().SetMaxCost(20 * YAPF_TILE_LENGTH);
/* find the best path */ /* find the best path */
if (!Yapf().FindPath(v)) return FindDepotData(); if (!Yapf().FindPath(v)) return FindDepotData();
@ -609,7 +609,7 @@ bool YapfTrainCheckReverse(const Train *v)
return reverse; return reverse;
} }
FindDepotData YapfTrainFindNearestDepot(const Train *v, int max_penalty) FindDepotData YapfTrainFindNearestDepot(const Train *v)
{ {
const Train *last_veh = v->Last(); const Train *last_veh = v->Last();
@ -618,8 +618,8 @@ FindDepotData YapfTrainFindNearestDepot(const Train *v, int max_penalty)
Trackdir td_rev = ReverseTrackdir(last_veh->GetVehicleTrackdir()); Trackdir td_rev = ReverseTrackdir(last_veh->GetVehicleTrackdir());
return _settings_game.pf.forbid_90_deg return _settings_game.pf.forbid_90_deg
? CYapfAnyDepotRail2::stFindNearestDepotTwoWay(v, origin.tile, origin.trackdir, last_tile, td_rev, max_penalty, YAPF_INFINITE_PENALTY) ? CYapfAnyDepotRail2::stFindNearestDepotTwoWay(v, origin.tile, origin.trackdir, last_tile, td_rev, YAPF_INFINITE_PENALTY)
: CYapfAnyDepotRail1::stFindNearestDepotTwoWay(v, origin.tile, origin.trackdir, last_tile, td_rev, max_penalty, YAPF_INFINITE_PENALTY); : CYapfAnyDepotRail1::stFindNearestDepotTwoWay(v, origin.tile, origin.trackdir, last_tile, td_rev, YAPF_INFINITE_PENALTY);
} }
bool YapfTrainFindNearestSafeTile(const Train *v, TileIndex tile, Trackdir td, bool override_railtype) bool YapfTrainFindNearestSafeTile(const Train *v, TileIndex tile, Trackdir td, bool override_railtype)

View File

@ -14,6 +14,13 @@
#include "../../safeguards.h" #include "../../safeguards.h"
static const uint YAPF_ROAD_MAXIMUM_GO_TO_DEPOT_PENALTY = 20 * YAPF_TILE_LENGTH; ///< What is the maximum penalty that may be endured for going to a depot
static const uint YAPF_ROAD_SLOPE_PENALTY = 2 * YAPF_TILE_LENGTH; ///< penalty for up-hill slope
static const uint YAPF_ROAD_CURVE_PENALTY = 1 * YAPF_TILE_LENGTH; ///< penalty for curves
static const uint YAPF_ROAD_CROSSING_PENALTY = 3 * YAPF_TILE_LENGTH; ///< penalty for level crossing
static const uint YAPF_ROAD_STOP_PENALTY = 8 * YAPF_TILE_LENGTH; ///< penalty for going through a drive-through road stop
static const uint YAPF_ROAD_STOP_OCCUPIED_PENALTY = 8 * YAPF_TILE_LENGTH; ///< penalty multiplied by the fill percentage of a drive-through road stop
static const uint YAPF_ROAD_STOP_BAY_OCCUPIED_PENALTY = 15 * YAPF_TILE_LENGTH; ///< penalty multiplied by the fill percentage of a road bay
template <class Types> template <class Types>
class CYapfCostRoadT class CYapfCostRoadT
@ -49,7 +56,7 @@ protected:
if (z2 - z1 > 1) { if (z2 - z1 > 1) {
/* Slope up */ /* Slope up */
return Yapf().PfGetSettings().road_slope_penalty; return YAPF_ROAD_SLOPE_PENALTY;
} }
return 0; return 0;
} }
@ -65,7 +72,7 @@ protected:
case MP_ROAD: case MP_ROAD:
/* Increase the cost for level crossings */ /* Increase the cost for level crossings */
if (IsLevelCrossing(tile)) { if (IsLevelCrossing(tile)) {
cost += Yapf().PfGetSettings().road_crossing_penalty; cost += YAPF_ROAD_CROSSING_PENALTY;
} }
break; break;
@ -75,17 +82,17 @@ protected:
const RoadStop *rs = RoadStop::GetByTile(tile, GetRoadStopType(tile)); const RoadStop *rs = RoadStop::GetByTile(tile, GetRoadStopType(tile));
if (IsDriveThroughStopTile(tile)) { if (IsDriveThroughStopTile(tile)) {
/* Increase the cost for drive-through road stops */ /* Increase the cost for drive-through road stops */
cost += Yapf().PfGetSettings().road_stop_penalty; cost += YAPF_ROAD_STOP_PENALTY;
DiagDirection dir = TrackdirToExitdir(trackdir); DiagDirection dir = TrackdirToExitdir(trackdir);
if (!RoadStop::IsDriveThroughRoadStopContinuation(tile, tile - TileOffsByDiagDir(dir))) { if (!RoadStop::IsDriveThroughRoadStopContinuation(tile, tile - TileOffsByDiagDir(dir))) {
/* When we're the first road stop in a 'queue' of them we increase /* When we're the first road stop in a 'queue' of them we increase
* cost based on the fill percentage of the whole queue. */ * cost based on the fill percentage of the whole queue. */
const RoadStop::Entry *entry = rs->GetEntry(dir); const RoadStop::Entry *entry = rs->GetEntry(dir);
cost += entry->GetOccupied() * Yapf().PfGetSettings().road_stop_occupied_penalty / entry->GetLength(); cost += entry->GetOccupied() * YAPF_ROAD_STOP_OCCUPIED_PENALTY / entry->GetLength();
} }
} else { } else {
/* Increase cost for filled road stops */ /* Increase cost for filled road stops */
cost += Yapf().PfGetSettings().road_stop_bay_occupied_penalty * (!rs->IsFreeBay(0) + !rs->IsFreeBay(1)) / 2; cost += YAPF_ROAD_STOP_BAY_OCCUPIED_PENALTY * (!rs->IsFreeBay(0) + !rs->IsFreeBay(1)) / 2;
} }
break; break;
} }
@ -95,7 +102,7 @@ protected:
} }
} else { } else {
/* non-diagonal trackdir */ /* non-diagonal trackdir */
cost = YAPF_TILE_CORNER_LENGTH + Yapf().PfGetSettings().road_curve_penalty; cost = YAPF_TILE_CORNER_LENGTH + YAPF_ROAD_CURVE_PENALTY;
} }
return cost; return cost;
} }
@ -479,10 +486,10 @@ public:
return true; return true;
} }
static FindDepotData stFindNearestDepot(const RoadVehicle *v, TileIndex tile, Trackdir td, int max_distance) static FindDepotData stFindNearestDepot(const RoadVehicle *v, TileIndex tile, Trackdir td)
{ {
Tpf pf; Tpf pf;
return pf.FindNearestDepot(v, tile, td, max_distance); return pf.FindNearestDepot(v, tile, td);
} }
/** /**
@ -490,13 +497,12 @@ public:
* @param v Vehicle * @param v Vehicle
* @param tile Tile of the vehicle. * @param tile Tile of the vehicle.
* @param td Trackdir of the vehicle. * @param td Trackdir of the vehicle.
* @param max_distance max length (penalty) for paths.
*/ */
inline FindDepotData FindNearestDepot(const RoadVehicle *v, TileIndex tile, Trackdir td, int max_distance) inline FindDepotData FindNearestDepot(const RoadVehicle *v, TileIndex tile, Trackdir td)
{ {
/* Set origin. */ /* Set origin. */
Yapf().SetOrigin(tile, TrackdirToTrackdirBits(td)); Yapf().SetOrigin(tile, TrackdirToTrackdirBits(td));
Yapf().SetMaxCost(max_distance); Yapf().SetMaxCost(YAPF_ROAD_MAXIMUM_GO_TO_DEPOT_PENALTY);
/* Find the best path and return if no depot is found. */ /* Find the best path and return if no depot is found. */
if (!Yapf().FindPath(v)) return FindDepotData(); if (!Yapf().FindPath(v)) return FindDepotData();
@ -524,23 +530,17 @@ struct CYapfRoad_TypesT
typedef CYapfCostRoadT<Types> PfCost; typedef CYapfCostRoadT<Types> PfCost;
}; };
struct CYapfRoad1 : CYapfT<CYapfRoad_TypesT<CYapfRoad1 , CRoadNodeListTrackDir, CYapfDestinationTileRoadT > > {}; struct CYapfRoad : CYapfT<CYapfRoad_TypesT<CYapfRoad , CRoadNodeListExitDir , CYapfDestinationTileRoadT > > {};
struct CYapfRoad2 : CYapfT<CYapfRoad_TypesT<CYapfRoad2 , CRoadNodeListExitDir , CYapfDestinationTileRoadT > > {}; struct CYapfRoadAnyDepot : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyDepot, CRoadNodeListExitDir , CYapfDestinationAnyDepotRoadT> > {};
struct CYapfRoadAnyDepot1 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyDepot1, CRoadNodeListTrackDir, CYapfDestinationAnyDepotRoadT> > {};
struct CYapfRoadAnyDepot2 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyDepot2, CRoadNodeListExitDir , CYapfDestinationAnyDepotRoadT> > {};
Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found, RoadVehPathCache &path_cache) Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found, RoadVehPathCache &path_cache)
{ {
Trackdir td_ret = _settings_game.pf.yapf.disable_node_optimization Trackdir td_ret = CYapfRoad::stChooseRoadTrack(v, tile, enterdir, path_found, path_cache);
? CYapfRoad1::stChooseRoadTrack(v, tile, enterdir, path_found, path_cache) // Trackdir
: CYapfRoad2::stChooseRoadTrack(v, tile, enterdir, path_found, path_cache); // ExitDir, allow 90-deg
return (td_ret != INVALID_TRACKDIR) ? td_ret : (Trackdir)FindFirstBit(trackdirs); return (td_ret != INVALID_TRACKDIR) ? td_ret : (Trackdir)FindFirstBit(trackdirs);
} }
FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_distance) FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v)
{ {
TileIndex tile = v->tile; TileIndex tile = v->tile;
Trackdir trackdir = v->GetVehicleTrackdir(); Trackdir trackdir = v->GetVehicleTrackdir();
@ -549,7 +549,5 @@ FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_dist
return FindDepotData(); return FindDepotData();
} }
return _settings_game.pf.yapf.disable_node_optimization return CYapfRoadAnyDepot::stFindNearestDepot(v, tile, trackdir);
? CYapfRoadAnyDepot1::stFindNearestDepot(v, tile, trackdir, max_distance) // Trackdir
: CYapfRoadAnyDepot2::stFindNearestDepot(v, tile, trackdir, max_distance); // ExitDir
} }

View File

@ -24,6 +24,9 @@ constexpr int MAX_SHIP_PF_NODES = (NUMBER_OR_WATER_REGIONS_LOOKAHEAD + 1) * WATE
constexpr int SHIP_LOST_PATH_LENGTH = 8; // The length of the (aimless) path assigned when a ship is lost. constexpr int SHIP_LOST_PATH_LENGTH = 8; // The length of the (aimless) path assigned when a ship is lost.
constexpr uint YAPF_SHIP_CURVE45_PENALTY = 1 * YAPF_TILE_LENGTH; ///< penalty for 45-deg curve for ships
constexpr uint YAPF_SHIP_CURVE90_PENALTY = 6 * YAPF_TILE_LENGTH; ///< penalty for 90-deg curve for ships
template <class Types> template <class Types>
class CYapfDestinationTileWaterT class CYapfDestinationTileWaterT
{ {
@ -224,7 +227,7 @@ public:
* However the pathfinder can hit the node limit in certain situations such as long aqueducts or maze-like terrain. * However the pathfinder can hit the node limit in certain situations such as long aqueducts or maze-like terrain.
* If that happens we run the pathfinder again, but restricted only to the regions provided by the region pathfinder. */ * If that happens we run the pathfinder again, but restricted only to the regions provided by the region pathfinder. */
for (int attempt = 0; attempt < 2; ++attempt) { for (int attempt = 0; attempt < 2; ++attempt) {
Tpf pf(MAX_SHIP_PF_NODES); Tpf pf;
/* Set origin and destination nodes */ /* Set origin and destination nodes */
pf.SetOrigin(v->tile, forward_dirs | reverse_dirs); pf.SetOrigin(v->tile, forward_dirs | reverse_dirs);
@ -346,10 +349,10 @@ public:
if (HasTrackdir(TrackdirCrossesTrackdirs(td1), td2)) { if (HasTrackdir(TrackdirCrossesTrackdirs(td1), td2)) {
/* 90-deg curve penalty. */ /* 90-deg curve penalty. */
return Yapf().PfGetSettings().ship_curve90_penalty; return YAPF_SHIP_CURVE90_PENALTY;
} else if (td2 != NextTrackdir(td1)) { } else if (td2 != NextTrackdir(td1)) {
/* 45-deg curve penalty. */ /* 45-deg curve penalty. */
return Yapf().PfGetSettings().ship_curve45_penalty; return YAPF_SHIP_CURVE45_PENALTY;
} }
return 0; return 0;
} }
@ -420,7 +423,7 @@ struct CYapfShip_TypesT
struct CYapfShip : CYapfT<CYapfShip_TypesT<CYapfShip, CFollowTrackWater, CShipNodeListExitDir > > struct CYapfShip : CYapfT<CYapfShip_TypesT<CYapfShip, CFollowTrackWater, CShipNodeListExitDir > >
{ {
explicit CYapfShip(int max_nodes) { this->max_search_nodes = max_nodes; } CYapfShip() {}
}; };
/** Ship controller helper - path finder invoker. */ /** Ship controller helper - path finder invoker. */

View File

@ -192,9 +192,7 @@ public:
{ {
const WaterRegionPatchDesc start_water_region_patch = GetWaterRegionPatchInfo(start_tile); const WaterRegionPatchDesc start_water_region_patch = GetWaterRegionPatchInfo(start_tile);
/* We reserve 4 nodes (patches) per water region. The vast majority of water regions have 1 or 2 regions so this should be a pretty Tpf pf;
* safe limit. We cap the limit at 65536 which is at a region size of 16x16 is equivalent to one node per region for a 4096x4096 map. */
Tpf pf(std::min(static_cast<int>(Map::Size() * NODES_PER_REGION) / WATER_REGION_NUMBER_OF_TILES, MAX_NUMBER_OF_NODES));
pf.SetDestination(start_water_region_patch); pf.SetDestination(start_water_region_patch);
if (v->current_order.IsType(OT_GOTO_STATION)) { if (v->current_order.IsType(OT_GOTO_STATION)) {
@ -297,7 +295,7 @@ typedef CNodeList_HashTableT<CYapfRegionNodeT<CYapfRegionPatchNodeKey>, 12, 12>
struct CYapfRegionWater : CYapfT<CYapfRegion_TypesT<CYapfRegionWater, CRegionNodeListWater>> struct CYapfRegionWater : CYapfT<CYapfRegion_TypesT<CYapfRegionWater, CRegionNodeListWater>>
{ {
explicit CYapfRegionWater(int max_nodes) { this->max_search_nodes = max_nodes; } CYapfRegionWater() {}
}; };
/** /**

View File

@ -337,16 +337,16 @@ CommandCost CmdBuildRoadVehicle(DoCommandFlag flags, TileIndex tile, const Engin
return CommandCost(); return CommandCost();
} }
static FindDepotData FindClosestRoadDepot(const RoadVehicle *v, int max_distance) static FindDepotData FindClosestRoadDepot(const RoadVehicle *v)
{ {
if (IsRoadDepotTile(v->tile)) return FindDepotData(v->tile, 0); if (IsRoadDepotTile(v->tile)) return FindDepotData(v->tile, 0);
return YapfRoadVehicleFindNearestDepot(v, max_distance); return YapfRoadVehicleFindNearestDepot(v);
} }
ClosestDepot RoadVehicle::FindClosestDepot() ClosestDepot RoadVehicle::FindClosestDepot()
{ {
FindDepotData rfdd = FindClosestRoadDepot(this, 0); FindDepotData rfdd = FindClosestRoadDepot(this);
if (rfdd.best_length == UINT_MAX) return ClosestDepot(); if (rfdd.best_length == UINT_MAX) return ClosestDepot();
return ClosestDepot(rfdd.tile, GetDepotIndex(rfdd.tile)); return ClosestDepot(rfdd.tile, GetDepotIndex(rfdd.tile));
@ -1673,11 +1673,9 @@ static void CheckIfRoadVehNeedsService(RoadVehicle *v)
return; return;
} }
uint max_penalty = _settings_game.pf.yapf.maximum_go_to_depot_penalty; FindDepotData rfdd = FindClosestRoadDepot(v);
FindDepotData rfdd = FindClosestRoadDepot(v, max_penalty);
/* Only go to the depot if it is not too far out of our way. */ /* Only go to the depot if it is not too far out of our way. */
if (rfdd.best_length == UINT_MAX || rfdd.best_length > max_penalty) { if (rfdd.best_length == UINT_MAX) {
if (v->current_order.IsType(OT_GOTO_DEPOT)) { if (v->current_order.IsType(OT_GOTO_DEPOT)) {
/* If we were already heading for a depot but it has /* If we were already heading for a depot but it has
* suddenly moved farther away, we continue our normal * suddenly moved farther away, we continue our normal

View File

@ -185,40 +185,13 @@ const SaveLoadCompat _settings_sl_compat[] = {
SLC_NULL(4, SLV_47, SLV_TABLE_CHUNKS), SLC_NULL(4, SLV_47, SLV_TABLE_CHUNKS),
SLC_NULL(8, SLV_130, SLV_TABLE_CHUNKS), SLC_NULL(8, SLV_130, SLV_TABLE_CHUNKS),
SLC_NULL(4, SLV_131, SLV_TABLE_CHUNKS), SLC_NULL(4, SLV_131, SLV_TABLE_CHUNKS),
SLC_VAR("pf.yapf.disable_node_optimization"), SLC_NULL(4 * 15 + 2, SLV_28, SLV_REMOVE_PF_SETTINGS), // YAPF, x34 (32 int, 2 bool)
SLC_VAR("pf.yapf.max_search_nodes"), SLC_NULL(4 * 4, SLV_100, SLV_REMOVE_PF_SETTINGS),
SLC_VAR("pf.yapf.rail_firstred_twoway_eol"), SLC_NULL(4 * 7, SLV_33, SLV_REMOVE_PF_SETTINGS),
SLC_VAR("pf.yapf.rail_firstred_penalty"), SLC_NULL(4 * 1, SLV_47, SLV_REMOVE_PF_SETTINGS),
SLC_VAR("pf.yapf.rail_firstred_exit_penalty"), SLC_NULL(4 * 2, SLV_130, SLV_REMOVE_PF_SETTINGS),
SLC_VAR("pf.yapf.rail_lastred_penalty"), SLC_NULL(4 * 1, SLV_131, SLV_REMOVE_PF_SETTINGS),
SLC_VAR("pf.yapf.rail_lastred_exit_penalty"), SLC_NULL(4 * 2, SLV_SHIP_CURVE_PENALTY, SLV_REMOVE_PF_SETTINGS),
SLC_VAR("pf.yapf.rail_station_penalty"),
SLC_VAR("pf.yapf.rail_slope_penalty"),
SLC_VAR("pf.yapf.rail_curve45_penalty"),
SLC_VAR("pf.yapf.rail_curve90_penalty"),
SLC_VAR("pf.yapf.rail_depot_reverse_penalty"),
SLC_VAR("pf.yapf.rail_crossing_penalty"),
SLC_VAR("pf.yapf.rail_look_ahead_max_signals"),
SLC_VAR("pf.yapf.rail_look_ahead_signal_p0"),
SLC_VAR("pf.yapf.rail_look_ahead_signal_p1"),
SLC_VAR("pf.yapf.rail_look_ahead_signal_p2"),
SLC_VAR("pf.yapf.rail_pbs_cross_penalty"),
SLC_VAR("pf.yapf.rail_pbs_station_penalty"),
SLC_VAR("pf.yapf.rail_pbs_signal_back_penalty"),
SLC_VAR("pf.yapf.rail_doubleslip_penalty"),
SLC_VAR("pf.yapf.rail_longer_platform_penalty"),
SLC_VAR("pf.yapf.rail_longer_platform_per_tile_penalty"),
SLC_VAR("pf.yapf.rail_shorter_platform_penalty"),
SLC_VAR("pf.yapf.rail_shorter_platform_per_tile_penalty"),
SLC_VAR("pf.yapf.road_slope_penalty"),
SLC_VAR("pf.yapf.road_curve_penalty"),
SLC_VAR("pf.yapf.road_crossing_penalty"),
SLC_VAR("pf.yapf.road_stop_penalty"),
SLC_VAR("pf.yapf.road_stop_occupied_penalty"),
SLC_VAR("pf.yapf.road_stop_bay_occupied_penalty"),
SLC_VAR("pf.yapf.maximum_go_to_depot_penalty"),
SLC_VAR("pf.yapf.ship_curve45_penalty"),
SLC_VAR("pf.yapf.ship_curve90_penalty"),
SLC_VAR("game_creation.land_generator"), SLC_VAR("game_creation.land_generator"),
SLC_VAR("game_creation.oil_refinery_limit"), SLC_VAR("game_creation.oil_refinery_limit"),
SLC_VAR("game_creation.tgen_smoothness"), SLC_VAR("game_creation.tgen_smoothness"),

View File

@ -391,6 +391,8 @@ enum SaveLoadVersion : uint16_t {
SLV_PRODUCTION_HISTORY, ///< 343 PR#10541 Industry production history. SLV_PRODUCTION_HISTORY, ///< 343 PR#10541 Industry production history.
SLV_ROAD_TYPE_LABEL_MAP, ///< 344 PR#13021 Add road type label map to allow upgrade/conversion of road types. SLV_ROAD_TYPE_LABEL_MAP, ///< 344 PR#13021 Add road type label map to allow upgrade/conversion of road types.
SLV_REMOVE_PF_SETTINGS, ///< 345 PR#10623 Removal of pathfinder settings.
SL_MAX_VERSION, ///< Highest possible saveload version SL_MAX_VERSION, ///< Highest possible saveload version
}; };

View File

@ -421,45 +421,6 @@ struct ScriptSettings {
uint32_t script_max_memory_megabytes; ///< limit on memory a single script instance may have allocated uint32_t script_max_memory_megabytes; ///< limit on memory a single script instance may have allocated
}; };
/** Settings related to the yet another pathfinder. */
struct YAPFSettings {
bool disable_node_optimization; ///< whether to use exit-dir instead of trackdir in node key
uint32_t max_search_nodes; ///< stop path-finding when this number of nodes visited
uint32_t maximum_go_to_depot_penalty; ///< What is the maximum penalty that may be endured for going to a depot
uint32_t road_slope_penalty; ///< penalty for up-hill slope
uint32_t road_curve_penalty; ///< penalty for curves
uint32_t road_crossing_penalty; ///< penalty for level crossing
uint32_t road_stop_penalty; ///< penalty for going through a drive-through road stop
uint32_t road_stop_occupied_penalty; ///< penalty multiplied by the fill percentage of a drive-through road stop
uint32_t road_stop_bay_occupied_penalty; ///< penalty multiplied by the fill percentage of a road bay
bool rail_firstred_twoway_eol; ///< treat first red two-way signal as dead end
uint32_t rail_firstred_penalty; ///< penalty for first red signal
uint32_t rail_firstred_exit_penalty; ///< penalty for first red exit signal
uint32_t rail_lastred_penalty; ///< penalty for last red signal
uint32_t rail_lastred_exit_penalty; ///< penalty for last red exit signal
uint32_t rail_station_penalty; ///< penalty for non-target station tile
uint32_t rail_slope_penalty; ///< penalty for up-hill slope
uint32_t rail_curve45_penalty; ///< penalty for curve
uint32_t rail_curve90_penalty; ///< penalty for 90-deg curve
uint32_t rail_depot_reverse_penalty; ///< penalty for reversing in the depot
uint32_t rail_crossing_penalty; ///< penalty for level crossing
uint32_t rail_look_ahead_max_signals; ///< max. number of signals taken into consideration in look-ahead load balancer
int32_t rail_look_ahead_signal_p0; ///< constant in polynomial penalty function
int32_t rail_look_ahead_signal_p1; ///< constant in polynomial penalty function
int32_t rail_look_ahead_signal_p2; ///< constant in polynomial penalty function
uint32_t rail_pbs_cross_penalty; ///< penalty for crossing a reserved tile
uint32_t rail_pbs_station_penalty; ///< penalty for crossing a reserved station tile
uint32_t rail_pbs_signal_back_penalty; ///< penalty for passing a pbs signal from the backside
uint32_t rail_doubleslip_penalty; ///< penalty for passing a double slip switch
uint32_t rail_longer_platform_penalty; ///< penalty for longer station platform than train
uint32_t rail_longer_platform_per_tile_penalty; ///< penalty for longer station platform than train (per tile)
uint32_t rail_shorter_platform_penalty; ///< penalty for shorter station platform than train
uint32_t rail_shorter_platform_per_tile_penalty; ///< penalty for shorter station platform than train (per tile)
uint32_t ship_curve45_penalty; ///< penalty for 45-deg curve for ships
uint32_t ship_curve90_penalty; ///< penalty for 90-deg curve for ships
};
/** Settings related to all pathfinders. */ /** Settings related to all pathfinders. */
struct PathfinderSettings { struct PathfinderSettings {
bool roadveh_queue; ///< buggy road vehicle queueing bool roadveh_queue; ///< buggy road vehicle queueing
@ -472,8 +433,6 @@ struct PathfinderSettings {
bool reserve_paths; ///< always reserve paths regardless of signal type. bool reserve_paths; ///< always reserve paths regardless of signal type.
uint8_t wait_for_pbs_path; ///< how long to wait for a path reservation. uint8_t wait_for_pbs_path; ///< how long to wait for a path reservation.
uint8_t path_backoff_interval; ///< ticks between checks for a free path. uint8_t path_backoff_interval; ///< ticks between checks for a free path.
YAPFSettings yapf; ///< pathfinder settings for the yet another pathfinder
}; };
/** Settings related to orders. */ /** Settings related to orders. */

View File

@ -209,9 +209,8 @@ static void CheckIfShipNeedsService(Vehicle *v)
return; return;
} }
uint max_distance = _settings_game.pf.yapf.maximum_go_to_depot_penalty / YAPF_TILE_LENGTH; static const int MAXIMUM_GOTO_DEPOT_DISTANCE = 20;
const Depot *depot = FindClosestShipDepot(v, MAXIMUM_GOTO_DEPOT_DISTANCE);
const Depot *depot = FindClosestShipDepot(v, max_distance);
if (depot == nullptr) { if (depot == nullptr) {
if (v->current_order.IsType(OT_GOTO_DEPOT)) { if (v->current_order.IsType(OT_GOTO_DEPOT)) {

View File

@ -96,303 +96,3 @@ def = 20
min = 1 min = 1
max = 255 max = 255
cat = SC_EXPERT cat = SC_EXPERT
[SDT_BOOL]
var = pf.yapf.disable_node_optimization
from = SLV_28
def = false
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.max_search_nodes
type = SLE_UINT
from = SLV_28
def = AYSTAR_DEF_MAX_SEARCH_NODES
min = 500
max = 1000000
cat = SC_EXPERT
[SDT_BOOL]
var = pf.yapf.rail_firstred_twoway_eol
from = SLV_28
def = true
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_firstred_penalty
type = SLE_UINT
from = SLV_28
def = 10 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_firstred_exit_penalty
type = SLE_UINT
from = SLV_28
def = 100 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_lastred_penalty
type = SLE_UINT
from = SLV_28
def = 10 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_lastred_exit_penalty
type = SLE_UINT
from = SLV_28
def = 100 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_station_penalty
type = SLE_UINT
from = SLV_28
def = 10 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_slope_penalty
type = SLE_UINT
from = SLV_28
def = 2 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_curve45_penalty
type = SLE_UINT
from = SLV_28
def = 1 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_curve90_penalty
type = SLE_UINT
from = SLV_28
def = 6 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_depot_reverse_penalty
type = SLE_UINT
from = SLV_28
def = 50 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_crossing_penalty
type = SLE_UINT
from = SLV_28
def = 3 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_look_ahead_max_signals
type = SLE_UINT
from = SLV_28
def = 10
min = 1
max = 100
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_look_ahead_signal_p0
type = SLE_INT
from = SLV_28
def = 500
min = -1000000
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_look_ahead_signal_p1
type = SLE_INT
from = SLV_28
def = -100
min = -1000000
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_look_ahead_signal_p2
type = SLE_INT
from = SLV_28
def = 5
min = -1000000
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_pbs_cross_penalty
type = SLE_UINT
from = SLV_100
def = 3 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_pbs_station_penalty
type = SLE_UINT
from = SLV_100
def = 8 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_pbs_signal_back_penalty
type = SLE_UINT
from = SLV_100
def = 15 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_doubleslip_penalty
type = SLE_UINT
from = SLV_100
def = 1 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_longer_platform_penalty
type = SLE_UINT
from = SLV_33
def = 8 * YAPF_TILE_LENGTH
min = 0
max = 20000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_longer_platform_per_tile_penalty
type = SLE_UINT
from = SLV_33
def = 0 * YAPF_TILE_LENGTH
min = 0
max = 20000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_shorter_platform_penalty
type = SLE_UINT
from = SLV_33
def = 40 * YAPF_TILE_LENGTH
min = 0
max = 20000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.rail_shorter_platform_per_tile_penalty
type = SLE_UINT
from = SLV_33
def = 0 * YAPF_TILE_LENGTH
min = 0
max = 20000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.road_slope_penalty
type = SLE_UINT
from = SLV_33
def = 2 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.road_curve_penalty
type = SLE_UINT
from = SLV_33
def = 1 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.road_crossing_penalty
type = SLE_UINT
from = SLV_33
def = 3 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.road_stop_penalty
type = SLE_UINT
from = SLV_47
def = 8 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.road_stop_occupied_penalty
type = SLE_UINT
from = SLV_130
def = 8 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.road_stop_bay_occupied_penalty
type = SLE_UINT
from = SLV_130
def = 15 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.maximum_go_to_depot_penalty
type = SLE_UINT
from = SLV_131
def = 20 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.ship_curve45_penalty
type = SLE_UINT
from = SLV_SHIP_CURVE_PENALTY
def = 1 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT
[SDT_VAR]
var = pf.yapf.ship_curve90_penalty
type = SLE_UINT
from = SLV_SHIP_CURVE_PENALTY
def = 6 * YAPF_TILE_LENGTH
min = 0
max = 1000000
cat = SC_EXPERT

View File

@ -2159,11 +2159,10 @@ CommandCost CmdForceTrainProceed(DoCommandFlag flags, VehicleID veh_id)
/** /**
* Try to find a depot nearby. * Try to find a depot nearby.
* @param v %Train that wants a depot. * @param v %Train that wants a depot.
* @param max_distance Maximal search distance.
* @return Information where the closest train depot is located. * @return Information where the closest train depot is located.
* @pre The given vehicle must not be crashed! * @pre The given vehicle must not be crashed!
*/ */
static FindDepotData FindClosestTrainDepot(Train *v, int max_distance) static FindDepotData FindClosestTrainDepot(Train *v)
{ {
assert(!(v->vehstatus & VS_CRASHED)); assert(!(v->vehstatus & VS_CRASHED));
@ -2172,12 +2171,12 @@ static FindDepotData FindClosestTrainDepot(Train *v, int max_distance)
PBSTileInfo origin = FollowTrainReservation(v); PBSTileInfo origin = FollowTrainReservation(v);
if (IsRailDepotTile(origin.tile)) return FindDepotData(origin.tile, 0); if (IsRailDepotTile(origin.tile)) return FindDepotData(origin.tile, 0);
return YapfTrainFindNearestDepot(v, max_distance); return YapfTrainFindNearestDepot(v);
} }
ClosestDepot Train::FindClosestDepot() ClosestDepot Train::FindClosestDepot()
{ {
FindDepotData tfdd = FindClosestTrainDepot(this, 0); FindDepotData tfdd = FindClosestTrainDepot(this);
if (tfdd.best_length == UINT_MAX) return ClosestDepot(); if (tfdd.best_length == UINT_MAX) return ClosestDepot();
return ClosestDepot(tfdd.tile, GetDepotIndex(tfdd.tile), tfdd.reverse); return ClosestDepot(tfdd.tile, GetDepotIndex(tfdd.tile), tfdd.reverse);
@ -4148,11 +4147,9 @@ static void CheckIfTrainNeedsService(Train *v)
return; return;
} }
uint max_penalty = _settings_game.pf.yapf.maximum_go_to_depot_penalty; FindDepotData tfdd = FindClosestTrainDepot(v);
FindDepotData tfdd = FindClosestTrainDepot(v, max_penalty);
/* Only go to the depot if it is not too far out of our way. */ /* Only go to the depot if it is not too far out of our way. */
if (tfdd.best_length == UINT_MAX || tfdd.best_length > max_penalty) { if (tfdd.best_length == UINT_MAX) {
if (v->current_order.IsType(OT_GOTO_DEPOT)) { if (v->current_order.IsType(OT_GOTO_DEPOT)) {
/* If we were already heading for a depot but it has /* If we were already heading for a depot but it has
* suddenly moved farther away, we continue our normal * suddenly moved farther away, we continue our normal