1
0
Fork 0
pull/10623/merge
Charles Pigott 2024-11-17 16:16:48 +01:00 committed by GitHub
commit 03115f91a5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
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);
/* Add the parent g-value to the new g-value */
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 */
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.
* @return Possible values:
* - #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_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);
}
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 */
return AYSTAR_LIMIT_REACHED;
} else {

View File

@ -33,12 +33,14 @@ enum AystarStatus {
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_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.
};
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;
struct PathNode : CYapfNodeT<AyStarNode, PathNode> {
@ -122,8 +124,6 @@ struct AyStar {
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.
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 */
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.
* @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
*/
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.
* @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
*/
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.

View File

@ -58,10 +58,10 @@ public:
NodeList nodes; ///< node list multi-container
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_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
int stats_cost_calcs = 0; ///< stats - how many node's costs were calculated
@ -72,7 +72,7 @@ public:
public:
/** default constructor */
inline CYapfBaseT() : settings(&_settings_game.pf.yapf), max_search_nodes(PfGetSettings().max_search_nodes) {}
inline CYapfBaseT() {}
/** default destructor */
~CYapfBaseT() {}
@ -85,19 +85,13 @@ protected:
}
public:
/** return current settings (can be custom - company based - but later) */
inline const YAPFSettings &PfGetSettings() const
{
return *this->settings;
}
/**
* Main pathfinder routine:
* - set startup node(s)
* - main loop that stops if:
* - the destination was found
* - 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
*/
inline bool FindPath(const VehicleType *v)
@ -117,7 +111,7 @@ public:
}
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.InsertClosedNode(*best_open_node);
@ -226,7 +220,7 @@ public:
/* 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. */
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 */
Node *open_node = this->nodes.FindOpenNode(n.GetKey());

View File

@ -108,7 +108,7 @@ public:
/** return true if first two-way signal should be treated as dead end */
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_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>
class CYapfCostRailT : public CYapfCostBase {
public:
@ -47,7 +66,24 @@ protected:
*/
int max_cost;
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:
bool stopped_on_first_two_way_signal;
@ -56,17 +92,7 @@ protected:
static constexpr int MAX_SEGMENT_COST = 10000;
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 */
Tpf &Yapf()
@ -78,7 +104,7 @@ public:
inline int SlopeCost(TileIndex tile, Trackdir td)
{
if (!stSlopeCost(tile, td)) return 0;
return Yapf().PfGetSettings().rail_slope_penalty;
return YAPF_RAIL_SLOPE_PENALTY;
}
inline int CurveCost(Trackdir td1, Trackdir td2)
@ -89,10 +115,10 @@ public:
if (TrackFollower::Allow90degTurns()
&& HasTrackdir(TrackdirCrossesTrackdirs(td1), td2)) {
/* 90-deg curve penalty */
cost += Yapf().PfGetSettings().rail_curve90_penalty;
cost += YAPF_RAIL_CURVE90_PENALTY;
} else if (td2 != NextTrackdir(td1)) {
/* 45-deg curve penalty */
cost += Yapf().PfGetSettings().rail_curve45_penalty;
cost += YAPF_RAIL_CURVE45_PENALTY;
}
return cost;
}
@ -102,7 +128,7 @@ public:
if (IsPlainRailTile(tile1) && IsPlainRailTile(tile2)) {
bool t1 = KillFirstBit(GetTrackBits(tile1) & DiagdirReachesTracks(ReverseDiagDir(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;
}
@ -118,7 +144,7 @@ public:
case MP_ROAD:
/* Increase the cost for level crossings */
if (IsLevelCrossing(tile)) {
cost += Yapf().PfGetSettings().rail_crossing_penalty;
cost += YAPF_RAIL_CROSSING_PENALTY;
}
break;
@ -149,9 +175,9 @@ public:
if (!IsPbsSignal(n.last_signal_type)) return 0;
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))) {
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;
return cost * (skipped + 1);
}
@ -208,9 +234,9 @@ public:
if (n.num_signals_passed == 0) {
switch (sig_type) {
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_ENTRY: cost += Yapf().PfGetSettings().rail_firstred_penalty; break;
case SIGTYPE_ENTRY: cost += YAPF_RAIL_FIRSTRED_PENALTY; break;
default: break;
}
}
@ -222,7 +248,7 @@ public:
}
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;
if (missing_platform_length < 0) {
/* 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) {
/* 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;
}
@ -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) {
/* Penalty for reversing in a depot. */
assert(IsRailDepot(cur.tile));
segment_cost += Yapf().PfGetSettings().rail_depot_reverse_penalty;
segment_cost += YAPF_RAIL_DEPOT_REVERSE_PENALTY;
} else if (IsRailDepotTile(cur.tile)) {
/* 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 ||
!IsSafeWaitingPosition(v, t, td, true, _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. */
@ -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;
/* We don't know yet if the station is our target or not. Act like
* 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) */
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) {
/* Possible safe tile, but not so good as it's the back of a signal... */
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.last_red_signal_type == SIGTYPE_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)) {
/* 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);
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). */
extra_cost -= Yapf().PfGetSettings().rail_station_penalty * platform_length;
extra_cost -= YAPF_RAIL_STATION_PENALTY * platform_length;
/* Add penalty for the inappropriate platform length. */
extra_cost += PlatformLengthPenalty(platform_length);
}

