(svn r14048) -Fix (r14019) [FS#2222]: Redo the check for reserved tracks properly this time. (michi_cc)

replace/41b28d7194a279bdc17475d4fbe2ea6ec885a466
rubidium 16 years ago
parent d0c1a989a4
commit c04ab6628b

@ -14,8 +14,6 @@
template <TransportType Ttr_type_, bool T90deg_turns_allowed_ = true, bool Tmask_reserved_tracks = false> template <TransportType Ttr_type_, bool T90deg_turns_allowed_ = true, bool Tmask_reserved_tracks = false>
struct CFollowTrackT struct CFollowTrackT
{ {
typedef CFollowTrackT<Ttr_type_, T90deg_turns_allowed_, false> BaseNoMask;
enum ErrorCode { enum ErrorCode {
EC_NONE, EC_NONE,
EC_OWNER, EC_OWNER,
@ -79,7 +77,7 @@ struct CFollowTrackT
FORCEINLINE bool IsTram() {return IsRoadTT() && HasBit(m_veh->u.road.compatible_roadtypes, ROADTYPE_TRAM);} FORCEINLINE bool IsTram() {return IsRoadTT() && HasBit(m_veh->u.road.compatible_roadtypes, ROADTYPE_TRAM);}
FORCEINLINE static bool IsRoadTT() {return TT() == TRANSPORT_ROAD;} FORCEINLINE static bool IsRoadTT() {return TT() == TRANSPORT_ROAD;}
FORCEINLINE static bool Allow90degTurns() {return T90deg_turns_allowed_;} FORCEINLINE static bool Allow90degTurns() {return T90deg_turns_allowed_;}
FORCEINLINE static bool MaskReservedTracks() {return IsRailTT() && Tmask_reserved_tracks;} FORCEINLINE static bool DoTrackMasking() {return IsRailTT() && Tmask_reserved_tracks;}
/** Tests if a tile is a road tile with a single tramtrack (tram can reverse) */ /** Tests if a tile is a road tile with a single tramtrack (tram can reverse) */
FORCEINLINE DiagDirection GetSingleTramBit(TileIndex tile) FORCEINLINE DiagDirection GetSingleTramBit(TileIndex tile)
@ -124,32 +122,37 @@ struct CFollowTrackT
return false; return false;
} }
} }
if (MaskReservedTracks()) { return true;
if (m_is_station) { }
/* Check skipped station tiles as well. */
TileIndexDiff diff = TileOffsByDiagDir(m_exitdir); inline bool MaskReservedTracks()
for (TileIndex tile = m_new_tile - diff * m_tiles_skipped; tile != m_new_tile; tile += diff) { {
if (GetRailwayStationReservation(tile)) { if (!DoTrackMasking()) return true;
m_new_td_bits = TRACKDIR_BIT_NONE;
m_err = EC_RESERVED; if (m_is_station) {
return false; /* Check skipped station tiles as well. */
} TileIndexDiff diff = TileOffsByDiagDir(m_exitdir);
for (TileIndex tile = m_new_tile - diff * m_tiles_skipped; tile != m_new_tile; tile += diff) {
if (GetRailwayStationReservation(tile)) {
m_new_td_bits = TRACKDIR_BIT_NONE;
m_err = EC_RESERVED;
return false;
} }
} }
}
TrackBits reserved = GetReservedTrackbits(m_new_tile); TrackBits reserved = GetReservedTrackbits(m_new_tile);
/* Mask already reserved trackdirs. */ /* Mask already reserved trackdirs. */
m_new_td_bits &= ~TrackBitsToTrackdirBits(reserved); m_new_td_bits &= ~TrackBitsToTrackdirBits(reserved);
/* Mask out all trackdirs that conflict with the reservation. */ /* Mask out all trackdirs that conflict with the reservation. */
uint bits = (uint)TrackdirBitsToTrackBits(m_new_td_bits); uint bits = (uint)TrackdirBitsToTrackBits(m_new_td_bits);
int i; int i;
FOR_EACH_SET_BIT(i, bits) { FOR_EACH_SET_BIT(i, bits) {
if (TracksOverlap(reserved | TrackToTrackBits((Track)i))) m_new_td_bits &= ~TrackToTrackdirBits((Track)i); if (TracksOverlap(reserved | TrackToTrackBits((Track)i))) m_new_td_bits &= ~TrackToTrackdirBits((Track)i);
} }
if (m_new_td_bits == TRACKDIR_BIT_NONE) { if (m_new_td_bits == TRACKDIR_BIT_NONE) {
m_err = EC_RESERVED; m_err = EC_RESERVED;
return false; return false;
}
} }
return true; return true;
} }

