diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 3b93a5d32c..24e5c7b774 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -886,22 +886,32 @@ static CommandCost CmdRailTrackHelper(DoCommandFlag flags, TileIndex tile, TileI if (ret.Failed()) return ret; bool had_success = false; + bool under_tunnelbridge = false; CommandCost last_error = CMD_ERROR; for (;;) { - ret = remove ? Command::Do(flags, tile, TrackdirToTrack(trackdir)) : Command::Do(flags, tile, railtype, TrackdirToTrack(trackdir), auto_remove_signals); - - if (ret.Failed()) { - last_error = ret; - if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT && !remove) { - if (fail_on_obstacle) return last_error; - if (had_success) break; // Keep going if we haven't constructed any rail yet, skipping the start of the drag + /* Don't try to place rail between tunnelbridge ends */ + if (IsTileType(tile, MP_TUNNELBRIDGE)) { + under_tunnelbridge = !under_tunnelbridge; + } else if (!under_tunnelbridge) { + if (remove) { + ret = Command::Do(flags, tile, TrackdirToTrack(trackdir)); + } else { + ret = Command::Do(flags, tile, railtype, TrackdirToTrack(trackdir), auto_remove_signals); } - /* Ownership errors are more important. */ - if (last_error.GetErrorMessage() == STR_ERROR_OWNED_BY && remove) break; - } else { - had_success = true; - total_cost.AddCost(ret); + if (ret.Failed()) { + last_error = ret; + if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT && !remove) { + if (fail_on_obstacle) return last_error; + if (had_success) break; // Keep going if we haven't constructed any rail yet, skipping the start of the drag + } + + /* Ownership errors are more important. */ + if (last_error.GetErrorMessage() == STR_ERROR_OWNED_BY && remove) break; + } else { + had_success = true; + total_cost.AddCost(ret); + } } if (tile == end_tile) break; diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 1d814a65ee..c2501a1d12 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -1007,49 +1007,55 @@ CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex end_tile, TileIndex bool had_bridge = false; bool had_tunnel = false; bool had_success = false; + bool under_tunnelbridge = false; /* Start tile is the first tile clicked by the user. */ for (;;) { - RoadBits bits = AxisToRoadBits(axis); - - /* Determine which road parts should be built. */ - if (!is_ai && start_tile != end_tile) { - /* Only build the first and last roadbit if they can connect to something. */ - if (tile == end_tile && !CanConnectToRoad(tile, rt, dir)) { - bits = DiagDirToRoadBits(ReverseDiagDir(dir)); - } else if (tile == start_tile && !CanConnectToRoad(tile, rt, ReverseDiagDir(dir))) { - bits = DiagDirToRoadBits(dir); + /* Don't try to place road between tunnelbridge ends */ + if (IsTileType(tile, MP_TUNNELBRIDGE)) { + under_tunnelbridge = !under_tunnelbridge; + } else if (!under_tunnelbridge) { + RoadBits bits = AxisToRoadBits(axis); + + /* Determine which road parts should be built. */ + if (!is_ai && start_tile != end_tile) { + /* Only build the first and last roadbit if they can connect to something. */ + if (tile == end_tile && !CanConnectToRoad(tile, rt, dir)) { + bits = DiagDirToRoadBits(ReverseDiagDir(dir)); + } else if (tile == start_tile && !CanConnectToRoad(tile, rt, ReverseDiagDir(dir))) { + bits = DiagDirToRoadBits(dir); + } + } else { + /* Road parts only have to be built at the start tile or at the end tile. */ + if (tile == end_tile && !end_half) bits &= DiagDirToRoadBits(ReverseDiagDir(dir)); + if (tile == start_tile && start_half) bits &= DiagDirToRoadBits(dir); } - } else { - /* Road parts only have to be built at the start tile or at the end tile. */ - if (tile == end_tile && !end_half) bits &= DiagDirToRoadBits(ReverseDiagDir(dir)); - if (tile == start_tile && start_half) bits &= DiagDirToRoadBits(dir); - } - CommandCost ret = Command::Do(flags, tile, bits, rt, drd, 0); - if (ret.Failed()) { - last_error = ret; - if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT) { - if (is_ai) return last_error; - if (had_success) break; // Keep going if we haven't constructed any road yet, skipping the start of the drag - } - } else { - had_success = true; - /* Only pay for the upgrade on one side of the bridges and tunnels */ - if (IsTileType(tile, MP_TUNNELBRIDGE)) { - if (IsBridge(tile)) { - if (!had_bridge || GetTunnelBridgeDirection(tile) == dir) { - cost.AddCost(ret); - } - had_bridge = true; - } else { // IsTunnel(tile) - if (!had_tunnel || GetTunnelBridgeDirection(tile) == dir) { - cost.AddCost(ret); - } - had_tunnel = true; + CommandCost ret = Command::Do(flags, tile, bits, rt, drd, 0); + if (ret.Failed()) { + last_error = ret; + if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT) { + if (is_ai) return last_error; + if (had_success) break; // Keep going if we haven't constructed any road yet, skipping the start of the drag } } else { - cost.AddCost(ret); + had_success = true; + /* Only pay for the upgrade on one side of the bridges and tunnels */ + if (IsTileType(tile, MP_TUNNELBRIDGE)) { + if (IsBridge(tile)) { + if (!had_bridge || GetTunnelBridgeDirection(tile) == dir) { + cost.AddCost(ret); + } + had_bridge = true; + } else { // IsTunnel(tile) + if (!had_tunnel || GetTunnelBridgeDirection(tile) == dir) { + cost.AddCost(ret); + } + had_tunnel = true; + } + } else { + cost.AddCost(ret); + } } }