diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 9dc2e88449..8dab81559b 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -2123,49 +2123,28 @@ void Vehicle::ResetRefitCaps() for (Vehicle *v = this; v != NULL; v = v->Next()) v->refit_cap = v->cargo_cap; } -/** - * Simulated cargo type and capacity for prediction of future links. - */ -struct RefitDesc { - CargoID cargo; ///< Cargo type the vehicle will be carrying. - uint16 capacity; ///< Capacity the vehicle will have. - uint16 remaining; ///< Capacity remaining from before the previous refit. - RefitDesc(CargoID cargo, uint16 capacity, uint16 remaining) : - cargo(cargo), capacity(capacity), remaining(remaining) {} -}; - -typedef std::list RefitList; -typedef std::map CapacitiesMap; - /** * Predict a vehicle's course from its current state and refresh all links it * will visit. + * @param capacities Current added capacities per cargo ID in the consist. + * @param refit_capacities Current state of capacity remaining from previous + * refits versus overall capacity per vehicle in the consist. + * @param first Order that was checked first in the overall run. If this is + * encountered again the refreshing is considered finished. + * @param cur Last stop where the consist could interact with cargo. + * @param next Next order to be checked. + * @param hops Number of hops already used up. If more than two times the + * number of orders in the list have been checked refreshing is stopped. + * @param was_refit If the consist was refit since the last stop where it could + * interact with cargo. + * @param has_cargo If the consist could leave the last stop where it could + * interact with cargo carrying cargo + * (i.e. not an "unload all" + "no loading" order). */ -void Vehicle::RefreshNextHopsStats() +void Vehicle::RefreshNextHopsStats(CapacitiesMap &capacities, + RefitList &refit_capacities, const Order *first, const Order *cur, + const Order *next, uint hops, bool was_refit, bool has_cargo) { - /* Assemble list of capacities and set last loading stations to 0. */ - CapacitiesMap capacities; - RefitList refit_capacities; - for (Vehicle *v = this; v != NULL; v = v->Next()) { - refit_capacities.push_back(RefitDesc(v->cargo_type, v->cargo_cap, v->refit_cap)); - if (v->refit_cap > 0) capacities[v->cargo_type] += v->refit_cap; - } - - /* If orders were deleted while loading, we're done here.*/ - if (this->orders.list == NULL) return; - - const Order *first = this->GetOrder(this->cur_implicit_order_index); - - /* Make sure the first order is a useful order. */ - first = this->orders.list->GetNextDecisionNode(first, 0); - if (first == NULL) return; - - const Order *cur = first; - const Order *next = first; - bool has_cargo = this->last_loading_station != INVALID_STATION; - bool was_refit = false; - uint hops = 0; - while (next != NULL) { /* If the refit cargo is CT_AUTO_REFIT, we're optimistic and assume the @@ -2275,6 +2254,33 @@ void Vehicle::RefreshNextHopsStats() } } +/** + * Predict a vehicle's course from its current state and refresh all links it + * will visit. + */ +void Vehicle::RefreshNextHopsStats() +{ + /* Assemble list of capacities and set last loading stations to 0. */ + CapacitiesMap capacities; + RefitList refit_capacities; + for (Vehicle *v = this; v != NULL; v = v->Next()) { + refit_capacities.push_back(RefitDesc(v->cargo_type, v->cargo_cap, v->refit_cap)); + if (v->refit_cap > 0) capacities[v->cargo_type] += v->refit_cap; + } + + /* If orders were deleted while loading, we're done here.*/ + if (this->orders.list == NULL) return; + + const Order *first = this->GetOrder(this->cur_implicit_order_index); + + /* Make sure the first order is a useful order. */ + first = this->orders.list->GetNextDecisionNode(first, 0); + if (first == NULL) return; + + this->RefreshNextHopsStats(capacities, refit_capacities, first, first, + first, 0, false, this->last_loading_station != INVALID_STATION); +} + /** * Handle the loading of the vehicle; when not it skips through dummy * orders and does nothing in all other cases. diff --git a/src/vehicle_base.h b/src/vehicle_base.h index be3a4058f7..4eecda6ccd 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -23,6 +23,8 @@ #include "transport_type.h" #include "group_type.h" #include "base_consist.h" +#include +#include /** Vehicle status bits in #Vehicle::vehstatus. */ enum VehStatus { @@ -124,15 +126,33 @@ extern void FixOldVehicles(); struct GRFFile; +/** + * Simulated cargo type and capacity for prediction of future links. + */ +struct RefitDesc { + CargoID cargo; ///< Cargo type the vehicle will be carrying. + uint16 capacity; ///< Capacity the vehicle will have. + uint16 remaining; ///< Capacity remaining from before the previous refit. + RefitDesc(CargoID cargo, uint16 capacity, uint16 remaining) : + cargo(cargo), capacity(capacity), remaining(remaining) {} +}; + /** %Vehicle data structure. */ struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle, BaseConsist { private: + typedef std::list RefitList; + typedef std::map CapacitiesMap; + Vehicle *next; ///< pointer to the next vehicle in the chain Vehicle *previous; ///< NOSAVE: pointer to the previous vehicle in the chain Vehicle *first; ///< NOSAVE: pointer to the first vehicle in the chain Vehicle *next_shared; ///< pointer to the next vehicle that shares the order Vehicle *previous_shared; ///< NOSAVE: pointer to the previous vehicle in the shared order chain + + void RefreshNextHopsStats(CapacitiesMap &capacities, + RefitList &refit_capacities, const Order *first, const Order *cur, + const Order *next, uint hops, bool was_refit, bool has_cargo); public: friend const SaveLoad *GetVehicleDescription(VehicleType vt); ///< So we can use private/protected variables in the saveload code friend void FixOldVehicles();