Unreserve and re-reserve reservations to bidi bridge/tunnel entrances when reversing train inside
This commit is contained in:
@@ -2176,6 +2176,32 @@ void ReverseTrainDirection(Train *v)
|
|||||||
/* Clear path reservation in front if train is not stuck. */
|
/* Clear path reservation in front if train is not stuck. */
|
||||||
if (!HasBit(v->flags, VRF_TRAIN_STUCK)) FreeTrainTrackReservation(v);
|
if (!HasBit(v->flags, VRF_TRAIN_STUCK)) FreeTrainTrackReservation(v);
|
||||||
|
|
||||||
|
std::vector<Train *> re_reserve_trains;
|
||||||
|
{
|
||||||
|
/* Temporarily clear and restore reservations to bidi tunnel/bridge entrances when reversing train inside,
|
||||||
|
* to avoid outgoing and incoming reservations becoming merged */
|
||||||
|
auto find_train_reservations = [&re_reserve_trains, &v](TileIndex tile) {
|
||||||
|
TrackBits reserved = GetAcrossTunnelBridgeReservationTrackBits(tile);
|
||||||
|
Track track;
|
||||||
|
while ((track = RemoveFirstTrack(&reserved)) != INVALID_TRACK) {
|
||||||
|
Train *res_train = GetTrainForReservation(tile, track);
|
||||||
|
if (res_train != nullptr && res_train != v) {
|
||||||
|
FreeTrainTrackReservation(res_train);
|
||||||
|
re_reserve_trains.push_back(res_train);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (IsTunnelBridgeWithSignalSimulation(v->tile) && IsTunnelBridgeSignalSimulationBidirectional(v->tile)) {
|
||||||
|
find_train_reservations(v->tile);
|
||||||
|
find_train_reservations(GetOtherTunnelBridgeEnd(v->tile));
|
||||||
|
}
|
||||||
|
Train *last = v->Last();
|
||||||
|
if (IsTunnelBridgeWithSignalSimulation(last->tile) && IsTunnelBridgeSignalSimulationBidirectional(last->tile)) {
|
||||||
|
find_train_reservations(last->tile);
|
||||||
|
find_train_reservations(GetOtherTunnelBridgeEnd(last->tile));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((v->track & TRACK_BIT_WORMHOLE) && IsTunnelBridgeWithSignalSimulation(v->tile)) {
|
if ((v->track & TRACK_BIT_WORMHOLE) && IsTunnelBridgeWithSignalSimulation(v->tile)) {
|
||||||
/* Clear exit tile reservation if train was on approach to exit and had reserved it */
|
/* Clear exit tile reservation if train was on approach to exit and had reserved it */
|
||||||
Axis axis = DiagDirToAxis(GetTunnelBridgeDirection(v->tile));
|
Axis axis = DiagDirToAxis(GetTunnelBridgeDirection(v->tile));
|
||||||
@@ -2236,6 +2262,10 @@ void ReverseTrainDirection(Train *v)
|
|||||||
crossing = TrainApproachingCrossingTile(v);
|
crossing = TrainApproachingCrossingTile(v);
|
||||||
if (crossing != INVALID_TILE) MaybeBarCrossingWithSound(crossing);
|
if (crossing != INVALID_TILE) MaybeBarCrossingWithSound(crossing);
|
||||||
|
|
||||||
|
for (uint i = 0; i < re_reserve_trains.size(); ++i) {
|
||||||
|
TryPathReserve(re_reserve_trains[i], true);
|
||||||
|
}
|
||||||
|
|
||||||
/* If we are inside a depot after reversing, don't bother with path reserving. */
|
/* If we are inside a depot after reversing, don't bother with path reserving. */
|
||||||
if (v->track == TRACK_BIT_DEPOT) {
|
if (v->track == TRACK_BIT_DEPOT) {
|
||||||
/* Can't be stuck here as inside a depot is always a safe tile. */
|
/* Can't be stuck here as inside a depot is always a safe tile. */
|
||||||
|
Reference in New Issue
Block a user