Changeset - r11981:3840cc07cbe4
[Not reviewed]
master
0 24 0
rubidium - 16 years ago 2009-05-22 22:33:05
rubidium@openttd.org
(svn r16392) -Codechange: move some variables (the ones that aren't caches) from VehicleRail to Train
24 files changed with 269 insertions and 267 deletions:
0 comments (0 inline, 0 general)
src/articulated_vehicles.cpp
Show inline comments
 
@@ -312,8 +312,8 @@ void AddArticulatedParts(Vehicle *first,
 
				Train *t = new Train();
 
				t->subtype = 0;
 
				previous->SetNext(t);
 
				t->u.rail.track = front->u.rail.track;
 
				t->u.rail.railtype = front->u.rail.railtype;
 
				t->track = front->track;
 
				t->railtype = front->railtype;
 
				t->u.rail.first_engine = front->engine_type;
 

	
 
				t->spritenum = e_artic->u.rail.image_index;
src/autoreplace_cmd.cpp
Show inline comments
 
@@ -92,7 +92,7 @@ static void TransferCargo(Vehicle *old_v
 
	assert(!part_of_chain || new_head->IsPrimaryVehicle());
 
	/* Loop through source parts */
 
	for (Vehicle *src = old_veh; src != NULL; src = src->Next()) {
 
		if (!part_of_chain && src->type == VEH_TRAIN && src != old_veh && src != ((Train *)old_veh)->u.rail.other_multiheaded_part && !IsArticulatedPart(src)) {
 
		if (!part_of_chain && src->type == VEH_TRAIN && src != old_veh && src != ((Train *)old_veh)->other_multiheaded_part && !IsArticulatedPart(src)) {
 
			/* Skip vehicles, which do not belong to old_veh */
 
			src = GetLastEnginePart((Train *)src);
 
			continue;
 
@@ -101,7 +101,7 @@ static void TransferCargo(Vehicle *old_v
 

	
 
		/* Find free space in the new chain */
 
		for (Vehicle *dest = new_head; dest != NULL && src->cargo.Count() > 0; dest = dest->Next()) {
 
			if (!part_of_chain && dest->type == VEH_TRAIN && dest != new_head && dest != ((Train *)new_head)->u.rail.other_multiheaded_part && !IsArticulatedPart(dest)) {
 
			if (!part_of_chain && dest->type == VEH_TRAIN && dest != new_head && dest != ((Train *)new_head)->other_multiheaded_part && !IsArticulatedPart(dest)) {
 
				/* Skip vehicles, which do not belong to new_head */
 
				dest = GetLastEnginePart((Train *)dest);
 
				continue;
 
@@ -269,7 +269,7 @@ static CommandCost BuildReplacementVehic
 
	}
 

	
 
	/* Try to reverse the vehicle, but do not care if it fails as the new type might not be reversible */
 
	if (new_veh->type == VEH_TRAIN && HasBit(((Train *)old_veh)->u.rail.flags, VRF_REVERSE_DIRECTION)) {
 
	if (new_veh->type == VEH_TRAIN && HasBit(((Train *)old_veh)->flags, VRF_REVERSE_DIRECTION)) {
 
		DoCommand(0, new_veh->index, true, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
 
	}
 

	
src/elrail.cpp
Show inline comments
 
@@ -558,12 +558,12 @@ bool SettingsDisableElrail(int32 p1)
 
			if (v->type != VEH_TRAIN) continue;
 

	
 
			Train *t = (Train *)v;
 
			if (t->u.rail.railtype == RAILTYPE_ELECTRIC) {
 
			if (t->railtype == RAILTYPE_ELECTRIC) {
 
				/* this railroad vehicle is now compatible only with elrail,
 
				 *  so add there also normal rail compatibility */
 
				t->u.rail.compatible_railtypes |= RAILTYPES_RAIL;
 
				t->u.rail.railtype = RAILTYPE_RAIL;
 
				SetBit(t->u.rail.flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL);
 
				t->compatible_railtypes |= RAILTYPES_RAIL;
 
				t->railtype = RAILTYPE_RAIL;
 
				SetBit(t->flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL);
 
			}
 
		}
 
	}
src/newgrf_engine.cpp
Show inline comments
 
@@ -672,12 +672,12 @@ static uint32 VehicleGetVariable(const R
 
				const Train *u = IsTrainWagon(v) && HasBit(v->vehicle_flags, VRF_POWEREDWAGON) ? t->First() : t;
 
				RailType railtype = GetRailType(v->tile);
 
				bool powered = IsTrainEngine(v) || (IsTrainWagon(v) && HasBit(v->vehicle_flags, VRF_POWEREDWAGON));
 
				bool has_power = powered && HasPowerOnRail(u->u.rail.railtype, railtype);
 
				bool is_electric = powered && u->u.rail.railtype == RAILTYPE_ELECTRIC;
 
				bool has_power = powered && HasPowerOnRail(u->railtype, railtype);
 
				bool is_electric = powered && u->railtype == RAILTYPE_ELECTRIC;
 

	
 
				if (has_power) SetBit(modflags, 5);
 
				if (is_electric && !has_power) SetBit(modflags, 6);
 
				if (HasBit(t->u.rail.flags, VRF_TOGGLE_REVERSE)) SetBit(modflags, 8);
 
				if (HasBit(t->flags, VRF_TOGGLE_REVERSE)) SetBit(modflags, 8);
 
			}
 
			if (HasBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE)) SetBit(modflags, 10);
 

	
 
@@ -736,7 +736,7 @@ static uint32 VehicleGetVariable(const R
 
		case 0x47: return GB(Engine::Get(v->engine_type)->internal_id, 8, 8);
 
		case 0x48:
 
			if (v->type != VEH_TRAIN || v->spritenum != 0xFD) return v->spritenum;
 
			return HasBit(((Train *)v)->u.rail.flags, VRF_REVERSE_DIRECTION) ? 0xFE : 0xFD;
 
			return HasBit(((Train *)v)->flags, VRF_REVERSE_DIRECTION) ? 0xFE : 0xFD;
 

	
 
		case 0x49: return v->day_counter;
 
		case 0x4A: return v->breakdowns_since_last_service;
 
@@ -770,8 +770,8 @@ static uint32 VehicleGetVariable(const R
 
		case VEH_TRAIN: {
 
			Train *t = (Train *)v;
 
			switch (variable - 0x80) {
 
				case 0x62: return t->u.rail.track;
 
				case 0x66: return t->u.rail.railtype;
 
				case 0x62: return t->track;
 
				case 0x66: return t->railtype;
 
				case 0x73: return t->u.rail.cached_veh_length;
 
				case 0x74: return t->u.rail.cached_power;
 
				case 0x75: return GB(t->u.rail.cached_power,  8, 24);
src/npf.cpp
Show inline comments
 
@@ -1070,8 +1070,8 @@ NPFFoundTargetData NPFRouteToSafeTile(co
 
	start1.direction = trackdir;
 
	NPFSetFlag(&start1, NPF_FLAG_IGNORE_RESERVED, true);
 

	
 
	RailTypes railtypes = v->u.rail.compatible_railtypes;
 
	if (override_railtype) railtypes |= GetRailTypeInfo(v->u.rail.railtype)->compatible_railtypes;
 
	RailTypes railtypes = v->compatible_railtypes;
 
	if (override_railtype) railtypes |= GetRailTypeInfo(v->railtype)->compatible_railtypes;
 

	
 
	/* perform a breadth first search. Target is NULL,
 
	 * since we are just looking for any safe tile...*/
src/pbs.cpp
Show inline comments
 
@@ -236,7 +236,7 @@ static Vehicle *FindTrainOnTrackEnum(Veh
 
	if (v->type != VEH_TRAIN || (v->vehstatus & VS_CRASHED)) return NULL;
 

	
 
	Train *t = (Train *)v;
 
	if (HasBit((TrackBits)t->u.rail.track, TrackdirToTrack(info->res.trackdir))) {
 
	if (HasBit((TrackBits)t->track, TrackdirToTrack(info->res.trackdir))) {
 
		t = t->First();
 

	
 
		/* ALWAYS return the lowest ID (anti-desync!) */
 
@@ -264,7 +264,7 @@ PBSTileInfo FollowTrainReservation(const
 
	if (IsRailDepotTile(tile) && !GetRailDepotReservation(tile)) return PBSTileInfo(tile, trackdir, false);
 

	
 
	FindTrainOnTrackInfo ftoti;
 
	ftoti.res = FollowReservation(v->owner, GetRailTypeInfo(v->u.rail.railtype)->compatible_railtypes, tile, trackdir);
 
	ftoti.res = FollowReservation(v->owner, GetRailTypeInfo(v->railtype)->compatible_railtypes, tile, trackdir);
 
	ftoti.res.okay = IsSafeWaitingPosition(v, ftoti.res.tile, ftoti.res.trackdir, true, _settings_game.pf.forbid_90_deg);
 
	if (train_on_res != NULL) *train_on_res = HasVehicleOnPos(ftoti.res.tile, &ftoti, FindTrainOnTrackEnum);
 
	return ftoti.res;
 
@@ -333,7 +333,7 @@ bool IsSafeWaitingPosition(const Train *
 
	}
 

	
 
	/* Check next tile. For perfomance reasons, we check for 90 degree turns ourself. */
 
	CFollowTrackRail ft(v, GetRailTypeInfo(v->u.rail.railtype)->compatible_railtypes);
 
	CFollowTrackRail ft(v, GetRailTypeInfo(v->railtype)->compatible_railtypes);
 

	
 
	/* End of track? */
 
	if (!ft.Follow(tile, trackdir)) {
 
@@ -376,7 +376,7 @@ bool IsWaitingPositionFree(const Train *
 
	if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, trackdir) && !IsPbsSignal(GetSignalType(tile, track))) return true;
 

	
 
	/* Check the next tile, if it's a PBS signal, it has to be free as well. */
 
	CFollowTrackRail ft(v, GetRailTypeInfo(v->u.rail.railtype)->compatible_railtypes);
 
	CFollowTrackRail ft(v, GetRailTypeInfo(v->railtype)->compatible_railtypes);
 

	
 
	if (!ft.Follow(tile, trackdir)) return true;
 

	
src/rail_cmd.cpp
Show inline comments
 
@@ -93,7 +93,7 @@ Vehicle *EnsureNoTrainOnTrackProc(Vehicl
 
	if (v->type != VEH_TRAIN) return NULL;
 

	
 
	Train *t = (Train *)v;
 
	if ((t->u.rail.track != rail_bits) && !TracksOverlap(t->u.rail.track | rail_bits)) return NULL;
 
	if ((t->track != rail_bits) && !TracksOverlap(t->track | rail_bits)) return NULL;
 

	
 
	_error_message = VehicleInTheWayErrMsg(v);
 
	return v;
 
@@ -1308,7 +1308,7 @@ CommandCost CmdConvertRail(TileIndex til
 
					Track     track;
 
					while ((track = RemoveFirstTrack(&reserved)) != INVALID_TRACK) {
 
						Train *v = GetTrainForReservation(tile, track);
 
						if (v != NULL && !HasPowerOnRail(v->u.rail.railtype, totype)) {
 
						if (v != NULL && !HasPowerOnRail(v->railtype, totype)) {
 
							/* No power on new rail type, reroute. */
 
							FreeTrainTrackReservation(v);
 
							*vehicles_affected.Append() = v;
 
@@ -1374,7 +1374,7 @@ CommandCost CmdConvertRail(TileIndex til
 
						Track track = DiagDirToDiagTrack(GetTunnelBridgeDirection(tile));
 
						if (GetTunnelBridgeReservation(tile)) {
 
							Train *v = GetTrainForReservation(tile, track);
 
							if (v != NULL && !HasPowerOnRail(v->u.rail.railtype, totype)) {
 
							if (v != NULL && !HasPowerOnRail(v->railtype, totype)) {
 
								/* No power on new rail type, reroute. */
 
								FreeTrainTrackReservation(v);
 
								*vehicles_affected.Append() = v;
 
@@ -2484,7 +2484,7 @@ static VehicleEnterTileStatus VehicleEnt
 
	} else if (_fractcoords_enter[dir] == fract_coord) {
 
		if (DiagDirToDir(ReverseDiagDir(dir)) == v->direction) {
 
			/* enter the depot */
 
			v->u.rail.track = TRACK_BIT_DEPOT,
 
			v->track = TRACK_BIT_DEPOT,
 
			v->vehstatus |= VS_HIDDEN; // hide it
 
			v->direction = ReverseDir(v->direction);
 
			if (v->Next() == NULL) VehicleEnterDepot(v);
 
@@ -2498,7 +2498,7 @@ static VehicleEnterTileStatus VehicleEnt
 
			/* leave the depot? */
 
			if ((v = v->Next()) != NULL) {
 
				v->vehstatus &= ~VS_HIDDEN;
 
				v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y);
 
				v->track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y);
 
			}
 
		}
 
	}
src/saveload/afterload.cpp
Show inline comments
 
@@ -912,7 +912,7 @@ bool AfterLoadGame()
 
				continue;
 
			}
 
			if (v->type == VEH_TRAIN) {
 
				((Train *)v)->u.rail.track = TRACK_BIT_WORMHOLE;
 
				((Train *)v)->track = TRACK_BIT_WORMHOLE;
 
			} else {
 
				((RoadVehicle *)v)->state = RVSB_WORMHOLE;
 
			}
 
@@ -928,7 +928,7 @@ bool AfterLoadGame()
 
			if (v->type == VEH_TRAIN) {
 
				RailType rt = RailVehInfo(v->engine_type)->railtype;
 

	
 
				((Train *)v)->u.rail.railtype = rt;
 
				((Train *)v)->railtype = rt;
 
				if (rt == RAILTYPE_ELECTRIC) min_rail = RAILTYPE_RAIL;
 
			}
 
		}
 
@@ -1704,10 +1704,10 @@ bool AfterLoadGame()
 
		FOR_ALL_VEHICLES(u) {
 
			if (u->type == VEH_TRAIN) {
 
				Train *v = (Train *)u;
 
				if ((v->u.rail.track & TRACK_BIT_WORMHOLE) == TRACK_BIT_WORMHOLE) {
 
				if ((v->track & TRACK_BIT_WORMHOLE) == TRACK_BIT_WORMHOLE) {
 
					TryReserveRailTrack(v->tile, DiagDirToDiagTrack(GetTunnelBridgeDirection(v->tile)));
 
				} else if ((v->u.rail.track & TRACK_BIT_MASK) != TRACK_BIT_NONE) {
 
					TryReserveRailTrack(v->tile, TrackBitsToTrack(v->u.rail.track));
 
				} else if ((v->track & TRACK_BIT_MASK) != TRACK_BIT_NONE) {
 
					TryReserveRailTrack(v->tile, TrackBitsToTrack(v->track));
 
				}
 
			}
 
		}
src/saveload/oldloader_sl.cpp
Show inline comments
 
@@ -1079,10 +1079,10 @@ static uint16 _old_next_ptr;
 
static VehicleID _current_vehicle_id;
 

	
 
static const OldChunks vehicle_train_chunk[] = {
 
	OCL_SVAR(  OC_UINT8, VehicleRail, track ),
 
	OCL_SVAR(  OC_UINT8, VehicleRail, force_proceed ),
 
	OCL_SVAR( OC_UINT16, VehicleRail, crash_anim_pos ),
 
	OCL_SVAR(  OC_UINT8, VehicleRail, railtype ),
 
	OCL_SVAR(  OC_UINT8, Train, track ),
 
	OCL_SVAR(  OC_UINT8, Train, force_proceed ),
 
	OCL_SVAR( OC_UINT16, Train, crash_anim_pos ),
 
	OCL_SVAR(  OC_UINT8, Train, railtype ),
 

	
 
	OCL_NULL( 5 ), ///< Junk
 

	
 
@@ -1157,7 +1157,7 @@ static bool LoadOldVehicleUnion(Loadgame
 
	} else {
 
		switch (v->type) {
 
			default: NOT_REACHED();
 
			case VEH_TRAIN   : res = LoadChunk(ls, &v->u.rail,     vehicle_train_chunk);    break;
 
			case VEH_TRAIN   : res = LoadChunk(ls, v, vehicle_train_chunk);    break;
 
			case VEH_ROAD    : res = LoadChunk(ls, v, vehicle_road_chunk);     break;
 
			case VEH_SHIP    : res = LoadChunk(ls, v, vehicle_ship_chunk);     break;
 
			case VEH_AIRCRAFT: res = LoadChunk(ls, v, vehicle_air_chunk);      break;
 
@@ -1315,7 +1315,7 @@ bool LoadOldVehicle(LoadgameState *ls, i
 
					};
 
					if (v->spritenum / 2 >= lengthof(spriteset_rail)) return false;
 
					v->spritenum = spriteset_rail[v->spritenum / 2]; // adjust railway sprite set offset
 
					((Train *)v)->u.rail.railtype = type == 0x25 ? 1 : 0; // monorail / rail
 
					((Train *)v)->railtype = type == 0x25 ? 1 : 0; // monorail / rail
 
					break;
 
				}
 

	
src/saveload/vehicle_sl.cpp
Show inline comments
 
@@ -24,7 +24,7 @@ void ConnectMultiheadedTrains()
 

	
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->type == VEH_TRAIN) {
 
			((Train *)v)->u.rail.other_multiheaded_part = NULL;
 
			((Train *)v)->other_multiheaded_part = NULL;
 
		}
 
	}
 

	
 
@@ -46,7 +46,7 @@ void ConnectMultiheadedTrains()
 
			bool sequential_matching = IsFrontEngine(v);
 

	
 
			for (Train *u = (Train *)v; u != NULL; u = (Train *)GetNextVehicle(u)) {
 
				if (u->u.rail.other_multiheaded_part != NULL) continue; // we already linked this one
 
				if (u->other_multiheaded_part != NULL) continue; // we already linked this one
 

	
 
				if (IsMultiheaded(u)) {
 
					if (!IsTrainEngine(u)) {
 
@@ -60,7 +60,7 @@ void ConnectMultiheadedTrains()
 
					Train *w;
 
					if (sequential_matching) {
 
						for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
 
							if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
 
							if (w->engine_type != eid || w->other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
 

	
 
							/* we found a car to partner with this engine. Now we will make sure it face the right way */
 
							if (IsTrainEngine(w)) {
 
@@ -72,7 +72,7 @@ void ConnectMultiheadedTrains()
 
					} else {
 
						uint stack_pos = 0;
 
						for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
 
							if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
 
							if (w->engine_type != eid || w->other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
 

	
 
							if (IsTrainEngine(w)) {
 
								stack_pos++;
 
@@ -84,8 +84,8 @@ void ConnectMultiheadedTrains()
 
					}
 

	
 
					if (w != NULL) {
 
						w->u.rail.other_multiheaded_part = u;
 
						u->u.rail.other_multiheaded_part = w;
 
						w->other_multiheaded_part = u;
 
						u->other_multiheaded_part = w;
 
					} else {
 
						/* we got a front car and no rear cars. We will fake this one for forget that it should have been multiheaded */
 
						ClearMultiheaded(u);
 
@@ -525,13 +525,13 @@ const SaveLoad *GetVehicleDescription(Ve
 
	static const SaveLoad _train_desc[] = {
 
		SLE_WRITEBYTE(Vehicle, type, VEH_TRAIN),
 
		SLE_VEH_INCLUDEX(),
 
		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, crash_anim_pos),      SLE_UINT16),
 
		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, force_proceed),       SLE_UINT8),
 
		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, railtype),            SLE_UINT8),
 
		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, track),               SLE_UINT8),
 
		     SLE_VAR(Train, crash_anim_pos,      SLE_UINT16),
 
		     SLE_VAR(Train, force_proceed,       SLE_UINT8),
 
		     SLE_VAR(Train, railtype,            SLE_UINT8),
 
		     SLE_VAR(Train, track,               SLE_UINT8),
 

	
 
		SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags),               SLE_FILE_U8  | SLE_VAR_U16,   2,  99),
 
		SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags),               SLE_UINT16,                 100, SL_MAX_VERSION),
 
		 SLE_CONDVAR(Train, flags,               SLE_FILE_U8  | SLE_VAR_U16,   2,  99),
 
		 SLE_CONDVAR(Train, flags,               SLE_UINT16,                 100, SL_MAX_VERSION),
 
		SLE_CONDNULL(2, 2, 59),
 

	
 
		SLE_CONDNULL(2, 2, 19),
src/signal.cpp
Show inline comments
 
@@ -185,7 +185,7 @@ static SmallSet<DiagDirection, SIG_GLOB_
 
/** Check whether there is a train on rail, not in a depot */
 
static Vehicle *TrainOnTileEnum(Vehicle *v, void *)
 
{
 
	if (v->type != VEH_TRAIN || ((Train *)v)->u.rail.track == TRACK_BIT_DEPOT) return NULL;
 
	if (v->type != VEH_TRAIN || ((Train *)v)->track == TRACK_BIT_DEPOT) return NULL;
 

	
 
	return v;
 
}
src/train.h
Show inline comments
 
@@ -11,6 +11,33 @@
 

	
 
struct Train;
 

	
 
enum VehicleRailFlags {
 
	VRF_REVERSING         = 0,
 

	
 
	/* used to calculate if train is going up or down */
 
	VRF_GOINGUP           = 1,
 
	VRF_GOINGDOWN         = 2,
 

	
 
	/* used to store if a wagon is powered or not */
 
	VRF_POWEREDWAGON      = 3,
 

	
 
	/* used to reverse the visible direction of the vehicle */
 
	VRF_REVERSE_DIRECTION = 4,
 

	
 
	/* used to mark train as lost because PF can't find the route */
 
	VRF_NO_PATH_TO_DESTINATION = 5,
 

	
 
	/* used to mark that electric train engine is allowed to run on normal rail */
 
	VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL = 6,
 

	
 
	/* used for vehicle var 0xFE bit 8 (toggled each time the train is reversed, accurate for first vehicle only) */
 
	VRF_TOGGLE_REVERSE = 7,
 

	
 
	/* used to mark a train that can't get a path reservation */
 
	VRF_TRAIN_STUCK    = 8,
 
};
 

	
 

	
 
/** enum to handle train subtypes
 
 * Do not access it directly unless you have to. Use the access functions below
 
 * This is an enum to tell what bit to access as it is a bitmask
 
@@ -241,6 +268,17 @@ Money GetTrainRunningCost(const Train *v
 
 * As side-effect the vehicle type is set correctly.
 
 */
 
struct Train : public Vehicle {
 
	/* Link between the two ends of a multiheaded engine */
 
	Train *other_multiheaded_part;
 

	
 
	uint16 crash_anim_pos;
 

	
 
	uint16 flags;
 
	TrackBitsByte track;
 
	byte force_proceed;
 
	RailTypeByte railtype;
 
	RailTypes compatible_railtypes;
 

	
 
	/** Initializes the Vehicle to a train */
 
	Train() { this->type = VEH_TRAIN; }
 

	
src/train_cmd.cpp
Show inline comments
 
@@ -95,7 +95,7 @@ void TrainPowerChanged(Train *v)
 

	
 
		/* Power is not added for articulated parts */
 
		if (!IsArticulatedPart(u)) {
 
			bool engine_has_power = HasPowerOnRail(u->u.rail.railtype, railtype);
 
			bool engine_has_power = HasPowerOnRail(u->railtype, railtype);
 

	
 
			const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
 

	
 
@@ -112,7 +112,7 @@ void TrainPowerChanged(Train *v)
 
			}
 
		}
 

	
 
		if (HasBit(u->u.rail.flags, VRF_POWEREDWAGON) && HasPowerOnRail(v->u.rail.railtype, railtype)) {
 
		if (HasBit(u->flags, VRF_POWEREDWAGON) && HasPowerOnRail(v->railtype, railtype)) {
 
			total_power += RailVehInfo(u->u.rail.first_engine)->pow_wag_power;
 
		}
 
	}
 
@@ -148,7 +148,7 @@ static void TrainCargoChanged(Train *v)
 
		}
 

	
 
		/* powered wagons have extra weight added */
 
		if (HasBit(u->u.rail.flags, VRF_POWEREDWAGON)) {
 
		if (HasBit(u->flags, VRF_POWEREDWAGON)) {
 
			vweight += RailVehInfo(u->u.rail.first_engine)->pow_wag_weight;
 
		}
 

	
 
@@ -190,10 +190,10 @@ void CheckTrainsLengths()
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->type == VEH_TRAIN && v->First() == v && !(v->vehstatus & VS_CRASHED)) {
 
			for (const Train *u = (Train *)v, *w = (Train *)v->Next(); w != NULL; u = w, w = w->Next()) {
 
				if (u->u.rail.track != TRACK_BIT_DEPOT) {
 
					if ((w->u.rail.track != TRACK_BIT_DEPOT &&
 
				if (u->track != TRACK_BIT_DEPOT) {
 
					if ((w->track != TRACK_BIT_DEPOT &&
 
							max(abs(u->x_pos - w->x_pos), abs(u->y_pos - w->y_pos)) != u->u.rail.cached_veh_length) ||
 
							(w->u.rail.track == TRACK_BIT_DEPOT && TicksToLeaveDepot(u) <= 0)) {
 
							(w->track == TRACK_BIT_DEPOT && TicksToLeaveDepot(u) <= 0)) {
 
						SetDParam(0, v->index);
 
						SetDParam(1, v->owner);
 
						ShowErrorMessage(INVALID_STRING_ID, STR_BROKEN_VEHICLE_LENGTH, 0, 0);
 
@@ -223,7 +223,7 @@ void TrainConsistChanged(Train *v, bool 
 
	const RailVehicleInfo *rvi_v = RailVehInfo(v->engine_type);
 
	EngineID first_engine = IsFrontEngine(v) ? v->engine_type : INVALID_ENGINE;
 
	v->u.rail.cached_total_length = 0;
 
	v->u.rail.compatible_railtypes = RAILTYPES_NONE;
 
	v->compatible_railtypes = RAILTYPES_NONE;
 

	
 
	bool train_can_tilt = true;
 

	
 
@@ -235,7 +235,7 @@ void TrainConsistChanged(Train *v, bool 
 

	
 
		/* update the 'first engine' */
 
		u->u.rail.first_engine = v == u ? INVALID_ENGINE : first_engine;
 
		u->u.rail.railtype = rvi_u->railtype;
 
		u->railtype = rvi_u->railtype;
 

	
 
		if (IsTrainEngine(u)) first_engine = u->engine_type;
 

	
 
@@ -287,23 +287,23 @@ void TrainConsistChanged(Train *v, bool 
 
		if (rvi_v->pow_wag_power != 0 && rvi_u->railveh_type == RAILVEH_WAGON &&
 
			UsesWagonOverride(u) && !HasBit(u->u.rail.cached_vis_effect, 7)) {
 
			/* wagon is powered */
 
			SetBit(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status
 
			SetBit(u->flags, VRF_POWEREDWAGON); // cache 'powered' status
 
		} else {
 
			ClrBit(u->u.rail.flags, VRF_POWEREDWAGON);
 
			ClrBit(u->flags, VRF_POWEREDWAGON);
 
		}
 

	
 
		if (!IsArticulatedPart(u)) {
 
			/* Do not count powered wagons for the compatible railtypes, as wagons always
 
			   have railtype normal */
 
			if (rvi_u->power > 0) {
 
				v->u.rail.compatible_railtypes |= GetRailTypeInfo(u->u.rail.railtype)->powered_railtypes;
 
				v->compatible_railtypes |= GetRailTypeInfo(u->railtype)->powered_railtypes;
 
			}
 

	
 
			/* Some electric engines can be allowed to run on normal rail. It happens to all
 
			 * existing electric engines when elrails are disabled and then re-enabled */
 
			if (HasBit(u->u.rail.flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL)) {
 
				u->u.rail.railtype = RAILTYPE_RAIL;
 
				u->u.rail.compatible_railtypes |= RAILTYPES_RAIL;
 
			if (HasBit(u->flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL)) {
 
				u->railtype = RAILTYPE_RAIL;
 
				u->compatible_railtypes |= RAILTYPES_RAIL;
 
			}
 

	
 
			/* max speed is the minimum of the speed limits of all vehicles in the consist */
 
@@ -455,7 +455,7 @@ static int GetTrainAcceleration(Train *v
 

	
 
	if (max_speed != absolute_max_speed) {
 
		/* Apply the engine's rail type curve speed advantage, if it slowed by curves */
 
		const RailtypeInfo *rti = GetRailTypeInfo(v->u.rail.railtype);
 
		const RailtypeInfo *rti = GetRailTypeInfo(v->railtype);
 
		max_speed += (max_speed / 2) * rti->curve_speed;
 

	
 
		if (v->u.rail.cached_tilt) {
 
@@ -500,11 +500,11 @@ static int GetTrainAcceleration(Train *v
 
		num++;
 
		drag_coeff += 3;
 

	
 
		if (u->u.rail.track == TRACK_BIT_DEPOT) max_speed = min(max_speed, 61);
 

	
 
		if (HasBit(u->u.rail.flags, VRF_GOINGUP)) {
 
		if (u->track == TRACK_BIT_DEPOT) max_speed = min(max_speed, 61);
 

	
 
		if (HasBit(u->flags, VRF_GOINGUP)) {
 
			incl += u->u.rail.cached_veh_weight * 60; // 3% slope, quite a bit actually
 
		} else if (HasBit(u->u.rail.flags, VRF_GOINGDOWN)) {
 
		} else if (HasBit(u->flags, VRF_GOINGDOWN)) {
 
			incl -= u->u.rail.cached_veh_weight * 60;
 
		}
 
	}
 
@@ -514,7 +514,7 @@ static int GetTrainAcceleration(Train *v
 
	const int area = 120;
 
	const int friction = 35; //[1e-3]
 
	int resistance;
 
	if (v->u.rail.railtype != RAILTYPE_MAGLEV) {
 
	if (v->railtype != RAILTYPE_MAGLEV) {
 
		resistance = 13 * mass / 10;
 
		resistance += 60 * num;
 
		resistance += friction * mass * speed / 1000;
 
@@ -528,7 +528,7 @@ static int GetTrainAcceleration(Train *v
 
	const int max_te = v->u.rail.cached_max_te; // [N]
 
	int force;
 
	if (speed > 0) {
 
		switch (v->u.rail.railtype) {
 
		switch (v->railtype) {
 
			case RAILTYPE_RAIL:
 
			case RAILTYPE_ELECTRIC:
 
			case RAILTYPE_MONO:
 
@@ -545,7 +545,7 @@ static int GetTrainAcceleration(Train *v
 
		}
 
	} else {
 
		/* "kickoff" acceleration */
 
		force = (mode == AM_ACCEL && v->u.rail.railtype != RAILTYPE_MAGLEV) ? min(max_te, power) : power;
 
		force = (mode == AM_ACCEL && v->railtype != RAILTYPE_MAGLEV) ? min(max_te, power) : power;
 
		force = max(force, (mass * 8) + resistance);
 
	}
 

	
 
@@ -573,7 +573,7 @@ SpriteID Train::GetImage(Direction direc
 
	uint8 spritenum = this->spritenum;
 
	SpriteID sprite;
 

	
 
	if (HasBit(this->u.rail.flags, VRF_REVERSE_DIRECTION)) direction = ReverseDir(direction);
 
	if (HasBit(this->flags, VRF_REVERSE_DIRECTION)) direction = ReverseDir(direction);
 

	
 
	if (is_custom_sprite(spritenum)) {
 
		sprite = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(spritenum)));
 
@@ -677,7 +677,7 @@ static CommandCost CmdBuildRailWagon(Eng
 
		v->y_pos = y;
 
		v->z_pos = GetSlopeZ(x, y);
 
		v->owner = _current_company;
 
		v->u.rail.track = TRACK_BIT_DEPOT;
 
		v->track = TRACK_BIT_DEPOT;
 
		v->vehstatus = VS_HIDDEN | VS_DEFPAL;
 

	
 
//		v->subtype = 0;
 
@@ -696,7 +696,7 @@ static CommandCost CmdBuildRailWagon(Eng
 
		v->value = value.GetCost();
 
//		v->day_counter = 0;
 

	
 
		v->u.rail.railtype = rvi->railtype;
 
		v->railtype = rvi->railtype;
 

	
 
		v->build_year = _cur_year;
 
		v->cur_image = SPR_IMG_QUERY;
 
@@ -732,7 +732,7 @@ static void NormalizeTrainVehInDepot(con
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->type == VEH_TRAIN && IsFreeWagon(v) &&
 
				v->tile == u->tile &&
 
				((Train *)v)->u.rail.track == TRACK_BIT_DEPOT) {
 
				((Train *)v)->track == TRACK_BIT_DEPOT) {
 
			if (CmdFailed(DoCommand(0, v->index | (u->index << 16), 1, DC_EXEC,
 
					CMD_MOVE_RAIL_VEHICLE)))
 
				break;
 
@@ -751,14 +751,14 @@ static void AddRearEngineToMultiheadedTr
 
	u->x_pos = v->x_pos;
 
	u->y_pos = v->y_pos;
 
	u->z_pos = v->z_pos;
 
	u->u.rail.track = TRACK_BIT_DEPOT;
 
	u->track = TRACK_BIT_DEPOT;
 
	u->vehstatus = v->vehstatus & ~VS_STOPPED;
 
//	u->subtype = 0;
 
	u->spritenum = v->spritenum + 1;
 
	u->cargo_type = v->cargo_type;
 
	u->cargo_subtype = v->cargo_subtype;
 
	u->cargo_cap = v->cargo_cap;
 
	u->u.rail.railtype = v->u.rail.railtype;
 
	u->railtype = v->railtype;
 
	u->engine_type = v->engine_type;
 
	u->build_year = v->build_year;
 
	u->cur_image = SPR_IMG_QUERY;
 
@@ -769,8 +769,8 @@ static void AddRearEngineToMultiheadedTr
 
	VehicleMove(u, false);
 

	
 
	/* Now we need to link the front and rear engines together */
 
	v->u.rail.other_multiheaded_part = u;
 
	u->u.rail.other_multiheaded_part = v;
 
	v->other_multiheaded_part = u;
 
	u->other_multiheaded_part = v;
 
}
 

	
 
/** Build a railroad vehicle.
 
@@ -832,7 +832,7 @@ CommandCost CmdBuildRailVehicle(TileInde
 
		v->y_pos = y;
 
		v->z_pos = GetSlopeZ(x, y);
 
//		v->running_ticks = 0;
 
		v->u.rail.track = TRACK_BIT_DEPOT;
 
		v->track = TRACK_BIT_DEPOT;
 
		v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
 
		v->spritenum = rvi->image_index;
 
		v->cargo_type = e->GetDefaultCargoType();
 
@@ -850,7 +850,7 @@ CommandCost CmdBuildRailVehicle(TileInde
 
		v->max_age = e->lifelength * DAYS_IN_LEAP_YEAR;
 

	
 
		v->name = NULL;
 
		v->u.rail.railtype = rvi->railtype;
 
		v->railtype = rvi->railtype;
 
		_new_vehicle_id = v->index;
 

	
 
		v->service_interval = _settings_game.vehicle.servint_trains;
 
@@ -916,7 +916,7 @@ int CheckTrainInDepot(const Train *v, bo
 
		 *
 
		 * Also skip counting rear ends of multiheaded engines */
 
		if (!IsArticulatedPart(v) && !IsRearDualheaded(v)) count++;
 
		if (v->u.rail.track != TRACK_BIT_DEPOT || v->tile != tile ||
 
		if (v->track != TRACK_BIT_DEPOT || v->tile != tile ||
 
				(IsFrontEngine(v) && needs_to_be_stopped && !(v->vehstatus & VS_STOPPED))) {
 
			return -1;
 
		}
 
@@ -1021,8 +1021,8 @@ static void NormaliseTrainConsist(Train 
 
		Train *u;
 
		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);
 
		if (u == v->other_multiheaded_part) continue;
 
		AddWagonToConsist(v->other_multiheaded_part, u);
 
	}
 
}
 

	
 
@@ -1329,11 +1329,11 @@ CommandCost CmdMoveRailVehicle(TileIndex
 
			dst->SetNext(src);
 
		}
 

	
 
		if (src->u.rail.other_multiheaded_part != NULL) {
 
			if (src->u.rail.other_multiheaded_part == src_head) {
 
		if (src->other_multiheaded_part != NULL) {
 
			if (src->other_multiheaded_part == src_head) {
 
				src_head = src_head->Next();
 
			}
 
			AddWagonToConsist(src->u.rail.other_multiheaded_part, src);
 
			AddWagonToConsist(src->other_multiheaded_part, src);
 
		}
 

	
 
		/* If there is an engine behind first_engine we moved away, it should become new first_engine
 
@@ -1431,7 +1431,7 @@ CommandCost CmdSellRailWagon(TileIndex t
 
			/* 1. Delete the engine, if it is dualheaded also delete the matching
 
			 * rear engine of the loco (from the point of deletion onwards) */
 
			Train *rear = (IsMultiheaded(v) &&
 
				IsTrainEngine(v)) ? v->u.rail.other_multiheaded_part : NULL;
 
				IsTrainEngine(v)) ? v->other_multiheaded_part : NULL;
 

	
 
			if (rear != NULL) {
 
				cost.AddCost(-rear->value);
 
@@ -1510,7 +1510,7 @@ CommandCost CmdSellRailWagon(TileIndex t
 
				if (IsMultiheaded(v)) {
 
					if (IsTrainEngine(v)) {
 
						/* We got a front engine of a multiheaded set. Now we will sell the rear end too */
 
						Train *rear = v->u.rail.other_multiheaded_part;
 
						Train *rear = v->other_multiheaded_part;
 

	
 
						if (rear != NULL) {
 
							cost.AddCost(-rear->value);
 
@@ -1528,7 +1528,7 @@ CommandCost CmdSellRailWagon(TileIndex t
 
								delete rear;
 
							}
 
						}
 
					} else if (v->u.rail.other_multiheaded_part != NULL) {
 
					} else if (v->other_multiheaded_part != NULL) {
 
						/* The front to this engine is earlier in this train. Do nothing */
 
						continue;
 
					}
 
@@ -1597,9 +1597,9 @@ static inline void SetLastSpeed(Train *v
 
/** Mark a train as stuck and stop it if it isn't stopped right now. */
 
static void MarkTrainAsStuck(Train *v)
 
{
 
	if (!HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) {
 
	if (!HasBit(v->flags, VRF_TRAIN_STUCK)) {
 
		/* It is the first time the problem occured, set the "train stuck" flag. */
 
		SetBit(v->u.rail.flags, VRF_TRAIN_STUCK);
 
		SetBit(v->flags, VRF_TRAIN_STUCK);
 
		v->load_unload_time_rem = 0;
 

	
 
		/* Stop train */
 
@@ -1651,32 +1651,32 @@ static void ReverseTrainSwapVeh(Train *v
 
			a->vehstatus = tmp;
 
		}
 

	
 
		Swap(a->u.rail.track, b->u.rail.track);
 
		Swap(a->track, b->track);
 
		Swap(a->direction,    b->direction);
 

	
 
		/* toggle direction */
 
		if (a->u.rail.track != TRACK_BIT_DEPOT) a->direction = ReverseDir(a->direction);
 
		if (b->u.rail.track != TRACK_BIT_DEPOT) b->direction = ReverseDir(b->direction);
 
		if (a->track != TRACK_BIT_DEPOT) a->direction = ReverseDir(a->direction);
 
		if (b->track != TRACK_BIT_DEPOT) b->direction = ReverseDir(b->direction);
 

	
 
		Swap(a->x_pos, b->x_pos);
 
		Swap(a->y_pos, b->y_pos);
 
		Swap(a->tile,  b->tile);
 
		Swap(a->z_pos, b->z_pos);
 

	
 
		SwapTrainFlags(&a->u.rail.flags, &b->u.rail.flags);
 
		SwapTrainFlags(&a->flags, &b->flags);
 

	
 
		/* update other vars */
 
		UpdateVarsAfterSwap(a);
 
		UpdateVarsAfterSwap(b);
 

	
 
		/* call the proper EnterTile function unless we are in a wormhole */
 
		if (a->u.rail.track != TRACK_BIT_WORMHOLE) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
 
		if (b->u.rail.track != TRACK_BIT_WORMHOLE) VehicleEnterTile(b, b->tile, b->x_pos, b->y_pos);
 
		if (a->track != TRACK_BIT_WORMHOLE) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
 
		if (b->track != TRACK_BIT_WORMHOLE) VehicleEnterTile(b, b->tile, b->x_pos, b->y_pos);
 
	} else {
 
		if (a->u.rail.track != TRACK_BIT_DEPOT) a->direction = ReverseDir(a->direction);
 
		if (a->track != TRACK_BIT_DEPOT) a->direction = ReverseDir(a->direction);
 
		UpdateVarsAfterSwap(a);
 

	
 
		if (a->u.rail.track != TRACK_BIT_WORMHOLE) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
 
		if (a->track != TRACK_BIT_WORMHOLE) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
 
	}
 

	
 
	/* Update train's power incase tiles were different rail type */
 
@@ -1811,7 +1811,7 @@ static void AdvanceWagonsAfterSwap(Train
 
{
 
	/* first of all, fix the situation when the train was entering a depot */
 
	Train *dep = v; // last vehicle in front of just left depot
 
	while (dep->Next() != NULL && (dep->u.rail.track == TRACK_BIT_DEPOT || dep->Next()->u.rail.track != TRACK_BIT_DEPOT)) {
 
	while (dep->Next() != NULL && (dep->track == TRACK_BIT_DEPOT || dep->Next()->track != TRACK_BIT_DEPOT)) {
 
		dep = dep->Next(); // find first vehicle outside of a depot, with next vehicle inside a depot
 
	}
 

	
 
@@ -1823,7 +1823,7 @@ static void AdvanceWagonsAfterSwap(Train
 

	
 
		if (d <= 0) {
 
			leave->vehstatus &= ~VS_HIDDEN; // move it out of the depot
 
			leave->u.rail.track = TrackToTrackBits(GetRailDepotTrack(leave->tile));
 
			leave->track = TrackToTrackBits(GetRailDepotTrack(leave->tile));
 
			for (int i = 0; i >= d; i--) TrainController(leave, NULL); // maybe move it, and maybe let another wagon leave
 
		}
 
	} else {
 
@@ -1890,9 +1890,9 @@ static void ReverseTrainDirection(Train 
 
		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
 
	}
 

	
 
	ToggleBit(v->u.rail.flags, VRF_TOGGLE_REVERSE);
 

	
 
	ClrBit(v->u.rail.flags, VRF_REVERSING);
 
	ToggleBit(v->flags, VRF_TOGGLE_REVERSE);
 

	
 
	ClrBit(v->flags, VRF_REVERSING);
 

	
 
	/* recalculate cached data */
 
	TrainConsistChanged(v, true);
 
@@ -1908,16 +1908,16 @@ static void ReverseTrainDirection(Train 
 
	if (crossing != INVALID_TILE) MaybeBarCrossingWithSound(crossing);
 

	
 
	/* If we are inside a depot after reversing, don't bother with path reserving. */
 
	if (v->u.rail.track & TRACK_BIT_DEPOT) {
 
	if (v->track & TRACK_BIT_DEPOT) {
 
		/* Can't be stuck here as inside a depot is always a safe tile. */
 
		if (HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		ClrBit(v->u.rail.flags, VRF_TRAIN_STUCK);
 
		if (HasBit(v->flags, VRF_TRAIN_STUCK)) InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		ClrBit(v->flags, VRF_TRAIN_STUCK);
 
		return;
 
	}
 

	
 
	/* TrainExitDir does not always produce the desired dir for depots and
 
	 * tunnels/bridges that is needed for UpdateSignalsOnSegment. */
 
	DiagDirection dir = TrainExitDir(v->direction, v->u.rail.track);
 
	DiagDirection dir = TrainExitDir(v->direction, v->track);
 
	if (IsRailDepotTile(v->tile) || IsTileType(v->tile, MP_TUNNELBRIDGE)) dir = INVALID_DIAGDIR;
 

	
 
	if (UpdateSignalsOnSegment(v->tile, dir, v->owner) == SIGSEG_PBS || _settings_game.pf.reserve_paths) {
 
@@ -1925,7 +1925,7 @@ static void ReverseTrainDirection(Train 
 
		 * current tile as a safe tile or we would enter a PBS block without a reservation. */
 
		bool first_tile_okay = !(IsTileType(v->tile, MP_RAILWAY) &&
 
			HasSignalOnTrackdir(v->tile, v->GetVehicleTrackdir()) &&
 
			!IsPbsSignal(GetSignalType(v->tile, FindFirstTrack(v->u.rail.track))));
 
			!IsPbsSignal(GetSignalType(v->tile, FindFirstTrack(v->track))));
 

	
 
		if (IsRailwayStationTile(v->tile)) SetRailwayStationPlatformReservation(v->tile, TrackdirToExitdir(v->GetVehicleTrackdir()), true);
 
		if (TryPathReserve(v, false, first_tile_okay)) {
 
@@ -1935,9 +1935,9 @@ static void ReverseTrainDirection(Train 
 
			/* Do not wait for a way out when we're still loading */
 
			MarkTrainAsStuck(v);
 
		}
 
	} else if (HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) {
 
	} else if (HasBit(v->flags, VRF_TRAIN_STUCK)) {
 
		/* A train not inside a PBS block can't be stuck. */
 
		ClrBit(v->u.rail.flags, VRF_TRAIN_STUCK);
 
		ClrBit(v->flags, VRF_TRAIN_STUCK);
 
		v->load_unload_time_rem = 0;
 
	}
 
}
 
@@ -1969,7 +1969,7 @@ CommandCost CmdReverseTrainDirection(Til
 
		}
 

	
 
		if (flags & DC_EXEC) {
 
			ToggleBit(v->u.rail.flags, VRF_REVERSE_DIRECTION);
 
			ToggleBit(v->flags, VRF_REVERSE_DIRECTION);
 
			InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
		}
 
@@ -1990,7 +1990,7 @@ CommandCost CmdReverseTrainDirection(Til
 
			}
 

	
 
			if (_settings_game.vehicle.train_acceleration_model != TAM_ORIGINAL && v->cur_speed != 0) {
 
				ToggleBit(v->u.rail.flags, VRF_REVERSING);
 
				ToggleBit(v->flags, VRF_REVERSING);
 
			} else {
 
				v->cur_speed = 0;
 
				SetLastSpeed(v, 0);
 
@@ -2013,7 +2013,7 @@ CommandCost CmdForceTrainProceed(TileInd
 
	Vehicle *v = Vehicle::GetIfValid(p1);
 
	if (v == NULL || v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) ((Train *)v)->u.rail.force_proceed = 0x50;
 
	if (flags & DC_EXEC) ((Train *)v)->force_proceed = 0x50;
 

	
 
	return CommandCost();
 
}
 
@@ -2167,7 +2167,7 @@ static TrainFindDepotData FindClosestTra
 
	tfdd.best_length = UINT_MAX;
 

	
 
	uint8 pathfinder = _settings_game.pf.pathfinder_for_trains;
 
	if ((_settings_game.pf.reserve_paths || HasReservedTracks(v->tile, v->u.rail.track)) && pathfinder == VPF_NTP) pathfinder = VPF_NPF;
 
	if ((_settings_game.pf.reserve_paths || HasReservedTracks(v->tile, v->track)) && pathfinder == VPF_NTP) pathfinder = VPF_NPF;
 

	
 
	switch (pathfinder) {
 
		case VPF_YAPF: { // YAPF
 
@@ -2181,7 +2181,7 @@ static TrainFindDepotData FindClosestTra
 
			Trackdir trackdir_rev = ReverseTrackdir(last->GetVehicleTrackdir());
 

	
 
			assert(trackdir != INVALID_TRACKDIR);
 
			NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, TRANSPORT_RAIL, 0, v->owner, v->u.rail.compatible_railtypes, NPF_INFINITE_PENALTY);
 
			NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, TRANSPORT_RAIL, 0, v->owner, v->compatible_railtypes, NPF_INFINITE_PENALTY);
 
			if (ftd.best_bird_dist == 0) {
 
				/* Found target */
 
				tfdd.tile = ftd.node.tile;
 
@@ -2197,13 +2197,13 @@ static TrainFindDepotData FindClosestTra
 
		default:
 
		case VPF_NTP: { // NTP
 
			/* search in the forward direction first. */
 
			DiagDirection i = TrainExitDir(v->direction, v->u.rail.track);
 
			NewTrainPathfind(v->tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
 
			DiagDirection i = TrainExitDir(v->direction, v->track);
 
			NewTrainPathfind(v->tile, 0, v->compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
 
			if (tfdd.best_length == UINT_MAX){
 
				tfdd.reverse = true;
 
				/* search in backwards direction */
 
				i = TrainExitDir(ReverseDir(v->direction), v->u.rail.track);
 
				NewTrainPathfind(v->tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
 
				i = TrainExitDir(ReverseDir(v->direction), v->track);
 
				NewTrainPathfind(v->tile, 0, v->compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
 
			}
 
		} break;
 
	}
 
@@ -2282,7 +2282,7 @@ static void HandleLocomotiveSmokeCloud(c
 
		if (IsRailDepotTile(v->tile) || IsTunnelTile(v->tile)) continue;
 

	
 
		/* No sparks for electric vehicles on nonelectrified tracks */
 
		if (!HasPowerOnRail(v->u.rail.railtype, GetTileRailType(v->tile))) continue;
 
		if (!HasPowerOnRail(v->railtype, GetTileRailType(v->tile))) continue;
 

	
 
		if (effect_type == 0) {
 
			/* Use default effect type for engine class. */
 
@@ -2294,7 +2294,7 @@ static void HandleLocomotiveSmokeCloud(c
 
		int x = _vehicle_smoke_pos[v->direction] * effect_offset;
 
		int y = _vehicle_smoke_pos[(v->direction + 2) % 8] * effect_offset;
 

	
 
		if (HasBit(v->u.rail.flags, VRF_REVERSE_DIRECTION)) {
 
		if (HasBit(v->flags, VRF_REVERSE_DIRECTION)) {
 
			x = -x;
 
			y = -y;
 
		}
 
@@ -2355,7 +2355,7 @@ static void CheckNextTrainTile(Train *v)
 
	if (_settings_game.pf.path_backoff_interval == 255) return;
 

	
 
	/* Exit if we reached our destination depot or are inside a depot. */
 
	if ((v->tile == v->dest_tile && v->current_order.IsType(OT_GOTO_DEPOT)) || v->u.rail.track & TRACK_BIT_DEPOT) return;
 
	if ((v->tile == v->dest_tile && v->current_order.IsType(OT_GOTO_DEPOT)) || v->track & TRACK_BIT_DEPOT) return;
 
	/* Exit if we are on a station tile and are going to stop. */
 
	if (IsRailwayStationTile(v->tile) && v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile))) return;
 
	/* Exit if the current order doesn't have a destination, but the train has orders. */
 
@@ -2390,7 +2390,7 @@ static bool CheckTrainStayInDepot(Train 
 
{
 
	/* bail out if not all wagons are in the same depot or not in a depot at all */
 
	for (const Train *u = v; u != NULL; u = u->Next()) {
 
		if (u->u.rail.track != TRACK_BIT_DEPOT || u->tile != v->tile) return false;
 
		if (u->track != TRACK_BIT_DEPOT || u->tile != v->tile) return false;
 
	}
 

	
 
	/* if the train got no power, then keep it in the depot */
 
@@ -2402,7 +2402,7 @@ static bool CheckTrainStayInDepot(Train 
 

	
 
	SigSegState seg_state;
 

	
 
	if (v->u.rail.force_proceed == 0) {
 
	if (v->force_proceed == 0) {
 
		/* force proceed was not pressed */
 
		if (++v->load_unload_time_rem < 37) {
 
			InvalidateWindowClasses(WC_TRAINS_LIST);
 
@@ -2431,7 +2431,7 @@ static bool CheckTrainStayInDepot(Train 
 
	}
 

	
 
	/* Only leave when we can reserve a path to our destination. */
 
	if (seg_state == SIGSEG_PBS && !TryPathReserve(v) && v->u.rail.force_proceed == 0) {
 
	if (seg_state == SIGSEG_PBS && !TryPathReserve(v) && v->force_proceed == 0) {
 
		/* No path and no force proceed. */
 
		InvalidateWindowClasses(WC_TRAINS_LIST);
 
		MarkTrainAsStuck(v);
 
@@ -2445,8 +2445,8 @@ static bool CheckTrainStayInDepot(Train 
 
	InvalidateWindowClasses(WC_TRAINS_LIST);
 
	v->PlayLeaveStationSound();
 

	
 
	v->u.rail.track = TRACK_BIT_X;
 
	if (v->direction & 2) v->u.rail.track = TRACK_BIT_Y;
 
	v->track = TRACK_BIT_X;
 
	if (v->direction & 2) v->track = TRACK_BIT_Y;
 

	
 
	v->vehstatus &= ~VS_HIDDEN;
 
	v->cur_speed = 0;
 
@@ -2508,7 +2508,7 @@ void FreeTrainTrackReservation(const Tra
 
	/* Don't free reservation if it's not ours. */
 
	if (TracksOverlap(GetReservedTrackbits(tile) | TrackToTrackBits(TrackdirToTrack(td)))) return;
 

	
 
	CFollowTrackRail ft(v, GetRailTypeInfo(v->u.rail.railtype)->compatible_railtypes);
 
	CFollowTrackRail ft(v, GetRailTypeInfo(v->railtype)->compatible_railtypes);
 
	while (ft.Follow(tile, td)) {
 
		tile = ft.m_new_tile;
 
		TrackdirBits bits = ft.m_new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(tile));
 
@@ -2653,7 +2653,7 @@ static Track DoTrainPathfind(Train *v, T
 
			PBSTileInfo origin = FollowTrainReservation(v);
 
			assert(IsValidTrackdir(origin.trackdir));
 

	
 
			NPFFoundTargetData ftd = NPFRouteToStationOrTile(origin.tile, origin.trackdir, true, &fstd, TRANSPORT_RAIL, 0, v->owner, v->u.rail.compatible_railtypes);
 
			NPFFoundTargetData ftd = NPFRouteToStationOrTile(origin.tile, origin.trackdir, true, &fstd, TRANSPORT_RAIL, 0, v->owner, v->compatible_railtypes);
 

	
 
			if (dest != NULL) {
 
				dest->tile = ftd.node.tile;
 
@@ -2693,7 +2693,7 @@ static Track DoTrainPathfind(Train *v, T
 
			fd.best_track = INVALID_TRACKDIR;
 

	
 
			NewTrainPathfind(tile - TileOffsByDiagDir(enterdir), v->dest_tile,
 
				v->u.rail.compatible_railtypes, enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd);
 
				v->compatible_railtypes, enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd);
 

	
 
			/* check whether the path was found or only 'guessed' */
 
			if (fd.best_bird_dist != 0 && path_not_found != NULL) *path_not_found = true;
 
@@ -2980,9 +2980,9 @@ static Track ChooseTrainTrack(Train *v, 
 
		/* handle "path not found" state */
 
		if (path_not_found) {
 
			/* PF didn't find the route */
 
			if (!HasBit(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) {
 
			if (!HasBit(v->flags, VRF_NO_PATH_TO_DESTINATION)) {
 
				/* it is first time the problem occurred, set the "path not found" flag */
 
				SetBit(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
 
				SetBit(v->flags, VRF_NO_PATH_TO_DESTINATION);
 
				/* and notify user about the event */
 
				AI::NewEvent(v->owner, new AIEventVehicleLost(v->index));
 
				if (_settings_client.gui.lost_train_warn && v->owner == _local_company) {
 
@@ -2996,9 +2996,9 @@ static Track ChooseTrainTrack(Train *v, 
 
			}
 
		} else {
 
			/* route found, is the train marked with "path not found" flag? */
 
			if (HasBit(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) {
 
			if (HasBit(v->flags, VRF_NO_PATH_TO_DESTINATION)) {
 
				/* clear the flag as the PF's problem was solved */
 
				ClrBit(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
 
				ClrBit(v->flags, VRF_NO_PATH_TO_DESTINATION);
 
				/* can we also delete the "News" item somehow? */
 
			}
 
		}
 
@@ -3090,7 +3090,7 @@ bool TryPathReserve(Train *v, bool mark_
 
	/* We have to handle depots specially as the track follower won't look
 
	 * at the depot tile itself but starts from the next tile. If we are still
 
	 * inside the depot, a depot reservation can never be ours. */
 
	if (v->u.rail.track & TRACK_BIT_DEPOT) {
 
	if (v->track & TRACK_BIT_DEPOT) {
 
		if (GetDepotWaypointReservation(v->tile)) {
 
			if (mark_as_stuck) MarkTrainAsStuck(v);
 
			return false;
 
@@ -3102,7 +3102,7 @@ bool TryPathReserve(Train *v, bool mark_
 
	}
 

	
 
	/* Special check if we are in front of a two-sided conventional signal. */
 
	DiagDirection dir = TrainExitDir(v->direction, v->u.rail.track);
 
	DiagDirection dir = TrainExitDir(v->direction, v->track);
 
	TileIndex next_tile = TileAddByDiagDir(v->tile, dir);
 
	if (IsTileType(next_tile, MP_RAILWAY) && HasReservedTracks(next_tile, DiagdirReachesTracks(dir))) {
 
		/* Can have only one reserved trackdir. */
 
@@ -3120,8 +3120,8 @@ bool TryPathReserve(Train *v, bool mark_
 
	/* If we have a reserved path and the path ends at a safe tile, we are finished already. */
 
	if (origin.okay && (v->tile != origin.tile || first_tile_okay)) {
 
		/* Can't be stuck then. */
 
		if (HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		ClrBit(v->u.rail.flags, VRF_TRAIN_STUCK);
 
		if (HasBit(v->flags, VRF_TRAIN_STUCK)) InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		ClrBit(v->flags, VRF_TRAIN_STUCK);
 
		return true;
 
	}
 
	/* The path we are driving on is alread blocked by some other train.
 
@@ -3134,7 +3134,7 @@ bool TryPathReserve(Train *v, bool mark_
 
	}
 

	
 
	/* If we are in a depot, tentativly reserve the depot. */
 
	if (v->u.rail.track & TRACK_BIT_DEPOT) {
 
	if (v->track & TRACK_BIT_DEPOT) {
 
		SetDepotWaypointReservation(v->tile, true);
 
		if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(v->tile);
 
	}
 
@@ -3150,15 +3150,15 @@ bool TryPathReserve(Train *v, bool mark_
 

	
 
	if (!res_made) {
 
		/* Free the depot reservation as well. */
 
		if (v->u.rail.track & TRACK_BIT_DEPOT) SetDepotWaypointReservation(v->tile, false);
 
		if (v->track & TRACK_BIT_DEPOT) SetDepotWaypointReservation(v->tile, false);
 
		return false;
 
	}
 

	
 
	if (HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) {
 
	if (HasBit(v->flags, VRF_TRAIN_STUCK)) {
 
		v->load_unload_time_rem = 0;
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	}
 
	ClrBit(v->u.rail.flags, VRF_TRAIN_STUCK);
 
	ClrBit(v->flags, VRF_TRAIN_STUCK);
 
	return true;
 
}
 

	
 
@@ -3166,14 +3166,14 @@ bool TryPathReserve(Train *v, bool mark_
 
static bool CheckReverseTrain(Train *v)
 
{
 
	if (_settings_game.difficulty.line_reverse_mode != 0 ||
 
			v->u.rail.track == TRACK_BIT_DEPOT || v->u.rail.track == TRACK_BIT_WORMHOLE ||
 
			v->track == TRACK_BIT_DEPOT || v->track == TRACK_BIT_WORMHOLE ||
 
			!(v->direction & 1)) {
 
		return false;
 
	}
 

	
 
	uint reverse_best = 0;
 

	
 
	assert(v->u.rail.track);
 
	assert(v->track);
 

	
 
	switch (_settings_game.pf.pathfinder_for_trains) {
 
		case VPF_YAPF: // YAPF
 
@@ -3192,7 +3192,7 @@ static bool CheckReverseTrain(Train *v)
 
			assert(trackdir != INVALID_TRACKDIR);
 
			assert(trackdir_rev != INVALID_TRACKDIR);
 

	
 
			ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, &fstd, TRANSPORT_RAIL, 0, v->owner, v->u.rail.compatible_railtypes);
 
			ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, &fstd, TRANSPORT_RAIL, 0, v->owner, v->compatible_railtypes);
 
			if (ftd.best_bird_dist != 0) {
 
				/* We didn't find anything, just keep on going straight ahead */
 
				reverse_best = false;
 
@@ -3210,7 +3210,7 @@ static bool CheckReverseTrain(Train *v)
 
			TrainTrackFollowerData fd;
 
			FillWithStationData(&fd, v);
 

	
 
			int i = _search_directions[FindFirstTrack(v->u.rail.track)][DirToDiagDir(v->direction)];
 
			int i = _search_directions[FindFirstTrack(v->track)][DirToDiagDir(v->direction)];
 

	
 
			int best_track = -1;
 
			uint reverse = 0;
 
@@ -3221,7 +3221,7 @@ static bool CheckReverseTrain(Train *v)
 
				fd.best_bird_dist = UINT_MAX;
 
				fd.best_track_dist = UINT_MAX;
 

	
 
				NewTrainPathfind(v->tile, v->dest_tile, v->u.rail.compatible_railtypes, (DiagDirection)(reverse ^ i), (NTPEnumProc*)NtpCallbFindStation, &fd);
 
				NewTrainPathfind(v->tile, v->dest_tile, v->compatible_railtypes, (DiagDirection)(reverse ^ i), (NTPEnumProc*)NtpCallbFindStation, &fd);
 

	
 
				if (best_track != -1) {
 
					if (best_bird_dist != 0) {
 
@@ -3307,7 +3307,7 @@ static int UpdateTrainSpeed(Train *v)
 
{
 
	uint accel;
 

	
 
	if (v->vehstatus & VS_STOPPED || HasBit(v->u.rail.flags, VRF_REVERSING) || HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) {
 
	if (v->vehstatus & VS_STOPPED || HasBit(v->flags, VRF_REVERSING) || HasBit(v->flags, VRF_TRAIN_STUCK)) {
 
		switch (_settings_game.vehicle.train_acceleration_model) {
 
			default: NOT_REACHED();
 
			case TAM_ORIGINAL:  accel = v->acceleration * -4; break;
 
@@ -3377,10 +3377,10 @@ static byte AfterSetTrainPos(Train *v, b
 
	v->z_pos = GetSlopeZ(v->x_pos, v->y_pos);
 

	
 
	if (new_tile) {
 
		ClrBit(v->u.rail.flags, VRF_GOINGUP);
 
		ClrBit(v->u.rail.flags, VRF_GOINGDOWN);
 

	
 
		if (v->u.rail.track == TRACK_BIT_X || v->u.rail.track == TRACK_BIT_Y) {
 
		ClrBit(v->flags, VRF_GOINGUP);
 
		ClrBit(v->flags, VRF_GOINGDOWN);
 

	
 
		if (v->track == TRACK_BIT_X || v->track == TRACK_BIT_Y) {
 
			/* Any track that isn't TRACK_BIT_X or TRACK_BIT_Y cannot be sloped.
 
			 * To check whether the current tile is sloped, and in which
 
			 * direction it is sloped, we get the 'z' at the center of
 
@@ -3394,7 +3394,7 @@ static byte AfterSetTrainPos(Train *v, b
 
			/* For some reason tunnel tiles are always given as sloped :(
 
			 * But they are not sloped... */
 
			if (middle_z != v->z_pos && !IsTunnelTile(TileVirtXY(v->x_pos, v->y_pos))) {
 
				SetBit(v->u.rail.flags, (middle_z > old_z) ? VRF_GOINGUP : VRF_GOINGDOWN);
 
				SetBit(v->flags, (middle_z > old_z) ? VRF_GOINGUP : VRF_GOINGDOWN);
 
			}
 
		}
 
	}
 
@@ -3409,7 +3409,7 @@ static inline bool CheckCompatibleRail(c
 
	return
 
		IsTileOwner(tile, v->owner) && (
 
			!IsFrontEngine(v) ||
 
			HasBit(v->u.rail.compatible_railtypes, GetRailType(tile))
 
			HasBit(v->compatible_railtypes, GetRailType(tile))
 
		);
 
}
 

	
 
@@ -3435,7 +3435,7 @@ static inline void AffectSpeedByDirChang
 
	DirDiff diff = DirDifference(v->direction, new_dir);
 
	if (diff == DIRDIFF_SAME) return;
 

	
 
	const RailtypeSlowdownParams *rsp = &_railtype_slowdown[v->u.rail.railtype];
 
	const RailtypeSlowdownParams *rsp = &_railtype_slowdown[v->railtype];
 
	v->cur_speed -= (diff == DIRDIFF_45RIGHT || diff == DIRDIFF_45LEFT ? rsp->small_turn : rsp->large_turn) * v->cur_speed >> 8;
 
}
 

	
 
@@ -3444,7 +3444,7 @@ static inline void AffectSpeedByZChange(
 
{
 
	if (old_z == v->z_pos || _settings_game.vehicle.train_acceleration_model != TAM_ORIGINAL) return;
 

	
 
	const RailtypeSlowdownParams *rsp = &_railtype_slowdown[v->u.rail.railtype];
 
	const RailtypeSlowdownParams *rsp = &_railtype_slowdown[v->railtype];
 

	
 
	if (old_z < v->z_pos) {
 
		v->cur_speed -= (v->cur_speed * rsp->z_up >> 8);
 
@@ -3471,7 +3471,7 @@ static bool TrainMovedChangeSignals(Tile
 

	
 
static void SetVehicleCrashed(Train *v)
 
{
 
	if (v->u.rail.crash_anim_pos != 0) return;
 
	if (v->crash_anim_pos != 0) return;
 

	
 
	/* Free a possible path reservation and try to mark all tiles occupied by the train reserved. */
 
	if (IsFrontEngine(v)) {
 
@@ -3491,12 +3491,12 @@ static void SetVehicleCrashed(Train *v)
 
	/* we may need to update crossing we were approaching */
 
	TileIndex crossing = TrainApproachingCrossingTile(v);
 

	
 
	v->u.rail.crash_anim_pos++;
 
	v->crash_anim_pos++;
 

	
 
	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 

	
 
	if (v->u.rail.track == TRACK_BIT_DEPOT) {
 
	if (v->track == TRACK_BIT_DEPOT) {
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
	}
 

	
 
@@ -3557,7 +3557,7 @@ static Vehicle *FindTrainCollideEnum(Veh
 
	Vehicle *coll = v->First();
 

	
 
	/* can't collide with own wagons && can't crash in depot && the same height level */
 
	if (coll != tcc->v && ((Train *)v)->u.rail.track != TRACK_BIT_DEPOT && abs(v->z_pos - tcc->v->z_pos) < 6) {
 
	if (coll != tcc->v && ((Train *)v)->track != TRACK_BIT_DEPOT && abs(v->z_pos - tcc->v->z_pos) < 6) {
 
		int x_diff = v->x_pos - tcc->v->x_pos;
 
		int y_diff = v->y_pos - tcc->v->y_pos;
 

	
 
@@ -3572,10 +3572,10 @@ static Vehicle *FindTrainCollideEnum(Veh
 
		 * As there might be more than two trains involved, we have to do that for all vehicles */
 
		const Vehicle *u;
 
		FOR_ALL_VEHICLES(u) {
 
			if (u->type == VEH_TRAIN && HASBITS(u->vehstatus, VS_CRASHED) && (((Train *)u)->u.rail.track & TRACK_BIT_DEPOT) == TRACK_BIT_NONE) {
 
				TrackBits trackbits = ((Train *)u)->u.rail.track;
 
			if (u->type == VEH_TRAIN && HASBITS(u->vehstatus, VS_CRASHED) && (((Train *)u)->track & TRACK_BIT_DEPOT) == TRACK_BIT_NONE) {
 
				TrackBits trackbits = ((Train *)u)->track;
 
				if ((trackbits & TRACK_BIT_WORMHOLE) == TRACK_BIT_WORMHOLE) {
 
					/* Vehicle is inside a wormhole, v->u.rail.track contains no useful value then. */
 
					/* Vehicle is inside a wormhole, v->track contains no useful value then. */
 
					trackbits |= DiagDirToDiagTrackBits(GetTunnelBridgeDirection(u->tile));
 
				}
 
				TryReserveRailTrack(u->tile, TrackBitsToTrack(trackbits));
 
@@ -3595,16 +3595,16 @@ static Vehicle *FindTrainCollideEnum(Veh
 
static bool CheckTrainCollision(Train *v)
 
{
 
	/* can't collide in depot */
 
	if (v->u.rail.track == TRACK_BIT_DEPOT) return false;
 

	
 
	assert(v->u.rail.track == TRACK_BIT_WORMHOLE || TileVirtXY(v->x_pos, v->y_pos) == v->tile);
 
	if (v->track == TRACK_BIT_DEPOT) return false;
 

	
 
	assert(v->track == TRACK_BIT_WORMHOLE || TileVirtXY(v->x_pos, v->y_pos) == v->tile);
 

	
 
	TrainCollideChecker tcc;
 
	tcc.v = v;
 
	tcc.num = 0;
 

	
 
	/* find colliding vehicles */
 
	if (v->u.rail.track == TRACK_BIT_WORMHOLE) {
 
	if (v->track == TRACK_BIT_WORMHOLE) {
 
		FindVehicleOnPos(v->tile, &tcc, FindTrainCollideEnum);
 
		FindVehicleOnPos(GetOtherTunnelBridgeEnd(v->tile), &tcc, FindTrainCollideEnum);
 
	} else {
 
@@ -3631,8 +3631,8 @@ static Vehicle *CheckVehicleAtSignal(Veh
 
	DiagDirection exitdir = *(DiagDirection *)data;
 

	
 
	/* front engine of a train, not inside wormhole or depot, not crashed */
 
	if (v->type == VEH_TRAIN && IsFrontEngine(v) && (((Train *)v)->u.rail.track & TRACK_BIT_MASK) != 0 && !(v->vehstatus & VS_CRASHED)) {
 
		if (v->cur_speed <= 5 && TrainExitDir(v->direction, ((Train *)v)->u.rail.track) == exitdir) return v;
 
	if (v->type == VEH_TRAIN && IsFrontEngine(v) && (((Train *)v)->track & TRACK_BIT_MASK) != 0 && !(v->vehstatus & VS_CRASHED)) {
 
		if (v->cur_speed <= 5 && TrainExitDir(v->direction, ((Train *)v)->track) == exitdir) return v;
 
	}
 

	
 
	return NULL;
 
@@ -3648,11 +3648,11 @@ static void TrainController(Train *v, Ve
 
		bool update_signals_crossing = false; // will we update signals or crossing state?
 

	
 
		GetNewVehiclePosResult gp = GetNewVehiclePos(v);
 
		if (v->u.rail.track != TRACK_BIT_WORMHOLE) {
 
		if (v->track != TRACK_BIT_WORMHOLE) {
 
			/* Not inside tunnel */
 
			if (gp.old_tile == gp.new_tile) {
 
				/* Staying in the old tile */
 
				if (v->u.rail.track == TRACK_BIT_DEPOT) {
 
				if (v->track == TRACK_BIT_DEPOT) {
 
					/* Inside depot */
 
					gp.x = v->x_pos;
 
					gp.y = v->y_pos;
 
@@ -3690,7 +3690,7 @@ static void TrainController(Train *v, Ve
 
				if (_settings_game.pf.pathfinder_for_trains != VPF_NTP && _settings_game.pf.forbid_90_deg && prev == NULL) {
 
					/* We allow wagons to make 90 deg turns, because forbid_90_deg
 
					 * can be switched on halfway a turn */
 
					bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track));
 
					bits &= ~TrackCrossesTracks(FindFirstTrack(v->track));
 
				}
 

	
 
				if (bits == TRACK_BIT_NONE) goto invalid_rail;
 
@@ -3707,12 +3707,12 @@ static void TrainController(Train *v, Ve
 
					assert(chosen_track & (bits | GetReservedTrackbits(gp.new_tile)));
 

	
 
					/* Check if it's a red signal and that force proceed is not clicked. */
 
					if (red_signals & chosen_track && v->u.rail.force_proceed == 0) {
 
					if (red_signals & chosen_track && v->force_proceed == 0) {
 
						/* In front of a red signal */
 
						Trackdir i = FindFirstTrackdir(trackdirbits);
 

	
 
						/* Don't handle stuck trains here. */
 
						if (HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) return;
 
						if (HasBit(v->flags, VRF_TRAIN_STUCK)) return;
 

	
 
						if (!HasSignalOnTrackdir(gp.new_tile, ReverseTrackdir(i))) {
 
							v->cur_speed = 0;
 
@@ -3748,13 +3748,13 @@ static void TrainController(Train *v, Ve
 
					/* The wagon is active, simply follow the prev vehicle. */
 
					if (prev->tile == gp.new_tile) {
 
						/* Choose the same track as prev */
 
						if (prev->u.rail.track == TRACK_BIT_WORMHOLE) {
 
						if (prev->track == TRACK_BIT_WORMHOLE) {
 
							/* Vehicles entering tunnels enter the wormhole earlier than for bridges.
 
							 * However, just choose the track into the wormhole. */
 
							assert(IsTunnel(prev->tile));
 
							chosen_track = bits;
 
						} else {
 
							chosen_track = prev->u.rail.track;
 
							chosen_track = prev->track;
 
						}
 
					} else {
 
						/* Choose the track that leads to the tile where prev is.
 
@@ -3812,8 +3812,8 @@ static void TrainController(Train *v, Ve
 
						TrainPowerChanged(v->First());
 
					}
 

	
 
					v->u.rail.track = chosen_track;
 
					assert(v->u.rail.track);
 
					v->track = chosen_track;
 
					assert(v->track);
 
				}
 

	
 
				/* We need to update signal status, but after the vehicle position hash
 
@@ -3888,8 +3888,8 @@ static void TrainController(Train *v, Ve
 
					 * such a strange network that it is not possible, the train
 
					 * will be marked as stuck and the player has to deal with
 
					 * the problem. */
 
					if ((!HasReservedTracks(gp.new_tile, v->u.rail.track) &&
 
							!TryReserveRailTrack(gp.new_tile, FindFirstTrack(v->u.rail.track))) ||
 
					if ((!HasReservedTracks(gp.new_tile, v->track) &&
 
							!TryReserveRailTrack(gp.new_tile, FindFirstTrack(v->track))) ||
 
							!TryPathReserve(v)) {
 
						MarkTrainAsStuck(v);
 
					}
 
@@ -3930,11 +3930,11 @@ static Vehicle *CollectTrackbitsFromCras
 
	TrackBits *trackbits = (TrackBits *)data;
 

	
 
	if (v->type == VEH_TRAIN && (v->vehstatus & VS_CRASHED) != 0) {
 
		if ((((Train *)v)->u.rail.track & TRACK_BIT_WORMHOLE) == TRACK_BIT_WORMHOLE) {
 
			/* Vehicle is inside a wormhole, v->u.rail.track contains no useful value then. */
 
		if ((((Train *)v)->track & TRACK_BIT_WORMHOLE) == TRACK_BIT_WORMHOLE) {
 
			/* Vehicle is inside a wormhole, v->track contains no useful value then. */
 
			*trackbits |= DiagDirToDiagTrackBits(GetTunnelBridgeDirection(v->tile));
 
		} else {
 
			*trackbits |= ((Train *)v)->u.rail.track;
 
			*trackbits |= ((Train *)v)->track;
 
		}
 
	}
 

	
 
@@ -3964,13 +3964,13 @@ static void DeleteLastWagon(Train *v)
 
		TrainConsistChanged(first, false);
 
		/* Update the depot window if the first vehicle is in depot -
 
		 * if v == first, then it is updated in PreDestructor() */
 
		if (first->u.rail.track == TRACK_BIT_DEPOT) {
 
		if (first->track == TRACK_BIT_DEPOT) {
 
			InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
 
		}
 
	}
 

	
 
	/* 'v' shouldn't be accessed after it has been deleted */
 
	TrackBits trackbits = v->u.rail.track;
 
	TrackBits trackbits = v->track;
 
	TileIndex tile = v->tile;
 
	Owner owner = v->owner;
 

	
 
@@ -3978,7 +3978,7 @@ static void DeleteLastWagon(Train *v)
 
	v = NULL; // make sure nobody will try to read 'v' anymore
 

	
 
	if ((trackbits & TRACK_BIT_WORMHOLE) == TRACK_BIT_WORMHOLE) {
 
		/* Vehicle is inside a wormhole, v->u.rail.track contains no useful value then. */
 
		/* Vehicle is inside a wormhole, v->track contains no useful value then. */
 
		trackbits |= DiagDirToDiagTrackBits(GetTunnelBridgeDirection(tile));
 
	}
 

	
 
@@ -4025,14 +4025,14 @@ static void ChangeTrainDirRandomly(Train
 
			/* Refrain from updating the z position of the vehicle when on
 
			 * a bridge, because AfterSetTrainPos will put the vehicle under
 
			 * the bridge in that case */
 
			if (v->u.rail.track != TRACK_BIT_WORMHOLE) AfterSetTrainPos(v, false);
 
			if (v->track != TRACK_BIT_WORMHOLE) AfterSetTrainPos(v, false);
 
		}
 
	} while ((v = v->Next()) != NULL);
 
}
 

	
 
static bool HandleCrashedTrain(Train *v)
 
{
 
	int state = ++v->u.rail.crash_anim_pos;
 
	int state = ++v->crash_anim_pos;
 

	
 
	if (state == 4 && !(v->vehstatus & VS_HIDDEN)) {
 
		CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
 
@@ -4157,7 +4157,7 @@ static bool TrainApproachingLineEnd(Trai
 
static bool TrainCanLeaveTile(const Train *v)
 
{
 
	/* Exit if inside a tunnel/bridge or a depot */
 
	if (v->u.rail.track == TRACK_BIT_WORMHOLE || v->u.rail.track == TRACK_BIT_DEPOT) return false;
 
	if (v->track == TRACK_BIT_WORMHOLE || v->track == TRACK_BIT_DEPOT) return false;
 

	
 
	TileIndex tile = v->tile;
 

	
 
@@ -4191,7 +4191,7 @@ static TileIndex TrainApproachingCrossin
 

	
 
	if (!TrainCanLeaveTile(v)) return INVALID_TILE;
 

	
 
	DiagDirection dir = TrainExitDir(v->direction, v->u.rail.track);
 
	DiagDirection dir = TrainExitDir(v->direction, v->track);
 
	TileIndex tile = v->tile + TileOffsByDiagDir(dir);
 

	
 
	/* not a crossing || wrong axis || unusable rail (wrong type or owner) */
 
@@ -4227,7 +4227,7 @@ static bool TrainCheckIfLineEnds(Train *
 
	if (!TrainCanLeaveTile(v)) return true;
 

	
 
	/* Determine the non-diagonal direction in which we will exit this tile */
 
	DiagDirection dir = TrainExitDir(v->direction, v->u.rail.track);
 
	DiagDirection dir = TrainExitDir(v->direction, v->track);
 
	/* Calculate next tile */
 
	TileIndex tile = v->tile + TileOffsByDiagDir(dir);
 

	
 
@@ -4243,7 +4243,7 @@ static bool TrainCheckIfLineEnds(Train *
 
	/* mask unreachable track bits if we are forbidden to do 90deg turns */
 
	TrackBits bits = TrackdirBitsToTrackBits(trackdirbits);
 
	if (_settings_game.pf.pathfinder_for_trains != VPF_NTP && _settings_game.pf.forbid_90_deg) {
 
		bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track));
 
		bits &= ~TrackCrossesTracks(FindFirstTrack(v->track));
 
	}
 

	
 
	/* no suitable trackbits at all || unusable rail (wrong type or owner) */
 
@@ -4268,9 +4268,9 @@ static bool TrainLocoHandler(Train *v, b
 
		return mode ? true : HandleCrashedTrain(v); // 'this' can be deleted here
 
	}
 

	
 
	if (v->u.rail.force_proceed != 0) {
 
		v->u.rail.force_proceed--;
 
		ClrBit(v->u.rail.flags, VRF_TRAIN_STUCK);
 
	if (v->force_proceed != 0) {
 
		v->force_proceed--;
 
		ClrBit(v->flags, VRF_TRAIN_STUCK);
 
		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
	}
 

	
 
@@ -4283,7 +4283,7 @@ static bool TrainLocoHandler(Train *v, b
 
		if (!v->current_order.IsType(OT_LOADING)) v->breakdown_ctr--;
 
	}
 

	
 
	if (HasBit(v->u.rail.flags, VRF_REVERSING) && v->cur_speed == 0) {
 
	if (HasBit(v->flags, VRF_REVERSING) && v->cur_speed == 0) {
 
		ReverseTrainDirection(v);
 
	}
 

	
 
@@ -4313,18 +4313,18 @@ static bool TrainLocoHandler(Train *v, b
 
	}
 

	
 
	/* Handle stuck trains. */
 
	if (!mode && HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) {
 
	if (!mode && HasBit(v->flags, VRF_TRAIN_STUCK)) {
 
		++v->load_unload_time_rem;
 

	
 
		/* Should we try reversing this tick if still stuck? */
 
		bool turn_around = v->load_unload_time_rem % (_settings_game.pf.wait_for_pbs_path * DAY_TICKS) == 0 && _settings_game.pf.wait_for_pbs_path < 255;
 

	
 
		if (!turn_around && v->load_unload_time_rem % _settings_game.pf.path_backoff_interval != 0 && v->u.rail.force_proceed == 0) return true;
 
		if (!turn_around && v->load_unload_time_rem % _settings_game.pf.path_backoff_interval != 0 && v->force_proceed == 0) return true;
 
		if (!TryPathReserve(v)) {
 
			/* Still stuck. */
 
			if (turn_around) ReverseTrainDirection(v);
 

	
 
			if (HasBit(v->u.rail.flags, VRF_TRAIN_STUCK) && v->load_unload_time_rem > 2 * _settings_game.pf.wait_for_pbs_path * DAY_TICKS) {
 
			if (HasBit(v->flags, VRF_TRAIN_STUCK) && v->load_unload_time_rem > 2 * _settings_game.pf.wait_for_pbs_path * DAY_TICKS) {
 
				/* Show message to player. */
 
				if (_settings_client.gui.lost_train_warn && v->owner == _local_company) {
 
					SetDParam(0, v->index);
 
@@ -4337,8 +4337,8 @@ static bool TrainLocoHandler(Train *v, b
 
				v->load_unload_time_rem = 0;
 
			}
 
			/* Exit if force proceed not pressed, else reset stuck flag anyway. */
 
			if (v->u.rail.force_proceed == 0) return true;
 
			ClrBit(v->u.rail.flags, VRF_TRAIN_STUCK);
 
			if (v->force_proceed == 0) return true;
 
			ClrBit(v->flags, VRF_TRAIN_STUCK);
 
			v->load_unload_time_rem = 0;
 
			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
		}
 
@@ -4447,7 +4447,7 @@ bool Train::Tick()
 
		return TrainLocoHandler(this, true);
 
	} else if (IsFreeWagon(this) && HASBITS(this->vehstatus, VS_CRASHED)) {
 
		/* Delete flooded standalone wagon chain */
 
		if (++this->u.rail.crash_anim_pos >= 4400) {
 
		if (++this->crash_anim_pos >= 4400) {
 
			delete this;
 
			return false;
 
		}
 
@@ -4532,17 +4532,17 @@ Trackdir Train::GetVehicleTrackdir() con
 
{
 
	if (this->vehstatus & VS_CRASHED) return INVALID_TRACKDIR;
 

	
 
	if (this->u.rail.track == TRACK_BIT_DEPOT) {
 
	if (this->track == TRACK_BIT_DEPOT) {
 
		/* We'll assume the train is facing outwards */
 
		return DiagDirToDiagTrackdir(GetRailDepotDirection(this->tile)); // Train in depot
 
	}
 

	
 
	if (this->u.rail.track == TRACK_BIT_WORMHOLE) {
 
	if (this->track == TRACK_BIT_WORMHOLE) {
 
		/* train in tunnel or on bridge, so just use his direction and assume a diagonal track */
 
		return DiagDirToDiagTrackdir(DirToDiagDir(this->direction));
 
	}
 

	
 
	return TrackDirectionToTrackdir(FindFirstTrack(this->u.rail.track), this->direction);
 
	return TrackDirectionToTrackdir(FindFirstTrack(this->track), this->direction);
 
}
 

	
 
void InitializeTrains()
src/train_gui.cpp
Show inline comments
 
@@ -28,7 +28,7 @@ void CcBuildWagon(bool success, TileInde
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->type == VEH_TRAIN && IsFrontEngine(v) &&
 
				v->tile == tile &&
 
				((Train *)v)->u.rail.track == TRACK_BIT_DEPOT) {
 
				((Train *)v)->track == TRACK_BIT_DEPOT) {
 
			if (found != NULL) return; // must be exactly one.
 
			found = v;
 
		}
src/tunnelbridge_cmd.cpp
Show inline comments
 
@@ -1390,7 +1390,7 @@ static VehicleEnterTileStatus VehicleEnt
 

	
 
			vdir = DirToDiagDir(t->direction);
 

	
 
			if (t->u.rail.track != TRACK_BIT_WORMHOLE && dir == vdir) {
 
			if (t->track != TRACK_BIT_WORMHOLE && dir == vdir) {
 
				if (IsFrontEngine(t) && fc == _tunnel_fractcoord_1[dir]) {
 
					if (!PlayVehicleSound(t, VSE_TUNNEL) && RailVehInfo(t->engine_type)->engclass == 0) {
 
						SndPlayVehicleFx(SND_05_TRAIN_THROUGH_TUNNEL, v);
 
@@ -1399,7 +1399,7 @@ static VehicleEnterTileStatus VehicleEnt
 
				}
 
				if (fc == _tunnel_fractcoord_2[dir]) {
 
					t->tile = tile;
 
					t->u.rail.track = TRACK_BIT_WORMHOLE;
 
					t->track = TRACK_BIT_WORMHOLE;
 
					t->vehstatus |= VS_HIDDEN;
 
					return VETSB_ENTERED_WORMHOLE;
 
				}
 
@@ -1408,8 +1408,8 @@ static VehicleEnterTileStatus VehicleEnt
 
			if (dir == ReverseDiagDir(vdir) && fc == _tunnel_fractcoord_3[dir] && z == 0) {
 
				/* We're at the tunnel exit ?? */
 
				t->tile = tile;
 
				t->u.rail.track = (TrackBits)_exit_tunnel_track[dir];
 
				assert(t->u.rail.track);
 
				t->track = (TrackBits)_exit_tunnel_track[dir];
 
				assert(t->track);
 
				t->vehstatus &= ~VS_HIDDEN;
 
				return VETSB_ENTERED_WORMHOLE;
 
			}
 
@@ -1465,9 +1465,9 @@ static VehicleEnterTileStatus VehicleEnt
 
			switch (v->type) {
 
				case VEH_TRAIN: {
 
					Train *t = (Train *)v;
 
					t->u.rail.track = TRACK_BIT_WORMHOLE;
 
					ClrBit(t->u.rail.flags, VRF_GOINGUP);
 
					ClrBit(t->u.rail.flags, VRF_GOINGDOWN);
 
					t->track = TRACK_BIT_WORMHOLE;
 
					ClrBit(t->flags, VRF_GOINGUP);
 
					ClrBit(t->flags, VRF_GOINGDOWN);
 
				} break;
 

	
 
				case VEH_ROAD:
 
@@ -1486,8 +1486,8 @@ static VehicleEnterTileStatus VehicleEnt
 
			switch (v->type) {
 
				case VEH_TRAIN: {
 
					Train *t = (Train *)v;
 
					if (t->u.rail.track == TRACK_BIT_WORMHOLE) {
 
						t->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y);
 
					if (t->track == TRACK_BIT_WORMHOLE) {
 
						t->track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y);
 
						return VETSB_ENTERED_WORMHOLE;
 
					}
 
				} break;
src/vehicle.cpp
Show inline comments
 
@@ -982,7 +982,7 @@ void VehicleEnterDepot(Vehicle *v)
 
			if (!IsFrontEngine(v)) v = v->First();
 
			UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner);
 
			v->load_unload_time_rem = 0;
 
			ClrBit(((Train *)v)->u.rail.flags, VRF_TOGGLE_REVERSE);
 
			ClrBit(((Train *)v)->flags, VRF_TOGGLE_REVERSE);
 
			TrainConsistChanged((Train *)v, true);
 
			break;
 

	
src/vehicle_base.h
Show inline comments
 
@@ -45,14 +45,10 @@ enum VehicleFlags {
 
};
 

	
 
struct VehicleRail {
 
	/* Link between the two ends of a multiheaded engine */
 
	Train *other_multiheaded_part;
 

	
 
	/* Cached wagon override spritegroup */
 
	const struct SpriteGroup *cached_override;
 

	
 
	uint16 last_speed; // NOSAVE: only used in UI
 
	uint16 crash_anim_pos;
 

	
 
	/* cached values, recalculated on load and each time a vehicle is added to/removed from the consist. */
 
	uint32 cached_power;        ///< total power of the consist.
 
@@ -79,38 +75,6 @@ struct VehicleRail {
 
	/* NOSAVE: for wagon override - id of the first engine in train
 
	 * 0xffff == not in train */
 
	EngineID first_engine;
 

	
 
	uint16 flags;
 
	TrackBitsByte track;
 
	byte force_proceed;
 
	RailTypeByte railtype;
 
	RailTypes compatible_railtypes;
 
};
 

	
 
enum VehicleRailFlags {
 
	VRF_REVERSING         = 0,
 

	
 
	/* used to calculate if train is going up or down */
 
	VRF_GOINGUP           = 1,
 
	VRF_GOINGDOWN         = 2,
 

	
 
	/* used to store if a wagon is powered or not */
 
	VRF_POWEREDWAGON      = 3,
 

	
 
	/* used to reverse the visible direction of the vehicle */
 
	VRF_REVERSE_DIRECTION = 4,
 

	
 
	/* used to mark train as lost because PF can't find the route */
 
	VRF_NO_PATH_TO_DESTINATION = 5,
 

	
 
	/* used to mark that electric train engine is allowed to run on normal rail */
 
	VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL = 6,
 

	
 
	/* used for vehicle var 0xFE bit 8 (toggled each time the train is reversed, accurate for first vehicle only) */
 
	VRF_TOGGLE_REVERSE = 7,
 

	
 
	/* used to mark a train that can't get a path reservation */
 
	VRF_TRAIN_STUCK    = 8,
 
};
 

	
 
typedef Pool<Vehicle, VehicleID, 512, 64000> VehiclePool;
src/vehicle_cmd.cpp
Show inline comments
 
@@ -349,7 +349,7 @@ CommandCost CmdCloneVehicle(TileIndex ti
 

	
 
	if (!CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (v->type == VEH_TRAIN && (!IsFrontEngine(v) || v->u.rail.crash_anim_pos >= 4400)) return CMD_ERROR;
 
	if (v->type == VEH_TRAIN && (!IsFrontEngine(v) || ((Train *)v)->crash_anim_pos >= 4400)) return CMD_ERROR;
 

	
 
	/* check that we can allocate enough vehicles */
 
	if (!(flags & DC_EXEC)) {
 
@@ -381,8 +381,8 @@ CommandCost CmdCloneVehicle(TileIndex ti
 
		if (flags & DC_EXEC) {
 
			w = Vehicle::Get(_new_vehicle_id);
 

	
 
			if (v->type == VEH_TRAIN && HasBit(((Train *)v)->u.rail.flags, VRF_REVERSE_DIRECTION)) {
 
				SetBit(((Train *)w)->u.rail.flags, VRF_REVERSE_DIRECTION);
 
			if (v->type == VEH_TRAIN && HasBit(((Train *)v)->flags, VRF_REVERSE_DIRECTION)) {
 
				SetBit(((Train *)w)->flags, VRF_REVERSE_DIRECTION);
 
			}
 

	
 
			if (v->type == VEH_TRAIN && !IsFrontEngine(v)) {
src/vehicle_gui.cpp
Show inline comments
 
@@ -1469,7 +1469,7 @@ struct VehicleDetailsWindow : Window {
 
				SetDParam(1, v->u.rail.cached_power);
 
				SetDParam(0, v->u.rail.cached_weight);
 
				SetDParam(3, v->u.rail.cached_max_te / 1000);
 
				DrawString(2, this->width - 2, 25, (_settings_game.vehicle.train_acceleration_model != TAM_ORIGINAL && ((Train *)v)->u.rail.railtype != RAILTYPE_MAGLEV) ?
 
				DrawString(2, this->width - 2, 25, (_settings_game.vehicle.train_acceleration_model != TAM_ORIGINAL && ((Train *)v)->railtype != RAILTYPE_MAGLEV) ?
 
					STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :
 
					STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED);
 
				break;
 
@@ -1949,7 +1949,7 @@ struct VehicleViewWindow : Window {
 
			} else { // no train
 
				str = STR_VEHICLE_STATUS_STOPPED;
 
			}
 
		} else if (v->type == VEH_TRAIN && HasBit(((Train *)v)->u.rail.flags, VRF_TRAIN_STUCK)) {
 
		} else if (v->type == VEH_TRAIN && HasBit(((Train *)v)->flags, VRF_TRAIN_STUCK)) {
 
			str = STR_TRAIN_STUCK;
 
		} else { // vehicle is in a "normal" state, show current order
 
			switch (v->current_order.GetType()) {
src/vehiclelist.cpp
Show inline comments
 
@@ -29,7 +29,7 @@ void BuildDepotVehicleList(VehicleType t
 
		switch (type) {
 
			case VEH_TRAIN:
 
				if (IsArticulatedPart(v) || IsRearDualheaded(v)) continue;
 
				if (((Train *)v)->u.rail.track != TRACK_BIT_DEPOT) continue;
 
				if (((Train *)v)->track != TRACK_BIT_DEPOT) continue;
 
				if (wagons != NULL && IsFreeWagon(v->First())) {
 
					if (individual_wagons || IsFreeWagon(v)) *wagons->Append() = v;
 
					continue;
src/water_cmd.cpp
Show inline comments
 
@@ -816,7 +816,7 @@ static void FloodVehicle(Vehicle *v)
 
						FreeTrainTrackReservation((Train *)v);
 
						v->vehstatus |= VS_CRASHED;
 
					}
 
					v->u.rail.crash_anim_pos = 4000; // max 4440, disappear pretty fast
 
					((Train *)v)->crash_anim_pos = 4000; // max 4440, disappear pretty fast
 
					InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
 
					break;
 

	
src/yapf/follow_track.hpp
Show inline comments
 
@@ -55,7 +55,7 @@ struct CFollowTrackT
 
	{
 
		assert(!IsRailTT() || (v != NULL && v->type == VEH_TRAIN));
 
		m_veh = v;
 
		Init(v != NULL ? v->owner : INVALID_OWNER, railtype_override == INVALID_RAILTYPES ? ((Train *)v)->u.rail.compatible_railtypes : railtype_override, pPerf);
 
		Init(v != NULL ? v->owner : INVALID_OWNER, railtype_override == INVALID_RAILTYPES ? ((Train *)v)->compatible_railtypes : railtype_override, pPerf);
 
	}
 

	
 
	FORCEINLINE void Init(Owner o, RailTypes railtype_override, CPerformanceTimer *pPerf)
src/yapf/yapf_destrail.hpp
Show inline comments
 
@@ -13,8 +13,8 @@ protected:
 
public:
 
	void SetDestination(const Vehicle *v, bool override_rail_type = false)
 
	{
 
		m_compatible_railtypes = v->u.rail.compatible_railtypes;
 
		if (override_rail_type) m_compatible_railtypes |= GetRailTypeInfo(v->u.rail.railtype)->compatible_railtypes;
 
		m_compatible_railtypes = ((Train *)v)->compatible_railtypes;
 
		if (override_rail_type) m_compatible_railtypes |= GetRailTypeInfo(((Train *)v)->railtype)->compatible_railtypes;
 
	}
 

	
 
	bool IsCompatibleRailType(RailType rt)
src/yapf/yapf_rail.cpp
Show inline comments
 
@@ -550,7 +550,7 @@ bool YapfCheckReverseTrain(const Vehicle
 

	
 
	int reverse_penalty = 0;
 

	
 
	if (v->u.rail.track == TRACK_BIT_WORMHOLE) {
 
	if (v->track == TRACK_BIT_WORMHOLE) {
 
		/* front in tunnel / on bridge */
 
		DiagDirection dir_into_wormhole = GetTunnelBridgeDirection(tile);
 

	
 
@@ -565,7 +565,7 @@ bool YapfCheckReverseTrain(const Vehicle
 
		reverse_penalty -= DistanceManhattan(cur_tile, tile) * YAPF_TILE_LENGTH;
 
	}
 

	
 
	if (last_veh->u.rail.track == TRACK_BIT_WORMHOLE) {
 
	if (last_veh->track == TRACK_BIT_WORMHOLE) {
 
		/* back in tunnel / on bridge */
 
		DiagDirection dir_into_wormhole = GetTunnelBridgeDirection(tile_rev);
 

	
0 comments (0 inline, 0 general)