mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-09 23:50:25 +00:00
(svn r8869) [YAPF] -Fix: Large Train Stations/Trains makes OpenTTD crash (Jigsaw_Psyche)
This commit is contained in:
parent
433b8054e9
commit
029ceda0f1
@ -78,10 +78,10 @@ typedef CPerfStartFake CPerfStart;
|
|||||||
#include "../misc/hashtable.hpp"
|
#include "../misc/hashtable.hpp"
|
||||||
#include "../misc/binaryheap.hpp"
|
#include "../misc/binaryheap.hpp"
|
||||||
#include "nodelist.hpp"
|
#include "nodelist.hpp"
|
||||||
|
#include "follow_track.hpp"
|
||||||
#include "yapf_base.hpp"
|
#include "yapf_base.hpp"
|
||||||
#include "yapf_node.hpp"
|
#include "yapf_node.hpp"
|
||||||
#include "yapf_common.hpp"
|
#include "yapf_common.hpp"
|
||||||
#include "follow_track.hpp"
|
|
||||||
#include "yapf_costbase.hpp"
|
#include "yapf_costbase.hpp"
|
||||||
#include "yapf_costcache.hpp"
|
#include "yapf_costcache.hpp"
|
||||||
|
|
||||||
|
@ -7,10 +7,6 @@
|
|||||||
|
|
||||||
#include "../debug.h"
|
#include "../debug.h"
|
||||||
|
|
||||||
#include "../misc/fixedsizearray.hpp"
|
|
||||||
#include "../misc/blob.hpp"
|
|
||||||
#include "nodelist.hpp"
|
|
||||||
|
|
||||||
extern int _total_pf_time_us;
|
extern int _total_pf_time_us;
|
||||||
|
|
||||||
/** CYapfBaseT - A-star type path finder base class.
|
/** CYapfBaseT - A-star type path finder base class.
|
||||||
@ -46,6 +42,7 @@ template <class Types>
|
|||||||
class CYapfBaseT {
|
class CYapfBaseT {
|
||||||
public:
|
public:
|
||||||
typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
|
typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
|
||||||
|
typedef typename Types::TrackFollower TrackFollower;
|
||||||
typedef typename Types::NodeList NodeList; ///< our node list
|
typedef typename Types::NodeList NodeList; ///< our node list
|
||||||
typedef typename NodeList::Titem Node; ///< this will be our node type
|
typedef typename NodeList::Titem Node; ///< this will be our node type
|
||||||
typedef typename Node::Key Key; ///< key to hash tables
|
typedef typename Node::Key Key; ///< key to hash tables
|
||||||
@ -192,20 +189,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** add multiple nodes - direct children of the given node */
|
/** add multiple nodes - direct children of the given node */
|
||||||
FORCEINLINE void AddMultipleNodes(Node* parent, TileIndex tile, TrackdirBits td_bits)
|
FORCEINLINE void AddMultipleNodes(Node* parent, const TrackFollower &tf)
|
||||||
{
|
{
|
||||||
bool is_choice = (KillFirstBit2x64(td_bits) != 0);
|
bool is_choice = (KillFirstBit2x64(tf.m_new_td_bits) != 0);
|
||||||
for (TrackdirBits rtds = td_bits; rtds != TRACKDIR_BIT_NONE; rtds = (TrackdirBits)KillFirstBit2x64(rtds)) {
|
for (TrackdirBits rtds = tf.m_new_td_bits; rtds != TRACKDIR_BIT_NONE; rtds = (TrackdirBits)KillFirstBit2x64(rtds)) {
|
||||||
Trackdir td = (Trackdir)FindFirstBit2x64(rtds);
|
Trackdir td = (Trackdir)FindFirstBit2x64(rtds);
|
||||||
Node& n = Yapf().CreateNewNode();
|
Node& n = Yapf().CreateNewNode();
|
||||||
n.Set(parent, tile, td, is_choice);
|
n.Set(parent, tf.m_new_tile, td, is_choice);
|
||||||
Yapf().AddNewNode(n);
|
Yapf().AddNewNode(n, tf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** AddNewNode() - called by Tderived::PfFollowNode() for each child node.
|
/** AddNewNode() - called by Tderived::PfFollowNode() for each child node.
|
||||||
* Nodes are evaluated here and added into open list */
|
* Nodes are evaluated here and added into open list */
|
||||||
void AddNewNode(Node& n)
|
void AddNewNode(Node &n, const TrackFollower &tf)
|
||||||
{
|
{
|
||||||
// evaluate the node
|
// evaluate the node
|
||||||
bool bCached = Yapf().PfNodeCacheFetch(n);
|
bool bCached = Yapf().PfNodeCacheFetch(n);
|
||||||
@ -215,7 +212,7 @@ public:
|
|||||||
m_stats_cache_hits++;
|
m_stats_cache_hits++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bValid = Yapf().PfCalcCost(n);
|
bool bValid = Yapf().PfCalcCost(n, tf);
|
||||||
|
|
||||||
if (bCached) {
|
if (bCached) {
|
||||||
Yapf().PfNodeCacheFlush(n);
|
Yapf().PfNodeCacheFlush(n);
|
||||||
|
@ -66,7 +66,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** return one tile cost. If tile is a tunnel entry, it is moved to the end of tunnel */
|
/** return one tile cost. If tile is a tunnel entry, it is moved to the end of tunnel */
|
||||||
FORCEINLINE int OneTileCost(TileIndex& tile, Trackdir trackdir)
|
FORCEINLINE int OneTileCost(TileIndex prev_tile, TileIndex& tile, Trackdir trackdir)
|
||||||
{
|
{
|
||||||
int cost = 0;
|
int cost = 0;
|
||||||
// set base cost
|
// set base cost
|
||||||
@ -79,11 +79,6 @@ public:
|
|||||||
cost += Yapf().PfGetSettings().rail_crossing_penalty;
|
cost += Yapf().PfGetSettings().rail_crossing_penalty;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_STATION:
|
|
||||||
// penalty for passing station tiles
|
|
||||||
cost += Yapf().PfGetSettings().rail_station_penalty;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -178,7 +173,7 @@ public:
|
|||||||
/** Called by YAPF to calculate the cost from the origin to the given node.
|
/** Called by YAPF to calculate the cost from the origin to the given node.
|
||||||
* Calculates only the cost of given node, adds it to the parent node cost
|
* Calculates only the cost of given node, adds it to the parent node cost
|
||||||
* and stores the result into Node::m_cost member */
|
* and stores the result into Node::m_cost member */
|
||||||
FORCEINLINE bool PfCalcCost(Node& n)
|
FORCEINLINE bool PfCalcCost(Node &n, const TrackFollower &tf)
|
||||||
{
|
{
|
||||||
assert(!n.flags_u.flags_s.m_targed_seen);
|
assert(!n.flags_u.flags_s.m_targed_seen);
|
||||||
CPerfStart perf_cost(Yapf().m_perf_cost);
|
CPerfStart perf_cost(Yapf().m_perf_cost);
|
||||||
@ -201,8 +196,13 @@ public:
|
|||||||
|
|
||||||
bool target_seen = Yapf().PfDetectDestination(tile, trackdir);
|
bool target_seen = Yapf().PfDetectDestination(tile, trackdir);
|
||||||
|
|
||||||
|
if (tf.m_is_station) {
|
||||||
|
// station tiles have an extra penalty
|
||||||
|
segment_cost += Yapf().PfGetSettings().rail_station_penalty * (tf.m_tiles_skipped + 1);
|
||||||
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
segment_cost += Yapf().OneTileCost(tile, trackdir);
|
segment_cost += Yapf().OneTileCost(prev_tile, tile, trackdir);
|
||||||
segment_cost += Yapf().CurveCost(prev_trackdir, trackdir);
|
segment_cost += Yapf().CurveCost(prev_trackdir, trackdir);
|
||||||
segment_cost += Yapf().SlopeCost(tile, trackdir);
|
segment_cost += Yapf().SlopeCost(tile, trackdir);
|
||||||
segment_cost += Yapf().SignalCost(n, tile, trackdir);
|
segment_cost += Yapf().SignalCost(n, tile, trackdir);
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
{
|
{
|
||||||
TrackFollower F(Yapf().GetVehicle());
|
TrackFollower F(Yapf().GetVehicle());
|
||||||
if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir()))
|
if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir()))
|
||||||
Yapf().AddMultipleNodes(&old_node, F.m_new_tile, F.m_new_td_bits);
|
Yapf().AddMultipleNodes(&old_node, F);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return debug report character to identify the transportation type
|
/// return debug report character to identify the transportation type
|
||||||
@ -99,7 +99,7 @@ public:
|
|||||||
{
|
{
|
||||||
TrackFollower F(Yapf().GetVehicle());
|
TrackFollower F(Yapf().GetVehicle());
|
||||||
if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir()))
|
if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir()))
|
||||||
Yapf().AddMultipleNodes(&old_node, F.m_new_tile, F.m_new_td_bits);
|
Yapf().AddMultipleNodes(&old_node, F);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return debug report character to identify the transportation type
|
/// return debug report character to identify the transportation type
|
||||||
|
@ -72,7 +72,7 @@ public:
|
|||||||
/** Called by YAPF to calculate the cost from the origin to the given node.
|
/** Called by YAPF to calculate the cost from the origin to the given node.
|
||||||
* Calculates only the cost of given node, adds it to the parent node cost
|
* Calculates only the cost of given node, adds it to the parent node cost
|
||||||
* and stores the result into Node::m_cost member */
|
* and stores the result into Node::m_cost member */
|
||||||
FORCEINLINE bool PfCalcCost(Node& n)
|
FORCEINLINE bool PfCalcCost(Node& n, const TrackFollower &tf)
|
||||||
{
|
{
|
||||||
int segment_cost = 0;
|
int segment_cost = 0;
|
||||||
// start at n.m_key.m_tile / n.m_key.m_td and walk to the end of segment
|
// start at n.m_key.m_tile / n.m_key.m_td and walk to the end of segment
|
||||||
@ -246,7 +246,7 @@ public:
|
|||||||
{
|
{
|
||||||
TrackFollower F(Yapf().GetVehicle());
|
TrackFollower F(Yapf().GetVehicle());
|
||||||
if (F.Follow(old_node.m_segment_last_tile, old_node.m_segment_last_td))
|
if (F.Follow(old_node.m_segment_last_tile, old_node.m_segment_last_td))
|
||||||
Yapf().AddMultipleNodes(&old_node, F.m_new_tile, F.m_new_td_bits);
|
Yapf().AddMultipleNodes(&old_node, F);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return debug report character to identify the transportation type
|
/// return debug report character to identify the transportation type
|
||||||
|
@ -28,7 +28,7 @@ public:
|
|||||||
{
|
{
|
||||||
TrackFollower F;
|
TrackFollower F;
|
||||||
if (F.Follow(old_node.m_key.m_tile, old_node.m_key.m_td))
|
if (F.Follow(old_node.m_key.m_tile, old_node.m_key.m_td))
|
||||||
Yapf().AddMultipleNodes(&old_node, F.m_new_tile, F.m_new_td_bits);
|
Yapf().AddMultipleNodes(&old_node, F);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return debug report character to identify the transportation type
|
/// return debug report character to identify the transportation type
|
||||||
@ -88,6 +88,7 @@ class CYapfCostShipT
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
|
typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
|
||||||
|
typedef typename Types::TrackFollower TrackFollower;
|
||||||
typedef typename Types::NodeList::Titem Node; ///< this will be our node type
|
typedef typename Types::NodeList::Titem Node; ///< this will be our node type
|
||||||
typedef typename Node::Key Key; ///< key to hash tables
|
typedef typename Node::Key Key; ///< key to hash tables
|
||||||
|
|
||||||
@ -99,7 +100,7 @@ public:
|
|||||||
/** Called by YAPF to calculate the cost from the origin to the given node.
|
/** Called by YAPF to calculate the cost from the origin to the given node.
|
||||||
* Calculates only the cost of given node, adds it to the parent node cost
|
* Calculates only the cost of given node, adds it to the parent node cost
|
||||||
* and stores the result into Node::m_cost member */
|
* and stores the result into Node::m_cost member */
|
||||||
FORCEINLINE bool PfCalcCost(Node& n)
|
FORCEINLINE bool PfCalcCost(Node& n, const TrackFollower &tf)
|
||||||
{
|
{
|
||||||
// base tile cost depending on distance
|
// base tile cost depending on distance
|
||||||
int c = IsDiagonalTrackdir(n.GetTrackdir()) ? 10 : 7;
|
int c = IsDiagonalTrackdir(n.GetTrackdir()) ? 10 : 7;
|
||||||
|
Loading…
Reference in New Issue
Block a user