diff options
Diffstat (limited to 'src/ship_cmd.cpp')
-rw-r--r-- | src/ship_cmd.cpp | 66 |
1 files changed, 44 insertions, 22 deletions
diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 08b07a07d..73f2ee97f 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -34,6 +34,8 @@ #include "tunnelbridge_map.h" #include "zoom_func.h" #include "framerate_type.h" +#include "industry.h" +#include "industry_map.h" #include "table/strings.h" @@ -289,8 +291,8 @@ TileIndex Ship::GetOrderStationLocation(StationID station) if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION; const Station *st = Station::Get(station); - if (st->dock_tile != INVALID_TILE) { - return TILE_ADD(st->dock_tile, ToTileIndexDiff(GetDockOffset(st->dock_tile))); + if (CanVehicleUseStation(this, st)) { + return st->xy; } else { this->IncrementRealOrderIndex(); return 0; @@ -597,6 +599,28 @@ static bool ShipMoveUpDownOnLock(Ship *v) return true; } +/** + * Test if a tile is a docking tile for the given station. + * @param tile Docking tile to test. + * @param station Destination station. + * @return true iff docking tile is next to station. + */ +bool IsShipDestinationTile(TileIndex tile, StationID station) +{ + assert(IsDockingTile(tile)); + /* Check each tile adjacent to docking tile. */ + 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 (IsTileType(t, MP_INDUSTRY)) { + const Industry *i = Industry::GetByTile(t); + if (i->neutral_station != nullptr && i->neutral_station->index == station) return true; + } + } + return false; +} + static void ShipController(Ship *v) { uint32 r; @@ -665,26 +689,24 @@ static void ShipController(Ship *v) UpdateVehicleTimetable(v, true); v->IncrementRealOrderIndex(); v->current_order.MakeDummy(); - } else { - /* Non-buoy orders really need to reach the tile */ - if (v->dest_tile == gp.new_tile) { - if (v->current_order.IsType(OT_GOTO_DEPOT)) { - if ((gp.x & 0xF) == 8 && (gp.y & 0xF) == 8) { - VehicleEnterDepot(v); - return; - } - } else if (v->current_order.IsType(OT_GOTO_STATION)) { - v->last_station_visited = v->current_order.GetDestination(); - - /* Process station in the orderlist. */ - Station *st = Station::Get(v->current_order.GetDestination()); - if (st->facilities & FACIL_DOCK) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations - ShipArrivesAt(v, st); - v->BeginLoading(); - } else { // leave stations without docks right aways - v->current_order.MakeLeaveStation(); - v->IncrementRealOrderIndex(); - } + } else if (v->current_order.IsType(OT_GOTO_DEPOT) && + v->dest_tile == gp.new_tile) { + /* Depot orders really need to reach the tile */ + if ((gp.x & 0xF) == 8 && (gp.y & 0xF) == 8) { + VehicleEnterDepot(v); + return; + } + } else if (v->current_order.IsType(OT_GOTO_STATION) && IsDockingTile(gp.new_tile)) { + /* Process station in the orderlist. */ + Station *st = Station::Get(v->current_order.GetDestination()); + if (st->docking_station.Contains(gp.new_tile) && IsShipDestinationTile(gp.new_tile, st->index)) { + v->last_station_visited = st->index; + if (st->facilities & FACIL_DOCK) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations + ShipArrivesAt(v, st); + v->BeginLoading(); + } else { // leave stations without docks right aways + v->current_order.MakeLeaveStation(); + v->IncrementRealOrderIndex(); } } } |