changeset 8997:19392bf555ff draft

(svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID It's designed to save a bit of CPU time, specially if the replacement isn't buildable (think autorenew of old vehicle)
author bjarni <bjarni@openttd.org>
date Sat, 19 Apr 2008 17:47:56 +0000
parents 6a811008eb9f
children ba68f4945b28
files src/autoreplace_cmd.cpp src/vehicle.cpp
diffstat 2 files changed, 34 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/autoreplace_cmd.cpp
+++ b/src/autoreplace_cmd.cpp
@@ -117,31 +117,26 @@
 	return CT_NO_REFIT; // We failed to find a cargo type on the old vehicle and we will not refit the new one
 }
 
-/* Replaces a vehicle (used to be called autorenew)
+/** Replaces a vehicle (used to be called autorenew)
  * This function is only called from MaybeReplaceVehicle()
  * Must be called with _current_player set to the owner of the vehicle
  * @param w Vehicle to replace
  * @param flags is the flags to use when calling DoCommand(). Mainly DC_EXEC counts
+ * @param p The vehicle owner (faster than refinding the pointer)
+ * @param new_engine_type The EngineID to replace to
  * @return value is cost of the replacement or CMD_ERROR
  */
-static CommandCost ReplaceVehicle(Vehicle **w, byte flags, Money total_cost)
+static CommandCost ReplaceVehicle(Vehicle **w, byte flags, Money total_cost, const Player *p, EngineID new_engine_type)
 {
 	CommandCost cost;
 	CommandCost sell_value;
 	Vehicle *old_v = *w;
-	const Player *p = GetPlayer(old_v->owner);
-	EngineID new_engine_type;
 	const UnitID cached_unitnumber = old_v->unitnumber;
 	bool new_front = false;
 	Vehicle *new_v = NULL;
 	char *vehicle_name = NULL;
 	CargoID replacement_cargo_type;
 
-	/* Check if there is a autoreplacement set for the vehicle */
-	new_engine_type = EngineReplacementForPlayer(p, old_v->engine_type, old_v->group_id);
-	/* if not, just renew to the same type */
-	if (new_engine_type == INVALID_ENGINE) new_engine_type = old_v->engine_type;
-
 	replacement_cargo_type = GetNewCargoTypeForReplace(old_v, new_engine_type);
 
 	/* check if we can't refit to the needed type, so no replace takes place to prevent the vehicle from altering cargo type */
@@ -292,6 +287,32 @@
 	return cost;
 }
 
+/** Get the EngineID of the replacement for a vehicle
+ * @param v The vehicle to find a replacement for
+ * @param p The vehicle's owner (it's faster to forward the pointer than refinding it)
+ * @return the EngineID of the replacement. INVALID_ENGINE if no buildable replacement is found
+ */
+static EngineID GetNewEngineType(const Vehicle *v, const Player *p)
+{
+	if (v->type == VEH_TRAIN && IsRearDualheaded(v)) {
+		/* we build the rear ends of multiheaded trains with the front ones */
+		return INVALID_ENGINE;
+	}
+
+	EngineID e = EngineReplacementForPlayer(p, v->engine_type, v->group_id);
+
+	if (e != INVALID_ENGINE && IsEngineBuildable(e, v->type, _current_player)) {
+		return e;
+	}
+
+	if (v->NeedsAutorenewing(p) && // replace if engine is too old
+	    IsEngineBuildable(v->engine_type, v->type, _current_player)) { // engine can still be build
+		return v->engine_type;
+	}
+
+	return INVALID_ENGINE;
+}
+
 /** replaces a vehicle if it's set for autoreplace or is too old
  * (used to be called autorenew)
  * @param v The vehicle to replace
@@ -348,19 +369,11 @@
 		cost = CommandCost(EXPENSES_NEW_VEHICLES);
 		w = v;
 		do {
-			if (w->type == VEH_TRAIN && IsRearDualheaded(w)) {
-				/* we build the rear ends of multiheaded trains with the front ones */
-				continue;
-			}
-
-			// check if the vehicle should be replaced
-			if (!w->NeedsAutorenewing(p) || // replace if engine is too old
-					w->max_age == 0) { // rail cars got a max age of 0
-				if (!EngineHasReplacementForPlayer(p, w->engine_type, w->group_id)) continue;
-			}
+			EngineID new_engine = GetNewEngineType(w, p);
+			if (new_engine == INVALID_ENGINE) continue;
 
 			/* Now replace the vehicle */
-			cost.AddCost(ReplaceVehicle(&w, flags, cost.GetCost()));
+			cost.AddCost(ReplaceVehicle(&w, flags, cost.GetCost(), p, new_engine));
 
 			if (flags & DC_EXEC &&
 					(w->type != VEH_TRAIN || w->u.rail.first_engine == INVALID_ENGINE)) {
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -106,6 +106,7 @@
 
 	if (!p->engine_renew) return false;
 	if (this->age - this->max_age < (p->engine_renew_months * 30)) return false;
+	if (this->age == 0) return false; // rail cars don't age and lacks a max age
 
 	return true;
 }