|
@@ -332,12 +332,24 @@ void Ship::UpdateDeltaXY()
|
|
|
*/
|
|
|
static Vehicle *EnsureNoMovingShipProc(Vehicle *v, void *data)
|
|
|
{
|
|
|
return v->type == VEH_SHIP && (v->vehstatus & (VS_HIDDEN | VS_STOPPED)) == 0 ? v : nullptr;
|
|
|
}
|
|
|
|
|
|
static bool CheckReverseShip(const Ship *v)
|
|
|
{
|
|
|
/* Ask pathfinder for best direction */
|
|
|
bool reverse = false;
|
|
|
switch (_settings_game.pf.pathfinder_for_ships) {
|
|
|
case VPF_NPF: reverse = NPFShipCheckReverse(v); break;
|
|
|
case VPF_YAPF: reverse = YapfShipCheckReverse(v); break;
|
|
|
default: NOT_REACHED();
|
|
|
}
|
|
|
return reverse;
|
|
|
}
|
|
|
|
|
|
static bool CheckShipLeaveDepot(Ship *v)
|
|
|
{
|
|
|
if (!v->IsChainInDepot()) return false;
|
|
|
|
|
|
/* We are leaving a depot, but have to go to the exact same one; re-enter */
|
|
|
if (v->current_order.IsType(OT_GOTO_DEPOT) &&
|
|
@@ -361,20 +373,13 @@ static bool CheckShipLeaveDepot(Ship *v)
|
|
|
DiagDirection south_dir = AxisToDiagDir(axis);
|
|
|
TileIndex south_neighbour = TILE_ADD(tile, 2 * TileOffsByDiagDir(south_dir));
|
|
|
|
|
|
TrackBits north_tracks = DiagdirReachesTracks(north_dir) & GetTileShipTrackStatus(north_neighbour);
|
|
|
TrackBits south_tracks = DiagdirReachesTracks(south_dir) & GetTileShipTrackStatus(south_neighbour);
|
|
|
if (north_tracks && south_tracks) {
|
|
|
/* Ask pathfinder for best direction */
|
|
|
bool reverse = false;
|
|
|
switch (_settings_game.pf.pathfinder_for_ships) {
|
|
|
case VPF_NPF: reverse = NPFShipCheckReverse(v); break;
|
|
|
case VPF_YAPF: reverse = YapfShipCheckReverse(v); break;
|
|
|
default: NOT_REACHED();
|
|
|
}
|
|
|
if (reverse) north_tracks = TRACK_BIT_NONE;
|
|
|
if (CheckReverseShip(v)) north_tracks = TRACK_BIT_NONE;
|
|
|
}
|
|
|
|
|
|
if (north_tracks) {
|
|
|
/* Leave towards north */
|
|
|
v->rotation = v->direction = DiagDirToDir(north_dir);
|
|
|
} else if (south_tracks) {
|
|
@@ -621,21 +626,23 @@ bool IsShipDestinationTile(TileIndex til
|
|
|
static void ShipController(Ship *v)
|
|
|
{
|
|
|
uint32 r;
|
|
|
const byte *b;
|
|
|
Track track;
|
|
|
TrackBits tracks;
|
|
|
GetNewVehiclePosResult gp;
|
|
|
|
|
|
v->tick_counter++;
|
|
|
v->current_order_time++;
|
|
|
|
|
|
if (v->HandleBreakdown()) return;
|
|
|
|
|
|
if (v->vehstatus & VS_STOPPED) return;
|
|
|
|
|
|
ProcessOrders(v);
|
|
|
if (ProcessOrders(v) && CheckReverseShip(v)) goto reverse_direction;
|
|
|
|
|
|
v->HandleLoading();
|
|
|
|
|
|
if (v->current_order.IsType(OT_LOADING)) return;
|
|
|
|
|
|
if (CheckShipLeaveDepot(v)) return;
|
|
|
|
|
@@ -654,13 +661,13 @@ static void ShipController(Ship *v)
|
|
|
}
|
|
|
|
|
|
if (ShipMoveUpDownOnLock(v)) return;
|
|
|
|
|
|
if (!ShipAccelerate(v)) return;
|
|
|
|
|
|
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
|
|
|
gp = GetNewVehiclePos(v);
|
|
|
if (v->state != TRACK_BIT_WORMHOLE) {
|
|
|
/* Not on a bridge */
|
|
|
if (gp.old_tile == gp.new_tile) {
|
|
|
/* Staying in tile */
|
|
|
if (v->IsInDepot()) {
|
|
|
gp.x = v->x_pos;
|