@ -399,7 +399,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
} else if (cur.tile_type == MP_RAILWAY && IsRailWaypoint(cur.tile)) { } else if (cur.tile_type == MP_RAILWAY && IsRailWaypoint(cur.tile)) {
/* Waypoint is also a good reason to finish. */ /* Waypoint is also a good reason to finish. */
end_segment_reason |= ESRB_WAYPOINT; end_segment_reason |= ESRB_WAYPOINT;
} else if (TrackFollower::MaskReservedTracks() && cur.tile_type == MP_RAILWAY) { } else if (TrackFollower::DoTrackMasking() && cur.tile_type == MP_RAILWAY) {
/* Searching for a safe tile? */ /* Searching for a safe tile? */
if (HasSignalOnTrackdir(cur.tile, cur.td) && !IsPbsSignal(GetSignalType(cur.tile, TrackdirToTrack(cur.td)))) { if (HasSignalOnTrackdir(cur.tile, cur.td) && !IsPbsSignal(GetSignalType(cur.tile, TrackdirToTrack(cur.td)))) {
end_segment_reason |= ESRB_SAFE_TILE; end_segment_reason |= ESRB_SAFE_TILE;
@ -437,7 +437,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
end_segment_reason |= ESRB_DEAD_END; end_segment_reason |= ESRB_DEAD_END;
} }
if (TrackFollower::MaskReservedTracks() && tf_local.m_err != TrackFollower::EC_90DEG) { if (TrackFollower::DoTrackMasking() && tf_local.m_err != TrackFollower::EC_90DEG) {
if (!HasOnewaySignalBlockingTrackdir(cur.tile, cur.td)) end_segment_reason |= ESRB_SAFE_TILE; if (!HasOnewaySignalBlockingTrackdir(cur.tile, cur.td)) end_segment_reason |= ESRB_SAFE_TILE;
} }
break; break;
@ -453,7 +453,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
/* Gather the next tile/trackdir/tile_type/rail_type. */ /* Gather the next tile/trackdir/tile_type/rail_type. */
TILE next(tf_local.m_new_tile, (Trackdir)FindFirstBit2x64(tf_local.m_new_td_bits)); TILE next(tf_local.m_new_tile, (Trackdir)FindFirstBit2x64(tf_local.m_new_td_bits));
if (TrackFollower::MaskReservedTracks() && HasPbsSignalOnTrackdir(next.tile, next.td)) { if (TrackFollower::DoTrackMasking() && HasPbsSignalOnTrackdir(next.tile, next.td)) {
/* Possible safe tile. */ /* Possible safe tile. */
end_segment_reason |= ESRB_SAFE_TILE; end_segment_reason |= ESRB_SAFE_TILE;
} }

@ -182,8 +182,7 @@ struct CYapfRailNodeT
template <class Tbase, class Tfunc, class Tpf> template <class Tbase, class Tfunc, class Tpf>
bool IterateTiles(const Vehicle *v, Tpf &yapf, Tbase &obj, bool (Tfunc::*func)(TileIndex, Trackdir)) const bool IterateTiles(const Vehicle *v, Tpf &yapf, Tbase &obj, bool (Tfunc::*func)(TileIndex, Trackdir)) const
{ {
typedef typename Tbase::TrackFollower TrackFollower; typename Tbase::TrackFollower ft(v, yapf.GetCompatibleRailTypes());
typename TrackFollower::BaseNoMask ft(v, yapf.GetCompatibleRailTypes());
TileIndex cur = base::GetTile(); TileIndex cur = base::GetTile();
Trackdir cur_td = base::GetTrackdir(); Trackdir cur_td = base::GetTrackdir();

@ -223,7 +223,7 @@ public:
inline void PfFollowNode(Node& old_node) inline void PfFollowNode(Node& old_node)
{ {
TrackFollower F(Yapf().GetVehicle(), Yapf().GetCompatibleRailTypes()); TrackFollower F(Yapf().GetVehicle(), Yapf().GetCompatibleRailTypes());
if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir())) if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir()) && F.MaskReservedTracks())
Yapf().AddMultipleNodes(&old_node, F); Yapf().AddMultipleNodes(&old_node, F);
} }

Loading…
Cancel
Save