Validate lookahead reservation end OK before calling FollowTrainReservation
This commit is contained in:
17
src/pbs.cpp
17
src/pbs.cpp
@@ -657,6 +657,23 @@ static Vehicle *FindTrainOnTrackEnum(Vehicle *v, void *data)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ValidateLookAhead(const Train *v)
|
||||
{
|
||||
TileIndex tile = v->lookahead->reservation_end_tile;
|
||||
Trackdir trackdir = v->lookahead->reservation_end_trackdir;
|
||||
|
||||
if (HasBit(v->lookahead->flags, TRLF_TB_EXIT_FREE)) {
|
||||
if (!likely(IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL && TrackdirEntersTunnelBridge(tile, trackdir))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (HasBit(v->lookahead->flags, TRLF_DEPOT_END) && !IsRailDepotTile(tile)) return false;
|
||||
|
||||
TrackdirBits trackdirbits = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0));
|
||||
if (!HasTrackdir(trackdirbits, trackdir)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Follow a train reservation to the last tile.
|
||||
|
@@ -141,6 +141,7 @@ enum FollowTrainReservationFlags {
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(FollowTrainReservationFlags)
|
||||
|
||||
bool ValidateLookAhead(const Train *v);
|
||||
PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res = nullptr, FollowTrainReservationFlags flags = FTRF_NONE);
|
||||
void ApplyAvailableFreeTunnelBridgeTiles(TrainReservationLookAhead *lookahead, int free_tiles, TileIndex tile, TileIndex end);
|
||||
void TryCreateLookAheadForTrainInTunnelBridge(Train *t);
|
||||
|
@@ -67,10 +67,11 @@ struct ChooseTrainTrackLookAheadState {
|
||||
|
||||
/** Flags for ChooseTrainTrack */
|
||||
enum ChooseTrainTrackFlags {
|
||||
CTTF_NONE = 0, ///< No flags
|
||||
CTTF_FORCE_RES = 0x01, ///< Force a reservation to be made
|
||||
CTTF_MARK_STUCK = 0x02, ///< The train has to be marked as stuck when needed
|
||||
CTTF_NON_LOOKAHEAD = 0x04, ///< Any lookahead should not be used, if necessary reset the lookahead state
|
||||
CTTF_NONE = 0, ///< No flags
|
||||
CTTF_FORCE_RES = 0x01, ///< Force a reservation to be made
|
||||
CTTF_MARK_STUCK = 0x02, ///< The train has to be marked as stuck when needed
|
||||
CTTF_NON_LOOKAHEAD = 0x04, ///< Any lookahead should not be used, if necessary reset the lookahead state
|
||||
CTTF_NO_LOOKAHEAD_VALIDATE = 0x08, ///< Don't validate the lookahead state as it has already been done
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(ChooseTrainTrackFlags)
|
||||
|
||||
@@ -90,6 +91,11 @@ static void TrainEnterStation(Train *v, StationID station);
|
||||
static void UnreserveBridgeTunnelTile(TileIndex tile);
|
||||
static bool CheckTrainStayInWormHolePathReserve(Train *t, TileIndex tile);
|
||||
|
||||
inline void ClearLookAheadIfInvalid(Train *v)
|
||||
{
|
||||
if (v->lookahead != nullptr && !ValidateLookAhead(v)) v->lookahead.reset();
|
||||
}
|
||||
|
||||
static const byte _vehicle_initial_x_fract[4] = {10, 8, 4, 8};
|
||||
static const byte _vehicle_initial_y_fract[4] = { 8, 4, 8, 10};
|
||||
|
||||
@@ -2984,6 +2990,8 @@ static FindDepotData FindClosestTrainDepot(Train *v, int max_distance)
|
||||
|
||||
if (IsRailDepotTile(v->tile)) return FindDepotData(v->tile, 0);
|
||||
|
||||
if (v->lookahead != nullptr && !ValidateLookAhead(v)) return FindDepotData();
|
||||
|
||||
PBSTileInfo origin = FollowTrainReservation(v, nullptr, FTRF_OKAY_UNUSED);
|
||||
if (IsRailDepotTile(origin.tile)) return FindDepotData(origin.tile, 0);
|
||||
|
||||
@@ -3900,7 +3908,7 @@ static void TryLongReserveChooseTrainTrack(Train *v, TileIndex tile, Trackdir td
|
||||
}
|
||||
SetTunnelBridgeExitSignalState(exit_tile, SIGNAL_STATE_GREEN);
|
||||
|
||||
ChooseTrainTrack(v, ft.m_new_tile, ft.m_exitdir, TrackdirBitsToTrackBits(ft.m_new_td_bits), force_res ? CTTF_FORCE_RES : CTTF_NONE, nullptr, lookahead_state);
|
||||
ChooseTrainTrack(v, ft.m_new_tile, ft.m_exitdir, TrackdirBitsToTrackBits(ft.m_new_td_bits), CTTF_NO_LOOKAHEAD_VALIDATE | (force_res ? CTTF_FORCE_RES : CTTF_NONE), nullptr, lookahead_state);
|
||||
|
||||
if (reserved_bits == GetReservedTrackbits(ft.m_new_tile)) {
|
||||
/* next tile is still not reserved, so unreserve exit and restore signal state */
|
||||
@@ -3921,12 +3929,14 @@ static void TryLongReserveChooseTrainTrack(Train *v, TileIndex tile, Trackdir td
|
||||
CFollowTrackRail ft(v);
|
||||
if (ft.Follow(tile, td) && HasLongReservePbsSignalOnTrackdir(v, ft.m_new_tile, FindFirstTrackdir(ft.m_new_td_bits), !long_enough)) {
|
||||
// We reserved up to a LR signal, reserve past it as well. recursion
|
||||
ChooseTrainTrack(v, ft.m_new_tile, ft.m_exitdir, TrackdirBitsToTrackBits(ft.m_new_td_bits), force_res ? CTTF_FORCE_RES : CTTF_NONE, nullptr, lookahead_state);
|
||||
ChooseTrainTrack(v, ft.m_new_tile, ft.m_exitdir, TrackdirBitsToTrackBits(ft.m_new_td_bits), CTTF_NO_LOOKAHEAD_VALIDATE | (force_res ? CTTF_FORCE_RES : CTTF_NONE), nullptr, lookahead_state);
|
||||
}
|
||||
}
|
||||
|
||||
static void TryLongReserveChooseTrainTrackFromReservationEnd(Train *v, bool no_reserve_vehicle_tile)
|
||||
{
|
||||
ClearLookAheadIfInvalid(v);
|
||||
|
||||
PBSTileInfo origin = FollowTrainReservation(v, nullptr, FTRF_OKAY_UNUSED);
|
||||
if (IsRailDepotTile(origin.tile)) return;
|
||||
|
||||
@@ -4012,6 +4022,10 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
v->lookahead.reset();
|
||||
}
|
||||
|
||||
if (!(flags & CTTF_NO_LOOKAHEAD_VALIDATE)) {
|
||||
ClearLookAheadIfInvalid(v);
|
||||
}
|
||||
|
||||
PBSTileInfo origin = FollowTrainReservation(v, nullptr, FTRF_OKAY_UNUSED);
|
||||
PBSTileInfo res_dest(tile, INVALID_TRACKDIR, false);
|
||||
DiagDirection dest_enterdir = enterdir;
|
||||
@@ -4186,6 +4200,8 @@ bool TryPathReserve(Train *v, bool mark_as_stuck, bool first_tile_okay)
|
||||
{
|
||||
assert(v->IsFrontEngine());
|
||||
|
||||
ClearLookAheadIfInvalid(v);
|
||||
|
||||
if (v->lookahead != nullptr && HasBit(v->lookahead->flags, TRLF_DEPOT_END)) return true;
|
||||
|
||||
/* We have to handle depots specially as the track follower won't look
|
||||
|
Reference in New Issue
Block a user