diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -662,7 +662,7 @@ CommandCost ClearTile_Station(TileIndex * @param check_clear if clearing tile should be performed (in wich case, cost will be added) * @return the cost in case of success, or an error code if it failed. */ -CommandCost CheckFlatLandBelow(TileIndex tile, uint w, uint h, DoCommandFlag flags, uint invalid_dirs, StationID *station, bool check_clear = true) +CommandCost CheckFlatLandBelow(TileIndex tile, uint w, uint h, DoCommandFlag flags, uint invalid_dirs, StationID *station, bool check_clear = true, RailType rt = INVALID_RAILTYPE) { CommandCost cost(EXPENSES_CONSTRUCTION); int allowed_z = -1; @@ -723,6 +723,29 @@ CommandCost CheckFlatLandBelow(TileIndex } } } else if (check_clear) { + /* Rail type is only valid when building a railway station; in station to + * build isn't a rail station it's INVALID_RAILTYPE. */ + if (rt != INVALID_RAILTYPE && + IsPlainRailTile(tile_cur) && !HasSignals(tile_cur) && + HasPowerOnRail(GetRailType(tile), rt)) { + /* Allow overbuilding if the tile: + * - has rail, but no signals + * - it has exactly one track + * - the track is in line with the station + * - the current rail type has power on the to-be-built type (e.g. convert normal rail to el rail) + */ + TrackBits tracks = GetTrackBits(tile_cur); + Track track = RemoveFirstTrack(&tracks); + Track expected_track = HasBit(invalid_dirs, DIAGDIR_NE) ? TRACK_X : TRACK_Y; + + if (tracks == TRACK_BIT_NONE && track == expected_track) { + CommandCost ret = DoCommand(tile_cur, 0, track, flags, CMD_REMOVE_SINGLE_RAIL); + if (CmdFailed(ret)) return ret; + cost.AddCost(ret); + /* With flags & ~DC_EXEC CmdLandscapeClear would fail since the rail still exists */ + continue; + } + } CommandCost ret = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR); if (CmdFailed(ret)) return ret; cost.AddCost(ret); @@ -975,7 +998,7 @@ CommandCost CmdBuildRailStation(TileInde /* If DC_EXEC is in flag, do not want to pass it to CheckFlatLandBelow, because of a nice bug * for detail info, see: * https://sourceforge.net/tracker/index.php?func=detail&aid=1029064&group_id=103924&atid=636365 */ - CommandCost ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags & ~DC_EXEC, 5 << axis, _settings_game.station.nonuniform_stations ? &est : NULL); + CommandCost ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags & ~DC_EXEC, 5 << axis, _settings_game.station.nonuniform_stations ? &est : NULL, true, rt); if (CmdFailed(ret)) return ret; CommandCost cost(EXPENSES_CONSTRUCTION, ret.GetCost() + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len); @@ -1045,7 +1068,7 @@ CommandCost CmdBuildRailStation(TileInde /* Now really clear the land below the station * It should never return CMD_ERROR.. but you never know ;) * (a bit strange function name for it, but it really does clear the land, when DC_EXEC is in flags) */ - ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags, 5 << axis, _settings_game.station.nonuniform_stations ? &est : NULL); + ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags, 5 << axis, _settings_game.station.nonuniform_stations ? &est : NULL, true, rt); if (CmdFailed(ret)) return ret; st->train_station = new_location; diff --git a/src/unmovable_cmd.cpp b/src/unmovable_cmd.cpp --- a/src/unmovable_cmd.cpp +++ b/src/unmovable_cmd.cpp @@ -99,7 +99,7 @@ void UpdateCompanyHQ(Company *c, uint sc MarkTileDirtyByTile(tile + TileDiffXY(1, 1)); } -extern CommandCost CheckFlatLandBelow(TileIndex tile, uint w, uint h, DoCommandFlag flags, uint invalid_dirs, StationID *station, bool check_clear = true); +extern CommandCost CheckFlatLandBelow(TileIndex tile, uint w, uint h, DoCommandFlag flags, uint invalid_dirs, StationID *station, bool check_clear = true, RailType rt = INVALID_RAILTYPE); /** Build or relocate the HQ. This depends if the HQ is already built or not * @param tile tile where the HQ will be built or relocated to