Feature: Multi-tile docks and docking points.

This commit is contained in:
peter1138
2019-03-11 10:37:47 +00:00
committed by Niels Martin Hansen
parent f1c3915341
commit f538179878
27 changed files with 471 additions and 80 deletions

View File

@@ -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();
}
}
}