1
0
Fork 0

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

pull/10321/head
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(); void OnNewDay();
uint Crash(bool flooded = false); uint Crash(bool flooded = false);
TileIndex GetOrderStationLocation(StationID station); 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 * 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); const Station *st = GetTargetAirportIfValid(this);
/* If the station is not a valid airport or if it has no hangars */ /* 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 */ /* the aircraft has to search for a hangar on its own */
StationID station = FindNearestHangar(this); StationID station = FindNearestHangar(this);
if (station == INVALID_STATION) return false; if (station == INVALID_STATION) return ClosestDepot();
st = Station::Get(station); st = Station::Get(station);
} }
if (location != nullptr) *location = st->xy; return ClosestDepot(st->xy, st->index);
if (destination != nullptr) *destination = st->index;
return true;
} }
static void CheckIfAircraftNeedsService(Aircraft *v) 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) { if (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
/* We need to search for the nearest depot (hangar). */ /* We need to search for the nearest depot (hangar). */
TileIndex location; ClosestDepot closestDepot = v->FindClosestDepot();
DestinationID destination;
bool reverse;
if (v->FindClosestDepot(&location, &destination, &reverse)) { if (closestDepot.found) {
/* PBS reservations cannot reverse */ /* PBS reservations cannot reverse */
if (pbs_look_ahead && reverse) return false; if (pbs_look_ahead && closestDepot.reverse) return false;
v->SetDestTile(location); v->SetDestTile(closestDepot.location);
v->current_order.SetDestination(destination); v->current_order.SetDestination(closestDepot.destination);
/* If there is no depot in front, reverse automatically (trains only) */ /* 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) { if (v->type == VEH_AIRCRAFT) {
Aircraft *a = Aircraft::From(v); 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 */ /* The aircraft is now heading for a different hangar than the next in the orders */
extern void AircraftNextAirportPos_and_Order(Aircraft *a); extern void AircraftNextAirportPos_and_Order(Aircraft *a);
AircraftNextAirportPos_and_Order(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; uint Crash(bool flooded = false) override;
Trackdir GetVehicleTrackdir() const override; Trackdir GetVehicleTrackdir() const override;
TileIndex GetOrderStationLocation(StationID station) override; TileIndex GetOrderStationLocation(StationID station) override;
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) override; ClosestDepot FindClosestDepot() override;
bool IsBus() const; 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); 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; return ClosestDepot(rfdd.tile, GetDepotIndex(rfdd.tile));
if (destination != nullptr) *destination = GetDepotIndex(rfdd.tile);
return true;
} }
/** /**

View File

@ -3185,17 +3185,15 @@ bool AfterLoadGame()
TileIndex cur_tile = rv->tile; TileIndex cur_tile = rv->tile;
if (!IsLevelCrossingTile(cur_tile)) continue; if (!IsLevelCrossingTile(cur_tile)) continue;
TileIndex location; ClosestDepot closestDepot = rv->FindClosestDepot();
DestinationID destination;
bool reverse = true;
/* Try to find a depot with a distance limit of 512 tiles (Manhattan distance). */ /* 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. */ /* Teleport all parts of articulated vehicles. */
for (RoadVehicle *u = rv; u != nullptr; u = u->Next()) { for (RoadVehicle *u = rv; u != nullptr; u = u->Next()) {
u->tile = location; u->tile = closestDepot.location;
int x = TileX(location) * TILE_SIZE + TILE_SIZE / 2; int x = TileX(closestDepot.location) * TILE_SIZE + TILE_SIZE / 2;
int y = TileY(location) * TILE_SIZE + TILE_SIZE / 2; int y = TileY(closestDepot.location) * TILE_SIZE + TILE_SIZE / 2;
u->x_pos = x; u->x_pos = x;
u->y_pos = y; u->y_pos = y;
u->z_pos = GetSlopePixelZ(x, 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. */ /** We want to 'destruct' the right class. */
virtual ~Ship() { this->PreDestructor(); } virtual ~Ship() { this->PreDestructor(); }
void MarkDirty(); void MarkDirty() override;
void UpdateDeltaXY(); void UpdateDeltaXY() override;
ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_SHIP_REVENUE : EXPENSES_SHIP_RUN; } ExpensesType GetExpenseType(bool income) const override { return income ? EXPENSES_SHIP_REVENUE : EXPENSES_SHIP_RUN; }
void PlayLeaveStationSound(bool force = false) const; void PlayLeaveStationSound(bool force = false) const override;
bool IsPrimaryVehicle() const { return true; } bool IsPrimaryVehicle() const override { return true; }
void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const; void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const override;
int GetDisplaySpeed() const { return this->cur_speed / 2; } int GetDisplaySpeed() const override { return this->cur_speed / 2; }
int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed / 2; } int GetDisplayMaxSpeed() const override { return this->vcache.cached_max_speed / 2; }
int GetCurrentMaxSpeed() const { return std::min<int>(this->vcache.cached_max_speed, this->current_order.GetMaxSpeed() * 2); } int GetCurrentMaxSpeed() const override { return std::min<int>(this->vcache.cached_max_speed, this->current_order.GetMaxSpeed() * 2); }
Money GetRunningCost() const; Money GetRunningCost() const override;
bool IsInDepot() const { return this->state == TRACK_BIT_DEPOT; } bool IsInDepot() const override { return this->state == TRACK_BIT_DEPOT; }
bool Tick(); bool Tick() override;
void OnNewDay(); void OnNewDay() override;
Trackdir GetVehicleTrackdir() const; Trackdir GetVehicleTrackdir() const override;
TileIndex GetOrderStationLocation(StationID station); TileIndex GetOrderStationLocation(StationID station) override;
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse); ClosestDepot FindClosestDepot() override;
void UpdateCache(); void UpdateCache();
void SetDestTile(TileIndex tile); void SetDestTile(TileIndex tile) override;
}; };
bool IsShipDestinationTile(TileIndex tile, StationID station); bool IsShipDestinationTile(TileIndex tile, StationID station);

