train_cmd.c
changeset 1917 74cab7e464d1
parent 1909 8ef1a310dd39
child 1921 263f1bcfc038
--- a/train_cmd.c	Mon Jun 06 14:11:15 2005 +0000
+++ b/train_cmd.c	Mon Jun 06 14:26:15 2005 +0000
@@ -60,19 +60,31 @@
 }
 
 /**
- * Recalculates the cached stuff of a train. Should be called each time a vehicle is added to/removed from
- * the consist, and when the game is loaded.
- * @param v First vehicle of the consist.
+ * Recalculates the cached stuff of a train. Should be called each time a vehicle is added
+ * to/removed from the chain, and when the game is loaded.
+ * Note: this needs to be called too for 'wagon chains' (in the depot, without an engine)
+ * @param v First vehicle of the chain.
  */
 void TrainConsistChanged(Vehicle *v) {
-	const RailVehicleInfo *rvi_v = RailVehInfo(v->engine_type);
+	const RailVehicleInfo *rvi_v;
 	Vehicle *u;
 	uint16 max_speed = 0xFFFF;
 	uint32 power = 0;
+	EngineID first_engine;
+
+	assert(v->type == VEH_Train);
+
+	assert(v->subtype == TS_Front_Engine || v->subtype == TS_Free_Car);
+
+	rvi_v = RailVehInfo(v->engine_type);
+	first_engine = (v->subtype == TS_Front_Engine) ? v->engine_type : INVALID_VEHICLE;
 
 	for (u = v; u != NULL; u = u->next) {
 		const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
 
+		// update the 'first engine'
+		u->u.rail.first_engine = (v == u) ? INVALID_VEHICLE : first_engine;
+
 		// power is the sum of the powers of all engines and powered wagons in the consist
 		power += rvi_u->power;
 
@@ -449,11 +461,6 @@
 			if (u != NULL) {
 				u->next = v;
 				v->subtype = TS_Not_First;
-				v->u.rail.first_engine = u->u.rail.first_engine;
-				if (v->u.rail.first_engine == 0xffff && u->subtype == TS_Front_Engine)
-					v->u.rail.first_engine = u->engine_type;
-			} else {
-				v->u.rail.first_engine = 0xffff;
 			}
 
 			v->cargo_type = rvi->cargo_type;
@@ -471,6 +478,7 @@
 			_new_wagon_id = v->index;
 
 			VehiclePositionChanged(v);
+			TrainConsistChanged(GetFirstVehicleInChain(v));
 
 			InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 		}
@@ -547,7 +555,6 @@
 	u->z_pos = v->z_pos;
 	u->z_height = 6;
 	u->u.rail.track = 0x80;
-	v->u.rail.first_engine = 0xffff;
 	u->vehstatus = v->vehstatus & ~VS_STOPPED;
 	u->subtype = TS_Not_First;
 	u->spritenum = v->spritenum + 1;
@@ -620,7 +627,6 @@
 			v->z_pos = GetSlopeZ(x,y);
 			v->z_height = 6;
 			v->u.rail.track = 0x80;
-			v->u.rail.first_engine = 0xffff;
 			v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
 			v->spritenum = rvi->image_index;
 			v->cargo_type = rvi->cargo_type;
@@ -705,14 +711,11 @@
 {
 	Vehicle *u;
 
-	v->u.rail.first_engine = INVALID_VEHICLE;
-
 	// unlinking the first vehicle of the chain?
 	if (v == first) {
 		v = v->next;
 		if (v == NULL) return NULL;
 
-		for (u = v; u != NULL; u = u->next) u->u.rail.first_engine = v->engine_type;
 		v->subtype = TS_Free_Car;
 		return v;
 	}
@@ -838,10 +841,12 @@
 				Vehicle *v = src_head;
 				while (v->next != src) v=v->next;
 				v->next = NULL;
+			} else {
+				src_head = NULL;
 			}
 		} else {
 			// unlink single wagon from linked list
-			UnlinkWagon(src, src_head);
+			src_head = UnlinkWagon(src, src_head);
 			src->next = NULL;
 		}
 
@@ -854,11 +859,10 @@
 					assert(src->orders == NULL);
 					src->num_orders = 0;
 				}
-				dst_head = src;
 			} else {
 				src->subtype = TS_Free_Car;
 			}
