summaryrefslogtreecommitdiff
path: root/src/rail_cmd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rail_cmd.cpp')
-rw-r--r--src/rail_cmd.cpp100
1 files changed, 88 insertions, 12 deletions
diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp
index 4c34f1ca8..e71f562ac 100644
--- a/src/rail_cmd.cpp
+++ b/src/rail_cmd.cpp
@@ -1069,9 +1069,12 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
if (sigtype > SIGTYPE_LAST) return CMD_ERROR;
if (cycle_start > cycle_stop || cycle_stop > SIGTYPE_LAST) return CMD_ERROR;
- /* You can only build signals on plain rail tiles, and the selected track must exist */
- if (!ValParamTrackOrientation(track) || !IsPlainRailTile(tile) ||
- !HasTrack(tile, track)) {
+ /* You can only build signals on plain rail tiles or tunnel/bridges, and the selected track must exist */
+ if (IsTileType(tile, MP_TUNNELBRIDGE)) {
+ if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) return CMD_ERROR;
+ CommandCost ret = EnsureNoTrainOnTrack(GetOtherTunnelBridgeEnd(tile), track);
+ //if (ret.Failed()) return ret;
+ } else if (!ValParamTrackOrientation(track) || !IsPlainRailTile(tile) || !HasTrack(tile, track)) {
return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK);
}
/* Protect against invalid signal copying */
@@ -1080,6 +1083,53 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
CommandCost ret = CheckTileOwnership(tile);
if (ret.Failed()) return ret;
+ CommandCost cost;
+ /* handle signals simulation on tunnel/bridge. */
+ if (IsTileType(tile, MP_TUNNELBRIDGE)) {
+ TileIndex tile_exit = GetOtherTunnelBridgeEnd(tile);
+ cost = CommandCost();
+ if (!HasWormholeSignals(tile)) { // toggle signal zero costs.
+ if (p2 != 12) cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_SIGNALS] * ((GetTunnelBridgeLength(tile, tile_exit) + 4) >> 2)); // minimal 1
+ }
+ if (flags & DC_EXEC) {
+ if (p2 == 0 && HasWormholeSignals(tile)){ // Toggle signal if already signals present.
+ if (IsTunnelBridgeEntrance (tile)) {
+ ClrBitTunnelBridgeSignal(tile);
+ ClrBitTunnelBridgeExit(tile_exit);
+ SetBitTunnelBridgeExit(tile);
+ SetBitTunnelBridgeSignal(tile_exit);
+ } else {
+ ClrBitTunnelBridgeSignal(tile_exit);
+ ClrBitTunnelBridgeExit(tile);
+ SetBitTunnelBridgeExit(tile_exit);
+ SetBitTunnelBridgeSignal(tile);
+ }
+ } else{
+ /* Create one direction tunnel/bridge if required. */
+ if (p2 == 0) {
+ SetBitTunnelBridgeSignal(tile);
+ SetBitTunnelBridgeExit(tile_exit);
+ } 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))) {
+ SetBitTunnelBridgeSignal(tile);
+ SetBitTunnelBridgeExit(tile_exit);
+ } else {
+ SetBitTunnelBridgeSignal(tile_exit);
+ SetBitTunnelBridgeExit(tile);
+ }
+ }
+ }
+ MarkTileDirtyByTile(tile);
+ MarkTileDirtyByTile(tile_exit);
+ AddSideToSignalBuffer(tile, INVALID_DIAGDIR, _current_company);
+ YapfNotifyTrackLayoutChange(tile, track);
+ }
+ return cost;
+ }
+
/* See if this is a valid track combination for signals (no overlap) */
if (TracksOverlap(GetTrackBits(tile))) return_cmd_error(STR_ERROR_NO_SUITABLE_RAILROAD_TRACK);
@@ -1089,7 +1139,6 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
/* you can not convert a signal if no signal is on track */
if (convert_signal && !HasSignalOnTrack(tile, track)) return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS);
- CommandCost cost;
if (!HasSignalOnTrack(tile, track)) {
/* build new signals */
cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_SIGNALS]);
@@ -1243,6 +1292,7 @@ static bool AdvanceSignalAutoFill(TileIndex &tile, Trackdir &trackdir, bool remo
break;
case MP_TUNNELBRIDGE: {
+ if (!remove && HasWormholeSignals(tile)) return false;
if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) return false;
if (GetTunnelBridgeDirection(tile) != TrackdirToExitdir(trackdir)) return false;
break;
@@ -1501,22 +1551,48 @@ CommandCost CmdBuildSignalTrack(TileIndex tile, DoCommandFlag flags, uint32 p1,
CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
{
Track track = Extract<Track, 0, 3>(p1);
+ Money cost = _price[PR_CLEAR_SIGNALS];
- if (!ValParamTrackOrientation(track) || !IsPlainRailTile(tile) || !HasTrack(tile, track)) {
- return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK);
- }
- if (!HasSignalOnTrack(tile, track)) {
- return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS);
+ 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);
+
+ cost *= ((GetTunnelBridgeLength(tile, end) + 4) >> 2);
+
+ CommandCost ret = EnsureNoTrainOnTrack(GetOtherTunnelBridgeEnd(tile), track);
+ //if (ret.Failed()) return ret;
+ } else {
+ if (!ValParamTrackOrientation(track) || !IsPlainRailTile(tile) || !HasTrack(tile, track)) {
+ return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK);
+ }
+ if (!HasSignalOnTrack(tile, track)) {
+ return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS);
+ }
+ CommandCost ret = EnsureNoTrainOnTrack(tile, track);
+ //if (ret.Failed()) return ret;
}
/* Only water can remove signals from anyone */
if (_current_company != OWNER_WATER) {
- CommandCost ret = CheckTileOwnership(tile);
- if (ret.Failed()) return ret;
}
/* Do it? */
if (flags & DC_EXEC) {
+
+ if (HasWormholeSignals(tile)) { // handle tunnel/bridge signals.
+ TileIndex end = GetOtherTunnelBridgeEnd(tile);
+ ClrBitTunnelBridgeExit(tile);
+ ClrBitTunnelBridgeExit(end);
+ ClrBitTunnelBridgeSignal(tile);
+ ClrBitTunnelBridgeSignal(end);
+ _m[tile].m2 = 0;
+ _m[end].m2 = 0;
+ MarkTileDirtyByTile(tile);
+ MarkTileDirtyByTile(end);
+ return CommandCost(EXPENSES_CONSTRUCTION, cost);
+ }
+
Train *v = nullptr;
if (HasReservedTracks(tile, TrackToTrackBits(track))) {
v = GetTrainForReservation(tile, track);
@@ -1552,7 +1628,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1
MarkTileDirtyByTile(tile);
}
- return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_SIGNALS]);
+ return CommandCost(EXPENSES_CONSTRUCTION, cost);
}
/**