# HG changeset patch # User KUDr # Date 1149197975 0 # Node ID c846bc28d6864a139b6308a30e4d910a378dea32 # Parent be53f1351e5d3d28e1f2f1f398d315f7e39c1936 (svn r5066) -Feature: [YAPF] Train selects the best station platform by length diff --git a/settings.c b/settings.c --- a/settings.c +++ b/settings.c @@ -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() }; diff --git a/yapf/follow_track.hpp b/yapf/follow_track.hpp --- a/yapf/follow_track.hpp +++ b/yapf/follow_track.hpp @@ -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; } diff --git a/yapf/yapf.h b/yapf/yapf.h --- a/yapf/yapf.h +++ b/yapf/yapf.h @@ -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 */ diff --git a/yapf/yapf.hpp b/yapf/yapf.hpp --- a/yapf/yapf.hpp +++ b/yapf/yapf.hpp @@ -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" diff --git a/yapf/yapf_costrail.hpp b/yapf/yapf_costrail.hpp --- a/yapf/yapf_costrail.hpp +++ b/yapf/yapf_costrail.hpp @@ -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; diff --git a/yapf/yapf_road.cpp b/yapf/yapf_road.cpp --- a/yapf/yapf_road.cpp +++ b/yapf/yapf_road.cpp @@ -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); diff --git a/yapf/yapf_settings.h b/yapf/yapf_settings.h --- a/yapf/yapf_settings.h +++ b/yapf/yapf_settings.h @@ -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