Codechange: refactor FindClosestDepot to not use pointers, but return a struct

This commit is contained in:
Rubidium 2023-01-03 22:33:09 +01:00 committed by rubidium42
parent b3907b1359
commit 375a5b8e3f
12 changed files with 69 additions and 82 deletions

View File

@ -110,7 +110,7 @@ struct Aircraft FINAL : public SpecializedVehicle<Aircraft, VEH_AIRCRAFT> {
void OnNewDay();
uint Crash(bool flooded = false);
TileIndex GetOrderStationLocation(StationID station);
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
ClosestDepot FindClosestDepot();
/**
* Check if the aircraft type is a normal flying device; eg

View File

@ -388,7 +388,7 @@ CommandCost CmdBuildAircraft(DoCommandFlag flags, TileIndex tile, const Engine *
}
bool Aircraft::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)
ClosestDepot Aircraft::FindClosestDepot()
{
const Station *st = GetTargetAirportIfValid(this);
/* If the station is not a valid airport or if it has no hangars */
@ -396,15 +396,12 @@ bool Aircraft::FindClosestDepot(TileIndex *location, DestinationID *destination,
/* the aircraft has to search for a hangar on its own */
StationID station = FindNearestHangar(this);
if (station == INVALID_STATION) return false;
if (station == INVALID_STATION) return ClosestDepot();
st = Station::Get(station);
}
if (location != nullptr) *location = st->xy;
if (destination != nullptr) *destination = st->index;
return true;
return ClosestDepot(st->xy, st->index);
}
static void CheckIfAircraftNeedsService(Aircraft *v)

View File

