changeset 14024:7b24b1bfb31b draft

(svn r18566) -Codechange: When both the union and intersection of refit masks of articulated vehicles are needed, they can be determined at once.
author frosch <frosch@openttd.org>
date Sun, 20 Dec 2009 14:28:55 +0000
parents 5ec270a4cb43
children ec50d4cd06b5
files src/articulated_vehicles.cpp src/articulated_vehicles.h src/autoreplace_cmd.cpp
diffstat 3 files changed, 39 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/src/articulated_vehicles.cpp
+++ b/src/articulated_vehicles.cpp
@@ -148,6 +148,33 @@
 }
 
 /**
+ * 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
@@ -155,21 +182,9 @@
  */
 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 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 @@
 {
 	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;
--- 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);
--- a/src/autoreplace_cmd.cpp
+++ b/src/autoreplace_cmd.cpp
@@ -170,13 +170,13 @@
 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.