Update to 1.10.0-beta1
This commit is contained in:
103
src/ship_cmd.cpp
103
src/ship_cmd.cpp
@@ -29,12 +29,13 @@
|
||||
#include "sound_func.h"
|
||||
#include "ai/ai.hpp"
|
||||
#include "game/game.hpp"
|
||||
#include "pathfinder/opf/opf_ship.h"
|
||||
#include "engine_base.h"
|
||||
#include "company_base.h"
|
||||
#include "tunnelbridge_map.h"
|
||||
#include "zoom_func.h"
|
||||
#include "framerate_type.h"
|
||||
#include "industry.h"
|
||||
#include "industry_map.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
@@ -146,7 +147,7 @@ static const Depot *FindClosestShipDepot(const Vehicle *v, uint max_distance)
|
||||
{
|
||||
/* Find the closest depot */
|
||||
const Depot *depot;
|
||||
const Depot *best_depot = NULL;
|
||||
const Depot *best_depot = nullptr;
|
||||
/* If we don't have a maximum distance, i.e. distance = 0,
|
||||
* we want to find any depot so the best distance of no
|
||||
* depot must be more than any correct distance. On the
|
||||
@@ -178,7 +179,6 @@ static void CheckIfShipNeedsService(Vehicle *v)
|
||||
|
||||
uint max_distance;
|
||||
switch (_settings_game.pf.pathfinder_for_ships) {
|
||||
case VPF_OPF: max_distance = 12; break;
|
||||
case VPF_NPF: max_distance = _settings_game.pf.npf.maximum_go_to_depot_penalty / NPF_TILE_LENGTH; break;
|
||||
case VPF_YAPF: max_distance = _settings_game.pf.yapf.maximum_go_to_depot_penalty / YAPF_TILE_LENGTH; break;
|
||||
default: NOT_REACHED();
|
||||
@@ -186,7 +186,7 @@ static void CheckIfShipNeedsService(Vehicle *v)
|
||||
|
||||
const Depot *depot = FindClosestShipDepot(v, max_distance);
|
||||
|
||||
if (depot == NULL) {
|
||||
if (depot == nullptr) {
|
||||
if (v->current_order.IsType(OT_GOTO_DEPOT)) {
|
||||
v->current_order.MakeDummy();
|
||||
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
|
||||
@@ -291,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;
|
||||
@@ -335,7 +335,7 @@ void Ship::UpdateDeltaXY()
|
||||
*/
|
||||
static Vehicle *EnsureNoVisibleShipProc(Vehicle *v, void *data)
|
||||
{
|
||||
return v->type == VEH_SHIP && (v->vehstatus & VS_HIDDEN) == 0 ? v : NULL;
|
||||
return v->type == VEH_SHIP && (v->vehstatus & VS_HIDDEN) == 0 ? v : nullptr;
|
||||
}
|
||||
|
||||
static bool CheckShipLeaveDepot(Ship *v)
|
||||
@@ -354,7 +354,7 @@ static bool CheckShipLeaveDepot(Ship *v)
|
||||
|
||||
/* Don't leave depot if another vehicle is already entering/leaving */
|
||||
/* This helps avoid CPU load if many ships are set to start at the same time */
|
||||
if (HasVehicleOnPos(v->tile, NULL, &EnsureNoVisibleShipProc)) return true;
|
||||
if (HasVehicleOnPos(v->tile, nullptr, &EnsureNoVisibleShipProc)) return true;
|
||||
|
||||
TileIndex tile = v->tile;
|
||||
Axis axis = GetShipDepotAxis(tile);
|
||||
@@ -369,9 +369,7 @@ static bool CheckShipLeaveDepot(Ship *v)
|
||||
if (north_tracks && south_tracks) {
|
||||
/* Ask pathfinder for best direction */
|
||||
bool reverse = false;
|
||||
bool path_found;
|
||||
switch (_settings_game.pf.pathfinder_for_ships) {
|
||||
case VPF_OPF: reverse = OPFShipChooseTrack(v, north_neighbour, north_dir, north_tracks, path_found) == INVALID_TRACK; break; // OPF always allows reversing
|
||||
case VPF_NPF: reverse = NPFShipCheckReverse(v); break;
|
||||
case VPF_YAPF: reverse = YapfShipCheckReverse(v); break;
|
||||
default: NOT_REACHED();
|
||||
@@ -470,18 +468,11 @@ static Track ChooseShipTrack(Ship *v, TileIndex tile, DiagDirection enterdir, Tr
|
||||
bool path_found = true;
|
||||
Track track;
|
||||
|
||||
if (v->dest_tile == 0 || DistanceManhattan(tile, v->dest_tile) > SHIP_MAX_ORDER_DISTANCE + 5) {
|
||||
/* No destination or destination too far, don't invoke pathfinder. */
|
||||
if (v->dest_tile == 0) {
|
||||
/* No destination, don't invoke pathfinder. */
|
||||
track = TrackBitsToTrack(v->state);
|
||||
if (!IsDiagonalTrack(track)) track = TrackToOppositeTrack(track);
|
||||
if (!HasBit(tracks, track)) {
|
||||
/* Can't continue in same direction so pick first available track. */
|
||||
if (_settings_game.pf.forbid_90_deg) {
|
||||
tracks &= ~TrackCrossesTracks(TrackdirToTrack(v->GetVehicleTrackdir()));
|
||||
if (tracks == TRACK_BIT_NONE) return INVALID_TRACK;
|
||||
}
|
||||
track = FindFirstTrack(tracks);
|
||||
}
|
||||
if (!HasBit(tracks, track)) track = FindFirstTrack(tracks);
|
||||
path_found = false;
|
||||
} else {
|
||||
/* Attempt to follow cached path. */
|
||||
@@ -499,7 +490,6 @@ static Track ChooseShipTrack(Ship *v, TileIndex tile, DiagDirection enterdir, Tr
|
||||
}
|
||||
|
||||
switch (_settings_game.pf.pathfinder_for_ships) {
|
||||
case VPF_OPF: track = OPFShipChooseTrack(v, tile, enterdir, tracks, path_found); break;
|
||||
case VPF_NPF: track = NPFShipChooseTrack(v, path_found); break;
|
||||
case VPF_YAPF: track = YapfShipChooseTrack(v, tile, enterdir, tracks, path_found, v->path); break;
|
||||
default: NOT_REACHED();
|
||||
@@ -521,9 +511,6 @@ static inline TrackBits GetAvailShipTracks(TileIndex tile, DiagDirection dir, Tr
|
||||
{
|
||||
TrackBits tracks = GetTileShipTrackStatus(tile) & DiagdirReachesTracks(dir);
|
||||
|
||||
/* Do not remove 90 degree turns for OPF, as it isn't able to find paths taking it into account. */
|
||||
if (_settings_game.pf.forbid_90_deg && _settings_game.pf.pathfinder_for_ships != VPF_OPF) tracks &= ~TrackCrossesTracks(TrackdirToTrack(trackdir));
|
||||
|
||||
return tracks;
|
||||
}
|
||||
|
||||
@@ -612,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 && IsValidDockingDirectionForDock(t, d)) 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;
|
||||
@@ -680,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 away
|
||||
v->current_order.MakeLeaveStation();
|
||||
v->IncrementRealOrderIndex();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -767,7 +774,7 @@ static void ShipController(Ship *v)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ship is back on the bridge head, we need to comsume its path
|
||||
/* Ship is back on the bridge head, we need to consume its path
|
||||
* cache entry here as we didn't have to choose a ship track. */
|
||||
if (!v->path.empty()) v->path.pop_front();
|
||||
}
|
||||
@@ -884,10 +891,10 @@ bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, boo
|
||||
{
|
||||
const Depot *depot = FindClosestShipDepot(this, 0);
|
||||
|
||||
if (depot == NULL) return false;
|
||||
if (depot == nullptr) return false;
|
||||
|
||||
if (location != NULL) *location = depot->xy;
|
||||
if (destination != NULL) *destination = depot->index;
|
||||
if (location != nullptr) *location = depot->xy;
|
||||
if (destination != nullptr) *destination = depot->index;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user