(svn r5066) -Feature: [YAPF] Train selects the best station platform by length
authorKUDr
Thu, 01 Jun 2006 21:39:35 +0000
changeset 3931 b946fc6e7188
parent 3930 1c293cf92ab5
child 3932 dfe10fa5ce4f
(svn r5066) -Feature: [YAPF] Train selects the best station platform by length
settings.c
yapf/follow_track.hpp
yapf/yapf.h
yapf/yapf.hpp
yapf/yapf_costrail.hpp
yapf/yapf_road.cpp
yapf/yapf_settings.h
--- a/settings.c	Thu Jun 01 21:00:59 2006 +0000
+++ b/settings.c	Thu Jun 01 21:39:35 2006 +0000
@@ -1407,6 +1407,9 @@
 	SDT_CONDVAR (Patches, yapf.rail_look_ahead_signal_p0  , SLE_INT , 28, SL_MAX_VERSION, 0, 0,   500                   , -1000000, 1000000, STR_NULL, NULL),
 	SDT_CONDVAR (Patches, yapf.rail_look_ahead_signal_p1  , SLE_INT , 28, SL_MAX_VERSION, 0, 0,  -100                   , -1000000, 1000000, STR_NULL, NULL),
 	SDT_CONDVAR (Patches, yapf.rail_look_ahead_signal_p2  , SLE_INT , 28, SL_MAX_VERSION, 0, 0,     5                   , -1000000, 1000000, STR_NULL, NULL),
+	// penalties for too long or too short station platforms (TODO: NS flag or higher revision?)
+	SDT_CONDVAR (Patches, yapf.rail_longer_platform_penalty,  SLE_UINT, 28, SL_MAX_VERSION,NS, 0,  10 * YAPF_TILE_LENGTH,        0,   20000, STR_NULL, NULL),
+	SDT_CONDVAR (Patches, yapf.rail_shorter_platform_penalty, SLE_UINT, 28, SL_MAX_VERSION,NS, 0, 100 * YAPF_TILE_LENGTH,        0,   20000, STR_NULL, NULL),
 
 	SDT_END()
 };
--- a/yapf/follow_track.hpp	Thu Jun 01 21:00:59 2006 +0000
+++ b/yapf/follow_track.hpp	Thu Jun 01 21:39:35 2006 +0000
@@ -27,8 +27,8 @@
 		m_new_tile = INVALID_TILE;
 		m_new_td_bits = TRACKDIR_BIT_NONE;
 		m_exitdir = INVALID_DIAGDIR;
-		m_is_tunnel = false;
-		m_tunnel_tiles_skipped = 0;
+		m_is_station = m_is_tunnel = false;
+		m_tiles_skipped = 0;
 	}
 
 	FORCEINLINE static TransportType TT() {return Ttr_type_;}
@@ -57,7 +57,7 @@
 	}
 
 protected:
-	/** Follow the m_exitdir from m_old_tile and fill m_new_tile and m_tunnel_tiles_skipped */
+	/** Follow the m_exitdir from m_old_tile and fill m_new_tile and m_tiles_skipped */
 	FORCEINLINE void FollowTileExit()
 	{
 		// extra handling for tunnels in our direction
@@ -68,17 +68,27 @@
 				FindLengthOfTunnelResult flotr = FindLengthOfTunnel(m_old_tile, m_exitdir);
 				m_new_tile = flotr.tile;
 				m_is_tunnel = true;
-				m_tunnel_tiles_skipped = flotr.length - 1;
+				m_tiles_skipped = flotr.length - 1;
 				return;
 			}
 			assert(ReverseDiagDir(tunnel_enterdir) == m_exitdir);
 		}
-		// not a tunnel
+		// not a tunnel or station
 		m_is_tunnel = false;
-		m_tunnel_tiles_skipped = 0;
-		// normal tile
+		m_tiles_skipped = 0;
+
+		// normal or station tile
 		TileIndexDiff diff = TileOffsByDir(m_exitdir);
 		m_new_tile = TILE_ADD(m_old_tile, diff);
+
+		// special handling for stations
+		if (IsRailTT() && IsRailwayStationTile(m_new_tile)) {
+			m_is_station = true;
+		} else if (IsRoadTT() && IsRoadStopTile(m_new_tile)) {
+			m_is_station = true;
+		} else {
+			m_is_station = false;
+		}
 	}
 
 	/** stores track status (available trackdirs) for the new tile into m_new_td_bits */
@@ -171,6 +181,21 @@
 			if (tunnel_enterdir != m_exitdir)
 				return false;
 		}
+
+		// special handling for rail stations - get to the end of platform
+		if (IsRailTT() && m_is_station) {
+			// entered railway station
+			// get platform length
+			uint length = GetPlatformLength(m_new_tile, TrackdirToExitdir(m_old_td));
+			// how big step we must do to get to the last platform tile;
+			m_tiles_skipped = length - 1;
+			// move to the platform end
+			TileIndexDiff diff = TileOffsByDir(m_exitdir);
+			diff *= m_tiles_skipped;
+			m_new_tile = TILE_ADD(m_new_tile, diff);
+			return true;
+		}
+
 		return true;
 	}
 
