src/train_cmd.cpp
branchnoai
changeset 9701 d1ac22c62f64
parent 9694 e72987579514
child 9703 d2a6acdbd665
--- a/src/train_cmd.cpp	Sun Aug 19 14:04:13 2007 +0000
+++ b/src/train_cmd.cpp	Sun Sep 02 11:17:33 2007 +0000
@@ -71,7 +71,7 @@
 	uint32 total_power = 0;
 	uint32 max_te = 0;
 
-	for (const Vehicle *u = v; u != NULL; u = u->next) {
+	for (const Vehicle *u = v; u != NULL; u = u->Next()) {
 		/* Power is not added for articulated parts */
 		if (IsArticulatedPart(u)) continue;
 
@@ -113,7 +113,7 @@
 {
 	uint32 weight = 0;
 
-	for (Vehicle *u = v; u != NULL; u = u->next) {
+	for (Vehicle *u = v; u != NULL; u = u->Next()) {
 		uint32 vweight = GetCargo(u->cargo_type)->weight * u->cargo.Count() * FreightWagonMult(u->cargo_type) / 16;
 
 		/* Vehicle weight is not added for articulated parts. */
@@ -159,11 +159,11 @@
 	v->u.rail.cached_total_length = 0;
 	v->u.rail.compatible_railtypes = 0;
 
-	for (Vehicle *u = v; u != NULL; u = u->next) {
+	for (Vehicle *u = v; u != NULL; u = u->Next()) {
 		const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
 
-		/* Update the v->first cache. This is faster than having to brute force it later. */
-		if (u->first == NULL) u->first = v;
+		/* Check the v->first cache. */
+		assert(u->First() == v);
 
 		/* update the 'first engine' */
 		u->u.rail.first_engine = v == u ? INVALID_ENGINE : first_engine;
@@ -236,7 +236,7 @@
 			veh_len = GetVehicleCallback(CBID_VEHICLE_LENGTH, 0, 0, u->engine_type, u);
 		}
 		if (veh_len == CALLBACK_FAILED) veh_len = rvi_u->shorten_factor;
-		veh_len = clamp(veh_len, 0, u->next == NULL ? 7 : 5); // the clamp on vehicles not the last in chain is stricter, as too short wagons can break the 'follow next vehicle' code
+		veh_len = clamp(veh_len, 0, u->Next() == NULL ? 7 : 5); // the clamp on vehicles not the last in chain is stricter, as too short wagons can break the 'follow next vehicle' code
 		u->u.rail.cached_veh_length = 8 - veh_len;
 		v->u.rail.cached_total_length += u->u.rail.cached_veh_length;
 	}
@@ -302,7 +302,7 @@
 static int GetTrainAcceleration(Vehicle *v, bool mode)
 {
 	int max_speed = 2000;
-	int speed = v->cur_speed * 10 / 16; //[mph]
+	int speed = v->GetDisplaySpeed(); //[mph]
 	int curvecount[2] = {0, 0};
 
 	/*first find the curve speed limit */
@@ -310,9 +310,9 @@
 	int sum = 0;
 	int pos = 0;
 	int lastpos = -1;
-	for (const Vehicle *u = v; u->next != NULL; u = u->next, pos++) {
+	for (const Vehicle *u = v; u->Next() != NULL; u = u->Next(), pos++) {
 		Direction dir = u->direction;
-		Direction ndir = u->next->direction;
+		Direction ndir = u->Next()->direction;
 		int i;
 
 		for (i = 0; i < 2; i++) {
@@ -372,7 +372,7 @@
 	int num = 0; //number of vehicles, change this into the number of axles later
 	int incl = 0;
 	int drag_coeff = 20; //[1e-4]
-	for (const Vehicle *u = v; u != NULL; u = u->next) {
+	for (const Vehicle *u = v; u != NULL; u = u->Next()) {
 		num++;
 		drag_coeff += 3;
 
@@ -559,7 +559,7 @@
 			SetTrainWagon(v);
 
 			if (u != NULL) {
-				u->next = v;
+				u->SetNext(v);
 			} else {
 				SetFreeWagon(v);
 				InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
@@ -584,12 +584,12 @@
 			_new_vehicle_id = v->index;
 
 			VehiclePositionChanged(v);
-			TrainConsistChanged(GetFirstVehicleInChain(v));
-			UpdateTrainGroupID(GetFirstVehicleInChain(v));
+			TrainConsistChanged(v->First());
+			UpdateTrainGroupID(v->First());
 
 			InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 			if (IsLocalPlayer()) {
-				InvalidateAutoreplaceWindow(VEH_TRAIN, v->group_id); // updates the replace Train window
+				InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Train window
 			}
 			GetPlayer(_current_player)->num_engines[engine]++;
 		}
@@ -621,6 +621,7 @@
 
 static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building)
 {
+	u = new (u) Train();
 	u->direction = v->direction;
 	u->owner = v->owner;
 	u->tile = v->tile;
@@ -629,7 +630,6 @@
 	u->z_pos = v->z_pos;
 	u->u.rail.track = TRACK_BIT_DEPOT;
 	u->vehstatus = v->vehstatus & ~VS_STOPPED;
-	u = new (u) Train();
 	u->subtype = 0;
 	SetMultiheaded(u);
 	u->spritenum = v->spritenum + 1;
@@ -637,7 +637,7 @@
 	u->cargo_subtype = v->cargo_subtype;
 	u->cargo_cap = v->cargo_cap;
 	u->u.rail.railtype = v->u.rail.railtype;
-	if (building) v->next = u;
+	if (building) v->SetNext(u);
 	u->engine_type = v->engine_type;
 	u->build_year = v->build_year;
 	if (building) v->value >>= 1;
@@ -773,7 +773,7 @@
 			RebuildVehicleLists();
 			InvalidateWindow(WC_COMPANY, v->owner);
 			if (IsLocalPlayer())
-				InvalidateAutoreplaceWindow(VEH_TRAIN, v->group_id); // updates the replace Train window
+				InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Train window
 
 			GetPlayer(_current_player)->num_engines[p1]++;
 		}
@@ -793,7 +793,7 @@
 	if (!IsTileDepotType(tile, TRANSPORT_RAIL) || v->cur_speed != 0) return -1;
 
 	int count = 0;
-	for (; v != NULL; v = v->next) {
+	for (; v != NULL; v = v->Next()) {
 		/* This count is used by the depot code to determine the number of engines
 		 * in the consist. Exclude articulated parts so that autoreplacing to
 		 * engines with more articulated parts than before works correctly.
@@ -841,8 +841,7 @@
 
 	Vehicle *u;
 	for (u = first; GetNextVehicle(u) != v; u = GetNextVehicle(u)) {}
-	GetLastEnginePart(u)->next = GetNextVehicle(v);
-	v->first = NULL; // we shouldn't point to the old first, since the vehicle isn't in that chain anymore
+	GetLastEnginePart(u)->SetNext(GetNextVehicle(v));
 	return first;
 }
 
@@ -858,7 +857,7 @@
 			Vehicle *v = dst;
 
 			while (v->engine_type == eng) {
-				v = v->next;
+				v = v->Next();
 				if (v == NULL) return dst;
 			}
 		}
@@ -873,11 +872,12 @@
  */
 static void AddWagonToConsist(Vehicle *v, Vehicle *dest)
 {
-	UnlinkWagon(v, GetFirstVehicleInChain(v));
+	UnlinkWagon(v, v->First());
 	if (dest == NULL) return;
 
-	v->next = dest->next;
-	dest->next = v;
+	Vehicle *next = dest->Next();
+	dest->SetNext(v);
+	v->SetNext(next);
 	ClearFreeWagon(v);
 	ClearFrontEngine(v);
 }
@@ -897,7 +897,7 @@
 
 		/* make sure that there are no free cars before next engine */
 		Vehicle *u;
-		for (u = v; u->next != NULL && !IsTrainEngine(u->next); u = u->next) {}
+		for (u = v; u->Next() != NULL && !IsTrainEngine(u->Next()); u = u->Next()) {}
 
 		if (u == v->u.rail.other_multiheaded_part) continue;
 		AddWagonToConsist(v->u.rail.other_multiheaded_part, u);
@@ -934,19 +934,19 @@
 	}
 
 	/* if an articulated part is being handled, deal with its parent vehicle */
-	while (IsArticulatedPart(src)) src = GetPrevVehicleInChain(src);
+	while (IsArticulatedPart(src)) src = src->Previous();
 	if (dst != NULL) {
-		while (IsArticulatedPart(dst)) dst = GetPrevVehicleInChain(dst);
+		while (IsArticulatedPart(dst)) dst = dst->Previous();
 	}
 
 	/* don't move the same vehicle.. */
 	if (src == dst) return CommandCost();
 
 	/* locate the head of the two chains */
-	Vehicle *src_head = GetFirstVehicleInChain(src);
+	Vehicle *src_head = src->First();
 	Vehicle *dst_head;
 	if (dst != NULL) {
-		dst_head = GetFirstVehicleInChain(dst);
+		dst_head = dst->First();
 		if (dst_head->tile != src_head->tile) return CMD_ERROR;
 		/* Now deal with articulated part of destination wagon */
 		dst = GetLastEnginePart(dst);
@@ -1023,10 +1023,6 @@
 
 	/* do it? */
 	if (flags & DC_EXEC) {
-		/* clear the ->first cache */
-		for (Vehicle *u = src_head; u != NULL; u = u->next) u->first = NULL;
-		for (Vehicle *u = dst_head; u != NULL; u = u->next) u->first = NULL;
-
 		/* If we move the front Engine and if the second vehicle is not an engine
 		   add the whole vehicle to the DEFAULT_GROUP */
 		if (IsFrontEngine(src) && !IsDefaultGroupID(src->group_id)) {
@@ -1042,7 +1038,7 @@
 			if (src != src_head) {
 				Vehicle *v = src_head;
 				while (GetNextVehicle(v) != src) v = GetNextVehicle(v);
-				GetLastEnginePart(v)->next = NULL;
+				GetLastEnginePart(v)->SetNext(NULL);
 			} else {
 				InvalidateWindowData(WC_VEHICLE_DEPOT, src_head->tile); // We removed a line
 				src_head = NULL;
@@ -1052,7 +1048,7 @@
 			if (src_head == dst_head) dst_head = NULL;
 			/* unlink single wagon from linked list */
 			src_head = UnlinkWagon(src, src_head);
-			GetLastEnginePart(src)->next = NULL;
+			GetLastEnginePart(src)->SetNext(NULL);
 		}
 
 		if (dst == NULL) {
@@ -1098,17 +1094,16 @@
 				Vehicle *v;
 
 				for (v = src; GetNextVehicle(v) != NULL; v = GetNextVehicle(v));
-				GetLastEnginePart(v)->next = dst->next;
+				GetLastEnginePart(v)->SetNext(dst->Next());
 			}
-			dst->next = src;
+			dst->SetNext(src);
 		}
+
 		if (src->u.rail.other_multiheaded_part != NULL) {
 			if (src->u.rail.other_multiheaded_part == src_head) {
-				src_head = src_head->next;
+				src_head = src_head->Next();
 			}
 			AddWagonToConsist(src->u.rail.other_multiheaded_part, src);
-			/* previous line set the front engine to the old front. We need to clear that */
-			src->u.rail.other_multiheaded_part->first = NULL;
 		}
 
 		/* If there is an engine behind first_engine we moved away, it should become new first_engine
@@ -1219,8 +1214,8 @@
 
 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 
-	while (IsArticulatedPart(v)) v = GetPrevVehicleInChain(v);
-	Vehicle *first = GetFirstVehicleInChain(v);
+	while (IsArticulatedPart(v)) v = v->Previous();
+	Vehicle *first = v->First();
 
 	/* make sure the vehicle is stopped in the depot */
 	if (CheckTrainStoppedInDepot(first) < 0) {
@@ -1263,9 +1258,6 @@
 			if ((flags & DC_EXEC) && v == first) {
 				Vehicle *new_f = GetNextVehicle(first);
 
-				/* 2.1 If the first wagon is sold, update the first-> pointers to NULL */
-				for (Vehicle *tmp = first; tmp != NULL; tmp = tmp->next) tmp->first = NULL;
-
 				/* 2.2 If there are wagons present after the deleted front engine, check
 				 * if the second wagon (which will be first) is an engine. If it is one,
 				 * promote it as a new train, retaining the unitnumber, orders */
@@ -1300,7 +1292,7 @@
 					first->next_shared = NULL;
 
 					/* If we deleted a window then open a new one for the 'new' train */
-					if (IsLocalPlayer() && w != NULL) ShowTrainViewWindow(new_f);
+					if (IsLocalPlayer() && w != NULL) ShowVehicleViewWindow(new_f);
 				}
 			}
 
@@ -1471,8 +1463,8 @@
 	Vehicle *a, *b;
 
 	/* locate vehicles to swap */
-	for (a = v; l != 0; l--) a = a->next;
-	for (b = v; r != 0; r--) b = b->next;
+	for (a = v; l != 0; l--) a = a->Next();
+	for (b = v; r != 0; r--) b = b->Next();
 
 	if (a != b) {
 		/* swap the hidden bits */
@@ -1540,30 +1532,30 @@
 static void AdvanceWagons(Vehicle *v, bool before)
 {
 	Vehicle *base = v;
-	Vehicle *first = base->next;
+	Vehicle *first = base->Next();
 	uint length = CountVehiclesInChain(v);
 
 	while (length > 2) {
 		/* find pairwise matching wagon
 		 * start<>end, start+1<>end-1, ... */
 		Vehicle *last = first;
-		for (uint i = length - 3; i > 0; i--) last = last->next;
+		for (uint i = length - 3; i > 0; i--) last = last->Next();
 
 		int differential = last->u.rail.cached_veh_length - base->u.rail.cached_veh_length;
 		if (before) differential *= -1;
 
 		if (differential > 0) {
 			/* disconnect last car to make sure only this subset moves */
-			Vehicle *tempnext = last->next;
-			last->next = NULL;
+			Vehicle *tempnext = last->Next();
+			last->SetNext(NULL);
 
 			for (int i = 0; i < differential; i++) TrainController(first, false);
 
-			last->next = tempnext;
+			last->SetNext(tempnext);
 		}
 
 		base = first;
-		first = first->next;
+		first = first->Next();
 		length -= 2;
 	}
 }
@@ -1594,7 +1586,7 @@
 	/* count number of vehicles */
 	int r = -1;
 	const Vehicle *u = v;
-	do r++; while ( (u = u->next) != NULL );
+	do r++; while ((u = u->Next()) != NULL);
 
 	AdvanceWagons(v, true);
 
@@ -1634,7 +1626,7 @@
 			return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
 		}
 
-		Vehicle *front = GetFirstVehicleInChain(v);
+		Vehicle *front = v->First();
 		/* make sure the vehicle is stopped in the depot */
 		if (CheckTrainStoppedInDepot(front) < 0) {
 			return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
@@ -1646,8 +1638,8 @@
 			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 		}
 	} else {
-		/*turn the whole train around */
-		if (v->u.rail.crash_anim_pos != 0 || v->breakdown_ctr != 0) return CMD_ERROR;
+		/* turn the whole train around */
+		if (v->vehstatus & VS_CRASHED || v->breakdown_ctr != 0) return CMD_ERROR;
 
 		if (flags & DC_EXEC) {
 			if (_patches.realistic_acceleration && v->cur_speed != 0) {
@@ -1773,12 +1765,12 @@
 				}
 			}
 		}
-	} while ((v = v->next) != NULL && !only_this);
+	} while ((v = v->Next()) != NULL && !only_this);
 
 	_returned_refit_capacity = num;
 
 	/* Update the train's cached variables */
-	if (flags & DC_EXEC) TrainConsistChanged(GetFirstVehicleInChain(GetVehicle(p1)));
+	if (flags & DC_EXEC) TrainConsistChanged(GetVehicle(p1)->First());
 
 	return cost;
 }
@@ -2018,7 +2010,7 @@
 			}
 			break;
 		}
-	} while ((v = v->next) != NULL);
+	} while ((v = v->Next()) != NULL);
 
 	if (sound) PlayVehicleSound(u, VSE_TRAIN_EFFECT);
 }
@@ -2047,7 +2039,7 @@
 static bool CheckTrainStayInDepot(Vehicle *v)
 {
 	/* bail out if not all wagons are in the same depot or not in a depot at all */
-	for (const Vehicle *u = v; u != NULL; u = u->next) {
+	for (const Vehicle *u = v; u != NULL; u = u->Next()) {
 		if (u->u.rail.track != TRACK_BIT_DEPOT || u->tile != v->tile) return false;
 	}
 
@@ -2471,7 +2463,7 @@
 	do {
 		v->cur_image = v->GetImage(v->direction);
 		MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1);
-	} while ((v = v->next) != NULL);
+	} while ((v = v->Next()) != NULL);
 
 	/* need to update acceleration and cached values since the goods on the train changed. */
 	TrainCargoChanged(this);
@@ -2719,7 +2711,7 @@
 			myabs(v->x_pos - tcc->v->x_pos) < 6 &&
 			myabs(v->y_pos - tcc->v->y_pos) < 6 ) {
 
-		Vehicle *coll = GetFirstVehicleInChain(v);
+		Vehicle *coll = v->First();
 
 		/* it can't collide with its own wagons */
 		if (tcc->v == coll ||
@@ -2757,7 +2749,7 @@
 
 	TrainCollideChecker tcc;
 	tcc.v = v;
-	tcc.v_skip = v->next;
+	tcc.v_skip = v->Next();
 	tcc.num = 0;
 
 	/* find colliding vehicles */
@@ -2809,7 +2801,7 @@
 	Vehicle *prev;
 
 	/* For every vehicle after and including the given vehicle */
-	for (prev = GetPrevVehicleInChain(v); v != NULL; prev = v, v = v->next) {
+	for (prev = v->Previous(); v != NULL; prev = v, v = v->Next()) {
 		DiagDirection enterdir = DIAGDIR_BEGIN;
 		bool update_signals = false;
 		BeginVehicleMove(v);
@@ -2936,7 +2928,7 @@
 					goto invalid_rail;
 				}
 
-				if (IsLevelCrossingTile(v->tile) && v->next == NULL) {
+				if (IsLevelCrossingTile(v->tile) && v->Next() == NULL) {
 					UnbarCrossing(v->tile);
 					MarkTileDirtyByTile(v->tile);
 				}
@@ -2947,7 +2939,7 @@
 					v->tile = gp.new_tile;
 
 					if (GetTileRailType(gp.new_tile) != GetTileRailType(gp.old_tile)) {
-						TrainPowerChanged(GetFirstVehicleInChain(v));
+						TrainPowerChanged(v->First());
 					}
 
 					v->u.rail.track = chosen_track;
@@ -2999,7 +2991,7 @@
 
 			/* Signals can only change when the first
 			 * (above) or the last vehicle moves. */
-			if (v->next == NULL) TrainMovedChangeSignals(gp.old_tile, ReverseDiagDir(enterdir));
+			if (v->Next() == NULL) TrainMovedChangeSignals(gp.old_tile, ReverseDiagDir(enterdir));
 		}
 	}
 	return;
@@ -3030,8 +3022,8 @@
 	 * *u is then the one-before-last wagon, and *v the last
 	 * one which will physicially be removed */
 	Vehicle *u = v;
-	for (; v->next != NULL; v = v->next) u = v;
-	u->next = NULL;
+	for (; v->Next() != NULL; v = v->Next()) u = v;
+	u->SetNext(NULL);
 
 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 	DeleteWindowById(WC_VEHICLE_VIEW, v->index);
@@ -3092,7 +3084,7 @@
 			   the bridge in that case */
 			if (v->u.rail.track != TRACK_BIT_WORMHOLE) AfterSetTrainPos(v, false);
 		}
-	} while ((v = v->next) != NULL);
+	} while ((v = v->Next()) != NULL);
 }
 
 static void HandleCrashedTrain(Vehicle *v)
@@ -3119,7 +3111,7 @@
 					EV_EXPLOSION_SMALL);
 				break;
 			}
