Index: src/station_cmd.cpp =================================================================== --- src/station_cmd.cpp (revision 27655) +++ src/station_cmd.cpp (working copy) @@ -2443,6 +2443,48 @@ return false; } +/** + * Ensure this tile is not a target for ships to get to a nearby dock. + * @note Also takes into account Oil Rigs, even those under construction. + * @param tile Tile to query + * @param diagdir Optional diagonal direction to look for axis compatibility. + * @return Succeeded if the tile is not a ship docking area of a nearby dock, + * or an error message if the tile is a ship docking area of a nearby + dock. + * @note If the axis of a provided diagdir is equal to the axis of a nearby + * docking area, it returns Succeeded. If diagdir is not provided, only + * the docking area location is ensured. + */ +static CommandCost EnsureNoDockingTile(TileIndex tile, DiagDirection diagdir = INVALID_DIAGDIR) +{ + Axis axis = diagdir == INVALID_DIAGDIR ? INVALID_AXIS : DiagDirToAxis(diagdir); + + for (DiagDirection rot = DIAGDIR_BEGIN; rot < DIAGDIR_END; rot++) { + TileIndex tc = TileAddByDiagDir(tile, rot); + if (IsTileType(tc, MP_STATION) && (IsDock(tc) || IsOilRig(tc))) { + Station *dock = Station::GetByTile(tc); + TileIndex docking_location = TILE_ADD(dock->dock_tile, ToTileIndexDiff(GetDockOffset(dock->dock_tile))); + if (axis == INVALID_AXIS) { + return_cmd_error(STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK); + } else { + if (tile == docking_location) { + Axis axis_tc = DiagDirToAxis(rot); + if (axis != axis_tc) { + return_cmd_error(STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK); + } + } + } + } + if (axis != AXIS_X && DiagDirToAxis(rot) == AXIS_X) { + if (IsTileType(tc + TileDiffXY(-1, 0), MP_INDUSTRY) && GetIndustryGfx(tc + TileDiffXY(-1, 0)) == GFX_OILRIG_1) { + return_cmd_error(STR_ERROR_SITE_UNSUITABLE); + } + } + } + + return CommandCost(); +} + static const TileIndexDiffC _dock_tileoffs_chkaround[] = { {-1, 0}, { 0, 0}, @@ -2493,6 +2535,10 @@ if (IsBridgeAbove(tile_cur)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); + /* Make sure there are no adjacent or incompatible ship docking areas */ + ret = EnsureNoDockingTile(tile_cur, direction); + if (ret.Failed()) return ret; + /* Get the water class of the water tile before it is cleared.*/ WaterClass wc = GetWaterClass(tile_cur);