mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-01-23 23:52:37 +00:00
(svn r5066) -Feature: [YAPF] Train selects the best station platform by length
This commit is contained in:
parent
76a8f036df
commit
bd25f49d3f
@ -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()
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user