-		} while ((u = u->next) != NULL);
+		} while ((u = u->Next()) != NULL);
 	}
 
 	if (state <= 240 && !(v->tick_counter & 3)) ChangeTrainDirRandomly(v);
@@ -3257,7 +3249,7 @@
 static void TrainLocoHandler(Vehicle *v, bool mode)
 {
 	/* train has crashed? */
-	if (v->u.rail.crash_anim_pos != 0) {
+	if (v->vehstatus & VS_CRASHED) {
 		if (!mode) HandleCrashedTrain(v);
 		return;
 	}
@@ -3315,6 +3307,25 @@
 }
 
 
+
+Money Train::GetRunningCost() const
+{
+	Money cost = 0;
+	const Vehicle *v = this;
+
+	do {
+		const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
+
+		byte cost_factor = GetVehicleProperty(v, 0x0D, rvi->running_cost_base);
+		if (cost_factor == 0) continue;
+
+		cost += cost_factor * _price.running_rail[rvi->running_cost_class];
+	} while ((v = GetNextVehicle(v)) != NULL);
+
+	return cost;
+}
+
+
 void Train::Tick()
 {
 	if (_age_cargo_skip_counter == 0) this->cargo.AgeCargo();
@@ -3339,18 +3350,8 @@
 
 static void CheckIfTrainNeedsService(Vehicle *v)
 {
-	if (_patches.servint_trains == 0)                   return;
-	if (!VehicleNeedsService(v))                        return;
-	if (v->vehstatus & VS_STOPPED)                      return;
-	if (_patches.gotodepot && VehicleHasDepotOrders(v)) return;
-
-	/* Don't interfere with a depot visit scheduled by the user, or a
-	 * depot visit by the order list. */
-	if (v->current_order.type == OT_GOTO_DEPOT &&
-			(v->current_order.flags & (OF_HALT_IN_DEPOT | OF_PART_OF_ORDERS)) != 0)
-		return;
-
-	if (CheckTrainIsInsideDepot(v)) {
+	if (_patches.servint_trains == 0 || !VehicleNeedsService(v)) return;
+	if (v->IsInDepot()) {
 		VehicleServiceInDepot(v);
 		return;
 	}
@@ -3377,8 +3378,6 @@
 		return;
 	}
 
-	if (v->current_order.type == OT_LOADING) v->LeaveStation();
-
 	v->current_order.type = OT_GOTO_DEPOT;
 	v->current_order.flags = OF_NON_STOP;
 	v->current_order.dest = depot->index;
@@ -3386,22 +3385,6 @@
 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 }
 
-Money GetTrainRunningCost(const Vehicle *v)
-{
-	Money cost = 0;
-
-	do {
-		const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
-
-		byte cost_factor = GetVehicleProperty(v, 0x0D, rvi->running_cost_base);
-		if (cost_factor == 0) continue;
-
-		cost += cost_factor * _price.running_rail[rvi->running_cost_class];
-	} while ((v = GetNextVehicle(v)) != NULL);
-
-	return cost;
-}
-
 void OnNewDay_Train(Vehicle *v)
 {
 	if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v);
@@ -3422,7 +3405,7 @@
 
 		if ((v->vehstatus & VS_STOPPED) == 0) {
 			/* running costs */
-			CommandCost cost(GetTrainRunningCost(v) / 364);
+			CommandCost cost(v->GetRunningCost() / 364);
 
 			v->profit_this_year -= cost.GetCost() >> 8;
 
@@ -3497,7 +3480,7 @@
 					}
 
 					Vehicle *w;
-					for (w = u->next; w != NULL && (w->engine_type != u->engine_type || w->u.rail.other_multiheaded_part != NULL); w = GetNextVehicle(w));
+					for (w = u->Next(); w != NULL && (w->engine_type != u->engine_type || w->u.rail.other_multiheaded_part != NULL); w = GetNextVehicle(w));
 					if (w != NULL) {
 						/* we found a car to partner with this engine. Now we will make sure it face the right way */
 						if (IsTrainEngine(w)) {