Fix clearing of train reservations in tunnels and on bridges.

(cherry picked from commit e2c4fb517d1064b163d8f2b0627506d785ffb3ed)

See: #46
pull/59/head
keldorkatarn 7 years ago committed by Jonathan G Rennison
parent c92a28a072
commit c2678b896e

@ -2287,43 +2287,29 @@ static void UnreserveBridgeTunnelTile(TileIndex tile)
* @param v %Train owning the reservation.
* @param tile Tile with reservation to clear.
* @param track_dir Track direction to clear.
* @param tunbridge_clear_unsignaled_other_end Whether to clear the far end of unsignalled tunnels/bridges.
*/
static void ClearPathReservation(const Train *v, TileIndex tile, Trackdir track_dir)
static void ClearPathReservation(const Train *v, TileIndex tile, Trackdir track_dir, bool tunbridge_clear_unsignaled_other_end = false)
{
DiagDirection dir = TrackdirToExitdir(track_dir);
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
/* Are we just leaving a tunnel/bridge? */
if (GetTunnelBridgeDirection(tile) == ReverseDiagDir(dir)) {
TileIndex end = GetOtherTunnelBridgeEnd(tile);
TileIndex end = GetOtherTunnelBridgeEnd(tile);
UnreserveBridgeTunnelTile(tile);
bool free = TunnelBridgeIsFree(tile, end, v).Succeeded();
if (IsTunnelBridgeWithSignalSimulation(tile)) {
UnreserveBridgeTunnelTile(tile);
if (IsTunnelBridgeWithSignalSimulation(tile)) {
/* Are we just leaving a tunnel/bridge? */
if (GetTunnelBridgeDirection(tile) == ReverseDiagDir(dir)) {
bool free = TunnelBridgeIsFree(tile, end, v).Succeeded();
HandleLastTunnelBridgeSignals(tile, end, dir, free);
if (_settings_client.gui.show_track_reservation) {
MarkTileDirtyByTile(tile);
}
} else if (free) {
/* Free the reservation only if no other train is on the tiles. */
UnreserveBridgeTunnelTile(tile);
UnreserveBridgeTunnelTile(end);
if (_settings_client.gui.show_track_reservation) {
if (IsBridge(tile)) {
MarkBridgeDirty(tile);
} else {
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(end);
}
}
}
} else if (GetTunnelBridgeDirection(tile) == dir && IsTunnelBridgeWithSignalSimulation(tile)) {
/* cancelling reservation of entry ramp, due to reverse */
UnreserveBridgeTunnelTile(tile);
if (_settings_client.gui.show_track_reservation) {
MarkTileDirtyByTile(tile);
}
} else if (tunbridge_clear_unsignaled_other_end) {
UnreserveBridgeTunnelTile(end);
}
if (_settings_client.gui.show_track_reservation) {
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(end);
}
} else if (IsRailStationTile(tile)) {
TileIndex new_tile = TileAddByDiagDir(tile, dir);
@ -2391,6 +2377,11 @@ void FreeTrainTrackReservation(const Train *v, TileIndex origin, Trackdir orig_t
} else if (HasSignalOnTrackdir(tile, ReverseTrackdir(td)) && IsOnewaySignal(tile, TrackdirToTrack(td))) {
break;
}
} else if (IsTunnelBridgeWithSignalSimulation(tile)) {
TileIndex end = GetOtherTunnelBridgeEnd(tile);
bool free = TunnelBridgeIsFree(tile, end, v).Succeeded();
if (!free && GetTunnelBridgeDirection(tile) == ReverseDiagDir(TrackdirToExitdir(td))) break;
}
/* Don't free first station/bridge/tunnel if we are on it. */
@ -3052,12 +3043,7 @@ uint Train::Crash(bool flooded)
* Also clear all reserved tracks the train is currently on. */
if (!HasBit(this->flags, VRF_TRAIN_STUCK)) FreeTrainTrackReservation(this);
for (const Train *v = this; v != NULL; v = v->Next()) {
ClearPathReservation(v, v->tile, v->GetVehicleTrackdir());
if (IsTileType(v->tile, MP_TUNNELBRIDGE)) {
/* ClearPathReservation will not free the wormhole exit
* if the train has just entered the wormhole. */
UnreserveBridgeTunnelTile(GetOtherTunnelBridgeEnd(v->tile));
}
ClearPathReservation(v, v->tile, v->GetVehicleTrackdir(), true);
}
/* we may need to update crossing we were approaching,
@ -3553,7 +3539,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
}
/* Clear any track reservation when the last vehicle leaves the tile */
if (v->Next() == NULL) ClearPathReservation(v, v->tile, v->GetVehicleTrackdir());
if (v->Next() == NULL) ClearPathReservation(v, v->tile, v->GetVehicleTrackdir(), true);
v->tile = gp.new_tile;

Loading…
Cancel
Save