MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / DeleteLastWagon

Function DeleteLastWagon

src/train_cmd.cpp:3635–3708  ·  view source on GitHub ↗

* Deletes/Clears the last wagon of a crashed train. It takes the engine of the * train, then goes to the last wagon and deletes that. Each call to this function * will remove the last wagon of a crashed train. If this wagon was on a crossing, * or inside a tunnel/bridge, recalculate the signals as they might need updating * @param v the Vehicle of which last wagon is to be removed */

Source from the content-addressed store, hash-verified

3633 * @param v the Vehicle of which last wagon is to be removed
3634 */
3635static void DeleteLastWagon(Train *v)
3636{
3637 Train *first = v->First();
3638
3639 /* Go to the last wagon and delete the link pointing there
3640 * new_last is then the one-before-last wagon, and v the last
3641 * one which will physically be removed */
3642 Train *new_last = v;
3643 for (; v->Next() != nullptr; v = v->Next()) new_last = v;
3644 new_last->SetNext(nullptr);
3645
3646 if (first != v) {
3647 /* Recalculate cached train properties */
3648 first->ConsistChanged(CCF_ARRANGE);
3649 /* Update the depot window if the first vehicle is in depot -
3650 * if v == first, then it is updated in PreDestructor() */
3651 if (first->track == TRACK_BIT_DEPOT) {
3652 SetWindowDirty(WC_VEHICLE_DEPOT, first->tile);
3653 }
3654 v->last_station_visited = first->last_station_visited; // for PreDestructor
3655 }
3656
3657 /* 'v' shouldn't be accessed after it has been deleted */
3658 TrackBits trackbits = v->track;
3659 TileIndex tile = v->tile;
3660 Owner owner = v->owner;
3661
3662 delete v;
3663 v = nullptr; // make sure nobody will try to read 'v' anymore
3664
3665 if (trackbits == TRACK_BIT_WORMHOLE) {
3666 /* Vehicle is inside a wormhole, v->track contains no useful value then. */
3667 trackbits = DiagDirToDiagTrackBits(GetTunnelBridgeDirection(tile));
3668 }
3669
3670 Track track = TrackBitsToTrack(trackbits);
3671 if (HasReservedTracks(tile, trackbits)) {
3672 UnreserveRailTrack(tile, track);
3673
3674 /* If there are still crashed vehicles on the tile, give the track reservation to them */
3675 TrackBits remaining_trackbits = TRACK_BIT_NONE;
3676 for (const Vehicle *u : VehiclesOnTile(tile)) {
3677 if (u->type != VEH_TRAIN || !u->vehstatus.Test(VehState::Crashed)) continue;
3678 TrackBits train_tbits = Train::From(u)->track;
3679 if (train_tbits == TRACK_BIT_WORMHOLE) {
3680 /* Vehicle is inside a wormhole, u->track contains no useful value then. */
3681 remaining_trackbits |= DiagDirToDiagTrackBits(GetTunnelBridgeDirection(u->tile));
3682 } else if (train_tbits != TRACK_BIT_DEPOT) {
3683 remaining_trackbits |= train_tbits;
3684 }
3685 }
3686
3687 /* It is important that these two are the first in the loop, as reservation cannot deal with every trackbit combination */
3688 assert(TRACK_BEGIN == TRACK_X && TRACK_Y == TRACK_BEGIN + 1);
3689 for (Track t : SetTrackBitIterator(remaining_trackbits)) TryReserveRailTrack(tile, t);
3690 }
3691
3692 /* check if the wagon was on a road/rail-crossing */

Callers 1

HandleCrashedTrainFunction · 0.85

Calls 15

SetWindowDirtyFunction · 0.85
DiagDirToDiagTrackBitsFunction · 0.85
GetTunnelBridgeDirectionFunction · 0.85
TrackBitsToTrackFunction · 0.85
HasReservedTracksFunction · 0.85
UnreserveRailTrackFunction · 0.85
VehiclesOnTileClass · 0.85
TryReserveRailTrackFunction · 0.85
IsLevelCrossingTileFunction · 0.85
UpdateLevelCrossingFunction · 0.85
IsRailStationTileFunction · 0.85

Tested by

no test coverage detected