Merge branch 'signal_tunnels_bridges-sx' into jgrpp
# Conflicts: # src/saveload/afterload.cpp # src/saveload/extended_ver_sl.cpp # src/signal.cpp # src/train_cmd.cpp
This commit is contained in:
@@ -2376,6 +2376,12 @@ static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDir
|
||||
}
|
||||
}
|
||||
|
||||
static void UnreserveBridgeTunnelTile(TileIndex tile)
|
||||
{
|
||||
SetTunnelBridgeReservation(tile, false);
|
||||
if (IsTunnelBridgeExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitGreen(tile, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the reservation of \a tile that was just left by a wagon on \a track_dir.
|
||||
* @param v %Train owning the reservation.
|
||||
@@ -2392,10 +2398,16 @@ static void ClearPathReservation(const Train *v, TileIndex tile, Trackdir track_
|
||||
TileIndex end = GetOtherTunnelBridgeEnd(tile);
|
||||
|
||||
bool free = TunnelBridgeIsFree(tile, end, v).Succeeded();
|
||||
if (free) {
|
||||
if (HasWormholeSignals(tile)) {
|
||||
UnreserveBridgeTunnelTile(tile);
|
||||
HandleLastTunnelBridgeSignals(tile, end, dir, free);
|
||||
if (_settings_client.gui.show_track_reservation) {
|
||||
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
|
||||
}
|
||||
} else if (free) {
|
||||
/* Free the reservation only if no other train is on the tiles. */
|
||||
SetTunnelBridgeReservation(tile, false);
|
||||
SetTunnelBridgeReservation(end, false);
|
||||
UnreserveBridgeTunnelTile(tile);
|
||||
UnreserveBridgeTunnelTile(end);
|
||||
|
||||
if (_settings_client.gui.show_track_reservation) {
|
||||
if (IsBridge(tile)) {
|
||||
@@ -2406,7 +2418,12 @@ static void ClearPathReservation(const Train *v, TileIndex tile, Trackdir track_
|
||||
}
|
||||
}
|
||||
}
|
||||
if (HasWormholeSignals(tile)) HandleLastTunnelBridgeSignals(tile, end, dir, free);
|
||||
} else if (GetTunnelBridgeDirection(tile) == dir && HasWormholeSignals(tile)) {
|
||||
/* cancelling reservation of entry ramp, due to reverse */
|
||||
UnreserveBridgeTunnelTile(tile);
|
||||
if (_settings_client.gui.show_track_reservation) {
|
||||
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
|
||||
}
|
||||
}
|
||||
} else if (IsRailStationTile(tile)) {
|
||||
TileIndex new_tile = TileAddByDiagDir(tile, dir);
|
||||
@@ -2935,6 +2952,12 @@ bool TryPathReserve(Train *v, bool mark_as_stuck, bool first_tile_okay)
|
||||
}
|
||||
}
|
||||
|
||||
if (IsTileType(v->tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(v->tile) &&
|
||||
DiagDirToDiagTrackBits(GetTunnelBridgeDirection(v->tile)) == v->track) {
|
||||
// prevent any attempt to reserve the wrong way onto a tunnel/bridge exit
|
||||
return false;
|
||||
}
|
||||
|
||||
Vehicle *other_train = NULL;
|
||||
PBSTileInfo origin = FollowTrainReservation(v, &other_train);
|
||||
/* The path we are driving on is already blocked by some other train.
|
||||
@@ -3167,6 +3190,11 @@ static TrainMovedChangeSignalEnum TrainMovedChangeSignal(Train* v, TileIndex til
|
||||
if (HasLongReservePbsSignalOnTrackdir(v, tile, trackdir)) return CHANGED_LR_PBS;
|
||||
}
|
||||
}
|
||||
if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(tile) && GetTunnelBridgeDirection(tile) == ReverseDiagDir(dir)) {
|
||||
if (UpdateSignalsOnSegment(tile, dir, GetTileOwner(tile)) == SIGSEG_PBS) {
|
||||
return CHANGED_NORMAL_TO_PBS_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
return CHANGED_NOTHING;
|
||||
}
|
||||
@@ -3208,7 +3236,7 @@ uint Train::Crash(bool flooded)
|
||||
if (IsTileType(v->tile, MP_TUNNELBRIDGE)) {
|
||||
/* ClearPathReservation will not free the wormhole exit
|
||||
* if the train has just entered the wormhole. */
|
||||
SetTunnelBridgeReservation(GetOtherTunnelBridgeEnd(v->tile), false);
|
||||
UnreserveBridgeTunnelTile(GetOtherTunnelBridgeEnd(v->tile));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3402,6 +3430,23 @@ static bool IsToCloseBehindTrain(Vehicle *v, TileIndex tile, bool check_endtile)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool CheckTrainStayInWormHolePathReserve(Train *t, TileIndex tile)
|
||||
{
|
||||
TileIndex veh_orig = t->tile;
|
||||
t->tile = tile;
|
||||
CFollowTrackRail ft(GetTileOwner(tile), GetRailTypeInfo(t->railtype)->compatible_railtypes);
|
||||
if (ft.Follow(tile, DiagDirToDiagTrackdir(ReverseDiagDir(GetTunnelBridgeDirection(tile))))) {
|
||||
TrackdirBits reserved = ft.m_new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(ft.m_new_tile));
|
||||
if (reserved == TRACKDIR_BIT_NONE) {
|
||||
/* next tile is not reserved, so reserve the exit tile */
|
||||
SetTunnelBridgeReservation(tile, true);
|
||||
}
|
||||
}
|
||||
bool ok = TryPathReserve(t);
|
||||
t->tile = veh_orig;
|
||||
return ok;
|
||||
}
|
||||
|
||||
/** Simulate signals in tunnel - bridge. */
|
||||
static bool CheckTrainStayInWormHole(Train *t, TileIndex tile)
|
||||
{
|
||||
@@ -3413,8 +3458,20 @@ static bool CheckTrainStayInWormHole(Train *t, TileIndex tile)
|
||||
ToggleBit(t->flags, VRF_REVERSING);
|
||||
return true;
|
||||
}
|
||||
SigSegState seg_state = _settings_game.pf.reserve_paths ? SIGSEG_PBS : UpdateSignalsOnSegment(tile, INVALID_DIAGDIR, t->owner);
|
||||
if (seg_state == SIGSEG_FULL || (seg_state == SIGSEG_PBS && !TryPathReserve(t))) {
|
||||
SigSegState seg_state = (_settings_game.pf.reserve_paths || IsTunnelBridgePBS(tile)) ? SIGSEG_PBS : UpdateSignalsOnSegment(tile, INVALID_DIAGDIR, t->owner);
|
||||
if (seg_state != SIGSEG_PBS) {
|
||||
CFollowTrackRail ft(GetTileOwner(tile), GetRailTypeInfo(t->railtype)->compatible_railtypes);
|
||||
if (ft.Follow(tile, DiagDirToDiagTrackdir(ReverseDiagDir(GetTunnelBridgeDirection(tile))))) {
|
||||
if (ft.m_new_td_bits != TRACKDIR_BIT_NONE && KillFirstBit(ft.m_new_td_bits) == TRACKDIR_BIT_NONE) {
|
||||
Trackdir td = FindFirstTrackdir(ft.m_new_td_bits);
|
||||
if (HasPbsSignalOnTrackdir(ft.m_new_tile, td)) {
|
||||
/* immediately after the exit, there is a PBS signal, switch to PBS mode */
|
||||
seg_state = SIGSEG_PBS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (seg_state == SIGSEG_FULL || (seg_state == SIGSEG_PBS && !CheckTrainStayInWormHolePathReserve(t, tile))) {
|
||||
t->vehstatus |= VS_TRAIN_SLOWING;
|
||||
t->cur_speed = 0;
|
||||
return true;
|
||||
@@ -3724,7 +3781,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
||||
} else {
|
||||
/* Handle signal simulation on tunnel/bridge. */
|
||||
TileIndex old_tile = TileVirtXY(v->x_pos, v->y_pos);
|
||||
if (old_tile != gp.new_tile && HasWormholeSignals(v->tile) && (v->IsFrontEngine() || v->Next() == NULL)){
|
||||
if (old_tile != gp.new_tile && HasWormholeSignals(v->tile) && (v->IsFrontEngine() || v->Next() == NULL)) {
|
||||
if (old_tile == v->tile) {
|
||||
if (v->IsFrontEngine() && v->force_proceed == 0 && IsTunnelBridgeExit(v->tile)) goto invalid_rail;
|
||||
/* Entered wormhole set counters. */
|
||||
@@ -3763,6 +3820,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
||||
v->x_pos = gp.x;
|
||||
v->y_pos = gp.y;
|
||||
UpdateSignalsOnSegment(old_tile, INVALID_DIAGDIR, v->owner);
|
||||
UnreserveBridgeTunnelTile(old_tile);
|
||||
}
|
||||
}
|
||||
if (distance == 0) v->load_unload_ticks++;
|
||||
|
Reference in New Issue
Block a user