View File

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

View File

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

View File

@ -2106,23 +2106,12 @@ static FindDepotData FindClosestTrainDepot(Train *v, int max_distance)
} }
} }
/** ClosestDepot Train::FindClosestDepot()
* 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)
{ {
FindDepotData tfdd = FindClosestTrainDepot(this, 0); 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; return ClosestDepot(tfdd.tile, GetDepotIndex(tfdd.tile), tfdd.reverse);
if (destination != nullptr) *destination = GetDepotIndex(tfdd.tile);
if (reverse != nullptr) *reverse = tfdd.reverse;
return true;
} }
/** Play a sound for a train leaving the station. */ /** Play a sound for a train leaving the station. */

View File

@ -2423,11 +2423,9 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command)
return CommandCost(); return CommandCost();
} }
TileIndex location; ClosestDepot closestDepot = this->FindClosestDepot();
DestinationID destination;
bool reverse;
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}; 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 (flags & DC_EXEC) {
if (this->current_order.IsType(OT_LOADING)) this->LeaveStation(); 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); SetBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
} }
this->SetDestTile(location); this->SetDestTile(closestDepot.location);
this->current_order.MakeGoToDepot(destination, ODTF_MANUAL); this->current_order.MakeGoToDepot(closestDepot.destination, ODTF_MANUAL);
if ((command & DepotCommand::Service) == DepotCommand::None) this->current_order.SetDepotActionType(ODATFB_HALT); if ((command & DepotCommand::Service) == DepotCommand::None) this->current_order.SetDepotActionType(ODATFB_HALT);
SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP); 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 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); Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(DC_EXEC, this->index, false);
} }
if (this->type == VEH_AIRCRAFT) { if (this->type == VEH_AIRCRAFT) {
Aircraft *a = Aircraft::From(this); 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 */ /* The aircraft is now heading for a different hangar than the next in the orders */
extern void AircraftNextAirportPos_and_Order(Aircraft *a); extern void AircraftNextAirportPos_and_Order(Aircraft *a);
AircraftNextAirportPos_and_Order(a); AircraftNextAirportPos_and_Order(a);

View File

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