changeset 18638:ac23ced64c4b draft

(svn r23485) -Fix: Autorefit failed if the first part of an articulated vehicle did not carry any cargo.
author frosch <frosch@openttd.org>
date Sat, 10 Dec 2011 21:00:57 +0000
parents 2c51accd82c3
children 14549b010f86
files src/economy.cpp
diffstat 1 files changed, 25 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/economy.cpp
+++ b/src/economy.cpp
@@ -1172,6 +1172,22 @@
 }
 
 /**
+ * Checks whether an articulated vehicle is empty.
+ * @param v Vehicle
+ * @return true if all parts are empty.
+ */
+static bool IsArticulatedVehicleEmpty(Vehicle *v)
+{
+	v = v->GetFirstEnginePart();
+
+	for (; v != NULL; v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : NULL) {
+		if (v->cargo.Count() != 0) return false;
+	}
+
+	return true;
+}
+
+/**
  * Loads/unload the vehicle if possible.
  * @param front the vehicle to be (un)loaded
  * @param cargo_left the amount of each cargo type that is
@@ -1221,8 +1237,11 @@
 
 	CargoPayment *payment = front->cargo_payment;
 
+	uint artic_part = 0; // Articulated part we are currently trying to load. (not counting parts without capacity)
 	for (Vehicle *v = front; v != NULL; v = v->Next()) {
+		if (v == front || !v->Previous()->HasArticulatedPart()) artic_part = 0;
 		if (v->cargo_cap == 0) continue;
+		artic_part++;
 
 		const Engine *e = v->GetEngine();
 		byte load_amount = e->info.load_amount;
@@ -1312,9 +1331,10 @@
 		/* Do not pick up goods when we have no-load set or loading is stopped. */
 		if (front->current_order.GetLoadType() & OLFB_NO_LOAD || HasBit(front->vehicle_flags, VF_STOP_LOADING)) continue;
 
-		/* This order has a refit, the vehicle is a normal vehicle and completely empty, do it now. */
-		if (front->current_order.IsRefit() && !v->IsArticulatedPart() && v->cargo.Count() == 0 &&
+		/* This order has a refit, if this is the first vehicle part carrying cargo and the whole vehicle is empty, try refitting. */
+		if (front->current_order.IsRefit() && artic_part == 1 && IsArticulatedVehicleEmpty(v) &&
 				(v->type != VEH_AIRCRAFT || (Aircraft::From(v)->IsNormalAircraft() && v->Next()->cargo.Count() == 0))) {
+			Vehicle *v_start = v->GetFirstEnginePart();
 			CargoID new_cid = front->current_order.GetRefitCargo();
 			byte new_subtype = front->current_order.GetRefitSubtype();
 
@@ -1322,7 +1342,7 @@
 
 			/* Check if all articulated parts are empty and collect refit mask. */
 			uint32 refit_mask = e->info.refit_mask;
-			Vehicle *w = v;
+			Vehicle *w = v_start;
 			while (w->HasArticulatedPart()) {
 				w = w->GetNextArticulatedPart();
 				if (w->cargo.Count() > 0) new_cid = CT_NO_REFIT;
@@ -1338,7 +1358,7 @@
 						/* Try to find out if auto-refitting would succeed. In case the refit is allowed,
 						 * the returned refit capacity will be greater than zero. */
 						new_subtype = GetBestFittingSubType(v, v, cid);
-						DoCommand(v->tile, v->index, cid | 1U << 6 | new_subtype << 8 | 1U << 16, DC_QUERY_COST, GetCmdRefitVeh(v)); // Auto-refit and only this vehicle including artic parts.
+						DoCommand(v_start->tile, v_start->index, cid | 1U << 6 | new_subtype << 8 | 1U << 16, DC_QUERY_COST, GetCmdRefitVeh(v_start)); // Auto-refit and only this vehicle including artic parts.
 						if (_returned_refit_capacity > 0) {
 							amount = cargo_left[cid];
 							new_cid = cid;
@@ -1349,7 +1369,7 @@
 
 			/* Refit if given a valid cargo. */
 			if (new_cid < NUM_CARGO) {
-				CommandCost cost = DoCommand(v->tile, v->index, new_cid | 1U << 6 | new_subtype << 8 | 1U << 16, DC_EXEC, GetCmdRefitVeh(v)); // Auto-refit and only this vehicle including artic parts.
+				CommandCost cost = DoCommand(v_start->tile, v_start->index, new_cid | 1U << 6 | new_subtype << 8 | 1U << 16, DC_EXEC, GetCmdRefitVeh(v_start)); // Auto-refit and only this vehicle including artic parts.
 				if (cost.Succeeded()) front->profit_this_year -= cost.GetCost() << 8;
 				ge = &st->goods[v->cargo_type];
 			}