@ -1982,23 +1982,21 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool
if (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
/* We need to search for the nearest depot (hangar). */
TileIndex location;
DestinationID destination;
bool reverse;
ClosestDepot closestDepot = v->FindClosestDepot();
if (v->FindClosestDepot(&location, &destination, &reverse)) {
if (closestDepot.found) {
/* PBS reservations cannot reverse */
if (pbs_look_ahead && reverse) return false;
if (pbs_look_ahead && closestDepot.reverse) return false;
v->SetDestTile(location);
v->current_order.SetDestination(destination);
v->SetDestTile(closestDepot.location);
v->current_order.SetDestination(closestDepot.destination);
/* If there is no depot in front, reverse automatically (trains only) */
if (v->type == VEH_TRAIN && reverse) Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(DC_EXEC, v->index, false);
if (v->type == VEH_TRAIN && closestDepot.reverse) Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(DC_EXEC, v->index, false);
if (v->type == VEH_AIRCRAFT) {
Aircraft *a = Aircraft::From(v);
if (a->state == FLYING && a->targetairport != destination) {
if (a->state == FLYING && a->targetairport != closestDepot.destination) {
/* The aircraft is now heading for a different hangar than the next in the orders */
extern void AircraftNextAirportPos_and_Order(Aircraft *a);
AircraftNextAirportPos_and_Order(a);

View File

@ -139,7 +139,7 @@ struct RoadVehicle FINAL : public GroundVehicle<RoadVehicle, VEH_ROAD> {
uint Crash(bool flooded = false) override;
Trackdir GetVehicleTrackdir() const override;
TileIndex GetOrderStationLocation(StationID station) override;
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) override;
ClosestDepot FindClosestDepot() override;
bool IsBus() const;

View File

@ -346,15 +346,12 @@ static FindDepotData FindClosestRoadDepot(const RoadVehicle *v, int max_distance
}
}
bool RoadVehicle::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)
ClosestDepot RoadVehicle::FindClosestDepot()
{
FindDepotData rfdd = FindClosestRoadDepot(this, 0);
if (rfdd.best_length == UINT_MAX) return false;
if (rfdd.best_length == UINT_MAX) return ClosestDepot();
if (location != nullptr) *location = rfdd.tile;
if (destination != nullptr) *destination = GetDepotIndex(rfdd.tile);
return true;
return ClosestDepot(rfdd.tile, GetDepotIndex(rfdd.tile));
}
/**

View File

@ -3185,17 +3185,15 @@ bool AfterLoadGame()
TileIndex cur_tile = rv->tile;
if (!IsLevelCrossingTile(cur_tile)) continue;
TileIndex location;
DestinationID destination;
bool reverse = true;
ClosestDepot closestDepot = rv->FindClosestDepot();
/* Try to find a depot with a distance limit of 512 tiles (Manhattan distance). */
if (rv->FindClosestDepot(&location, &destination, &reverse) && DistanceManhattan(rv->tile, location) < 512u) {
if (closestDepot.found && DistanceManhattan(rv->tile, closestDepot.location) < 512u) {
/* Teleport all parts of articulated vehicles. */
for (RoadVehicle *u = rv; u != nullptr; u = u->Next()) {
u->tile = location;
int x = TileX(location) * TILE_SIZE + TILE_SIZE / 2;
int y = TileY(location) * TILE_SIZE + TILE_SIZE / 2;
u->tile = closestDepot.location;
int x = TileX(closestDepot.location) * TILE_SIZE + TILE_SIZE / 2;
int y = TileY(closestDepot.location) * TILE_SIZE + TILE_SIZE / 2;
u->x_pos = x;
u->y_pos = y;
u->z_pos = GetSlopePixelZ(x, y);

View File

@ -35,24 +35,24 @@ struct Ship FINAL : public SpecializedVehicle<Ship, VEH_SHIP> {
/** We want to 'destruct' the right class. */
virtual ~Ship() { this->PreDestructor(); }
void MarkDirty();
void UpdateDeltaXY();
ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_SHIP_REVENUE : EXPENSES_SHIP_RUN; }
void PlayLeaveStationSound(bool force = false) const;
bool IsPrimaryVehicle() const { return true; }
void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const;
int GetDisplaySpeed() const { return this->cur_speed / 2; }
int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed / 2; }
int GetCurrentMaxSpeed() const { return std::min<int>(this->vcache.cached_max_speed, this->current_order.GetMaxSpeed() * 2); }
Money GetRunningCost() const;
bool IsInDepot() const { return this->state == TRACK_BIT_DEPOT; }
bool Tick();
void OnNewDay();
Trackdir GetVehicleTrackdir() const;
TileIndex GetOrderStationLocation(StationID station);
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
void MarkDirty() override;
void UpdateDeltaXY() override;
ExpensesType GetExpenseType(bool income) const override { return income ? EXPENSES_SHIP_REVENUE : EXPENSES_SHIP_RUN; }
void PlayLeaveStationSound(bool force = false) const override;
bool IsPrimaryVehicle() const override { return true; }
void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const override;
int GetDisplaySpeed() const override { return this->cur_speed / 2; }
int GetDisplayMaxSpeed() const override { return this->vcache.cached_max_speed / 2; }
int GetCurrentMaxSpeed() const override { return std::min<int>(this->vcache.cached_max_speed, this->current_order.GetMaxSpeed() * 2); }
Money GetRunningCost() const override;
bool IsInDepot() const override { return this->state == TRACK_BIT_DEPOT; }
bool Tick() override;
void OnNewDay() override;
Trackdir GetVehicleTrackdir() const override;
TileIndex GetOrderStationLocation(StationID station) override;
ClosestDepot FindClosestDepot() override;
void UpdateCache();
void SetDestTile(TileIndex tile);
void SetDestTile(TileIndex tile) override;
};
bool IsShipDestinationTile(TileIndex tile, StationID station);

View File

@ -913,14 +913,10 @@ CommandCost CmdBuildShip(DoCommandFlag flags, TileIndex tile, const Engine *e, V
return CommandCost();
}
bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)
ClosestDepot Ship::FindClosestDepot()
{
const Depot *depot = FindClosestShipDepot(this, 0);
if (depot == nullptr) return ClosestDepot();
if (depot == nullptr) return false;
if (location != nullptr) *location = depot->xy;
if (destination != nullptr) *destination = depot->index;
return true;
return ClosestDepot(depot->xy, depot->index);
}

View File

@ -124,7 +124,7 @@ struct Train FINAL : public GroundVehicle<Train, VEH_TRAIN> {
uint Crash(bool flooded = false) override;
Trackdir GetVehicleTrackdir() const override;
TileIndex GetOrderStationLocation(StationID station) override;
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) override;
ClosestDepot FindClosestDepot() override;
void ReserveTrackUnderConsist() const;

View File

@ -2106,23 +2106,12 @@ static FindDepotData FindClosestTrainDepot(Train *v, int max_distance)
}
}
/**
* Locate the closest depot for this consist, and return the information to the caller.
* @param[out] location If not \c nullptr and a depot is found, store its location in the given address.
* @param[out] destination If not \c nullptr and a depot is found, store its index in the given address.
* @param[out] reverse If not \c nullptr and a depot is found, store reversal information in the given address.
* @return A depot has been found.
*/
bool Train::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)
ClosestDepot Train::FindClosestDepot()
{
FindDepotData tfdd = FindClosestTrainDepot(this, 0);
if (tfdd.best_length == UINT_MAX) return false;
if (tfdd.best_length == UINT_MAX) return ClosestDepot();
if (location != nullptr) *location = tfdd.tile;
if (destination != nullptr) *destination = GetDepotIndex(tfdd.tile);
if (reverse != nullptr) *reverse = tfdd.reverse;
return true;
return ClosestDepot(tfdd.tile, GetDepotIndex(tfdd.tile), tfdd.reverse);
}
/** Play a sound for a train leaving the station. */

View File

@ -2423,11 +2423,9 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command)
return CommandCost();
}
TileIndex location;
DestinationID destination;
bool reverse;
ClosestDepot closestDepot = this->FindClosestDepot();
static const StringID no_depot[] = {STR_ERROR_UNABLE_TO_FIND_ROUTE_TO, STR_ERROR_UNABLE_TO_FIND_LOCAL_DEPOT, STR_ERROR_UNABLE_TO_FIND_LOCAL_DEPOT, STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR};
if (!this->FindClosestDepot(&location, &destination, &reverse)) return_cmd_error(no_depot[this->type]);
if (!closestDepot.found) return_cmd_error(no_depot[this->type]);
if (flags & DC_EXEC) {
if (this->current_order.IsType(OT_LOADING)) this->LeaveStation();
@ -2437,19 +2435,19 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command)
SetBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
}
this->SetDestTile(location);
this->current_order.MakeGoToDepot(destination, ODTF_MANUAL);
this->SetDestTile(closestDepot.location);
this->current_order.MakeGoToDepot(closestDepot.destination, ODTF_MANUAL);
if ((command & DepotCommand::Service) == DepotCommand::None) this->current_order.SetDepotActionType(ODATFB_HALT);
SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
/* If there is no depot in front and the train is not already reversing, reverse automatically (trains only) */
if (this->type == VEH_TRAIN && (reverse ^ HasBit(Train::From(this)->flags, VRF_REVERSING))) {
if (this->type == VEH_TRAIN && (closestDepot.reverse ^ HasBit(Train::From(this)->flags, VRF_REVERSING))) {
Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(DC_EXEC, this->index, false);
}
if (this->type == VEH_AIRCRAFT) {
Aircraft *a = Aircraft::From(this);
if (a->state == FLYING && a->targetairport != destination) {
if (a->state == FLYING && a->targetairport != closestDepot.destination) {
/* The aircraft is now heading for a different hangar than the next in the orders */
extern void AircraftNextAirportPos_and_Order(Aircraft *a);
AircraftNextAirportPos_and_Order(a);

View File

@ -220,6 +220,23 @@ struct RefitDesc {
cargo(cargo), capacity(capacity), remaining(remaining) {}
};
/**
* Structure to return information about the closest depot location,
* and whether it could be found.
*/
struct ClosestDepot {
TileIndex location;
DestinationID destination; ///< The DestinationID as used for orders.
bool reverse;
bool found;
ClosestDepot() :
location(INVALID_TILE), destination(0), reverse(false), found(false) {}
ClosestDepot(TileIndex location, DestinationID destination, bool reverse = false) :
location(location), destination(destination), reverse(reverse), found(true) {}
};
/** %Vehicle data structure. */
struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle, BaseConsist {
private:
@ -771,12 +788,9 @@ public:
/**
* Find the closest depot for this vehicle and tell us the location,
* DestinationID and whether we should reverse.
* @param location where do we go to?
* @param destination what hangar do we go to?
* @param reverse should the vehicle be reversed?
* @return true if a depot could be found.
* @return A structure with information about the closest depot, if found.
*/
virtual bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) { return false; }
virtual ClosestDepot FindClosestDepot() { return {}; }
virtual void SetDestTile(TileIndex tile) { this->dest_tile = tile; }