Changeset - r14014:448f8c2f27bc
[Not reviewed]
master
0 3 0
frosch - 15 years ago 2009-12-20 14:28:55
frosch@openttd.org
(svn r18566) -Codechange: When both the union and intersection of refit masks of articulated vehicles are needed, they can be determined at once.
3 files changed with 39 insertions and 39 deletions:
0 comments (0 inline, 0 general)
src/articulated_vehicles.cpp
Show inline comments
 
@@ -145,63 +145,62 @@ bool IsArticulatedVehicleRefittable(Engi
 
	}
 

	
 
	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
 
 * @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)
 
{
 
	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;
 
}
 

	
 
/**
 
 * Ands 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 every articulated part (with default capacity > 0)
 
 */
 
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;
 
}
 

	
 

	
 
/**
 
 * Tests if all parts of an articulated vehicle are refitted to the same cargo.
 
 * Note: Vehicles not carrying anything are ignored
 
@@ -250,14 +249,14 @@ bool IsArticulatedVehicleCarryingDiffere
 
 *    - intersection and union of refit masks.
 
 */
 
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;
 
	uint32 real_refit_intersection = UINT_MAX;
 
	CargoArray real_default_capacity;
 

	
src/articulated_vehicles.h
Show inline comments
 
@@ -15,12 +15,13 @@
 
#include "vehicle_type.h"
 
#include "engine_type.h"
 

	
 
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);
 
bool IsArticulatedVehicleRefittable(EngineID engine);
 
void CheckConsistencyOfArticulatedVehicle(const Vehicle *v);
 

	
src/autoreplace_cmd.cpp
Show inline comments
 
@@ -167,19 +167,19 @@ static bool VerifyAutoreplaceRefitForOrd
 
 *    CT_NO_REFIT is returned if no refit is needed
 
 *    CT_INVALID is returned when both old and new vehicle got cargo capacity and refitting the new one to the old one's cargo type isn't possible
 
 */
 
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.
 

	
 
		if (!part_of_chain) return CT_NO_REFIT;
 

	
 
		/* the old engine didn't have cargo capacity, but the new one does
0 comments (0 inline, 0 general)