View File

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

View File

@ -14,6 +14,13 @@
#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>
class CYapfCostRoadT
@ -49,7 +56,7 @@ protected:
if (z2 - z1 > 1) {
/* Slope up */
return Yapf().PfGetSettings().road_slope_penalty;
return YAPF_ROAD_SLOPE_PENALTY;
}
return 0;
}
@ -65,7 +72,7 @@ protected:
case MP_ROAD:
/* Increase the cost for level crossings */
if (IsLevelCrossing(tile)) {
cost += Yapf().PfGetSettings().road_crossing_penalty;
cost += YAPF_ROAD_CROSSING_PENALTY;
}
break;
@ -75,17 +82,17 @@ protected:
const RoadStop *rs = RoadStop::GetByTile(tile, GetRoadStopType(tile));
if (IsDriveThroughStopTile(tile)) {
/* Increase the cost for drive-through road stops */
cost += Yapf().PfGetSettings().road_stop_penalty;
cost += YAPF_ROAD_STOP_PENALTY;
DiagDirection dir = TrackdirToExitdir(trackdir);
if (!RoadStop::IsDriveThroughRoadStopContinuation(tile, tile - TileOffsByDiagDir(dir))) {
/* When we're the first road stop in a 'queue' of them we increase
* cost based on the fill percentage of the whole queue. */
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 {
/* 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;
}
@ -95,7 +102,7 @@ protected:
}
} else {
/* non-diagonal trackdir */
cost = YAPF_TILE_CORNER_LENGTH + Yapf().PfGetSettings().road_curve_penalty;
cost = YAPF_TILE_CORNER_LENGTH + YAPF_ROAD_CURVE_PENALTY;
}
return cost;
}
@ -479,10 +486,10 @@ public:
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;
return pf.FindNearestDepot(v, tile, td, max_distance);
return pf.FindNearestDepot(v, tile, td);
}
/**
@ -490,13 +497,12 @@ public:
* @param v Vehicle
* @param tile Tile 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. */
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. */
if (!Yapf().FindPath(v)) return FindDepotData();
@ -524,23 +530,17 @@ struct CYapfRoad_TypesT
typedef CYapfCostRoadT<Types> PfCost;
};
struct CYapfRoad1 : CYapfT<CYapfRoad_TypesT<CYapfRoad1 , CRoadNodeListTrackDir, CYapfDestinationTileRoadT > > {};
struct CYapfRoad2 : CYapfT<CYapfRoad_TypesT<CYapfRoad2 , CRoadNodeListExitDir , CYapfDestinationTileRoadT > > {};
struct CYapfRoadAnyDepot1 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyDepot1, CRoadNodeListTrackDir, CYapfDestinationAnyDepotRoadT> > {};
struct CYapfRoadAnyDepot2 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyDepot2, CRoadNodeListExitDir , CYapfDestinationAnyDepotRoadT> > {};
struct CYapfRoad : CYapfT<CYapfRoad_TypesT<CYapfRoad , CRoadNodeListExitDir , CYapfDestinationTileRoadT > > {};
struct CYapfRoadAnyDepot : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyDepot, CRoadNodeListExitDir , CYapfDestinationAnyDepotRoadT> > {};
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
? CYapfRoad1::stChooseRoadTrack(v, tile, enterdir, path_found, path_cache) // Trackdir
: CYapfRoad2::stChooseRoadTrack(v, tile, enterdir, path_found, path_cache); // ExitDir, allow 90-deg
Trackdir td_ret = CYapfRoad::stChooseRoadTrack(v, tile, enterdir, path_found, path_cache);
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;
Trackdir trackdir = v->GetVehicleTrackdir();
@ -549,7 +549,5 @@ FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_dist
return FindDepotData();
}
return _settings_game.pf.yapf.disable_node_optimization
? CYapfRoadAnyDepot1::stFindNearestDepot(v, tile, trackdir, max_distance) // Trackdir
: CYapfRoadAnyDepot2::stFindNearestDepot(v, tile, trackdir, max_distance); // ExitDir
return CYapfRoadAnyDepot::stFindNearestDepot(v, tile, trackdir);
}

