diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 423aa5dfce..0920b109bd 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -706,7 +706,7 @@ CommandCost CmdRefitAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) static void CheckIfAircraftNeedsService(Vehicle *v) { - if (_patches.servint_aircraft == 0 || !VehicleNeedsService(v)) return; + if (_patches.servint_aircraft == 0 || !v->NeedsAutomaticServicing()) return; if (v->IsInDepot()) { VehicleServiceInDepot(v); return; @@ -1370,7 +1370,7 @@ static void ProcessAircraftOrder(Vehicle *v) case OT_GOTO_DEPOT: if (!(v->current_order.flags & OFB_PART_OF_ORDERS)) return; if (v->current_order.flags & OFB_SERVICE_IF_NEEDED && - !VehicleNeedsService(v)) { + !v->NeedsServicing()) { UpdateVehicleTimetable(v, true); v->cur_order_index++; } diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 0e1843e2f4..cc4171af44 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -761,7 +761,7 @@ static void ProcessRoadVehOrder(Vehicle *v) /* Let a depot order in the orderlist interrupt. */ if (!(v->current_order.flags & OFB_PART_OF_ORDERS)) return; if (v->current_order.flags & OFB_SERVICE_IF_NEEDED && - !VehicleNeedsService(v)) { + !v->NeedsServicing()) { UpdateVehicleTimetable(v, true); v->cur_order_index++; } @@ -1977,7 +1977,7 @@ void RoadVehicle::Tick() static void CheckIfRoadVehNeedsService(Vehicle *v) { /* If we already got a slot at a stop, use that FIRST, and go to a depot later */ - if (v->u.road.slot != NULL || _patches.servint_roadveh == 0 || !VehicleNeedsService(v)) return; + if (v->u.road.slot != NULL || _patches.servint_roadveh == 0 || !v->NeedsAutomaticServicing()) return; if (v->IsInDepot()) { VehicleServiceInDepot(v); return; diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 7055fbb598..acae06119a 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -142,7 +142,7 @@ static const Depot* FindClosestShipDepot(const Vehicle* v) static void CheckIfShipNeedsService(Vehicle *v) { - if (_patches.servint_ships == 0 || !VehicleNeedsService(v)) return; + if (_patches.servint_ships == 0 || !v->NeedsAutomaticServicing()) return; if (v->IsInDepot()) { VehicleServiceInDepot(v); return; @@ -248,7 +248,7 @@ static void ProcessShipOrder(Vehicle *v) case OT_GOTO_DEPOT: if (!(v->current_order.flags & OFB_PART_OF_ORDERS)) return; if (v->current_order.flags & OFB_SERVICE_IF_NEEDED && - !VehicleNeedsService(v)) { + !v->NeedsServicing()) { UpdateVehicleTimetable(v, true); v->cur_order_index++; } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 74e74ff385..55d4d80786 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -2634,7 +2634,7 @@ static bool ProcessTrainOrder(Vehicle *v) case OT_GOTO_DEPOT: if (!(v->current_order.flags & OFB_PART_OF_ORDERS)) return false; if ((v->current_order.flags & OFB_SERVICE_IF_NEEDED) && - !VehicleNeedsService(v)) { + !v->NeedsServicing()) { UpdateVehicleTimetable(v, true); v->cur_order_index++; } @@ -3527,7 +3527,7 @@ static bool TrainCheckIfLineEnds(Vehicle *v) TileIndex tile = v->tile + TileOffsByDiagDir(dir); /* Determine the track status on the next tile */ - TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0, ReverseDiagDir(dir)) & _reachable_tracks[dir]; +; TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0, ReverseDiagDir(dir)) & _reachable_tracks[dir]; TrackdirBits trackdirbits = TrackStatusToTrackdirBits(ts); TrackdirBits red_signals = TrackStatusToRedSignals(ts); @@ -3665,7 +3665,7 @@ void Train::Tick() static void CheckIfTrainNeedsService(Vehicle *v) { - if (_patches.servint_trains == 0 || !VehicleNeedsService(v)) return; + if (_patches.servint_trains == 0 || !v->NeedsAutomaticServicing()) return; if (v->IsInDepot()) { VehicleServiceInDepot(v); return; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 6347b8e3e5..1dbdd4e929 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -119,22 +119,27 @@ void VehicleServiceInDepot(Vehicle *v) InvalidateWindow(WC_VEHICLE_DETAILS, v->index); // ensure that last service date and reliability are updated } -bool VehicleNeedsService(const Vehicle *v) +bool Vehicle::NeedsServicing() const { - if (v->vehstatus & (VS_STOPPED | VS_CRASHED)) return false; - if (v->current_order.type != OT_GOTO_DEPOT || !(v->current_order.flags & OFB_PART_OF_ORDERS)) { // Don't interfere with a depot visit by the order list - if (_patches.gotodepot && VehicleHasDepotOrders(v)) return false; - if (v->current_order.type == OT_LOADING) return false; - if (v->current_order.type == OT_GOTO_DEPOT && v->current_order.flags & OFB_HALT_IN_DEPOT) return false; - } + if (this->vehstatus & (VS_STOPPED | VS_CRASHED)) return false; if (_patches.no_servicing_if_no_breakdowns && _opt.diff.vehicle_breakdowns == 0) { - return EngineHasReplacementForPlayer(GetPlayer(v->owner), v->engine_type, v->group_id); /* Vehicles set for autoreplacing needs to go to a depot even if breakdowns are turned off */ + /* Vehicles set for autoreplacing needs to go to a depot even if breakdowns are turned off. + * Note: If servicing is enabled, we postpone replacement till next service. */ + return EngineHasReplacementForPlayer(GetPlayer(this->owner), this->engine_type, this->group_id); } return _patches.servint_ispercent ? - (v->reliability < GetEngine(v->engine_type)->reliability * (100 - v->service_interval) / 100) : - (v->date_of_last_service + v->service_interval < _date); + (this->reliability < GetEngine(this->engine_type)->reliability * (100 - this->service_interval) / 100) : + (this->date_of_last_service + this->service_interval < _date); +} + +bool Vehicle::NeedsAutomaticServicing() const +{ + if (_patches.gotodepot && VehicleHasDepotOrders(this)) return false; + if (this->current_order.type == OT_LOADING) return false; + if (this->current_order.type == OT_GOTO_DEPOT && this->current_order.flags & OFB_HALT_IN_DEPOT) return false; + return NeedsServicing(); } StringID VehicleInTheWayErrMsg(const Vehicle* v) diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 8bcaa2b475..2f69541941 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -486,6 +486,21 @@ public: inline bool IsOrderListShared() const { return this->next_shared != NULL || this->prev_shared != NULL; }; bool NeedsAutorenewing(const Player *p) const; + + /** + * Check if the vehicle needs to go to a depot in near future (if a opportunity presents itself) for service or replacement. + * + * @see NeedsAutomaticServicing() + * @return true if the vehicle should go to a depot if a opportunity presents itself. + */ + bool NeedsServicing() const; + + /** + * Checks if the current order should be interupted for a service-in-depot-order. + * @see NeedsServicing() + * @return true if the current order should be interupted. + */ + bool NeedsAutomaticServicing() const; }; /** diff --git a/src/vehicle_func.h b/src/vehicle_func.h index 874e8910d2..c2e0e8660a 100644 --- a/src/vehicle_func.h +++ b/src/vehicle_func.h @@ -67,8 +67,6 @@ void TrainConsistChanged(Vehicle *v); void TrainPowerChanged(Vehicle *v); Money GetTrainRunningCost(const Vehicle *v); -bool VehicleNeedsService(const Vehicle *v); - uint GenerateVehicleSortList(const Vehicle*** sort_list, uint16 *length_of_array, VehicleType type, PlayerID owner, uint32 index, uint16 window_type); void BuildDepotVehicleList(VehicleType type, TileIndex tile, Vehicle ***engine_list, uint16 *engine_list_length, uint16 *engine_count, Vehicle ***wagon_list, uint16 *wagon_list_length, uint16 *wagon_count); CommandCost SendAllVehiclesToDepot(VehicleType type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id);