From ec2656ab7ef6d924f3c30624bf1d3c7449403c6f Mon Sep 17 00:00:00 2001 From: peter1138 Date: Sat, 6 Apr 2019 23:33:09 +0100 Subject: [PATCH] Codechange: Restrict docking points of docks. --- src/ship_cmd.cpp | 2 +- src/station_cmd.cpp | 22 ++++++++++++++++++++++ src/station_func.h | 1 + src/water_cmd.cpp | 2 +- 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 73f2ee97f2..7b6be3a41a 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -612,7 +612,7 @@ bool IsShipDestinationTile(TileIndex tile, StationID station) for (DiagDirection d = DIAGDIR_BEGIN; d != DIAGDIR_END; d++) { TileIndex t = tile + TileOffsByDiagDir(d); if (!IsValidTile(t)) continue; - if (IsDockTile(t) && GetStationIndex(t) == station) return true; + if (IsDockTile(t) && GetStationIndex(t) == station && IsValidDockingDirectionForDock(t, d)) return true; if (IsTileType(t, MP_INDUSTRY)) { const Industry *i = Industry::GetByTile(t); if (i->neutral_station != nullptr && i->neutral_station->index == station) return true; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index a7d9866761..546aecc269 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2631,6 +2631,28 @@ void ClearDockingTilesCheckingNeighbours(TileIndex tile) } } +/** + * Check if a dock tile can be docked from the given direction. + * @param t Tile index of dock. + * @param d DiagDirection adjacent to dock being tested. + * @return True iff the dock can be docked from the given direction. + */ +bool IsValidDockingDirectionForDock(TileIndex t, DiagDirection d) +{ + assert(IsDockTile(t)); + + /** Bitmap of valid directions for each dock tile part. */ + static const uint8 _valid_docking_tile[] = { + 0, 0, 0, 0, // No docking against the slope part. + 1 << DIAGDIR_NE | 1 << DIAGDIR_SW, // Docking permitted at the end + 1 << DIAGDIR_NW | 1 << DIAGDIR_SE, // of the flat piers. + }; + + StationGfx gfx = GetStationGfx(t); + assert(gfx < lengthof(_valid_docking_tile)); + return HasBit(_valid_docking_tile[gfx], d); +} + /** * Find the part of a dock that is land-based * @param t Dock tile to find land part of diff --git a/src/station_func.h b/src/station_func.h index 44aec087fe..86aae1e56e 100644 --- a/src/station_func.h +++ b/src/station_func.h @@ -43,6 +43,7 @@ void DeleteOilRig(TileIndex t); void UpdateStationDockingTiles(Station *st); void RemoveDockingTile(TileIndex t); void ClearDockingTilesCheckingNeighbours(TileIndex tile); +bool IsValidDockingDirectionForDock(TileIndex t, DiagDirection d); /* Check if a rail station tile is traversable. */ bool IsStationTileBlocked(TileIndex tile); diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 158bd13f03..7091f9f2d4 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -187,7 +187,7 @@ void CheckForDockingTile(TileIndex t) TileIndex tile = t + TileOffsByDiagDir(d); if (!IsValidTile(tile)) continue; - if (IsDockTile(tile)) { + if (IsDockTile(tile) && IsValidDockingDirectionForDock(tile, d)) { Station::GetByTile(tile)->docking_station.Add(t); SetDockingTile(t, true); }