diff options
-rw-r--r-- | src/articulated_vehicles.cpp | 4 | ||||
-rw-r--r-- | src/autoreplace_cmd.cpp | 6 | ||||
-rw-r--r-- | src/elrail.cpp | 8 | ||||
-rw-r--r-- | src/newgrf_engine.cpp | 12 | ||||
-rw-r--r-- | src/npf.cpp | 4 | ||||
-rw-r--r-- | src/pbs.cpp | 8 | ||||
-rw-r--r-- | src/rail_cmd.cpp | 10 | ||||
-rw-r--r-- | src/saveload/afterload.cpp | 10 | ||||
-rw-r--r-- | src/saveload/oldloader_sl.cpp | 12 | ||||
-rw-r--r-- | src/saveload/vehicle_sl.cpp | 24 | ||||
-rw-r--r-- | src/signal.cpp | 2 | ||||
-rw-r--r-- | src/train.h | 38 | ||||
-rw-r--r-- | src/train_cmd.cpp | 308 | ||||
-rw-r--r-- | src/train_gui.cpp | 2 | ||||
-rw-r--r-- | src/tunnelbridge_cmd.cpp | 18 | ||||
-rw-r--r-- | src/vehicle.cpp | 2 | ||||
-rw-r--r-- | src/vehicle_base.h | 36 | ||||
-rw-r--r-- | src/vehicle_cmd.cpp | 6 | ||||
-rw-r--r-- | src/vehicle_gui.cpp | 4 | ||||
-rw-r--r-- | src/vehiclelist.cpp | 2 | ||||
-rw-r--r-- | src/water_cmd.cpp | 2 | ||||
-rw-r--r-- | src/yapf/follow_track.hpp | 2 | ||||
-rw-r--r-- | src/yapf/yapf_destrail.hpp | 4 | ||||
-rw-r--r-- | src/yapf/yapf_rail.cpp | 4 |
24 files changed, 265 insertions, 263 deletions
diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp index 2de9bac0f..233d3c9a7 100644 --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.cpp @@ -312,8 +312,8 @@ void AddArticulatedParts(Vehicle *first, VehicleType type) 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; diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 25bc39ea3..aaec89aa4 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -92,7 +92,7 @@ static void TransferCargo(Vehicle *old_veh, Vehicle *new_head, bool part_of_chai 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_veh, Vehicle *new_head, bool part_of_chai /* 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 BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic } /* 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); } diff --git a/src/elrail.cpp b/src/elrail.cpp index 78ee3c8a8..68b4a0e1d 100644 --- a/src/elrail.cpp +++ b/src/elrail.cpp @@ -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); } } } diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index dd971f7f1..63ee47c4c 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -672,12 +672,12 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by 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 ResolverObject *object, byte variable, by 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 ResolverObject *object, byte variable, by 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); diff --git a/src/npf.cpp b/src/npf.cpp index 5502b2206..65e3faa66 100644 --- a/src/npf.cpp +++ b/src/npf.cpp @@ -1070,8 +1070,8 @@ NPFFoundTargetData NPFRouteToSafeTile(const Train *v, TileIndex tile, Trackdir t 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...*/ diff --git a/src/pbs.cpp b/src/pbs.cpp index 26a586516..0554b2ecc 100644 --- a/src/pbs.cpp +++ b/src/pbs.cpp @@ -236,7 +236,7 @@ static Vehicle *FindTrainOnTrackEnum(Vehicle *v, void *data) 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 Train *v, bool *train_on_res) 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 *v, TileIndex tile, Trackdir trackdir, bo } /* 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 *v, TileIndex tile, Trackdir trackdir, bo 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; diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 6e9ecc37e..eb838ca26 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -93,7 +93,7 @@ Vehicle *EnsureNoTrainOnTrackProc(Vehicle *v, void *data) 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 tile, DoCommandFlag flags, uint32 p1, uint3 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 tile, DoCommandFlag flags, uint32 p1, uint3 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 VehicleEnter_Track(Vehicle *u, TileIndex tile, int } 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 VehicleEnter_Track(Vehicle *u, TileIndex tile, int /* 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); } } } diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 3e0309ac1..bc3aa436a 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -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)); } } } diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index e95748807..080ea6c90 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -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(LoadgameState *ls, int num) } 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, int num) }; 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; } diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 6901bef4f..cdf585eca 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -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(VehicleType vt) 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), diff --git a/src/signal.cpp b/src/signal.cpp index 4226a4446..8600e5a3b 100644 --- a/src/signal.cpp +++ b/src/signal.cpp @@ -185,7 +185,7 @@ static SmallSet<DiagDirection, SIG_GLOB_SIZE> _globset("_globset"); ///< set of /** 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; } diff --git a/src/train.h b/src/train.h index 86c8c8a21..95b128f9e 100644 --- a/src/train.h +++ b/src/train.h @@ -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; } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 31a7d7b26..4e597ec74 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -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 same_length) 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 same_length) /* 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 same_length) 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, bool mode) 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, bool mode) num++; drag_coeff += 3; - if (u->u.rail.track == TRACK_BIT_DEPOT) max_speed = min(max_speed, 61); + if (u->track == TRACK_BIT_DEPOT) max_speed = min(max_speed, 61); - if (HasBit(u->u.rail.flags, VRF_GOINGUP)) { + 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, bool mode) 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, bool mode) 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, bool mode) } } 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 direction) const 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(EngineID engine, TileIndex tile, DoCommandF 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(EngineID engine, TileIndex tile, DoCommandF 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(const Train *u) 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 AddRearEngineToMultiheadedTrain(Train *v) 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 AddRearEngineToMultiheadedTrain(Train *v) 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(TileIndex tile, DoCommandFlag flags, uint32 p1, 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(TileIndex tile, DoCommandFlag flags, uint32 p1, 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, bool needs_to_be_stopped) * * 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 *v) 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 tile, DoCommandFlag flags, uint32 p1, u 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 tile, DoCommandFlag flags, uint32 p1, uin /* 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 tile, DoCommandFlag flags, uint32 p1, uin 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 tile, DoCommandFlag flags, uint32 p1, uin 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, int spd) /** 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, int l, int r) 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 *v) { /* 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 *v) 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 *v) InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); } - ToggleBit(v->u.rail.flags, VRF_TOGGLE_REVERSE); + ToggleBit(v->flags, VRF_TOGGLE_REVERSE); - ClrBit(v->u.rail.flags, VRF_REVERSING); + ClrBit(v->flags, VRF_REVERSING); /* recalculate cached data */ TrainConsistChanged(v, true); @@ -1908,16 +1908,16 @@ static void ReverseTrainDirection(Train *v) 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 *v) * 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 *v) /* 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(TileIndex tile, DoCommandFlag flags, uint32 } 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(TileIndex tile, DoCommandFlag flags, uint32 } 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(TileIndex tile, DoCommandFlag flags, uint32 p1, 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 FindClosestTrainDepot(Train *v, int max_distance) 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 FindClosestTrainDepot(Train *v, int max_distance) 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 FindClosestTrainDepot(Train *v, int max_distance) 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(const Train *v) 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(const Train *v) 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 *v) { /* 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 *v) 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 *v) } /* 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 *v) 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 Train *v, TileIndex origin, Trackdir orig_t /* 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, TileIndex tile, DiagDirection enterdir, 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, TileIndex tile, DiagDirection enterdir, 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, TileIndex tile, DiagDirection enterdir, /* 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, TileIndex tile, DiagDirection enterdir, } } 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_as_stuck, bool first_tile_okay) /* 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_as_stuck, bool first_tile_okay) } /* 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_as_stuck, bool first_tile_okay) /* 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_as_stuck, bool first_tile_okay) } /* 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_as_stuck, bool first_tile_okay) 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_as_stuck, bool first_tile_okay) 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, bool new_tile) 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); + ClrBit(v->flags, VRF_GOINGUP); + ClrBit(v->flags, VRF_GOINGDOWN); - if (v->u.rail.track == TRACK_BIT_X || v->u.rail.track == TRACK_BIT_Y) { + 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, bool new_tile) /* 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(const Train *v, TileIndex tile) 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 AffectSpeedByDirChange(Train *v, Direction new_dir) 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(Train *v, byte old_z) { 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(TileIndex tile, DiagDirection dir) 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(Vehicle *v, void *data) 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(Vehicle *v, void *data) * 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(Vehicle *v, void *data) static bool CheckTrainCollision(Train *v) { /* can't collide in depot */ - if (v->u.rail.track == TRACK_BIT_DEPOT) return false; + if (v->track == TRACK_BIT_DEPOT) return false; - assert(v->u.rail.track == TRACK_BIT_WORMHOLE || TileVirtXY(v->x_pos, v->y_pos) == v->tile); + 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(Vehicle *v, void *data) 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, Vehicle *nomove) 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, Vehicle *nomove) 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, Vehicle *nomove) 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, Vehicle *nomove) /* 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, Vehicle *nomove) 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, Vehicle *nomove) * 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 *CollectTrackbitsFromCrashedVehiclesEnum(Vehicle *v, void *data) 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 *v) /* 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(Train *v, bool signal) 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 TrainApproachingCrossingTile(const Train *v) 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 *v) 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 *v) /* 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, bool mode) 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, bool mode) 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, bool mode) } /* 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, bool mode) 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() const { 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() diff --git a/src/train_gui.cpp b/src/train_gui.cpp index 1f16bbd15..d351ce708 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -28,7 +28,7 @@ void CcBuildWagon(bool success, TileIndex tile, uint32 p1, uint32 p2) 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; } diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 4cd0d2e5a..0c61b624b 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -1390,7 +1390,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti 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 VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti } 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 VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti 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 VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti 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 VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti 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; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 5cfb253bb..2950924b0 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -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; diff --git a/src/vehicle_base.h b/src/vehicle_base.h index cb18d2b69..6f2a1c91c 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -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; diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index dc21d1000..774daeac3 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -349,7 +349,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint 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 tile, DoCommandFlag flags, uint32 p1, uint 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)) { diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 6a6ee6bb3..9bee78ce0 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -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()) { diff --git a/src/vehiclelist.cpp b/src/vehiclelist.cpp index ab57da1e4..332ecf1be 100644 --- a/src/vehiclelist.cpp +++ b/src/vehiclelist.cpp @@ -29,7 +29,7 @@ void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engine 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; diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 2ba7dd8d5..d4b3f69a6 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -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; diff --git a/src/yapf/follow_track.hpp b/src/yapf/follow_track.hpp index a0f9dc37c..0263150fe 100644 --- a/src/yapf/follow_track.hpp +++ b/src/yapf/follow_track.hpp @@ -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) diff --git a/src/yapf/yapf_destrail.hpp b/src/yapf/yapf_destrail.hpp index fbdac4a71..99aa4ea48 100644 --- a/src/yapf/yapf_destrail.hpp +++ b/src/yapf/yapf_destrail.hpp @@ -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) diff --git a/src/yapf/yapf_rail.cpp b/src/yapf/yapf_rail.cpp index 2c05c68ff..7b4e4e9bb 100644 --- a/src/yapf/yapf_rail.cpp +++ b/src/yapf/yapf_rail.cpp @@ -550,7 +550,7 @@ bool YapfCheckReverseTrain(const Vehicle *vt) 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 *vt) 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); |