# HG changeset patch # User Patric Stout # Date 2021-01-06 20:12:32 # Node ID d0d308decaa465df05ef9ce01f1919a89e83ed56 # Parent dbb2ed121b40173a06063e8ffed53daca9144bc7 Fix #7656: destroying a tunnel/bridge now first removes the tracks for cost calculation This means that for rail tunnel/bridges, the rail is first sold, and the tunnel/bridge is destroyed after. This means destroying tunnels/ bridges now often makes you money, instead of costing. Similar, with road/tram tracks. Destroying a road+tram tunnel/bridge now costs the same amount of money as first removing the tram tracks and than destroying the road tunnel/bridge. Especially as tram tracks generate money when removing, this is a noticeable difference. diff --git a/regression/regression/result.txt b/regression/regression/result.txt --- a/regression/regression/result.txt +++ b/regression/regression/result.txt @@ -7314,7 +7314,7 @@ ERROR: IsEnd() is invalid as Begin() is IsBuoyTile(): false IsLockTile(): false IsCanalTile(): false - GetBankBalance(): 1999979664 + GetBankBalance(): 1999979304 BuildWaterDepot(): true BuildDock(): true BuildBuoy(): true @@ -7327,7 +7327,7 @@ ERROR: IsEnd() is invalid as Begin() is IsBuoyTile(): true IsLockTile(): true IsCanalTile(): true - GetBankBalance(): 1999965040 + GetBankBalance(): 1999964680 --AIWaypointList(BUOY)-- Count(): 1 @@ -7346,7 +7346,7 @@ ERROR: IsEnd() is invalid as Begin() is IsBuoyTile(): false IsLockTile(): false IsCanalTile(): false - GetBankBalance(): 1999959645 + GetBankBalance(): 1999959285 BuildWaterDepot(): true BuildDock(): true diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -214,6 +214,38 @@ CommandCost CheckBridgeAvailability(Brid } /** + * Calculate the base cost of clearing a tunnel/bridge per tile. + * @param tile Start tile of the tunnel/bridge. + * @return How much clearing this tunnel/bridge costs per tile. + */ +static Money TunnelBridgeClearCost(TileIndex tile, Price base_price) +{ + Money base_cost = _price[base_price]; + + /* Add the cost of the transport that is on the tunnel/bridge. */ + switch (GetTunnelBridgeTransportType(tile)) { + case TRANSPORT_ROAD: { + RoadType road_rt = GetRoadTypeRoad(tile); + RoadType tram_rt = GetRoadTypeTram(tile); + + if (road_rt != INVALID_ROADTYPE) { + base_cost += 2 * RoadClearCost(road_rt); + } + if (tram_rt != INVALID_ROADTYPE) { + base_cost += 2 * RoadClearCost(tram_rt); + } + } break; + + case TRANSPORT_RAIL: base_cost += RailClearCost(GetRailType(tile)); break; + /* Aquaducts have their own clear price. */ + case TRANSPORT_WATER: base_cost = _price[PR_CLEAR_AQUEDUCT]; break; + default: break; + } + + return base_cost; +} + +/** * Build a Bridge * @param end_tile end tile * @param flags type of operation @@ -373,7 +405,8 @@ CommandCost CmdBuildBridge(TileIndex end return_cmd_error(STR_ERROR_AREA_IS_OWNED_BY_ANOTHER); } - cost.AddCost(bridge_len * _price[PR_CLEAR_BRIDGE]); // The cost of clearing the current bridge. + /* The cost of clearing the current bridge. */ + cost.AddCost(bridge_len * TunnelBridgeClearCost(tile_start, PR_CLEAR_BRIDGE)); owner = GetTileOwner(tile_start); /* If bridge belonged to bankrupt company, it has a new owner now */ @@ -849,6 +882,7 @@ static CommandCost DoClearTunnel(TileInd ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM, flags); } + Money base_cost = TunnelBridgeClearCost(tile, PR_CLEAR_TUNNEL); uint len = GetTunnelBridgeLength(tile, endtile) + 2; // Don't forget the end tiles. if (flags & DC_EXEC) { @@ -889,7 +923,8 @@ static CommandCost DoClearTunnel(TileInd DoClearSquare(endtile); } } - return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_TUNNEL] * len); + + return CommandCost(EXPENSES_CONSTRUCTION, len * base_cost); } @@ -928,7 +963,7 @@ static CommandCost DoClearBridge(TileInd ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM, flags); } - Money base_cost = (GetTunnelBridgeTransportType(tile) != TRANSPORT_WATER) ? _price[PR_CLEAR_BRIDGE] : _price[PR_CLEAR_AQUEDUCT]; + Money base_cost = TunnelBridgeClearCost(tile, PR_CLEAR_BRIDGE); uint len = GetTunnelBridgeLength(tile, endtile) + 2; // Don't forget the end tiles. if (flags & DC_EXEC) {