1
0
Fork 0

Change: Adapt how ships enter and leave extended depots.

pull/8480/head
J0anJosep 2020-12-24 00:45:07 +01:00
parent 3715dcf2d7
commit 8a9a627577
1 changed files with 52 additions and 32 deletions

View File

@ -374,6 +374,12 @@ static bool CheckReverseShip(const Ship *v, Trackdir *trackdir = nullptr)
return YapfShipCheckReverse(v, trackdir); return YapfShipCheckReverse(v, trackdir);
} }
static bool CheckPlaceShipOnDepot(TileIndex tile)
{
assert(IsShipDepotTile(tile));
return !IsExtendedDepot(tile) || IsExtendedDepotEmpty(tile);
}
void HandleShipEnterDepot(Ship *v) void HandleShipEnterDepot(Ship *v)
{ {
assert(IsShipDepotTile(v->tile)); assert(IsShipDepotTile(v->tile));
@ -403,45 +409,55 @@ static bool CheckShipLeaveDepot(Ship *v)
/* We are leaving a depot, but have to go to the exact same one; re-enter */ /* We are leaving a depot, but have to go to the exact same one; re-enter */
if (v->current_order.IsType(OT_GOTO_DEPOT) && if (v->current_order.IsType(OT_GOTO_DEPOT) &&
IsShipDepotTile(v->tile) && GetDepotIndex(v->tile) == v->current_order.GetDestination()) { IsShipDepotTile(v->tile) && GetDepotIndex(v->tile) == v->current_order.GetDestination()) {
VehicleEnterDepot(v); HandleShipEnterDepot(v);
return true; return true;
} }
/* Don't leave depot if no destination set */ /* Don't leave depot if no destination set */
if (v->dest_tile == 0) return true; if (v->dest_tile == 0) return true;
/* Don't leave depot if another vehicle is already entering/leaving */ if (!IsExtendedDepot(v->tile)) {
/* This helps avoid CPU load if many ships are set to start at the same time */ /* Don't leave depot if another vehicle is already entering/leaving */
if (HasVehicleOnPos(v->tile, nullptr, &EnsureNoMovingShipProc)) return true; /* This helps avoid CPU load if many ships are set to start at the same time */
if (HasVehicleOnPos(v->tile, nullptr, &EnsureNoMovingShipProc)) return true;
TileIndex tile = v->tile; TileIndex tile = v->tile;
Axis axis = GetShipDepotAxis(tile); Axis axis = GetShipDepotAxis(tile);
bool reverse = false;
DiagDirection north_dir = ReverseDiagDir(AxisToDiagDir(axis)); DiagDirection north_dir = ReverseDiagDir(AxisToDiagDir(axis));
TileIndex north_neighbour = TileAdd(tile, TileOffsByDiagDir(north_dir)); TileIndex north_neighbour = TileAdd(tile, TileOffsByDiagDir(north_dir));
DiagDirection south_dir = AxisToDiagDir(axis); DiagDirection south_dir = AxisToDiagDir(axis);
TileIndex south_neighbour = TileAdd(tile, 2 * TileOffsByDiagDir(south_dir)); TileIndex south_neighbour = TileAdd(tile, 2 * TileOffsByDiagDir(south_dir));
TrackBits north_tracks = DiagdirReachesTracks(north_dir) & GetTileShipTrackStatus(north_neighbour); TrackBits north_tracks = DiagdirReachesTracks(north_dir) & GetTileShipTrackStatus(north_neighbour);
TrackBits south_tracks = DiagdirReachesTracks(south_dir) & GetTileShipTrackStatus(south_neighbour); TrackBits south_tracks = DiagdirReachesTracks(south_dir) & GetTileShipTrackStatus(south_neighbour);
if (north_tracks && south_tracks) { if (north_tracks && south_tracks) {
if (CheckReverseShip(v)) 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) {
/* Leave towards south */
v->rotation = v->direction = DiagDirToDir(south_dir);
} else {
/* Both ways blocked */
return false;
}
v->state = AxisToTrackBits(axis);
v->vehstatus &= ~VS_HIDDEN;
/* Leave towards south if reverse. */
v->rotation = v->direction = DiagDirToDir(reverse ? south_dir : north_dir);
v->state = AxisToTrackBits(axis);
v->vehstatus &= ~VS_HIDDEN;
} }
if (north_tracks) { v->state &= ~TRACK_BIT_DEPOT;
/* Leave towards north */
v->rotation = v->direction = DiagDirToDir(north_dir);
} else if (south_tracks) {
/* Leave towards south */
v->rotation = v->direction = DiagDirToDir(south_dir);
} else {
/* Both ways blocked */
return false;
}
v->state = AxisToTrackBits(axis);
v->vehstatus &= ~VS_HIDDEN;
v->cur_speed = 0; v->cur_speed = 0;
v->UpdateViewport(true, true); v->UpdateViewport(true, true);
DepotID depot_id = GetDepotIndex(v->tile); DepotID depot_id = GetDepotIndex(v->tile);
@ -733,6 +749,8 @@ static void ShipController(Ship *v)
if (v->vehstatus & VS_STOPPED) return; if (v->vehstatus & VS_STOPPED) return;
if (v->ContinueServicing()) return;
if (ProcessOrders(v) && CheckReverseShip(v)) return ReverseShip(v); if (ProcessOrders(v) && CheckReverseShip(v)) return ReverseShip(v);
v->HandleLoading(); v->HandleLoading();
@ -816,10 +834,12 @@ static void ShipController(Ship *v)
IsShipDepotTile(gp.new_tile) && IsShipDepotTile(gp.new_tile) &&
GetOtherShipDepotTile(gp.new_tile) == gp.old_tile && GetOtherShipDepotTile(gp.new_tile) == gp.old_tile &&
v->current_order.GetDestination() == GetDepotIndex(gp.new_tile)) { v->current_order.GetDestination() == GetDepotIndex(gp.new_tile)) {
HandleShipEnterDepot(v); if (CheckPlaceShipOnDepot(v->tile)) {
v->UpdatePosition(); HandleShipEnterDepot(v);
v->UpdateViewport(true, true); v->UpdatePosition();
return; v->UpdateViewport(true, true);
return;
}
} }
const DiagDirection diagdir = DiagdirBetweenTiles(gp.old_tile, gp.new_tile); const DiagDirection diagdir = DiagdirBetweenTiles(gp.old_tile, gp.new_tile);