mirror of https://github.com/OpenTTD/OpenTTD
Merge 00c314d5e9
into a6c526cfa0
commit
03115f91a5
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -58,10 +58,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
|
||||||
|
@ -72,7 +72,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() {}
|
||||||
|
@ -85,19 +85,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)
|
||||||
|
@ -117,7 +111,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);
|
||||||
|
@ -226,7 +220,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());
|
||||||
|
|
|
@ -108,7 +108,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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 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
|
||||||
{
|
{
|
||||||
|
@ -223,7 +226,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);
|
||||||
|
@ -345,10 +348,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;
|
||||||
}
|
}
|
||||||
|
@ -419,7 +422,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. */
|
||||||
|
|
|
@ -179,9 +179,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)) {
|
||||||
|
@ -284,7 +282,7 @@ typedef NodeList<CYapfRegionNodeT<CYapfRegionPatchNodeKey>, 12, 12> CRegionNodeL
|
||||||
|
|
||||||
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() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"),
|
||||||
|
|
|
@ -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_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_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
|
SL_MAX_VERSION, ///< Highest possible saveload version
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue