summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKUDr <kudr@openttd.org>2006-06-01 21:39:35 +0000
committerKUDr <kudr@openttd.org>2006-06-01 21:39:35 +0000
commitbd25f49d3f5252ba473759320b86f581be9c79fd (patch)
tree62d7336add925121331528ae4303d15bda9672ac
parent76a8f036df11a961a286dc4d5447a090a35bf4aa (diff)
downloadopenttd-bd25f49d3f5252ba473759320b86f581be9c79fd.tar.xz
(svn r5066) -Feature: [YAPF] Train selects the best station platform by length
-rw-r--r--settings.c3
-rw-r--r--yapf/follow_track.hpp41
-rw-r--r--yapf/yapf.h3
-rw-r--r--yapf/yapf.hpp1
-rw-r--r--yapf/yapf_costrail.hpp33
-rw-r--r--yapf/yapf_road.cpp2
-rw-r--r--yapf/yapf_settings.h3
7 files changed, 75 insertions, 11 deletions
diff --git a/settings.c b/settings.c
index 3ac000c22..1fd5e5d05 100644
--- a/settings.c
+++ b/settings.c
@@ -1407,6 +1407,9 @@ const SettingDesc _patch_settings[] = {
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
index e566a8e5e..7a191f311 100644
--- a/yapf/follow_track.hpp
+++ b/yapf/follow_track.hpp
@@ -27,8 +27,8 @@ struct CFollowTrackT : public FollowTrack_t
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 @@ struct CFollowTrackT : public FollowTrack_t
}
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 @@ protected:
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 @@ protected:
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 @@ protected:
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
index 0bcbe071b..4fc0b0043 100644
--- a/yapf/yapf.h
+++ b/yapf/yapf.h
@@ -37,7 +37,8 @@ typedef struct FollowTrack_t
// 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
index 6c7044310..50ae497ad 100644
--- a/yapf/yapf.hpp
+++ b/yapf/yapf.hpp
@@ -13,6 +13,7 @@ EXTERN_C_BEGIN
#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
index 6085197ab..76af3652b 100644
--- a/yapf/yapf_costrail.hpp
+++ b/yapf/yapf_costrail.hpp
@@ -138,6 +138,24 @@ public:
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 @@ public:
}
// 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
index 3cedb6719..3f2a9fe40 100644
--- a/yapf/yapf_road.cpp
+++ b/yapf/yapf_road.cpp
@@ -89,7 +89,7 @@ public:
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
index 3596b6ac3..475c7acc8 100644
--- a/yapf/yapf_settings.h
+++ b/yapf/yapf_settings.h
@@ -51,6 +51,9 @@ YS_DEF_BEGIN
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