diff --git a/docs/landscape.html b/docs/landscape.html
index f60e859fc3..525294d392 100644
--- a/docs/landscape.html
+++ b/docs/landscape.html
@@ -1446,7 +1446,7 @@
m3 bits 7..4: owner of tram
m3 bits 3..0: track type for railway
m5 bit 4: pbs reservation state for railway
- m5 bits 7 clear: tunnel entrance/exit
+ m5 bit 7 clear: tunnel entrance/exit
m5 bit 7 set: bridge ramp
+ m5 bits 6..5: signal simulation (signals on bridge/tunnels patch)
+
+
+ 0 |
+ no signal simulation |
+
+
+
+ 1 |
+ signal simulation entrance (bit 5 set) |
+
+
+
+ 2 |
+ signal simulation exit (bit 6 set) |
+
+
+ If signal simulation entrance or exit:
+
+ - m6 bit 6: set = PBS signals, clear = block signals
+ - m6 bit 1: set = semaphore signals, clear = light signals
+ - m6 bit 0: set = signal shows green, clear = signal shows red
+ - m2 bits 15..0: for bridges only: for signals 0..15 on bridge, signal is visually red if corresponding bit in 0..15 is set
+
+
m5 bits 3..2: transport type
diff --git a/docs/landscape_grid.html b/docs/landscape_grid.html
index d34fe9840c..2db8e015fb 100644
--- a/docs/landscape_grid.html
+++ b/docs/landscape_grid.html
@@ -9,6 +9,7 @@
span.option{ font-family: "Courier New", Courier, mono; background-color: rgb(255,255, 30); }
span.free { font-family: "Courier New", Courier, mono; background-color: rgb(30, 178, 54); }
span.used { font-family: "Courier New", Courier, mono; }
+ span.used_p{ font-family: "Courier New", Courier, mono; background-color: cyan; }
td.bits { white-space: nowrap; text-align: center; font-family: "Courier New", Courier, mono; }
td.caption { white-space: nowrap; text-align: left; }
td li { white-space: nowrap; text-align: left; }
@@ -23,6 +24,7 @@ the array so you can quickly see what is used and what is not.
- O - bit is free
- X - bit is used
+ - P - bit is used by patch feature
- - bit of attribute is abused for different purposes, i.e. other bits define the actual meaning.
- ~ - bit is accessed, but does not really have a meaning (e.g. owner of clear land is always OWNER_NONE)
@@ -334,8 +336,8 @@ the array so you can quickly see what is used and what is not.
OOOO OOOO OOOO OOOO |
XXXX XXXX |
OOOO OOOO |
- XOOX XXXX |
- OOOO OOOO |
+ XPPX XXXX |
+ OPOO OOPP |
XXXX XXXX |
@@ -343,11 +345,11 @@ the array so you can quickly see what is used and what is not.
-inherit- |
-inherit- |
-inherit- |
+ PPPP PPPP PPPP PPPP |
-inherit- |
-inherit- |
-inherit- |
- -inherit- |
- OOXX XXOO |
+ OPXX XXPP |
-inherit- |
diff --git a/src/pathfinder/npf/npf.cpp b/src/pathfinder/npf/npf.cpp
index 496a9fdc53..41ec4b53f3 100644
--- a/src/pathfinder/npf/npf.cpp
+++ b/src/pathfinder/npf/npf.cpp
@@ -936,7 +936,7 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current)
break;
}
}
- if (IsTileType(dst_tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(dst_tile) && DiagDirToDiagTrackdir(GetTunnelBridgeDirection(dst_tile)) == dst_trackdir) {
+ if (IsTileType(dst_tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(dst_tile) && DiagDirToDiagTrackdir(GetTunnelBridgeDirection(dst_tile)) == dst_trackdir) {
/* Entering a signalled bridge/tunnel from the wrong side, equivalent to encountering a one-way signal from the wrong side */
break;
}
diff --git a/src/pathfinder/yapf/yapf_costrail.hpp b/src/pathfinder/yapf/yapf_costrail.hpp
index 15da32d9f7..5b90f0b82e 100644
--- a/src/pathfinder/yapf/yapf_costrail.hpp
+++ b/src/pathfinder/yapf/yapf_costrail.hpp
@@ -244,7 +244,7 @@ public:
}
}
}
- if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(tile) && DiagDirToDiagTrackdir(GetTunnelBridgeDirection(tile)) == trackdir) {
+ if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(tile) && DiagDirToDiagTrackdir(GetTunnelBridgeDirection(tile)) == trackdir) {
/* Entering a signalled bridge/tunnel from the wrong side, equivalent to encountering a one-way signal from the wrong side */
n.m_segment->m_end_segment_reason |= ESRB_DEAD_END;
}
diff --git a/src/pbs.cpp b/src/pbs.cpp
index c0962557fb..ef81c8ed16 100644
--- a/src/pbs.cpp
+++ b/src/pbs.cpp
@@ -125,7 +125,7 @@ bool TryReserveRailTrack(TileIndex tile, Track t, bool trigger_stations)
case MP_TUNNELBRIDGE:
if (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL && !GetTunnelBridgeReservationTrackBits(tile)) {
SetTunnelBridgeReservation(tile, true);
- if (IsTunnelBridgeExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitGreen(tile, true);
+ if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN);
MarkTileDirtyByTile(tile);
return true;
}
@@ -181,7 +181,7 @@ void UnreserveRailTrack(TileIndex tile, Track t)
case MP_TUNNELBRIDGE:
if (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) {
SetTunnelBridgeReservation(tile, false);
- if (IsTunnelBridgeExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitGreen(tile, false);
+ if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_RED);
MarkTileDirtyByTile(tile);
}
break;
@@ -252,7 +252,7 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra
if (IsRailDepotTile(tile)) break;
/* Non-pbs signal? Reservation can't continue. */
if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, trackdir) && !IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) break;
- if (IsTileType(tile, MP_TUNNELBRIDGE) && HasWormholeSignals(tile)) break;
+ if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeWithSignalSimulation(tile)) break;
}
return PBSTileInfo(tile, trackdir, false);
@@ -281,7 +281,7 @@ static Vehicle *FindTrainOnTrackEnum(Vehicle *v, void *data)
/* Do not find trains inside signalled bridge/tunnels.
* Trains on the ramp/entrance itself are found though.
*/
- if (IsTileType(info->res.tile, MP_TUNNELBRIDGE) && HasWormholeSignals(info->res.tile) && info->res.tile != TileVirtXY(t->x_pos, t->y_pos)) {
+ if (IsTileType(info->res.tile, MP_TUNNELBRIDGE) && IsTunnelBridgeWithSignalSimulation(info->res.tile) && info->res.tile != TileVirtXY(t->x_pos, t->y_pos)) {
return NULL;
}
}
@@ -329,7 +329,7 @@ PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res)
if (ftoti.best != NULL) *train_on_res = ftoti.best->First();
}
}
- if (*train_on_res == NULL && IsTileType(ftoti.res.tile, MP_TUNNELBRIDGE) && !HasWormholeSignals(ftoti.res.tile)) {
+ if (*train_on_res == NULL && IsTileType(ftoti.res.tile, MP_TUNNELBRIDGE) && !IsTunnelBridgeWithSignalSimulation(ftoti.res.tile)) {
/* The target tile is a bridge/tunnel, also check the other end tile. */
FindVehicleOnPos(GetOtherTunnelBridgeEnd(ftoti.res.tile), &ftoti, FindTrainOnTrackEnum);
if (ftoti.best != NULL) *train_on_res = ftoti.best->First();
@@ -405,7 +405,7 @@ bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bo
}
if (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) {
- if (IsTunnelBridgeEntrance(tile)) {
+ if (IsTunnelBridgeSignalSimulationEntrance(tile)) {
return true;
}
}
@@ -458,7 +458,7 @@ bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bo
/* Not reserved and depot or not a pbs signal -> free. */
if (IsRailDepotTile(tile)) return true;
if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, trackdir) && !IsPbsSignal(GetSignalType(tile, track))) return true;
- if (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL && IsTunnelBridgeEntrance(tile)) return true;
+ if (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL && IsTunnelBridgeSignalSimulationEntrance(tile)) return true;
/* Check the next tile, if it's a PBS signal, it has to be free as well. */
CFollowTrackRail ft(v, GetRailTypeInfo(v->railtype)->compatible_railtypes);
diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp
index 51c8addaf0..f2c6e01c39 100644
--- a/src/rail_cmd.cpp
+++ b/src/rail_cmd.cpp
@@ -1061,7 +1061,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
cost = CommandCost();
bool flip_variant = false;
bool is_pbs = (sigtype == SIGTYPE_PBS) || (sigtype == SIGTYPE_PBS_ONEWAY);
- if (!HasWormholeSignals(tile)) { // toggle signal zero costs.
+ if (!IsTunnelBridgeWithSignalSimulation(tile)) { // toggle signal zero costs.
if (convert_signal) return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS);
if (p2 != 12) cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_SIGNALS] * ((GetTunnelBridgeLength(tile, tile_exit) + 4) >> 2)); // minimal 1
} else {
@@ -1074,7 +1074,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
}
}
if (flags & DC_EXEC) {
- if (p2 == 0 && HasWormholeSignals(tile)) { // Toggle signal if already signals present.
+ if (p2 == 0 && IsTunnelBridgeWithSignalSimulation(tile)) { // Toggle signal if already signals present.
if (convert_signal) {
if (flip_variant) {
SetTunnelBridgeSemaphore(tile, !IsTunnelBridgeSemaphore(tile));
@@ -1088,37 +1088,42 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
SetTunnelBridgePBS(tile, !IsTunnelBridgePBS(tile));
SetTunnelBridgePBS(tile_exit, IsTunnelBridgePBS(tile));
} else {
- if (IsTunnelBridgeEntrance(tile)) {
- ClrBitTunnelBridgeSignal(tile);
- ClrBitTunnelBridgeExit(tile_exit);
- SetBitTunnelBridgeExit(tile);
- SetBitTunnelBridgeSignal(tile_exit);
+ if (IsTunnelBridgeSignalSimulationEntrance(tile)) {
+ ClrTunnelBridgeSignalSimulationEntrance(tile);
+ ClrTunnelBridgeSignalSimulationExit(tile_exit);
+ SetTunnelBridgeSignalSimulationExit(tile);
+ SetTunnelBridgeSignalSimulationEntrance(tile_exit);
+ SetTunnelBridgeSignalState(tile_exit, SIGNAL_STATE_GREEN);
} else {
- ClrBitTunnelBridgeSignal(tile_exit);
- ClrBitTunnelBridgeExit(tile);
- SetBitTunnelBridgeExit(tile_exit);
- SetBitTunnelBridgeSignal(tile);
+ ClrTunnelBridgeSignalSimulationEntrance(tile_exit);
+ ClrTunnelBridgeSignalSimulationExit(tile);
+ SetTunnelBridgeSignalSimulationExit(tile_exit);
+ SetTunnelBridgeSignalSimulationEntrance(tile);
+ SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN);
}
}
} else {
/* Create one direction tunnel/bridge if required. */
if (p2 == 0) {
- SetBitTunnelBridgeSignal(tile);
- SetBitTunnelBridgeExit(tile_exit);
+ SetTunnelBridgeSignalSimulationEntrance(tile);
+ SetTunnelBridgeSignalSimulationExit(tile_exit);
+ SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN);
} else if (p2 == 4 || p2 == 8) {
DiagDirection tbdir = GetTunnelBridgeDirection(tile);
/* If signal only on one side build accoringly one-way tunnel/bridge. */
if ((p2 == 8 && (tbdir == DIAGDIR_NE || tbdir == DIAGDIR_SE)) ||
(p2 == 4 && (tbdir == DIAGDIR_SW || tbdir == DIAGDIR_NW))) {
- ClrBitTunnelBridgeExit(tile);
- ClrBitTunnelBridgeSignal(tile_exit);
- SetBitTunnelBridgeSignal(tile);
- SetBitTunnelBridgeExit(tile_exit);
+ ClrTunnelBridgeSignalSimulationExit(tile);
+ ClrTunnelBridgeSignalSimulationEntrance(tile_exit);
+ SetTunnelBridgeSignalSimulationEntrance(tile);
+ SetTunnelBridgeSignalSimulationExit(tile_exit);
+ SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN);
} else {
- ClrBitTunnelBridgeSignal(tile);
- ClrBitTunnelBridgeExit(tile_exit);
- SetBitTunnelBridgeSignal(tile_exit);
- SetBitTunnelBridgeExit(tile);
+ ClrTunnelBridgeSignalSimulationEntrance(tile);
+ ClrTunnelBridgeSignalSimulationExit(tile_exit);
+ SetTunnelBridgeSignalSimulationEntrance(tile_exit);
+ SetTunnelBridgeSignalSimulationExit(tile);
+ SetTunnelBridgeSignalState(tile_exit, SIGNAL_STATE_GREEN);
}
}
if (p2 == 0 || p2 == 4 || p2 == 8) {
@@ -1128,8 +1133,8 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
SetTunnelBridgePBS(tile_exit, is_pbs);
}
}
- if (IsTunnelBridgeExit(tile) && IsTunnelBridgePBS(tile) && !HasTunnelBridgeReservation(tile)) SetTunnelBridgeExitGreen(tile, false);
- if (IsTunnelBridgeExit(tile_exit) && IsTunnelBridgePBS(tile_exit) && !HasTunnelBridgeReservation(tile_exit)) SetTunnelBridgeExitGreen(tile_exit, false);
+ if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile) && !HasTunnelBridgeReservation(tile)) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_RED);
+ if (IsTunnelBridgeSignalSimulationExit(tile_exit) && IsTunnelBridgePBS(tile_exit) && !HasTunnelBridgeReservation(tile_exit)) SetTunnelBridgeSignalState(tile_exit, SIGNAL_STATE_RED);
MarkBridgeOrTunnelDirty(tile);
AddSideToSignalBuffer(tile, INVALID_DIAGDIR, GetTileOwner(tile));
AddSideToSignalBuffer(tile_exit, INVALID_DIAGDIR, GetTileOwner(tile));
@@ -1305,7 +1310,7 @@ static bool CheckSignalAutoFill(TileIndex &tile, Trackdir &trackdir, int &signal
return true;
case MP_TUNNELBRIDGE: {
- if (!remove && HasWormholeSignals(tile)) return false;
+ if (!remove && IsTunnelBridgeWithSignalSimulation(tile)) return false;
TileIndex orig_tile = tile; // backup old value
if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) return false;
@@ -1556,7 +1561,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
TileIndex end = GetOtherTunnelBridgeEnd(tile);
if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK);
- if (!HasWormholeSignals(tile)) return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS);
+ if (!IsTunnelBridgeWithSignalSimulation(tile)) return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS);
cost *= ((GetTunnelBridgeLength(tile, end) + 4) >> 2);
@@ -1584,12 +1589,12 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1
/* Do it? */
if (flags & DC_EXEC) {
- if (HasWormholeSignals(tile)) { // handle tunnel/bridge signals.
+ if (IsTunnelBridgeWithSignalSimulation(tile)) { // handle tunnel/bridge signals.
TileIndex end = GetOtherTunnelBridgeEnd(tile);
- ClrBitTunnelBridgeExit(tile);
- ClrBitTunnelBridgeExit(end);
- ClrBitTunnelBridgeSignal(tile);
- ClrBitTunnelBridgeSignal(end);
+ ClrTunnelBridgeSignalSimulationExit(tile);
+ ClrTunnelBridgeSignalSimulationExit(end);
+ ClrTunnelBridgeSignalSimulationEntrance(tile);
+ ClrTunnelBridgeSignalSimulationEntrance(end);
_m[tile].m2 = 0;
_m[end].m2 = 0;
MarkBridgeOrTunnelDirty(tile);
diff --git a/src/rail_map.h b/src/rail_map.h
index d2befc4686..05faec9018 100644
--- a/src/rail_map.h
+++ b/src/rail_map.h
@@ -480,7 +480,7 @@ static inline bool HasOnewaySignalBlockingTrackdir(TileIndex tile, Trackdir td)
!HasSignalOnTrackdir(tile, td) && IsOnewaySignal(tile, TrackdirToTrack(td))) {
return true;
}
- if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(tile) &&
+ if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(tile) &&
DiagDirToDiagTrackdir(GetTunnelBridgeDirection(tile)) == td) {
return true;
}
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp
index a187cad8f7..76f0d2ec6e 100644
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -2972,13 +2972,28 @@ bool AfterLoadGame()
/* set the semaphore bit to match what it would have been in v1 */
/* clear the PBS bit, update the end signal state */
for (TileIndex t = 0; t < map_size; t++) {
- if (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL && HasWormholeSignals(t)) {
+ if (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL && IsTunnelBridgeWithSignalSimulation(t)) {
SetTunnelBridgeSemaphore(t, _cur_year < _settings_client.gui.semaphore_build_before);
SetTunnelBridgePBS(t, false);
UpdateSignalsOnSegment(t, INVALID_DIAGDIR, GetTileOwner(t));
}
}
}
+ if (SlXvIsFeaturePresent(XSLFI_SIG_TUNNEL_BRIDGE, 1, 2)) {
+ /* red/green signal state bit for tunnel entrances moved
+ * to no longer re-use signalled tunnel exit bit
+ */
+ for (TileIndex t = 0; t < map_size; t++) {
+ if (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL && IsTunnelBridgeWithSignalSimulation(t)) {
+ if (HasBit(_m[t].m5, 5)) {
+ /* signalled tunnel entrance */
+ SignalState state = HasBit(_m[t].m5, 6) ? SIGNAL_STATE_RED : SIGNAL_STATE_GREEN;
+ ClrBit(_m[t].m5, 6);
+ SetTunnelBridgeSignalState(t, state);
+ }
+ }
+ }
+ }
/* Station acceptance is some kind of cache */
if (IsSavegameVersionBefore(127)) {
diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp
index 67e1cc195c..f62dec524b 100644
--- a/src/saveload/extended_ver_sl.cpp
+++ b/src/saveload/extended_ver_sl.cpp
@@ -45,7 +45,7 @@ std::vector _sl_xv_discardable_chunk_ids; ///< list of chunks
static const uint32 _sl_xv_slxi_chunk_version = 0; ///< current version os SLXI chunk
const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
- { XSLFI_SIG_TUNNEL_BRIDGE, XSCF_NULL, 2, 2, "signal_tunnel_bridge", NULL, NULL, NULL },
+ { XSLFI_SIG_TUNNEL_BRIDGE, XSCF_NULL, 3, 3, "signal_tunnel_bridge", NULL, NULL, NULL },
{ XSLFI_NULL, XSCF_NULL, 0, 0, NULL, NULL, NULL, NULL },// This is the end marker
};
diff --git a/src/signal.cpp b/src/signal.cpp
index 4639def78f..57eabb5a84 100644
--- a/src/signal.cpp
+++ b/src/signal.cpp
@@ -384,13 +384,13 @@ static SigFlags ExploreSegment(Owner owner)
if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) continue;
DiagDirection dir = GetTunnelBridgeDirection(tile);
- if (HasWormholeSignals(tile)) {
+ if (IsTunnelBridgeWithSignalSimulation(tile)) {
if (enterdir == INVALID_DIAGDIR) { // incoming from the wormhole
- if (!(flags & SF_TRAIN) && IsTunnelBridgeExit(tile)) { // tunnel entrence is ignored
+ if (!(flags & SF_TRAIN) && IsTunnelBridgeSignalSimulationExit(tile)) { // tunnel entrence is ignored
if (HasVehicleOnPos(GetOtherTunnelBridgeEnd(tile), &tile, &TrainInWormholeTileEnum)) flags |= SF_TRAIN;
if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, &tile, &TrainInWormholeTileEnum)) flags |= SF_TRAIN;
}
- if (IsTunnelBridgeExit(tile) && !_tbuset.Add(tile, INVALID_TRACKDIR)) {
+ if (IsTunnelBridgeSignalSimulationExit(tile) && !_tbuset.Add(tile, INVALID_TRACKDIR)) {
return flags | SF_FULL;
}
enterdir = dir;
@@ -398,7 +398,7 @@ static SigFlags ExploreSegment(Owner owner)
tile += TileOffsByDiagDir(exitdir); // just skip to next tile
} else { // NOT incoming from the wormhole!
if (ReverseDiagDir(enterdir) != dir) continue;
- if (IsTunnelBridgeExit(tile)) {
+ if (IsTunnelBridgeSignalSimulationExit(tile)) {
if (IsTunnelBridgePBS(tile)) {
flags |= SF_PBS;
} else if (!_tbuset.Add(tile, INVALID_TRACKDIR)) {
@@ -407,7 +407,7 @@ static SigFlags ExploreSegment(Owner owner)
}
if (!(flags & SF_TRAIN)) {
if (HasVehicleOnPos(tile, &tile, &TrainInWormholeTileEnum)) flags |= SF_TRAIN;
- if (!(flags & SF_TRAIN) && IsTunnelBridgeExit(tile)) {
+ if (!(flags & SF_TRAIN) && IsTunnelBridgeSignalSimulationExit(tile)) {
if (HasVehicleOnPos(GetOtherTunnelBridgeEnd(tile), &tile, &TrainInWormholeTileEnum)) flags |= SF_TRAIN;
}
}
@@ -453,12 +453,12 @@ static void UpdateSignalsAroundSegment(SigFlags flags)
Trackdir trackdir;
while (_tbuset.Get(&tile, &trackdir)) {
- if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(tile)) {
+ if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(tile)) {
if (IsTunnelBridgePBS(tile)) continue;
- bool old_state = IsTunnelBridgeExitGreen(tile);
- bool new_state = !(flags & SF_TRAIN);
+ SignalState old_state = GetTunnelBridgeSignalState(tile);
+ SignalState new_state = (flags & SF_TRAIN) ? SIGNAL_STATE_RED : SIGNAL_STATE_GREEN;
if (old_state != new_state) {
- SetTunnelBridgeExitGreen(tile, new_state);
+ SetTunnelBridgeSignalState(tile, new_state);
MarkTileDirtyByTile(tile);
}
continue;
@@ -545,7 +545,7 @@ static SigSegState UpdateSignalsInBuffer(Owner owner)
assert(GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL);
assert(dir == INVALID_DIAGDIR || dir == ReverseDiagDir(GetTunnelBridgeDirection(tile)));
_tbdset.Add(tile, INVALID_DIAGDIR); // we can safely start from wormhole centre
- if (!HasWormholeSignals(tile)) { // Don't worry with other side of tunnel.
+ if (!IsTunnelBridgeWithSignalSimulation(tile)) { // Don't worry with other side of tunnel.
_tbdset.Add(GetOtherTunnelBridgeEnd(tile), INVALID_DIAGDIR);
}
break;
diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp
index f914283a7d..9c1af7bb12 100644
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -1864,9 +1864,9 @@ void ReverseTrainDirection(Train *v)
}
/* We are inside tunnel/bidge with signals, reversing will close the entrance. */
- if (HasWormholeSignals(v->tile)) {
+ if (IsTunnelBridgeWithSignalSimulation(v->tile)) {
/* Flip signal on tunnel entrance tile red. */
- SetBitTunnelBridgeExit(v->tile);
+ SetTunnelBridgeSignalState(v->tile, SIGNAL_STATE_RED);
MarkTileDirtyByTile(v->tile);
/* Clear counters. */
v->wait_counter = 0;
@@ -2233,14 +2233,16 @@ static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDir
}
if (free) {
/* Open up the wormhole and clear m2. */
- _m[tile].m2 = 0;
- _m[end].m2 = 0;
+ if (IsBridge(end)) {
+ _m[tile].m2 = 0;
+ _m[end].m2 = 0;
+ }
- if (IsTunnelBridgeWithSignRed(end)) {
- ClrBitTunnelBridgeExit(end);
+ if (IsTunnelBridgeSignalSimulationEntrance(end) && GetTunnelBridgeSignalState(end) == SIGNAL_STATE_RED) {
+ SetTunnelBridgeSignalState(end, SIGNAL_STATE_GREEN);
if (!_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(end);
- } else if (IsTunnelBridgeWithSignRed(tile)) {
- ClrBitTunnelBridgeExit(tile);
+ } else if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeSignalState(tile) == SIGNAL_STATE_RED) {
+ SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN);
if (!_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(tile);
}
}
@@ -2249,7 +2251,7 @@ static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDir
static void UnreserveBridgeTunnelTile(TileIndex tile)
{
SetTunnelBridgeReservation(tile, false);
- if (IsTunnelBridgeExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitGreen(tile, false);
+ if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_RED);
}
/**
@@ -2268,7 +2270,7 @@ static void ClearPathReservation(const Train *v, TileIndex tile, Trackdir track_
TileIndex end = GetOtherTunnelBridgeEnd(tile);
bool free = TunnelBridgeIsFree(tile, end, v).Succeeded();
- if (HasWormholeSignals(tile)) {
+ if (IsTunnelBridgeWithSignalSimulation(tile)) {
UnreserveBridgeTunnelTile(tile);
HandleLastTunnelBridgeSignals(tile, end, dir, free);
if (_settings_client.gui.show_track_reservation) {
@@ -2288,7 +2290,7 @@ static void ClearPathReservation(const Train *v, TileIndex tile, Trackdir track_
}
}
}
- } else if (GetTunnelBridgeDirection(tile) == dir && HasWormholeSignals(tile)) {
+ } else if (GetTunnelBridgeDirection(tile) == dir && IsTunnelBridgeWithSignalSimulation(tile)) {
/* cancelling reservation of entry ramp, due to reverse */
UnreserveBridgeTunnelTile(tile);
if (_settings_client.gui.show_track_reservation) {
@@ -2769,7 +2771,7 @@ bool TryPathReserve(Train *v, bool mark_as_stuck, bool first_tile_okay)
}
}
- if (IsTileType(v->tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(v->tile) &&
+ if (IsTileType(v->tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(v->tile) &&
DiagDirToDiagTrackBits(GetTunnelBridgeDirection(v->tile)) == v->track) {
// prevent any attempt to reserve the wrong way onto a tunnel/bridge exit
return false;
@@ -2980,7 +2982,7 @@ static bool TrainMovedChangeSignals(TileIndex tile, DiagDirection dir)
if (!IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) return true;
}
}
- if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(tile) && GetTunnelBridgeDirection(tile) == ReverseDiagDir(dir)) {
+ if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(tile) && GetTunnelBridgeDirection(tile) == ReverseDiagDir(dir)) {
if (UpdateSignalsOnSegment(tile, dir, GetTileOwner(tile)) == SIGSEG_PBS) {
return true;
}
@@ -3247,7 +3249,7 @@ static bool CheckTrainStayInWormHole(Train *t, TileIndex tile)
if (t->force_proceed != 0) return false;
/* When not exit reverse train. */
- if (!IsTunnelBridgeExit(tile)) {
+ if (!IsTunnelBridgeSignalSimulationExit(tile)) {
t->cur_speed = 0;
ToggleBit(t->flags, VRF_REVERSING);
return true;
@@ -3287,8 +3289,8 @@ static void HandleSignalBehindTrain(Train *v, uint signal_number)
if(tile == v->tile) {
/* Flip signal on ramp. */
- if (IsTunnelBridgeWithSignRed(tile)) {
- ClrBitTunnelBridgeExit(tile);
+ if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeSignalState(tile) == SIGNAL_STATE_RED) {
+ SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN);
MarkTileDirtyByTile(tile);
}
} else if (IsBridge(v->tile) && signal_number <= 16) {
@@ -3482,20 +3484,20 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
goto invalid_rail;
}
- if (HasWormholeSignals(gp.new_tile)) {
+ if (IsTunnelBridgeWithSignalSimulation(gp.new_tile)) {
/* If red signal stop. */
if (v->IsFrontEngine() && v->force_proceed == 0) {
- if (IsTunnelBridgeWithSignRed(gp.new_tile)) {
+ if (IsTunnelBridgeSignalSimulationEntrance(gp.new_tile) && GetTunnelBridgeSignalState(gp.new_tile) == SIGNAL_STATE_RED) {
v->cur_speed = 0;
v->vehstatus |= VS_TRAIN_SLOWING;
return false;
}
- if (IsTunnelBridgeExit(gp.new_tile)) {
+ if (IsTunnelBridgeSignalSimulationExit(gp.new_tile)) {
v->cur_speed = 0;
goto invalid_rail;
}
/* Flip signal on tunnel entrance tile red. */
- SetBitTunnelBridgeExit(gp.new_tile);
+ SetTunnelBridgeSignalState(gp.new_tile, SIGNAL_STATE_RED);
MarkTileDirtyByTile(gp.new_tile);
}
}
@@ -3554,9 +3556,9 @@ 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 && IsTunnelBridgeWithSignalSimulation(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;
+ if (v->IsFrontEngine() && v->force_proceed == 0 && IsTunnelBridgeSignalSimulationExit(v->tile)) goto invalid_rail;
/* Entered wormhole set counters. */
v->wait_counter = (TILE_SIZE * _settings_game.construction.simulated_wormhole_signals) - TILE_SIZE;
v->load_unload_ticks = 0;
diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp
index 64bd366b15..6746de1da4 100644
--- a/src/tunnelbridge_cmd.cpp
+++ b/src/tunnelbridge_cmd.cpp
@@ -1166,15 +1166,13 @@ static void DrawTunnelBridgeRampSignal(const TileInfo *ti)
SignalType type = SIGTYPE_NORMAL;
- bool is_green;
+ bool is_green = (GetTunnelBridgeSignalState(ti->tile) == SIGNAL_STATE_GREEN);
bool show_exit;
- if (IsTunnelBridgeExit(ti->tile)) {
- is_green = IsTunnelBridgeExitGreen(ti->tile);
+ if (IsTunnelBridgeSignalSimulationExit(ti->tile)) {
show_exit = true;
position ^= 1;
if (IsTunnelBridgePBS(ti->tile)) type = SIGTYPE_PBS_ONEWAY;
} else {
- is_green = IsTunnelBridgeWithSignGreen(ti->tile);
show_exit = false;
}
@@ -1369,7 +1367,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, ti->x + BB_data[4], ti->y + BB_data[5], BB_data[6], BB_data[7], TILE_HEIGHT, ti->z);
/* Draw signals for tunnel. */
- if (HasWormholeSignals(ti->tile)) DrawTunnelBridgeRampSignal(ti);
+ if (IsTunnelBridgeWithSignalSimulation(ti->tile)) DrawTunnelBridgeRampSignal(ti);
DrawBridgeMiddle(ti);
} else { // IsBridge(ti->tile)
@@ -1479,7 +1477,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
}
/* Draw signals for bridge. */
- if (HasWormholeSignals(ti->tile)) DrawTunnelBridgeRampSignal(ti);
+ if (IsTunnelBridgeWithSignalSimulation(ti->tile)) DrawTunnelBridgeRampSignal(ti);
DrawBridgeMiddle(ti);
}
@@ -1616,7 +1614,7 @@ void DrawBridgeMiddle(const TileInfo *ti)
}
if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && !IsInvisibilitySet(TO_BRIDGES) && HasTunnelBridgeReservation(rampnorth)
- && !HasWormholeSignals(rampnorth)) {
+ && !IsTunnelBridgeWithSignalSimulation(rampnorth)) {
if (rti->UsesOverlay()) {
SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY);
AddSortableSpriteToDraw(overlay + RTO_X + axis, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, bridge_z, IsTransparencySet(TO_BRIDGES));
@@ -1630,8 +1628,8 @@ void DrawBridgeMiddle(const TileInfo *ti)
if (HasCatenaryDrawn(GetRailType(rampsouth))) {
DrawCatenaryOnBridge(ti);
}
- if (HasWormholeSignals(rampsouth)) {
- IsTunnelBridgeExit(rampsouth) ? DrawBrigeSignalOnMiddlePart(ti, rampnorth, z): DrawBrigeSignalOnMiddlePart(ti, rampsouth, z);
+ if (IsTunnelBridgeWithSignalSimulation(rampsouth)) {
+ IsTunnelBridgeSignalSimulationExit(rampsouth) ? DrawBrigeSignalOnMiddlePart(ti, rampnorth, z): DrawBrigeSignalOnMiddlePart(ti, rampsouth, z);
}
}
@@ -1721,9 +1719,9 @@ static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td)
TransportType tt = GetTunnelBridgeTransportType(tile);
if (IsTunnel(tile)) {
- td->str = (tt == TRANSPORT_RAIL) ? HasWormholeSignals(tile) ? STR_LAI_TUNNEL_DESCRIPTION_RAILROAD_SIGNAL : STR_LAI_TUNNEL_DESCRIPTION_RAILROAD : STR_LAI_TUNNEL_DESCRIPTION_ROAD;
+ td->str = (tt == TRANSPORT_RAIL) ? IsTunnelBridgeWithSignalSimulation(tile) ? STR_LAI_TUNNEL_DESCRIPTION_RAILROAD_SIGNAL : STR_LAI_TUNNEL_DESCRIPTION_RAILROAD : STR_LAI_TUNNEL_DESCRIPTION_ROAD;
} else { // IsBridge(tile)
- td->str = (tt == TRANSPORT_WATER) ? STR_LAI_BRIDGE_DESCRIPTION_AQUEDUCT : HasWormholeSignals(tile) ? STR_LAI_BRIDGE_DESCRIPTION_RAILROAD_SIGNAL : GetBridgeSpec(GetBridgeType(tile))->transport_name[tt];
+ td->str = (tt == TRANSPORT_WATER) ? STR_LAI_BRIDGE_DESCRIPTION_AQUEDUCT : IsTunnelBridgeWithSignalSimulation(tile) ? STR_LAI_BRIDGE_DESCRIPTION_RAILROAD_SIGNAL : GetBridgeSpec(GetBridgeType(tile))->transport_name[tt];
}
td->owner[0] = GetTileOwner(tile);
diff --git a/src/tunnelbridge_map.h b/src/tunnelbridge_map.h
index 2196f794f1..499aad99b7 100644
--- a/src/tunnelbridge_map.h
+++ b/src/tunnelbridge_map.h
@@ -14,6 +14,7 @@
#include "bridge_map.h"
#include "tunnel_map.h"
+#include "signal_type.h"
/**
@@ -122,40 +123,40 @@ static inline TrackBits GetTunnelBridgeReservationTrackBits(TileIndex t)
}
/**
- * Declare tunnel/bridge with signal simulation.
+ * Declare tunnel/bridge entrance with signal simulation.
* @param t the tunnel/bridge tile.
*/
-static inline void SetBitTunnelBridgeSignal(TileIndex t)
+static inline void SetTunnelBridgeSignalSimulationEntrance(TileIndex t)
{
assert(IsTileType(t, MP_TUNNELBRIDGE));
SetBit(_m[t].m5, 5);
}
/**
- * Remove tunnel/bridge with signal simulation.
+ * Remove tunnel/bridge entrance with signal simulation.
* @param t the tunnel/bridge tile.
*/
-static inline void ClrBitTunnelBridgeSignal(TileIndex t)
+static inline void ClrTunnelBridgeSignalSimulationEntrance(TileIndex t)
{
assert(IsTileType(t, MP_TUNNELBRIDGE));
ClrBit(_m[t].m5, 5);
}
/**
- * Declare tunnel/bridge exit.
+ * Declare tunnel/bridge exit with signal simulation.
* @param t the tunnel/bridge tile.
*/
-static inline void SetBitTunnelBridgeExit(TileIndex t)
+static inline void SetTunnelBridgeSignalSimulationExit(TileIndex t)
{
assert(IsTileType(t, MP_TUNNELBRIDGE));
SetBit(_m[t].m5, 6);
}
/**
- * Remove tunnel/bridge exit declaration.
+ * Remove tunnel/bridge exit with signal simulation.
* @param t the tunnel/bridge tile.
*/
-static inline void ClrBitTunnelBridgeExit(TileIndex t)
+static inline void ClrTunnelBridgeSignalSimulationExit(TileIndex t)
{
assert(IsTileType(t, MP_TUNNELBRIDGE));
ClrBit(_m[t].m5, 6);
@@ -167,85 +168,81 @@ static inline void ClrBitTunnelBridgeExit(TileIndex t)
* @param t the tile that might be a tunnel/bridge.
* @return true if and only if this tile is a tunnel/bridge with signal simulation.
*/
-static inline bool HasWormholeSignals(TileIndex t)
+static inline bool IsTunnelBridgeWithSignalSimulation(TileIndex t)
{
- return IsTileType(t, MP_TUNNELBRIDGE) && (HasBit(_m[t].m5, 5) || HasBit(_m[t].m5, 6)) ;
-}
-
-/**
- * Is this a tunnel/bridge with sign on green?
- * @param t the tile that might be a tunnel/bridge with sign set green.
- * @pre IsTileType(t, MP_TUNNELBRIDGE)
- * @return true if and only if this tile is a tunnel/bridge entrance.
- */
-static inline bool IsTunnelBridgeWithSignGreen(TileIndex t)
-{
- assert(IsTileType(t, MP_TUNNELBRIDGE));
- return HasBit(_m[t].m5, 5) && !HasBit(_m[t].m5, 6);
-}
-
-static inline bool IsTunnelBridgeWithSignRed(TileIndex t)
-{
- assert(IsTileType(t, MP_TUNNELBRIDGE));
- return HasBit(_m[t].m5, 5) && HasBit(_m[t].m5, 6);
+ return IsTileType(t, MP_TUNNELBRIDGE) && (HasBit(_m[t].m5, 5) || HasBit(_m[t].m5, 6));
}
/**
* Is this a tunnel/bridge entrance tile with signal?
* Tunnel bridge signal simulation has allways bit 5 on at entrance.
* @param t the tile that might be a tunnel/bridge.
+ * @pre IsTileType(t, MP_TUNNELBRIDGE)
* @return true if and only if this tile is a tunnel/bridge entrance.
*/
-static inline bool IsTunnelBridgeEntrance(TileIndex t)
+static inline bool IsTunnelBridgeSignalSimulationEntrance(TileIndex t)
{
assert(IsTileType(t, MP_TUNNELBRIDGE));
- return HasBit(_m[t].m5, 5) ;
+ return HasBit(_m[t].m5, 5) && !HasBit(_m[t].m5, 6);
}
/**
* Is this a tunnel/bridge exit?
* @param t the tile that might be a tunnel/bridge.
+ * @pre IsTileType(t, MP_TUNNELBRIDGE)
* @return true if and only if this tile is a tunnel/bridge exit.
*/
-static inline bool IsTunnelBridgeExit(TileIndex t)
+static inline bool IsTunnelBridgeSignalSimulationExit(TileIndex t)
{
assert(IsTileType(t, MP_TUNNELBRIDGE));
return !HasBit(_m[t].m5, 5) && HasBit(_m[t].m5, 6);
}
-static inline bool IsTunnelBridgeExitGreen(TileIndex t)
+/**
+ * Get the signal state for a tunnel/bridge entrance or exit with signal simulation
+ * @param t the tunnel/bridge entrance or exit tile with signal simulation
+ * @pre IsTunnelBridgeWithSignalSimulation(t)
+ * @return signal state
+ */
+static inline SignalState GetTunnelBridgeSignalState(TileIndex t)
{
- assert(IsTunnelBridgeExit(t));
- return HasBit(_me[t].m6, 0);
+ assert(IsTunnelBridgeWithSignalSimulation(t));
+ return HasBit(_me[t].m6, 0) ? SIGNAL_STATE_GREEN : SIGNAL_STATE_RED;
}
-static inline void SetTunnelBridgeExitGreen(TileIndex t, bool green)
+/**
+ * Set the signal state for a tunnel/bridge entrance or exit with signal simulation
+ * @param t the tunnel/bridge entrance or exit tile with signal simulation
+ * @pre IsTunnelBridgeWithSignalSimulation(t)
+ * @param state signal state
+ */
+static inline void SetTunnelBridgeSignalState(TileIndex t, SignalState state)
{
- assert(IsTunnelBridgeExit(t));
- SB(_me[t].m6, 0, 1, green ? 1 : 0);
+ assert(IsTunnelBridgeWithSignalSimulation(t));
+ SB(_me[t].m6, 0, 1, (state == SIGNAL_STATE_GREEN) ? 1 : 0);
}
static inline bool IsTunnelBridgeSemaphore(TileIndex t)
{
- assert(IsTileType(t, MP_TUNNELBRIDGE) && HasWormholeSignals(t));
+ assert(IsTunnelBridgeWithSignalSimulation(t));
return HasBit(_me[t].m6, 1);
}
static inline void SetTunnelBridgeSemaphore(TileIndex t, bool is_semaphore)
{
- assert(IsTileType(t, MP_TUNNELBRIDGE) && HasWormholeSignals(t));
+ assert(IsTunnelBridgeWithSignalSimulation(t));
SB(_me[t].m6, 1, 1, is_semaphore ? 1 : 0);
}
static inline bool IsTunnelBridgePBS(TileIndex t)
{
- assert(IsTileType(t, MP_TUNNELBRIDGE) && HasWormholeSignals(t));
+ assert(IsTunnelBridgeWithSignalSimulation(t));
return HasBit(_me[t].m6, 6);
}
static inline void SetTunnelBridgePBS(TileIndex t, bool is_pbs)
{
- assert(IsTileType(t, MP_TUNNELBRIDGE) && HasWormholeSignals(t));
+ assert(IsTunnelBridgeWithSignalSimulation(t));
SB(_me[t].m6, 6, 1, is_pbs ? 1 : 0);
}