-			src->u.rail.first_engine = 0xffff;
+			dst_head = src;
 		} else {
 			if (src->subtype == TS_Front_Engine) {
 				// the vehicle was previously a loco. need to free the order list and delete vehicle windows etc.
@@ -869,44 +873,42 @@
 			src->subtype = TS_Not_First;
 			src->unitnumber = 0; // doesn't occupy a unitnumber anymore.
 
-			// setup first_engine
-			src->u.rail.first_engine = dst->u.rail.first_engine;
-			if (src->u.rail.first_engine == 0xffff && dst->subtype == TS_Front_Engine)
-				src->u.rail.first_engine = dst->engine_type;
-
 			// link in the wagon(s) in the chain.
 			{
 				Vehicle *v;
 
-				for (v = src; v->next != NULL; v = v->next) {
-					v->next->u.rail.first_engine = v->u.rail.first_engine;
-				}
+				for (v = src; v->next != NULL; v = v->next) {};
 				v->next = dst->next;
 			}
 			dst->next = src;
 		}
 
-		if (src_head->subtype == TS_Front_Engine) {
+		if (src_head) {
 			TrainConsistChanged(src_head);
-			UpdateTrainAcceleration(src_head);
-		}
-		InvalidateWindow(WC_VEHICLE_DETAILS, src_head->index);
-		InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
+			if (src_head->subtype == TS_Front_Engine) {
+				UpdateTrainAcceleration(src_head);
+				InvalidateWindow(WC_VEHICLE_DETAILS, src_head->index);
+				/* Update the refit button and window */
+				InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
+				InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, 12);
+			}
+			/* Update the depot window */
+			InvalidateWindow(WC_VEHICLE_DEPOT, src_head->tile);
+		};
 
 		if (dst_head) {
+			TrainConsistChanged(dst_head);
 			if (dst_head->subtype == TS_Front_Engine) {
-				TrainConsistChanged(dst_head);
 				UpdateTrainAcceleration(dst_head);
+				InvalidateWindow(WC_VEHICLE_DETAILS, dst_head->index);
+				/* Update the refit button and window */
+				InvalidateWindowWidget(WC_VEHICLE_VIEW, dst_head->index, 12);
+				InvalidateWindow(WC_VEHICLE_REFIT, dst_head->index);
 			}
-			InvalidateWindow(WC_VEHICLE_DETAILS, dst_head->index);
-			/* Update the refit button and window */
-			InvalidateWindowWidget(WC_VEHICLE_VIEW, dst_head->index, 12);
-			InvalidateWindow(WC_VEHICLE_REFIT, dst_head->index);
+			/* Update the depot window */
+			InvalidateWindow(WC_VEHICLE_DEPOT, dst_head->tile);
 		}
 
-		/* I added this to so that the refit buttons get updated */
-		InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, 12);
-		InvalidateWindow(WC_VEHICLE_DEPOT, src_head->tile);
 		RebuildVehicleLists();
 	}
 
@@ -1048,11 +1050,13 @@
 				if (switch_engine) first->subtype = TS_Front_Engine;
 
 				/* 5. If the train still exists, update its acceleration, window, etc. */
-				if (first != NULL && first->subtype == TS_Front_Engine) {
-					InvalidateWindow(WC_VEHICLE_DETAILS, first->index);
-					InvalidateWindow(WC_VEHICLE_REFIT, first->index);
+				if (first != NULL) {
 					TrainConsistChanged(first);
-					UpdateTrainAcceleration(first);
+					if (first->subtype == TS_Front_Engine) {
+						InvalidateWindow(WC_VEHICLE_DETAILS, first->index);
+						InvalidateWindow(WC_VEHICLE_REFIT, first->index);
+						UpdateTrainAcceleration(first);
+					}
 				}
 
 
@@ -1103,9 +1107,10 @@
 			}
 
 			/* 3. If it is still a valid train after selling, update its acceleration and cached values */
-			if ((flags & DC_EXEC) && first != NULL && first->subtype == TS_Front_Engine) {
+			if ((flags & DC_EXEC) && first != NULL) {
 				TrainConsistChanged(first);
-				UpdateTrainAcceleration(first);
+				if (first->subtype == TS_Front_Engine)
+					UpdateTrainAcceleration(first);
 			}
 		} break;
 	}