summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKUDr <KUDr@openttd.org>2007-02-24 00:17:46 +0000
committerKUDr <KUDr@openttd.org>2007-02-24 00:17:46 +0000
commitefb3637d0f7fc423e2b4f31a67058455a5183da5 (patch)
treea567351d7e9a2e7575b410393280573e0ba04d98
parent98a4fc13996ae24728e051350ee0338a356af954 (diff)
downloadopenttd-efb3637d0f7fc423e2b4f31a67058455a5183da5.tar.xz
(svn r8869) [YAPF] -Fix: Large Train Stations/Trains makes OpenTTD crash (Jigsaw_Psyche)
-rw-r--r--src/yapf/yapf.hpp2
-rw-r--r--src/yapf/yapf_base.hpp19
-rw-r--r--src/yapf/yapf_costrail.hpp16
-rw-r--r--src/yapf/yapf_rail.cpp4
-rw-r--r--src/yapf/yapf_road.cpp4
-rw-r--r--src/yapf/yapf_ship.cpp5
6 files changed, 24 insertions, 26 deletions
diff --git a/src/yapf/yapf.hpp b/src/yapf/yapf.hpp
index bd94dacc6..90730b790 100644
--- a/src/yapf/yapf.hpp
+++ b/src/yapf/yapf.hpp
@@ -78,10 +78,10 @@ typedef CPerfStartFake CPerfStart;
#include "../misc/hashtable.hpp"
#include "../misc/binaryheap.hpp"
#include "nodelist.hpp"
+#include "follow_track.hpp"
#include "yapf_base.hpp"
#include "yapf_node.hpp"
#include "yapf_common.hpp"
-#include "follow_track.hpp"
#include "yapf_costbase.hpp"
#include "yapf_costcache.hpp"
diff --git a/src/yapf/yapf_base.hpp b/src/yapf/yapf_base.hpp
index 6218c6ec7..0d49171cd 100644
--- a/src/yapf/yapf_base.hpp
+++ b/src/yapf/yapf_base.hpp
@@ -7,10 +7,6 @@
#include "../debug.h"
-#include "../misc/fixedsizearray.hpp"
-#include "../misc/blob.hpp"
-#include "nodelist.hpp"
-
extern int _total_pf_time_us;
/** CYapfBaseT - A-star type path finder base class.
@@ -46,6 +42,7 @@ template <class Types>
class CYapfBaseT {
public:
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 NodeList::Titem Node; ///< this will be our node type
typedef typename Node::Key Key; ///< key to hash tables
@@ -192,20 +189,20 @@ public:
}
/** 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);
- for (TrackdirBits rtds = td_bits; rtds != TRACKDIR_BIT_NONE; rtds = (TrackdirBits)KillFirstBit2x64(rtds)) {
+ bool is_choice = (KillFirstBit2x64(tf.m_new_td_bits) != 0);
+ for (TrackdirBits rtds = tf.m_new_td_bits; rtds != TRACKDIR_BIT_NONE; rtds = (TrackdirBits)KillFirstBit2x64(rtds)) {
Trackdir td = (Trackdir)FindFirstBit2x64(rtds);
Node& n = Yapf().CreateNewNode();
- n.Set(parent, tile, td, is_choice);
- Yapf().AddNewNode(n);
+ n.Set(parent, tf.m_new_tile, td, is_choice);
+ Yapf().AddNewNode(n, tf);
}
}
/** AddNewNode() - called by Tderived::PfFollowNode() for each child node.
* Nodes are evaluated here and added into open list */
- void AddNewNode(Node& n)
+ void AddNewNode(Node &n, const TrackFollower &tf)
{
// evaluate the node
bool bCached = Yapf().PfNodeCacheFetch(n);
@@ -215,7 +212,7 @@ public:
m_stats_cache_hits++;
}
- bool bValid = Yapf().PfCalcCost(n);
+ bool bValid = Yapf().PfCalcCost(n, tf);
if (bCached) {
Yapf().PfNodeCacheFlush(n);
diff --git a/src/yapf/yapf_costrail.hpp b/src/yapf/yapf_costrail.hpp
index b776815dc..4335c8a5b 100644
--- a/src/yapf/yapf_costrail.hpp
+++ b/src/yapf/yapf_costrail.hpp
@@ -66,7 +66,7 @@ public:
}
/** 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;
// set base cost
@@ -79,11 +79,6 @@ public:
cost += Yapf().PfGetSettings().rail_crossing_penalty;
break;
- case MP_STATION:
- // penalty for passing station tiles
- cost += Yapf().PfGetSettings().rail_station_penalty;
- break;
-
default:
break;
}
@@ -178,7 +173,7 @@ public:
/** 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
* 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);
CPerfStart perf_cost(Yapf().m_perf_cost);
@@ -201,8 +196,13 @@ public:
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) {
- segment_cost += Yapf().OneTileCost(tile, trackdir);
+ segment_cost += Yapf().OneTileCost(prev_tile, tile, trackdir);
segment_cost += Yapf().CurveCost(prev_trackdir, trackdir);
segment_cost += Yapf().SlopeCost(tile, trackdir);
segment_cost += Yapf().SignalCost(n, tile, trackdir);
diff --git a/src/yapf/yapf_rail.cpp b/src/yapf/yapf_rail.cpp
index 8b88fde26..7e7713f48 100644
--- a/src/yapf/yapf_rail.cpp
+++ b/src/yapf/yapf_rail.cpp
@@ -36,7 +36,7 @@ public:
{
TrackFollower F(Yapf().GetVehicle());
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
@@ -99,7 +99,7 @@ public:
{
TrackFollower F(Yapf().GetVehicle());
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
diff --git a/src/yapf/yapf_road.cpp b/src/yapf/yapf_road.cpp
index 763d39af4..c22683c25 100644
--- a/src/yapf/yapf_road.cpp
+++ b/src/yapf/yapf_road.cpp
@@ -72,7 +72,7 @@ public:
/** 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
* 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;
// 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());
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
diff --git a/src/yapf/yapf_ship.cpp b/src/yapf/yapf_ship.cpp
index 43f7eca73..94c0016f3 100644
--- a/src/yapf/yapf_ship.cpp
+++ b/src/yapf/yapf_ship.cpp
@@ -28,7 +28,7 @@ public:
{
TrackFollower F;
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
@@ -88,6 +88,7 @@ class CYapfCostShipT
{
public:
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 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.
* Calculates only the cost of given node, adds it to the parent node cost
* 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
int c = IsDiagonalTrackdir(n.GetTrackdir()) ? 10 : 7;