changeset 9968:4ff475766d4f draft

(svn r14125) -Fix [FS#2237]: Segfault when autoreplace failed very early. Note: Proper indenting in next commit.
author frosch <frosch@openttd.org>
date Thu, 21 Aug 2008 20:42:45 +0000
parents b15bd9897237
children 7a0342e24e35
files src/autoreplace_cmd.cpp
diffstat 1 files changed, 13 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/autoreplace_cmd.cpp
+++ b/src/autoreplace_cmd.cpp
@@ -367,13 +367,13 @@
 		}
 		Vehicle *new_head = (new_vehs[0] != NULL ? new_vehs[0] : old_vehs[0]);
 
-		/* Separate the head, so we can start constructing the new chain */
+		/* Note: When autoreplace has already failed here, old_vehs[] is not completely initialized. But it is also not needed. */
 		if (cost.Succeeded()) {
+			/* Separate the head, so we can start constructing the new chain */
 			Vehicle *second = GetNextUnit(old_head);
 			if (second != NULL) cost.AddCost(MoveVehicle(second, NULL, DC_EXEC | DC_AUTOREPLACE, true));
 
 			assert(GetNextUnit(new_head) == NULL);
-		}
 
 		/* Append engines to the new chain
 		 * We do this from back to front, so that the head of the temporary vehicle chain does not change all the time.
@@ -468,7 +468,9 @@
 			}
 		}
 
-		/* If we are not in DC_EXEC undo everything */
+		/* If we are not in DC_EXEC undo everything, i.e. rearrange old vehicles.
+		 * We do this from back to front, so that the head of the temporary vehicle chain does not change all the time.
+		 * Note: The vehicle attach callback is disabled here :) */
 		if ((flags & DC_EXEC) == 0) {
 			/* Separate the head, so we can reattach the old vehicles */
 			Vehicle *second = GetNextUnit(old_head);
@@ -476,15 +478,16 @@
 
 			assert(GetNextUnit(old_head) == NULL);
 
-			/* Rearrange old vehicles and sell new
-			 * We do this from back to front, so that the head of the temporary vehicle chain does not change all the time.
-			 * Note: The vehicle attach callback is disabled here :) */
+			for (int i = num_units - 1; i > 0; i--) {
+				CommandCost ret = MoveVehicle(old_vehs[i], old_head, DC_EXEC | DC_AUTOREPLACE, false);
+				assert(ret.Succeeded());
+			}
+		}
+		}
 
+		/* Finally undo buying of new vehicles */
+		if ((flags & DC_EXEC) == 0) {
 			for (int i = num_units - 1; i >= 0; i--) {
-				if (i > 0) {
-					CommandCost ret = MoveVehicle(old_vehs[i], old_head, DC_EXEC | DC_AUTOREPLACE, false);
-					assert(ret.Succeeded());
-				}
 				if (new_vehs[i] != NULL) {
 					DoCommand(0, new_vehs[i]->index, 0, DC_EXEC, GetCmdSellVeh(new_vehs[i]));
 					new_vehs[i] = NULL;