diff options
-rw-r--r-- | src/articulated_vehicles.cpp | 59 | ||||
-rw-r--r-- | src/articulated_vehicles.h | 1 | ||||
-rw-r--r-- | src/autoreplace_cmd.cpp | 6 |
3 files changed, 33 insertions, 33 deletions
diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp index ccc929102..80a30952b 100644 --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.cpp @@ -148,28 +148,43 @@ bool IsArticulatedVehicleRefittable(EngineID engine) } /** - * Ors the refit_masks of all articulated parts. + * Merges the refit_masks of all articulated parts. * @param engine the first part * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask - * @return bit mask of CargoIDs which are a refit option for at least one articulated part + * @param union_mask returns bit mask of CargoIDs which are a refit option for at least one articulated part + * @param intersection_mask returns bit mask of CargoIDs which are a refit option for every articulated part (with default capacity > 0) */ -uint32 GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type) +void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, uint32 *union_mask, uint32 *intersection_mask) { const Engine *e = Engine::Get(engine); - uint32 cargos = GetAvailableVehicleCargoTypes(engine, include_initial_cargo_type); - - if (e->type != VEH_TRAIN && e->type != VEH_ROAD) return cargos; + uint32 veh_cargos = GetAvailableVehicleCargoTypes(engine, include_initial_cargo_type); + *union_mask = veh_cargos; + *intersection_mask = (veh_cargos != 0) ? veh_cargos : UINT32_MAX; - if (!HasBit(e->info.callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) return cargos; + if (e->type != VEH_TRAIN && e->type != VEH_ROAD) return; + if (!HasBit(e->info.callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) return; for (uint i = 1; i < MAX_ARTICULATED_PARTS; i++) { EngineID artic_engine = GetNextArticPart(i, engine); if (artic_engine == INVALID_ENGINE) break; - cargos |= GetAvailableVehicleCargoTypes(artic_engine, include_initial_cargo_type); + veh_cargos = GetAvailableVehicleCargoTypes(artic_engine, include_initial_cargo_type);; + *union_mask |= veh_cargos; + if (veh_cargos != 0) *intersection_mask &= veh_cargos; } +} - return cargos; +/** + * Ors the refit_masks of all articulated parts. + * @param engine the first part + * @param include_initial_cargo_type if true the default cargo type of the vehicle is included; if false only the refit_mask + * @return bit mask of CargoIDs which are a refit option for at least one articulated part + */ +uint32 GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type) +{ + uint32 union_mask, intersection_mask; + GetArticulatedRefitMasks(engine, include_initial_cargo_type, &union_mask, &intersection_mask); + return union_mask; } /** @@ -180,25 +195,9 @@ uint32 GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial_car */ uint32 GetIntersectionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type) { - const Engine *e = Engine::Get(engine); - uint32 cargos = UINT32_MAX; - - uint32 veh_cargos = GetAvailableVehicleCargoTypes(engine, include_initial_cargo_type); - if (veh_cargos != 0) cargos &= veh_cargos; - - if (e->type != VEH_TRAIN && e->type != VEH_ROAD) return cargos; - - if (!HasBit(e->info.callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) return cargos; - - for (uint i = 1; i < MAX_ARTICULATED_PARTS; i++) { - EngineID artic_engine = GetNextArticPart(i, engine); - if (artic_engine == INVALID_ENGINE) break; - - veh_cargos = GetAvailableVehicleCargoTypes(artic_engine, include_initial_cargo_type); - if (veh_cargos != 0) cargos &= veh_cargos; - } - - return cargos; + uint32 union_mask, intersection_mask; + GetArticulatedRefitMasks(engine, include_initial_cargo_type, &union_mask, &intersection_mask); + return intersection_mask; } @@ -253,8 +252,8 @@ void CheckConsistencyOfArticulatedVehicle(const Vehicle *v) { const Engine *engine = Engine::Get(v->engine_type); - uint32 purchase_refit_union = GetUnionOfArticulatedRefitMasks(v->engine_type, true); - uint32 purchase_refit_intersection = GetIntersectionOfArticulatedRefitMasks(v->engine_type, true); + uint32 purchase_refit_union, purchase_refit_intersection; + GetArticulatedRefitMasks(v->engine_type, true, &purchase_refit_union, &purchase_refit_intersection); CargoArray purchase_default_capacity = GetCapacityOfArticulatedParts(v->engine_type); uint32 real_refit_union = 0; diff --git a/src/articulated_vehicles.h b/src/articulated_vehicles.h index 37426b8b4..3a3940a9d 100644 --- a/src/articulated_vehicles.h +++ b/src/articulated_vehicles.h @@ -18,6 +18,7 @@ uint CountArticulatedParts(EngineID engine_type, bool purchase_window); CargoArray GetCapacityOfArticulatedParts(EngineID engine); void AddArticulatedParts(Vehicle *first); +void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, uint32 *union_mask, uint32 *intersection_mask); uint32 GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type); uint32 GetIntersectionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type); bool IsArticulatedVehicleCarryingDifferentCargos(const Vehicle *v, CargoID *cargo_type); diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index bf1104d34..0e7507cf6 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -170,13 +170,13 @@ static bool VerifyAutoreplaceRefitForOrders(const Vehicle *v, EngineID engine_ty static CargoID GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type, bool part_of_chain) { CargoID cargo_type; + uint32 available_cargo_types, union_mask; + GetArticulatedRefitMasks(engine_type, true, &union_mask, &available_cargo_types); - if (GetUnionOfArticulatedRefitMasks(engine_type, true) == 0) return CT_NO_REFIT; // Don't try to refit an engine with no cargo capacity + if (union_mask == 0) return CT_NO_REFIT; // Don't try to refit an engine with no cargo capacity if (IsArticulatedVehicleCarryingDifferentCargos(v, &cargo_type)) return CT_INVALID; // We cannot refit to mixed cargos in an automated way - uint32 available_cargo_types = GetIntersectionOfArticulatedRefitMasks(engine_type, true); - if (cargo_type == CT_INVALID) { if (v->type != VEH_TRAIN) return CT_NO_REFIT; // If the vehicle does not carry anything at all, every replacement is fine. |