changeset 18894:45d08c0d06e8 draft

(svn r23743) -Fix [FS#4906]: Call CB 15E for all vehicles before actually executing any refit.
author frosch <frosch@openttd.org>
date Tue, 03 Jan 2012 22:04:12 +0000
parents 7e608ea7c5da
children d0ca24721a85
files src/vehicle_cmd.cpp
diffstat 1 files changed, 38 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/vehicle_cmd.cpp
+++ b/src/vehicle_cmd.cpp
@@ -283,6 +283,13 @@
 	}
 }
 
+/** Helper structure for RefitVehicle() */
+struct RefitResult {
+	Vehicle *v;         ///< Vehicle to refit
+	uint capacity;      ///< New capacity of vehicle
+	uint mail_capacity; ///< New mail capacity of aircraft
+};
+
 /**
  * Refits a vehicle (chain).
  * This is the vehicle-type independent part of the CmdRefitXXX functions.
@@ -309,6 +316,9 @@
 		v = v->First();
 	}
 
+	static SmallVector<RefitResult, 16> refit_result;
+	refit_result.Clear();
+
 	v->InvalidateNewGRFCacheOfChain();
 	for (; v != NULL; v = (only_this ? NULL : v->Next())) {
 		if (v->type == VEH_TRAIN && !vehicles_to_refit.Contains(v->index) && !only_this) continue;
@@ -351,19 +361,38 @@
 		}
 		cost.AddCost(refit_cost);
 
-		if (flags & DC_EXEC) {
-			v->cargo.Truncate((v->cargo_type == new_cid) ? amount : 0);
-			v->cargo_type = new_cid;
-			v->cargo_cap = amount;
-			v->cargo_subtype = new_subtype;
-			if (v->type == VEH_AIRCRAFT) {
-				Vehicle *u = v->Next();
-				u->cargo_cap = mail_capacity;
-				u->cargo.Truncate(mail_capacity);
+		/* Record the refitting.
+		 * Do not execute the refitting immediately, so DetermineCapacity and GetRefitCost do the same in test and exec run.
+		 * (weird NewGRFs)
+		 * Note:
+		 *  - If the capacity of vehicles depends on other vehicles in the chain, the actual capacity is
+		 *    set after RefitVehicle() via ConsistChanged() and friends. The estimation via _returned_refit_capacity will be wrong.
+		 *  - We have to call the refit cost callback with the pre-refit configuration of the chain because we want refit and
+		 *    autorefit to behave the same, and we need its result for auto_refit_allowed.
+		 */
+		RefitResult *result = refit_result.Append();
+		result->v = v;
+		result->capacity = amount;
+		result->mail_capacity = mail_capacity;
+	}
+
+	if (flags & DC_EXEC) {
+		/* Store the result */
+		for (RefitResult *result = refit_result.Begin(); result != refit_result.End(); result++) {
+			Vehicle *u = result->v;
+			u->cargo.Truncate((u->cargo_type == new_cid) ? result->capacity : 0);
+			u->cargo_type = new_cid;
+			u->cargo_cap = result->capacity;
+			u->cargo_subtype = new_subtype;
+			if (u->type == VEH_AIRCRAFT) {
+				Vehicle *w = u->Next();
+				w->cargo_cap = result->mail_capacity;
+				w->cargo.Truncate(result->mail_capacity);
 			}
 		}
 	}
 
+	refit_result.Clear();
 	_returned_refit_capacity = total_capacity;
 	_returned_mail_refit_capacity = total_mail_capacity;
 	return cost;