diff options
author | fonsinchen <fonsinchen@openttd.org> | 2014-09-21 14:22:32 +0000 |
---|---|---|
committer | fonsinchen <fonsinchen@openttd.org> | 2014-09-21 14:22:32 +0000 |
commit | 831fb254f604309a255ea310bc6647cfa9c3fdc9 (patch) | |
tree | 2893b8190eee553c4f424af8e6852d099dbe174b /src | |
parent | 14a599409e2e73b7a31b12f80741baa07fc7502c (diff) | |
download | openttd-831fb254f604309a255ea310bc6647cfa9c3fdc9.tar.xz |
(svn r26889) -Feature: Predict links for station-autorefitting vehicles
Diffstat (limited to 'src')
-rw-r--r-- | src/linkgraph/refresh.cpp | 31 | ||||
-rw-r--r-- | src/linkgraph/refresh.h | 11 |
2 files changed, 26 insertions, 16 deletions
diff --git a/src/linkgraph/refresh.cpp b/src/linkgraph/refresh.cpp index d2a3bdda1..02f27f40c 100644 --- a/src/linkgraph/refresh.cpp +++ b/src/linkgraph/refresh.cpp @@ -81,18 +81,21 @@ LinkRefresher::LinkRefresher(Vehicle *vehicle, HopSet *seen_hops, bool allow_mer /** * Handle refit orders by updating capacities and refit_capacities. - * @param next Order to be processed. + * @param refit_cargo Cargo to refit to. + * @return True if any vehicle was refit; false if none was. */ -void LinkRefresher::HandleRefit(const Order *next) +bool LinkRefresher::HandleRefit(CargoID refit_cargo) { - this->cargo = next->GetRefitCargo(); + this->cargo = refit_cargo; RefitList::iterator refit_it = this->refit_capacities.begin(); + bool any_refit = false; for (Vehicle *v = this->vehicle; v != NULL; v = v->Next()) { const Engine *e = Engine::Get(v->engine_type); if (!HasBit(e->info.refit_mask, this->cargo)) { ++refit_it; continue; } + any_refit = true; /* Back up the vehicle's cargo type */ CargoID temp_cid = v->cargo_type; @@ -130,6 +133,7 @@ void LinkRefresher::HandleRefit(const Order *next) break; // aircraft have only one vehicle } } + return any_refit; } /** @@ -253,15 +257,20 @@ void LinkRefresher::RefreshLinks(const Order *cur, const Order *next, uint8 flag { while (next != NULL) { - /* If the refit cargo is CT_AUTO_REFIT, we're optimistic and assume the - * cargo will stay the same. The point of this method is to avoid - * deadlocks due to vehicles waiting for cargo that isn't being routed, - * yet. That situation will not occur if the vehicle is actually - * carrying a different cargo in the end. */ - if ((next->IsType(OT_GOTO_DEPOT) || next->IsType(OT_GOTO_STATION)) && - next->IsRefit() && !next->IsAutoRefit()) { + if ((next->IsType(OT_GOTO_DEPOT) || next->IsType(OT_GOTO_STATION)) && next->IsRefit()) { SetBit(flags, WAS_REFIT); - this->HandleRefit(next); + if (!next->IsAutoRefit()) { + this->HandleRefit(next->GetRefitCargo()); + } else if (!HasBit(flags, IN_AUTOREFIT)) { + SetBit(flags, IN_AUTOREFIT); + LinkRefresher backup(*this); + for (CargoID c = 0; c != NUM_CARGO; ++c) { + if (CargoSpec::Get(c)->IsValid() && this->HandleRefit(c)) { + this->RefreshLinks(cur, next, flags, num_hops); + *this = backup; + } + } + } } /* Only reset the refit capacities if the "previous" next is a station, diff --git a/src/linkgraph/refresh.h b/src/linkgraph/refresh.h index eac34266d..7c221bc22 100644 --- a/src/linkgraph/refresh.h +++ b/src/linkgraph/refresh.h @@ -31,10 +31,11 @@ protected: * an influence on the next one. */ enum RefreshFlags { - USE_NEXT, ///< There was a conditional jump. Try to use the given next order when looking for a new one. - HAS_CARGO, ///< Consist could leave the last stop where it could interact with cargo carrying cargo (i.e. not an "unload all" + "no loading" order). - WAS_REFIT, ///< Consist was refit since the last stop where it could interact with cargo. - RESET_REFIT ///< Consist had a chance to load since the last refit and the refit capacities can be reset. + USE_NEXT, ///< There was a conditional jump. Try to use the given next order when looking for a new one. + HAS_CARGO, ///< Consist could leave the last stop where it could interact with cargo carrying cargo (i.e. not an "unload all" + "no loading" order). + WAS_REFIT, ///< Consist was refit since the last stop where it could interact with cargo. + RESET_REFIT, ///< Consist had a chance to load since the last refit and the refit capacities can be reset. + IN_AUTOREFIT, ///< Currently doing an autorefit loop. Ignore the first autorefit order. }; /** @@ -92,7 +93,7 @@ protected: LinkRefresher(Vehicle *v, HopSet *seen_hops, bool allow_merge, bool is_full_loading); - void HandleRefit(const Order *next); + bool HandleRefit(CargoID refit_cargo); void ResetRefit(); void RefreshStats(const Order *cur, const Order *next); const Order *PredictNextOrder(const Order *cur, const Order *next, uint8 flags, uint num_hops = 0); |