diff --git a/src/economy.cpp b/src/economy.cpp index 1e0f2b2f49..44dceb1f2d 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1347,93 +1347,36 @@ static void ReserveConsist(Station *st, Vehicle *u, CargoArray *consist_capleft, * @tparam Taction Class of action to be applied. Must implement bool operator()([const] Vehicle *). * @param v First articulated part. * @param action Instance of Taction. - * @param abort_on_false If set, don't iterate other parts if one has returned false. * @return false if any of the action invocations returned false, true otherwise. */ template -bool IterateVehicleParts(Vehicle *v, Taction action, bool abort_on_false = false) +bool IterateVehicleParts(Vehicle *v, Taction action) { - bool result = true; for (Vehicle *w = v; w != NULL; w = w->HasArticulatedPart() ? w->GetNextArticulatedPart() : NULL) { - if (!action(w)) { - if (abort_on_false) return false; - result = false; - } + if (!action(w)) return false; if (w->type == VEH_TRAIN) { Train *train = Train::From(w); - if (train->IsMultiheaded() && !action(train->other_multiheaded_part)) { - if (abort_on_false) return false; - result = false; - } + if (train->IsMultiheaded() && !action(train->other_multiheaded_part)) return false; } } - if (v->type == VEH_AIRCRAFT && Aircraft::From(v)->IsNormalAircraft() && - !action(v->Next())) { - return false; - } - return result; + if (v->type == VEH_AIRCRAFT && Aircraft::From(v)->IsNormalAircraft()) return action(v->Next()); + return true; } /** - * Action to reserve cargo. + * Action to check if a vehicle has no stored cargo. */ -struct ReserveAction { - CargoArray &consist_capleft; ///< Capacities left in the consist. - Station *st; ///< Station to reserve cargo from. - StationIDStack &next_station; ///< Next hops to reserve cargo for. - bool do_reserve; ///< If we want cargo to be reserved at all. - - /** - * Create a reserve action. - * @param consist_capleft Capacities left in the consist. - * @param st Station to reserve cargo from. - * @param next_station Next hops to reserve cargo for. - */ - ReserveAction(CargoArray &consist_capleft, Station *st, StationIDStack &next_station, - bool do_reserve) : - consist_capleft(consist_capleft), st(st), next_station(next_station), - do_reserve(do_reserve) - {} - - uint operator()(Vehicle *v) - { - if (!do_reserve) return 0; - return this->st->goods[v->cargo_type].cargo.Reserve( - v->cargo_cap - v->cargo.RemainingCount(), - &v->cargo, this->st->xy, this->next_station); - } -}; - -/** - * Action to check if a vehicle has no stored cargo or otherwise reserve for it if Treserve is set. - * @tparam Treserve If true do reserve if vehicle has cargo, otherwise don't. - */ -struct CheckOrReserveAction : public ReserveAction +struct IsEmptyAction { /** - * Create a check/reserve action. - * @param consist_capleft Capacities left in the consist. - * @param st Station to reserve cargo from. - * @param next_station Next hops to reserve cargo for. - */ - CheckOrReserveAction(CargoArray &consist_capleft, Station *st, StationIDStack &next_station, - bool do_reserve) : - ReserveAction(consist_capleft, st, next_station, do_reserve) {} - - /** - * Checks if the vehicle has stored cargo and if yes, reserves more cargo for it. + * Checks if the vehicle has stored cargo. * @param v Vehicle to be checked. * @return true if v is either empty or has only reserved cargo, false otherwise. */ - bool operator()(Vehicle *v) + bool operator()(const Vehicle *v) { - if (v->cargo.StoredCount() == 0) { - return true; - } else { - this->consist_capleft[v->cargo_type] -= ReserveAction::operator()(v); - return false; - } + return v->cargo.StoredCount() == 0; } }; @@ -1497,17 +1440,20 @@ struct ReturnCargoAction /** * Action for finalizing a refit. */ -struct FinalizeRefitAction : public ReserveAction +struct FinalizeRefitAction { + CargoArray &consist_capleft; ///< Capacities left in the consist. + Station *st; ///< Station to reserve cargo from. + StationIDStack &next_station; ///< Next hops to reserve cargo for. + /** * Create a finalizing action. * @param consist_capleft Capacities left in the consist. * @param st Station to reserve cargo from. * @param next_station Next hops to reserve cargo for. */ - FinalizeRefitAction(CargoArray &consist_capleft, Station *st, StationIDStack &next_station, - bool do_reserve) : - ReserveAction(consist_capleft, st, next_station, do_reserve) {} + FinalizeRefitAction(CargoArray &consist_capleft, Station *st, StationIDStack &next_station) : + consist_capleft(consist_capleft), st(st), next_station(next_station) {} /** * Reserve cargo from the station and update the remaining consist capacities with the @@ -1517,7 +1463,8 @@ struct FinalizeRefitAction : public ReserveAction */ bool operator()(Vehicle *v) { - ReserveAction::operator()(v); + this->st->goods[v->cargo_type].cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(), + &v->cargo, st->xy, next_station); this->consist_capleft[v->cargo_type] += v->cargo_cap - v->cargo.RemainingCount(); return true; } @@ -1530,17 +1477,11 @@ struct FinalizeRefitAction : public ReserveAction * @param st Station the vehicle is loading at. * @param next_station Possible next stations the vehicle can travel to. * @param new_cid Target cargo for refit. - * @param full_load If the order we're currently following has a full load modifier. */ -static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station *st, - StationIDStack next_station, CargoID new_cid, bool full_load) +static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station *st, StationIDStack next_station, CargoID new_cid) { - bool reserve = full_load || new_cid == CT_AUTO_REFIT; Vehicle *v_start = v->GetFirstEnginePart(); - if (!IterateVehicleParts(v_start, - CheckOrReserveAction(consist_capleft, st, next_station, reserve), reserve)) { - return; - } + if (!IterateVehicleParts(v_start, IsEmptyAction())) return; Backup cur_company(_current_company, v->owner, FILE_LINE); @@ -1585,7 +1526,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station } /* Add new capacity to consist capacity and reserve cargo */ - IterateVehicleParts(v_start, FinalizeRefitAction(consist_capleft, st, next_station, reserve)); + IterateVehicleParts(v_start, FinalizeRefitAction(consist_capleft, st, next_station)); cur_company.Restore(); } @@ -1623,17 +1564,12 @@ static void LoadUnloadVehicle(Vehicle *front) Station *st = Station::Get(last_visited); StationIDStack next_station = front->GetNextStoppingStation(); - bool use_stationrefit = front->current_order.IsRefit(); + bool use_autorefit = front->current_order.IsRefit() && front->current_order.GetRefitCargo() == CT_AUTO_REFIT; CargoArray consist_capleft; - bool do_reserve = _settings_game.order.improved_load && - (front->current_order.GetLoadType() & OLFB_FULL_LOAD) != 0; - - /* Refitting to a fixed cargo will most likely invalidate any reservations, so we - * shouldn't do them here. HandleStationRefit reserves after refitting, or instead of - * refitting if the vehicle isn't empty. */ - if (do_reserve && !use_stationrefit) { - ReserveConsist(st, front, (use_stationrefit && front->load_unload_ticks != 0) ? - &consist_capleft : NULL, + if (_settings_game.order.improved_load && + ((front->current_order.GetLoadType() & OLFB_FULL_LOAD) != 0 || use_autorefit)) { + ReserveConsist(st, front, + (use_autorefit && front->load_unload_ticks != 0) ? &consist_capleft : NULL, next_station); } @@ -1743,9 +1679,8 @@ static void LoadUnloadVehicle(Vehicle *front) if (front->current_order.GetLoadType() & OLFB_NO_LOAD || HasBit(front->vehicle_flags, VF_STOP_LOADING)) continue; /* This order has a refit, if this is the first vehicle part carrying cargo and the whole vehicle is empty, try refitting. */ - if (use_stationrefit && artic_part == 1) { - HandleStationRefit(v, consist_capleft, st, next_station, - front->current_order.GetRefitCargo(), do_reserve); + if (front->current_order.IsRefit() && artic_part == 1) { + HandleStationRefit(v, consist_capleft, st, next_station, front->current_order.GetRefitCargo()); ge = &st->goods[v->cargo_type]; }