summaryrefslogtreecommitdiff
path: root/src/ship_cmd.cpp
diff options
context:
space:
mode:
authorpeter1138 <peter1138@openttd.org>2019-03-11 10:37:47 +0000
committerNiels Martin Hansen <nielsm@indvikleren.dk>2019-06-30 16:46:32 +0200
commitf538179878370b3bec8bf1575dc30c1377461ebc (patch)
tree890738c37245a49eb2a8ad52f4afb805baaa9d42 /src/ship_cmd.cpp
parentf1c39153413b07a964dfde8fd9d6310f0da4987b (diff)
downloadopenttd-f538179878370b3bec8bf1575dc30c1377461ebc.tar.xz
Feature: Multi-tile docks and docking points.
Diffstat (limited to 'src/ship_cmd.cpp')
-rw-r--r--src/ship_cmd.cpp66
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();
}
}
}