@@ -184,7 +209,7 @@
 				m_new_tile = m_old_tile;
 				m_new_td_bits = TrackdirToTrackdirBits(ReverseTrackdir(m_old_td));
 				m_exitdir = exitdir;
-				m_tunnel_tiles_skipped = 0;
+				m_tiles_skipped = 0;
 				m_is_tunnel = false;
 				return true;
 			}
--- a/yapf/yapf.h	Thu Jun 01 21:00:59 2006 +0000
+++ b/yapf/yapf.h	Thu Jun 01 21:39:35 2006 +0000
@@ -37,7 +37,8 @@
 //	TrackdirBits  m_red_td_bits;
 	DiagDirection m_exitdir;
 	bool          m_is_tunnel;
-	int           m_tunnel_tiles_skipped;
+	bool          m_is_station;
+	int           m_tiles_skipped;
 } FollowTrack_t;
 
 /** track followers */
--- a/yapf/yapf.hpp	Thu Jun 01 21:00:59 2006 +0000
+++ b/yapf/yapf.hpp	Thu Jun 01 21:39:35 2006 +0000
@@ -13,6 +13,7 @@
 #include "../tunnel_map.h"
 #include "../bridge_map.h"
 #include "../bridge.h"
+#include "../station.h"
 #include "../station_map.h"
 #include "../vehicle.h"
 #include "../variables.h"
--- a/yapf/yapf_costrail.hpp	Thu Jun 01 21:00:59 2006 +0000
+++ b/yapf/yapf_costrail.hpp	Thu Jun 01 21:39:35 2006 +0000
@@ -138,6 +138,24 @@
 		return cost;
 	}
 
+	FORCEINLINE int PlatformLengthPenalty(int platform_length)
+	{
+		int cost = 0;
+		const Vehicle* v = Yapf().GetVehicle();
+		assert(v != NULL);
+		assert(v->type == VEH_Train);
+		assert(v->u.rail.cached_total_length != 0);
+		int needed_platform_length = (v->u.rail.cached_total_length + TILE_SIZE - 1) / TILE_SIZE;
+		if (platform_length > needed_platform_length) {
+			// apply penalty for longer platform than needed
+			cost += Yapf().PfGetSettings().rail_longer_platform_penalty * (platform_length - needed_platform_length);
+		} else {
+			// apply penalty for shorter platform than needed
+			cost += Yapf().PfGetSettings().rail_shorter_platform_penalty * (needed_platform_length - platform_length);
+		}
+		return cost;
+	}
+
 public:
 	FORCEINLINE void SetMaxCost(int max_cost) {m_max_cost = max_cost;}
 
@@ -245,7 +263,20 @@
 			}
 
 			// if we skipped some tunnel tiles, add their cost
-			segment_cost += YAPF_TILE_LENGTH * F.m_tunnel_tiles_skipped;
+			segment_cost += YAPF_TILE_LENGTH * F.m_tiles_skipped;
+
+			// add penalty for skipped station tiles
+			if (F.m_is_station)
+			{
+				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;
+				}
+			}
 
 			// add min/max speed penalties
 			int min_speed = 0;
--- a/yapf/yapf_road.cpp	Thu Jun 01 21:00:59 2006 +0000
+++ b/yapf/yapf_road.cpp	Thu Jun 01 21:39:35 2006 +0000
@@ -89,7 +89,7 @@
 			if (F.m_new_tile == n.m_key.m_tile && new_td == n.m_key.m_td) return false;
 
 			// if we skipped some tunnel tiles, add their cost
-			segment_cost += 10 * F.m_tunnel_tiles_skipped;
+			segment_cost += 10 * F.m_tiles_skipped;
 
 			// add hilly terrain penalty
 			segment_cost += Yapf().SlopeCost(tile, F.m_new_tile, trackdir);
--- a/yapf/yapf_settings.h	Thu Jun 01 21:00:59 2006 +0000
+++ b/yapf/yapf_settings.h	Thu Jun 01 21:39:35 2006 +0000
@@ -51,6 +51,9 @@
 	YS_DEF(int32 , rail_look_ahead_signal_p0)  ///< constant in polynomial penalty function
 	YS_DEF(int32 , rail_look_ahead_signal_p1)  ///< constant in polynomial penalty function
 	YS_DEF(int32 , rail_look_ahead_signal_p2)  ///< constant in polynomial penalty function
+
+	YS_DEF(uint32, rail_longer_platform_penalty)  ///< penalty for longer  station platform than train
+	YS_DEF(uint32, rail_shorter_platform_penalty) ///< penalty for shorter station platform than train
 YS_DEF_END;
 
 #undef YS_DEF_BEGIN