diff options
Diffstat (limited to 'src/rail_cmd.cpp')
-rw-r--r-- | src/rail_cmd.cpp | 129 |
1 files changed, 110 insertions, 19 deletions
diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index e362a132b..327d8f998 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -41,6 +41,7 @@ typedef SmallVector<Train *, 16> TrainList; RailtypeInfo _railtypes[RAILTYPE_END]; +TileIndex _rail_track_endtile; ///< The end of a rail track; as hidden return from the rail build/remove command for GUI purposes. assert_compile(sizeof(_original_railtypes) <= sizeof(_railtypes)); @@ -557,6 +558,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u } cost.AddCost(RailBuildCost(railtype)); + _rail_track_endtile = tile; return cost; } @@ -701,6 +703,7 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, if (v != NULL) TryPathReserve(v, true); } + _rail_track_endtile = tile; return cost; } @@ -1011,9 +1014,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 */ @@ -1022,6 +1028,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, (ie, no overlap) */ TrackBits trackbits = GetTrackBits(tile); @@ -1038,7 +1091,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]); @@ -1196,6 +1248,7 @@ static bool CheckSignalAutoFill(TileIndex &tile, Trackdir &trackdir, int &signal return true; case MP_TUNNELBRIDGE: { + if (!remove && HasWormholeSignals(tile)) return false; TileIndex orig_tile = tile; // backup old value if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) return false; @@ -1307,7 +1360,8 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin bool had_success = false; for (;;) { /* only build/remove signals with the specified density */ - if (remove || minimise_gaps || signal_ctr % signal_density == 0) { + + if (remove || minimise_gaps || signal_ctr % signal_density == 0 || IsTileType(tile, MP_TUNNELBRIDGE)) { uint32 p1 = GB(TrackdirToTrack(trackdir), 0, 3); SB(p1, 3, 1, mode); SB(p1, 4, 1, semaphores); @@ -1343,13 +1397,20 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin /* Collect cost. */ if (!test_only) { - /* Be user-friendly and try placing signals as much as possible */ - if (ret.Succeeded()) { - had_success = true; - total_cost.AddCost(ret); - last_used_ctr = last_suitable_ctr; - last_suitable_tile = INVALID_TILE; + /* Be user-friendly and try placing signals as much as possible */ + if (ret.Succeeded()) { + had_success = true; + if (IsTileType(tile, MP_TUNNELBRIDGE)) { + if ((!autofill && GetTunnelBridgeDirection(tile) == TrackdirToExitdir(trackdir)) || + (autofill && GetTunnelBridgeDirection(tile) != TrackdirToExitdir(trackdir))) { + total_cost.AddCost(ret); + } } else { + total_cost.AddCost(ret); + } + last_used_ctr = last_suitable_ctr; + last_suitable_tile = INVALID_TILE; + } else { /* The "No railway" error is the least important one. */ if (ret.GetErrorMessage() != STR_ERROR_THERE_IS_NO_RAILROAD_TRACK || last_error.GetErrorMessage() == INVALID_STRING_ID) { @@ -1420,22 +1481,48 @@ CommandCost CmdBuildSignalTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *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 = NULL; if (HasReservedTracks(tile, TrackToTrackBits(track))) { v = GetTrainForReservation(tile, track); @@ -1471,7 +1558,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1 MarkTileDirtyByTile(tile); } - return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_SIGNALS]); + return CommandCost(EXPENSES_CONSTRUCTION, cost); } /** @@ -1946,6 +2033,7 @@ static void DrawTrackFence_WE_1(const TileInfo *ti, SpriteID base_image) ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z); } + /** * Draw fence at northern side of track. */ @@ -2483,11 +2571,14 @@ static Foundation GetFoundation_Track(TileIndex tile, Slope tileh) return IsPlainRail(tile) ? GetRailFoundation(tileh, GetTrackBits(tile)) : FlatteningFoundation(tileh); } + static void TileLoop_Track(TileIndex tile) { RailGroundType old_ground = GetRailGroundType(tile); RailGroundType new_ground; + ReduceStuckCounter(tile); + if (old_ground == RAIL_GROUND_WATER) { TileLoop_Water(tile); return; |