diff --git a/src/aircraft.h b/src/aircraft.h --- a/src/aircraft.h +++ b/src/aircraft.h @@ -110,7 +110,7 @@ struct Aircraft FINAL : public Specializ 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 diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -388,7 +388,7 @@ CommandCost CmdBuildAircraft(DoCommandFl } -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(TileInde /* 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) diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1982,23 +1982,21 @@ bool UpdateOrderDest(Vehicle *v, const O 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::Do(DC_EXEC, v->index, false); + if (v->type == VEH_TRAIN && closestDepot.reverse) Command::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); diff --git a/src/roadveh.h b/src/roadveh.h --- a/src/roadveh.h +++ b/src/roadveh.h @@ -139,7 +139,7 @@ struct RoadVehicle FINAL : public Ground 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; diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -346,15 +346,12 @@ static FindDepotData FindClosestRoadDepo } } -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)); } /** diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -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); diff --git a/src/ship.h b/src/ship.h --- a/src/ship.h +++ b/src/ship.h @@ -35,24 +35,24 @@ struct Ship FINAL : public SpecializedVe /** 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(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(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); diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -913,14 +913,10 @@ CommandCost CmdBuildShip(DoCommandFlag f return CommandCost(); } -bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) +ClosestDepot Ship::FindClosestDepot() { const Depot *depot = FindClosestShipDepot(this, 0); - - if (depot == nullptr) return false; + if (depot == nullptr) return ClosestDepot(); - if (location != nullptr) *location = depot->xy; - if (destination != nullptr) *destination = depot->index; - - return true; + return ClosestDepot(depot->xy, depot->index); } diff --git a/src/train.h b/src/train.h --- a/src/train.h +++ b/src/train.h @@ -124,7 +124,7 @@ struct Train FINAL : public GroundVehicl 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; diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -2106,23 +2106,12 @@ static FindDepotData FindClosestTrainDep } } -/** - * 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 (location != nullptr) *location = tfdd.tile; - if (destination != nullptr) *destination = GetDepotIndex(tfdd.tile); - if (reverse != nullptr) *reverse = tfdd.reverse; - - return true; + if (tfdd.best_length == UINT_MAX) return ClosestDepot(); + + return ClosestDepot(tfdd.tile, GetDepotIndex(tfdd.tile), tfdd.reverse); } /** Play a sound for a train leaving the station. */ diff --git a/src/vehicle.cpp b/src/vehicle.cpp --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -2423,11 +2423,9 @@ CommandCost Vehicle::SendToDepot(DoComma 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(DoComma 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::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); diff --git a/src/vehicle_base.h b/src/vehicle_base.h --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -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; }