(svn r2168) - Fix: Various stages of invisible trains, and wrong v->u.rail.track combinations. When a vehicle was sold its (possibly) assigned road slot for multislot was not cleared, thus resulting in a bug confusion. This should fix [ 1178520 ] Assertion failure in ai.c (invalid v->u.rail.track). With big thanks to TrueLight for the demo-recording patch, BJH for the wonderful savegame, Hackykid for his brilliant suggestions of the problem and Celestar for... ehm, making it all possible ;p
authorDarkvater
Fri, 08 Apr 2005 22:44:06 +0000
changeset 1664 000099fbae6e
parent 1663 b086c94fb9a5
child 1665 502e6aa3e60b
(svn r2168) - Fix: Various stages of invisible trains, and wrong v->u.rail.track combinations. When a vehicle was sold its (possibly) assigned road slot for multislot was not cleared, thus resulting in a bug confusion. This should fix [ 1178520 ] Assertion failure in ai.c (invalid v->u.rail.track). With big thanks to TrueLight for the demo-recording patch, BJH for the wonderful savegame, Hackykid for his brilliant suggestions of the problem and Celestar for... ehm, making it all possible ;p
roadveh_cmd.c
station_cmd.c
--- a/roadveh_cmd.c	Fri Apr 08 15:40:44 2005 +0000
+++ b/roadveh_cmd.c	Fri Apr 08 22:44:06 2005 +0000
@@ -229,6 +229,15 @@
 	return 0;
 }
 
+static inline void ClearSlot(Vehicle *v, RoadStop *rs)
+{
+	DEBUG(ms, 3) ("Multistop: Clearing slot %d at 0x%x", v->u.road.slotindex, rs->xy);
+	v->u.road.slot = NULL;
+	v->u.road.slot_age = 0;
+	if (rs != NULL)
+		rs->slot[v->u.road.slotindex] = INVALID_SLOT;
+}
+
 //  p1 = vehicle index in GetVehicle()
 //  p2 not used
 int32 CmdSellRoadVeh(int x, int y, uint32 flags, uint32 p1, uint32 p2)
@@ -253,6 +262,7 @@
 		RebuildVehicleLists();
 		InvalidateWindow(WC_COMPANY, v->owner);
 		DeleteWindowById(WC_VEHICLE_VIEW, v->index);
+		ClearSlot(v, v->u.road.slot);
 		DeleteVehicle(v);
 	}
 	InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Road); // updates the replace Road window
@@ -1177,14 +1187,6 @@
 
 static const byte _roadveh_data_2[4] = { 0,1,8,9 };
 
-static inline void ClearSlot(Vehicle *v, RoadStop *rs)
-{
-	DEBUG(ms, 3) ("Multistop: Clearing slot %d at 0x%x", v->u.road.slotindex, rs->xy);
-	v->u.road.slot = NULL;
-	v->u.road.slot_age = 0;
-	rs->slot[v->u.road.slotindex] = INVALID_SLOT;
-}
-
 static void RoadVehController(Vehicle *v)
 {
 	GetNewVehiclePosResult gp;
--- a/station_cmd.c	Fri Apr 08 15:40:44 2005 +0000
+++ b/station_cmd.c	Fri Apr 08 22:44:06 2005 +0000
@@ -2418,6 +2418,30 @@
 	}
 }
 
+static void CheckOrphanedSlots(const Station *st, RoadStopType rst)
+{
+	RoadStop *rs;
+	int k;
+
+	for (rs = GetPrimaryRoadStop(st, rst); rs != NULL; rs = rs->next) {
+		for (k = 0; k < NUM_SLOTS; k++) {
+			if (rs->slot[k] != INVALID_SLOT) {
+				Vehicle *v = GetVehicle(rs->slot[k]);
+
+				assert(v->type == VEH_Road);
+				if (v->u.road.slot != rs) {
+					DEBUG(ms, 1) ("Multistop: %s slot desync between stop at 0x%X of station %d "
+						"and Vehicle %d at going to 0x%X! (don't panic)", (v->cargo_type == CT_PASSENGERS) ? "Bus" : "Truck",
+						rs->xy, st->index, v->unitnumber, v->dest_tile);
+					v->u.road.slot = NULL;
+					v->u.road.slot_age = 0;
+					rs->slot[k] = INVALID_SLOT;
+				}
+			}
+		}
+	}
+}
+
 /* this function is called for one station each tick */
 static void StationHandleBigTick(Station *st)
 {
@@ -2428,52 +2452,9 @@
 			DeleteStation(st);
 	}
 
-	//Here we saveguard against orphaned slots
-	{
-		RoadStop *rs;
-
-		for (rs = GetPrimaryRoadStop(st, RS_BUS); rs != NULL; rs = rs->next) {
-			int k;
-			for (k = 0; k < NUM_SLOTS; k++) {
-				if (rs->slot[k] != INVALID_SLOT) {
-					Vehicle *v = GetVehicle(rs->slot[k]);
-
-					if (v->u.road.slot != rs) {
-						DEBUG(ms, 1) ("Multistop: Truck Slot Desync between stop at "
-							"0x%x of station %d (at 0x%x) and Vehicle %d at 0x%x, "
-							"going to 0x%x! "
-							"cleaning up (Don't panic)",
-							rs->xy, st->index, st->xy, v->unitnumber, v->tile,
-							v->dest_tile);
-						v->u.road.slot = NULL;
-						v->u.road.slot_age = 0;
-						rs->slot[k] = INVALID_SLOT;
-					}
-				}
-			}
-		}
-
-		for (rs = GetPrimaryRoadStop(st, RS_TRUCK); rs != NULL; rs = rs->next) {
-			int k;
-			for (k = 0; k < NUM_SLOTS; k++) {
-				if (rs->slot[k] != INVALID_SLOT) {
-					Vehicle *v = GetVehicle(rs->slot[k]);
-
-					if (v->u.road.slot != rs) {
-						DEBUG(ms, 1) ("Multistop: Truck Slot Desync between stop at "
-							"0x%x of station %d (at 0x%x) and Vehicle %d at 0x%x, "
-							"going to 0x%x! "
-							"cleaning up (Don't panic)",
-							rs->xy, st->index, st->xy, v->unitnumber, v->tile,
-							v->dest_tile);
-						v->u.road.slot = NULL;
-						v->u.road.slot_age = 0;
-						rs->slot[k] = INVALID_SLOT;
-					}
-				}
-			}
-		}
-	}
+	// Here we saveguard against orphaned slots
+	CheckOrphanedSlots(st, RS_BUS);
+	CheckOrphanedSlots(st, RS_TRUCK);
 }
 
 static inline void byte_inc_sat(byte *p) { byte b = *p + 1; if (b != 0) *p = b; }