(svn r8873) [0.5] -Backport from trunk (r8766, r8836, r8869): 0.5
authorDarkvater
Sat, 24 Feb 2007 01:39:59 +0000
branch0.5
changeset 5445 5af942067209
parent 5444 3209bb62403e
child 5446 68d042c57e9e
(svn r8873) [0.5] -Backport from trunk (r8766, r8836, r8869):
- Rail station platform penalty not calculated properly (r8766)
- Don't tell destination was found if it was only guessed (r8836)
- Large Train Stations/Trains causes assert due to wrong cost calculation (r8869)
yapf/yapf.hpp
yapf/yapf_base.hpp
yapf/yapf_costrail.hpp
yapf/yapf_rail.cpp
yapf/yapf_road.cpp
yapf/yapf_ship.cpp
--- a/yapf/yapf.hpp	Sat Feb 24 01:21:31 2007 +0000
+++ b/yapf/yapf.hpp	Sat Feb 24 01:39:59 2007 +0000
@@ -82,10 +82,10 @@
 #include "hashtable.hpp"
 #include "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"
 
--- a/yapf/yapf_base.hpp	Sat Feb 24 01:21:31 2007 +0000
+++ b/yapf/yapf_base.hpp	Sat Feb 24 01:39:59 2007 +0000
@@ -7,10 +7,6 @@
 #include "../debug.h"
 EXTERN_C_END
 
-#include "fixedsizearray.hpp"
-#include "blob.hpp"
-#include "nodelist.hpp"
-
 extern int _total_pf_time_us;
 
 /** CYapfBaseT - A-star type path finder base class.
@@ -46,6 +42,7 @@
 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
@@ -135,7 +132,7 @@
 				break;
 			}
 		}
-		bool bDestFound = (m_pBestDestNode != NULL);
+		bool bDestFound = (m_pBestDestNode != NULL) && (m_pBestDestNode != m_pBestIntermediateNode);
 
 #ifndef NO_DEBUG_MESSAGES
 		perf.Stop();
@@ -191,20 +188,20 @@
 	}
 
 	/** 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);
@@ -214,7 +211,7 @@
 			m_stats_cache_hits++;
 		}
 
-		bool bValid = Yapf().PfCalcCost(n);
+		bool bValid = Yapf().PfCalcCost(n, tf);
 
 		if (bCached) {
 			Yapf().PfNodeCacheFlush(n);
--- a/yapf/yapf_costrail.hpp	Sat Feb 24 01:21:31 2007 +0000
+++ b/yapf/yapf_costrail.hpp	Sat Feb 24 01:39:59 2007 +0000
@@ -64,7 +64,7 @@
 	}
 
 	/** 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
@@ -77,11 +77,6 @@
 						cost += Yapf().PfGetSettings().rail_crossing_penalty;
 					break;
 
-				case MP_STATION:
-					// penalty for passing station tiles
-					cost += Yapf().PfGetSettings().rail_station_penalty;
-					break;
-
 				default:
 					break;
 			}
@@ -176,7 +171,7 @@
 	/** 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);
@@ -199,8 +194,13 @@
 
 		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);
@@ -282,13 +282,13 @@
 			// add penalty for skipped station tiles
 			if (F.m_is_station)
 			{
+				uint platform_length = F.m_tiles_skipped + 1;
 				if (target_seen) {
 					// it is our destination station
-					uint platform_length = F.m_tiles_skipped + 1;
 					segment_cost += PlatformLengthPenalty(platform_length);
 				} else {
 					// station is not our destination station, apply penalty for skipped platform tiles
-					segment_cost += Yapf().PfGetSettings().rail_station_penalty * F.m_tiles_skipped;
+					segment_cost += Yapf().PfGetSettings().rail_station_penalty * platform_length;
 				}
 			}
 
--- a/yapf/yapf_rail.cpp	Sat Feb 24 01:21:31 2007 +0000
+++ b/yapf/yapf_rail.cpp	Sat Feb 24 01:39:59 2007 +0000
@@ -34,7 +34,7 @@
 	{
 		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
@@ -97,7 +97,7 @@
 	{
 		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
--- a/yapf/yapf_road.cpp	Sat Feb 24 01:21:31 2007 +0000
+++ b/yapf/yapf_road.cpp	Sat Feb 24 01:39:59 2007 +0000
@@ -66,7 +66,7 @@
 	/** 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
@@ -237,7 +237,7 @@
 	{
 		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
--- a/yapf/yapf_ship.cpp	Sat Feb 24 01:21:31 2007 +0000
+++ b/yapf/yapf_ship.cpp	Sat Feb 24 01:39:59 2007 +0000
@@ -26,7 +26,7 @@
 	{
 		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
@@ -86,6 +86,7 @@
 {
 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
 
@@ -97,7 +98,7 @@
 	/** 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;