diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index a92a675160..9f048a7c05 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1115,6 +1115,8 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, } } if (flags & DC_EXEC) { + Company * const c = Company::Get(GetTileOwner(tile)); + if (IsTunnelBridgeWithSignalSimulation(tile)) c->infrastructure.signal -= GetTunnelBridgeSignalSimulationSignalCount(tile, tile_exit); if (p2 == 0 && IsTunnelBridgeWithSignalSimulation(tile)) { // Toggle signal if already signals present. if (convert_signal) { if (flip_variant) { @@ -1167,6 +1169,8 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, AddSideToSignalBuffer(tile_exit, INVALID_DIAGDIR, GetTileOwner(tile)); YapfNotifyTrackLayoutChange(tile, track); YapfNotifyTrackLayoutChange(tile_exit, track); + if (IsTunnelBridgeWithSignalSimulation(tile)) c->infrastructure.signal += GetTunnelBridgeSignalSimulationSignalCount(tile, tile_exit); + DirtyCompanyInfrastructureWindows(GetTileOwner(tile)); } return cost; } @@ -1626,6 +1630,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1 if (IsTunnelBridgeWithSignalSimulation(tile)) { // handle tunnel/bridge signals. TileIndex end = GetOtherTunnelBridgeEnd(tile); + Company::Get(GetTileOwner(tile))->infrastructure.signal -= GetTunnelBridgeSignalSimulationSignalCount(tile, end); ClearBridgeTunnelSignalSimulation(end, tile); ClearBridgeTunnelSignalSimulation(tile, end); MarkBridgeOrTunnelDirty(tile); @@ -1633,6 +1638,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1 AddSideToSignalBuffer(end, INVALID_DIAGDIR, GetTileOwner(tile)); YapfNotifyTrackLayoutChange(tile, track); YapfNotifyTrackLayoutChange(end, track); + DirtyCompanyInfrastructureWindows(GetTileOwner(tile)); return CommandCost(EXPENSES_CONSTRUCTION, cost); } diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 6a0f019a21..7e4943f652 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -205,7 +205,12 @@ void AfterLoadCompanyStats() switch (GetTunnelBridgeTransportType(tile)) { case TRANSPORT_RAIL: c = Company::GetIfValid(GetTileOwner(tile)); - if (c != NULL) c->infrastructure.rail[GetRailType(tile)] += len; + if (c != NULL) { + c->infrastructure.rail[GetRailType(tile)] += len; + if (IsTunnelBridgeWithSignalSimulation(tile)) { + c->infrastructure.signal += GetTunnelBridgeSignalSimulationSignalCount(tile, other_end); + } + } break; case TRANSPORT_ROAD: { diff --git a/src/settings.cpp b/src/settings.cpp index d7be94a9f0..eddc7b21fd 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1159,6 +1159,14 @@ static bool InvalidateCompanyWindow(int32 p1) return true; } +static bool SimulatedWormholeSignalsChanged(int32 p1) +{ + extern void AfterLoadCompanyStats(); + AfterLoadCompanyStats(); + MarkWholeScreenDirty(); + return true; +} + /** Checks if any settings are set to incorrect values, and sets them to correct values in that case. */ static void ValidateSettings() { diff --git a/src/table/settings.ini b/src/table/settings.ini index e8ab4b075b..446203d138 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -44,6 +44,7 @@ static bool ZoomMinMaxChanged(int32 p1); static bool MaxVehiclesChanged(int32 p1); static bool ImprovedBreakdownsSettingChanged(int32 p1); static bool DayLengthChanged(int32 p1); +static bool SimulatedWormholeSignalsChanged(int32 p1); #ifdef ENABLE_NETWORK static bool UpdateClientName(int32 p1); @@ -606,7 +607,7 @@ min = 1 max = 16 str = STR_CONFIG_SETTING_SIMULATE_SIGNALS strval = STR_CONFIG_SETTING_SIMULATE_SIGNALS_VALUE -proc = RedrawScreen +proc = SimulatedWormholeSignalsChanged from = 0 cat = SC_BASIC patxname = ""signal_tunnel_bridge.construction.simulated_wormhole_signals"" diff --git a/src/tunnelbridge.h b/src/tunnelbridge.h index 9d5a4188b7..ab854132c2 100644 --- a/src/tunnelbridge.h +++ b/src/tunnelbridge.h @@ -17,6 +17,7 @@ void MarkBridgeDirty(TileIndex begin, TileIndex end, DiagDirection direction, uint bridge_height, const ZoomLevel mark_dirty_if_zoomlevel_is_below = ZOOM_LVL_END); void MarkBridgeDirty(TileIndex tile, const ZoomLevel mark_dirty_if_zoomlevel_is_below = ZOOM_LVL_END); void MarkBridgeOrTunnelDirty(TileIndex tile, const ZoomLevel mark_dirty_if_zoomlevel_is_below = ZOOM_LVL_END); +uint GetTunnelBridgeSignalSimulationSignalCount(uint length); /** * Calculates the length of a tunnel or a bridge (without end tiles) @@ -34,6 +35,17 @@ static inline uint GetTunnelBridgeLength(TileIndex begin, TileIndex end) return abs(x2 + y2 - x1 - y1) - 1; } +/** + * Get number of signals on bridge or tunnel with signal simulation. + * @param begin The begin of the tunnel or bridge. + * @param end The end of the tunnel or bridge. + * @pre IsTunnelBridgeWithSignalSimulation(begin) + */ +static inline uint GetTunnelBridgeSignalSimulationSignalCount(TileIndex begin, TileIndex end) +{ + return GetTunnelBridgeSignalSimulationSignalCount(GetTunnelBridgeLength(begin, end)); +} + extern TileIndex _build_tunnel_endtile; #endif /* TUNNELBRIDGE_H */ diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 63004ad94b..a8207f0018 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -96,6 +96,16 @@ void MarkBridgeOrTunnelDirty(TileIndex tile, const ZoomLevel mark_dirty_if_zooml } } +/** + * Get number of signals on bridge or tunnel with signal simulation. + * @param length Length of bridge/tunnel middle + * @return Number of signals on signalled bridge/tunnel of this length + */ +uint GetTunnelBridgeSignalSimulationSignalCount(uint length) +{ + return 2 + (length / _settings_game.construction.simulated_wormhole_signals); +} + /** Reset the data been eventually changed by the grf loaded. */ void ResetBridges() { @@ -855,6 +865,9 @@ static CommandCost DoClearTunnel(TileIndex tile, DoCommandFlag flags) if (Company::IsValidID(owner)) { Company::Get(owner)->infrastructure.rail[GetRailType(tile)] -= len * TUNNELBRIDGE_TRACKBIT_FACTOR; + if (IsTunnelBridgeWithSignalSimulation(tile)) { // handle tunnel/bridge signals. + Company::Get(GetTileOwner(tile))->infrastructure.signal -= GetTunnelBridgeSignalSimulationSignalCount(tile, endtile); + } DirtyCompanyInfrastructureWindows(owner); } @@ -942,7 +955,12 @@ static CommandCost DoClearBridge(TileIndex tile, DoCommandFlag flags) /* Update company infrastructure counts. */ if (rail) { - if (Company::IsValidID(owner)) Company::Get(owner)->infrastructure.rail[GetRailType(tile)] -= len * TUNNELBRIDGE_TRACKBIT_FACTOR; + if (Company::IsValidID(owner)) { + Company::Get(owner)->infrastructure.rail[GetRailType(tile)] -= len * TUNNELBRIDGE_TRACKBIT_FACTOR; + if (IsTunnelBridgeWithSignalSimulation(tile)) { // handle tunnel/bridge signals. + Company::Get(GetTileOwner(tile))->infrastructure.signal -= GetTunnelBridgeSignalSimulationSignalCount(tile, endtile); + } + } } else if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD) { RoadType rt; FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) { @@ -1870,6 +1888,12 @@ static void ChangeTileOwner_TunnelBridge(TileIndex tile, Owner old_owner, Owner if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.water += num_pieces; } + if (IsTunnelBridgeWithSignalSimulation(tile) && IsTunnelBridgeSignalSimulationEntrance(tile)) { + uint num_sigs = GetTunnelBridgeSignalSimulationSignalCount(tile, other_end); + Company::Get(old_owner)->infrastructure.signal -= num_sigs; + Company::Get(new_owner)->infrastructure.signal += num_sigs; + } + if (new_owner != INVALID_OWNER) { SetTileOwner(tile, new_owner); } else {