View File

@ -23,6 +23,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 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>
class CYapfDestinationTileWaterT
{
@ -223,7 +226,7 @@ public:
* 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. */
for (int attempt = 0; attempt < 2; ++attempt) {
Tpf pf(MAX_SHIP_PF_NODES);
Tpf pf;
/* Set origin and destination nodes */
pf.SetOrigin(v->tile, forward_dirs | reverse_dirs);
@ -345,10 +348,10 @@ public:
if (HasTrackdir(TrackdirCrossesTrackdirs(td1), td2)) {
/* 90-deg curve penalty. */
return Yapf().PfGetSettings().ship_curve90_penalty;
return YAPF_SHIP_CURVE90_PENALTY;
} else if (td2 != NextTrackdir(td1)) {
/* 45-deg curve penalty. */
return Yapf().PfGetSettings().ship_curve45_penalty;
return YAPF_SHIP_CURVE45_PENALTY;
}
return 0;
}
@ -419,7 +422,7 @@ struct CYapfShip_TypesT
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. */

View File

@ -179,9 +179,7 @@ public:
{
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
* 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));
Tpf pf;
pf.SetDestination(start_water_region_patch);
if (v->current_order.IsType(OT_GOTO_STATION)) {
@ -284,7 +282,7 @@ typedef NodeList<CYapfRegionNodeT<CYapfRegionPatchNodeKey>, 12, 12> CRegionNodeL
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();
}
static FindDepotData FindClosestRoadDepot(const RoadVehicle *v, int max_distance)
static FindDepotData FindClosestRoadDepot(const RoadVehicle *v)
{
if (IsRoadDepotTile(v->tile)) return FindDepotData(v->tile, 0);
return YapfRoadVehicleFindNearestDepot(v, max_distance);
return YapfRoadVehicleFindNearestDepot(v);
}
ClosestDepot RoadVehicle::FindClosestDepot()
{
FindDepotData rfdd = FindClosestRoadDepot(this, 0);
FindDepotData rfdd = FindClosestRoadDepot(this);
if (rfdd.best_length == UINT_MAX) return ClosestDepot();
return ClosestDepot(rfdd.tile, GetDepotIndex(rfdd.tile));
@ -1673,11 +1673,9 @@ static void CheckIfRoadVehNeedsService(RoadVehicle *v)
return;
}
uint max_penalty = _settings_game.pf.yapf.maximum_go_to_depot_penalty;
FindDepotData rfdd = FindClosestRoadDepot(v, max_penalty);
FindDepotData rfdd = FindClosestRoadDepot(v);
/* 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 we were already heading for a depot but it has
* 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(8, SLV_130, SLV_TABLE_CHUNKS),
SLC_NULL(4, SLV_131, SLV_TABLE_CHUNKS),
SLC_VAR("pf.yapf.disable_node_optimization"),
SLC_VAR("pf.yapf.max_search_nodes"),
SLC_VAR("pf.yapf.rail_firstred_twoway_eol"),
SLC_VAR("pf.yapf.rail_firstred_penalty"),
SLC_VAR("pf.yapf.rail_firstred_exit_penalty"),
SLC_VAR("pf.yapf.rail_lastred_penalty"),
SLC_VAR("pf.yapf.rail_lastred_exit_penalty"),
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_NULL(4 * 15 + 2, SLV_28, SLV_REMOVE_PF_SETTINGS), // YAPF, x34 (32 int, 2 bool)
SLC_NULL(4 * 4, SLV_100, SLV_REMOVE_PF_SETTINGS),
SLC_NULL(4 * 7, SLV_33, SLV_REMOVE_PF_SETTINGS),
SLC_NULL(4 * 1, SLV_47, SLV_REMOVE_PF_SETTINGS),
SLC_NULL(4 * 2, SLV_130, SLV_REMOVE_PF_SETTINGS),
SLC_NULL(4 * 1, SLV_131, SLV_REMOVE_PF_SETTINGS),
SLC_NULL(4 * 2, SLV_SHIP_CURVE_PENALTY, SLV_REMOVE_PF_SETTINGS),
SLC_VAR("game_creation.land_generator"),
SLC_VAR("game_creation.oil_refinery_limit"),
SLC_VAR("game_creation.tgen_smoothness"),

View File

@ -392,6 +392,8 @@ enum SaveLoadVersion : uint16_t {
SLV_ROAD_TYPE_LABEL_MAP, ///< 344 PR#13021 Add road type label map to allow upgrade/conversion of road types.
SLV_NONFLOODING_WATER_TILES, ///< 345 PR#13013 Store water tile non-flooding state.
SLV_REMOVE_PF_SETTINGS, ///< 345 PR#10623 Removal of pathfinder settings.
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
};
/** 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. */
struct PathfinderSettings {
bool roadveh_queue; ///< buggy road vehicle queueing
@ -472,8 +433,6 @@ struct PathfinderSettings {
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 path_backoff_interval; ///< ticks between checks for a free path.
YAPFSettings yapf; ///< pathfinder settings for the yet another pathfinder
};
/** Settings related to orders. */

View File

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

View File

@ -96,303 +96,3 @@ def = 20
min = 1
max = 255
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.
* @param v %Train that wants a depot.
* @param max_distance Maximal search distance.
* @return Information where the closest train depot is located.
* @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));
@ -2172,12 +2171,12 @@ static FindDepotData FindClosestTrainDepot(Train *v, int max_distance)
PBSTileInfo origin = FollowTrainReservation(v);
if (IsRailDepotTile(origin.tile)) return FindDepotData(origin.tile, 0);
return YapfTrainFindNearestDepot(v, max_distance);
return YapfTrainFindNearestDepot(v);
}
ClosestDepot Train::FindClosestDepot()
{
FindDepotData tfdd = FindClosestTrainDepot(this, 0);
FindDepotData tfdd = FindClosestTrainDepot(this);
if (tfdd.best_length == UINT_MAX) return ClosestDepot();
return ClosestDepot(tfdd.tile, GetDepotIndex(tfdd.tile), tfdd.reverse);
@ -4148,11 +4147,9 @@ static void CheckIfTrainNeedsService(Train *v)
return;
}
uint max_penalty = _settings_game.pf.yapf.maximum_go_to_depot_penalty;
FindDepotData tfdd = FindClosestTrainDepot(v, max_penalty);
FindDepotData tfdd = FindClosestTrainDepot(v);
/* 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 we were already heading for a depot but it has
* suddenly moved farther away, we continue our normal