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);