Index: src/station_cmd.cpp =================================================================== --- src/station_cmd.cpp (revision 27632) +++ src/station_cmd.cpp (working copy) @@ -2500,10 +2500,25 @@ if (ret.Failed()) return ret; tile_cur += TileOffsByDiagDir(direction); - if (!IsTileType(tile_cur, MP_WATER) || !IsTileFlat(tile_cur)) { + if (!IsTileType(tile_cur, MP_WATER) || (!IsTileFlat(tile_cur) && !IsSlopeWithOneCornerRaised(GetTileSlope(tile_cur)))) { return_cmd_error(STR_ERROR_SITE_UNSUITABLE); } + TileIndex tc = tile_cur; + DiagDirection dir_rotate = ReverseDiagDir(direction); + ret = EnsureNoShipFromDiagDir(tc, dir_rotate); + if (ret.Failed()) return ret; + + tc = dir_rotate == DIAGDIR_NE ? tc + TileDiffXY(-1, -1) : dir_rotate == DIAGDIR_NW ? tc + TileDiffXY(1, -1) : dir_rotate == DIAGDIR_SW ? tc + TileDiffXY(1, 1) : tc + TileDiffXY(-1, 1); + dir_rotate = ChangeDiagDir(dir_rotate, DIAGDIRDIFF_90RIGHT); + ret = EnsureNoShipFromDiagDir(tc, dir_rotate); + if (ret.Failed()) return ret; + + tc = dir_rotate == DIAGDIR_NE ? tc + TileDiffXY(-2, 0) : dir_rotate == DIAGDIR_NW ? tc + TileDiffXY(0, -2) : dir_rotate == DIAGDIR_SW ? tc + TileDiffXY(2, 0) : tc + TileDiffXY(0, 2); + dir_rotate = ReverseDiagDir(dir_rotate); + ret = EnsureNoShipFromDiagDir(tc, dir_rotate); + if (ret.Failed()) return ret; + TileArea dock_area = TileArea(tile + ToTileIndexDiff(_dock_tileoffs_chkaround[direction]), _dock_w_chk[direction], _dock_h_chk[direction]); Index: src/vehicle.cpp =================================================================== --- src/vehicle.cpp (revision 27632) +++ src/vehicle.cpp (working copy) @@ -484,6 +484,24 @@ return CommandCost(); } +/** +* Ensure there is no ship coming from or going to the given diagonal direction. +* @param tile Position to examine. +* @param diag_dir Diagonal direction +* @return Succeeded command (water is free) or failed command (a ship is found). +*/ +CommandCost EnsureNoShipFromDiagDir(TileIndex tile, DiagDirection diag_dir) +{ + if (HasTileWaterClass(tile)) { + TrackBits tb = TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0)); + if (((diag_dir == DIAGDIR_NE && (tb & TRACK_BIT_3WAY_NE) != 0) || (diag_dir == DIAGDIR_SE && (tb & TRACK_BIT_3WAY_SE) != 0) || (diag_dir == DIAGDIR_NW && (tb & TRACK_BIT_3WAY_NW) != 0) || (diag_dir == DIAGDIR_SW && (tb & TRACK_BIT_3WAY_SW) != 0)) && !IsShipDepotTile(tile) && IsTileType(tile, MP_WATER) && !IsLock(tile)) { + CommandCost ret = EnsureNoVehicleOnGround(tile); + if (ret.Failed()) return ret; + } + } + return CommandCost(); +} + /** Procedure called for every vehicle found in tunnel/bridge in the hash map */ static Vehicle *GetVehicleTunnelBridgeProc(Vehicle *v, void *data) { Index: src/vehicle_func.h =================================================================== --- src/vehicle_func.h (revision 27632) +++ src/vehicle_func.h (working copy) @@ -165,6 +165,7 @@ CommandCost EnsureNoVehicleOnGround(TileIndex tile); CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits); +CommandCost EnsureNoShipFromDiagDir(TileIndex tile, DiagDirection diag_dir); extern VehicleID _new_vehicle_id; extern uint16 _returned_refit_capacity; Index: src/water_cmd.cpp =================================================================== --- src/water_cmd.cpp (revision 27632) +++ src/water_cmd.cpp (working copy) @@ -135,6 +135,24 @@ cost.AddCost(ret); } + DiagDirection dir_rotate = axis == AXIS_X ? DIAGDIR_SE : DIAGDIR_NE; + TileIndex tc = tile + (axis == AXIS_X ? TileDiffXY(0, -1) : TileDiffXY(1, 0)); + ret = EnsureNoShipFromDiagDir(tc, dir_rotate); + if (ret.Failed()) return ret; + + tc = tile2 + (axis == AXIS_X ? TileDiffXY(0, -1) : TileDiffXY(1, 0)); + ret = EnsureNoShipFromDiagDir(tc, dir_rotate); + if (ret.Failed()) return ret; + + dir_rotate = ReverseDiagDir(dir_rotate); + tc = tile + (axis == AXIS_X ? TileDiffXY(0, 1) : TileDiffXY(-1, 0)); + ret = EnsureNoShipFromDiagDir(tc, dir_rotate); + if (ret.Failed()) return ret; + + tc = tile2 + (axis == AXIS_X ? TileDiffXY(0, 1) : TileDiffXY(-1, 0)); + ret = EnsureNoShipFromDiagDir(tc, dir_rotate); + if (ret.Failed()) return ret; + if (flags & DC_EXEC) { Depot *depot = new Depot(tile); depot->build_date = _date; @@ -372,6 +390,25 @@ DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile)); if (dir == INVALID_DIAGDIR) return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION); + Axis axis = DiagDirToAxis(dir); + DiagDirection dir_rotate = (dir == DIAGDIR_NE || dir == DIAGDIR_NW) ? ChangeDiagDir(dir, DIAGDIRDIFF_90RIGHT) : ChangeDiagDir(dir, DIAGDIRDIFF_90LEFT); + TileIndex tc = tile + (axis == AXIS_X ? TileDiffXY(-1, -1) : TileDiffXY(1, -1)); + CommandCost ret = EnsureNoShipFromDiagDir(tc, dir_rotate); + if (ret.Failed()) return ret; + + tc = tile + (axis == AXIS_X ? TileDiffXY(1, -1) : TileDiffXY(1, 1)); + ret = EnsureNoShipFromDiagDir(tc, dir_rotate); + if (ret.Failed()) return ret; + + dir_rotate = ReverseDiagDir(dir_rotate); + tc = tile + (axis == AXIS_X ? TileDiffXY(-1, 1) : TileDiffXY(-1, -1)); + ret = EnsureNoShipFromDiagDir(tc, dir_rotate); + if (ret.Failed()) return ret; + + tc = tile + (axis == AXIS_X ? TileDiffXY(1, 1) : TileDiffXY(-1, 1)); + ret = EnsureNoShipFromDiagDir(tc, dir_rotate); + if (ret.Failed()) return ret; + return DoBuildLock(tile, dir, flags); }