mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r18566) -Codechange: When both the union and intersection of refit masks of articulated vehicles are needed, they can be determined at once.
This commit is contained in:
parent
e5ebae1085
commit
1e1fa9ff2e
|
@ -147,6 +147,33 @@ bool IsArticulatedVehicleRefittable(EngineID engine)
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @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)
|
||||
*/
|
||||
void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, uint32 *union_mask, uint32 *intersection_mask)
|
||||
{
|
||||
const Engine *e = Engine::Get(engine);
|
||||
uint32 veh_cargos = GetAvailableVehicleCargoTypes(engine, include_initial_cargo_type);
|
||||
*union_mask = veh_cargos;
|
||||
*intersection_mask = (veh_cargos != 0) ? veh_cargos : UINT32_MAX;
|
||||
|
||||
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;
|
||||
|
||||
veh_cargos = GetAvailableVehicleCargoTypes(artic_engine, include_initial_cargo_type);;
|
||||
*union_mask |= veh_cargos;
|
||||
if (veh_cargos != 0) *intersection_mask &= veh_cargos;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ors the refit_masks of all articulated parts.
|
||||
* @param engine the first part
|
||||
|
@ -155,21 +182,9 @@ bool IsArticulatedVehicleRefittable(EngineID engine)
|
|||
*/
|
||||
uint32 GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type)
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
cargos |= GetAvailableVehicleCargoTypes(artic_engine, include_initial_cargo_type);
|
||||
}
|
||||
|
||||
return cargos;
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
Loading…
Reference in New Issue