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

Function ReverseTrainDirection

src/train_cmd.cpp:1985–2067  ·  view source on GitHub ↗

* Turn a train around. * @param v %Train to turn around. */

Source from the content-addressed store, hash-verified

1983 * @param v %Train to turn around.
1984 */
1985void ReverseTrainDirection(Train *v)
1986{
1987 if (IsRailDepotTile(v->tile)) {
1988 if (IsWholeTrainInsideDepot(v)) return;
1989 InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
1990 }
1991
1992 /* Clear path reservation in front if train is not stuck. */
1993 if (!v->flags.Test(VehicleRailFlag::Stuck)) FreeTrainTrackReservation(v);
1994
1995 /* Check if we were approaching a rail/road-crossing */
1996 TileIndex crossing = TrainApproachingCrossingTile(v);
1997
1998 /* count number of vehicles */
1999 int r = CountVehiclesInChain(v) - 1; // number of vehicles - 1
2000
2001 AdvanceWagonsBeforeSwap(v);
2002
2003 /* swap start<>end, start+1<>end-1, ... */
2004 int l = 0;
2005 do {
2006 ReverseTrainSwapVeh(v, l++, r--);
2007 } while (l <= r);
2008
2009 AdvanceWagonsAfterSwap(v);
2010
2011 if (IsRailDepotTile(v->tile)) {
2012 InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
2013 }
2014
2015 v->flags.Flip(VehicleRailFlag::Reversed);
2016 v->flags.Reset(VehicleRailFlag::Reversing);
2017
2018 /* recalculate cached data */
2019 v->ConsistChanged(CCF_TRACK);
2020
2021 /* update all images */
2022 for (Train *u = v; u != nullptr; u = u->Next()) u->UpdateViewport(false, false);
2023
2024 /* update crossing we were approaching */
2025 if (crossing != INVALID_TILE) UpdateLevelCrossing(crossing);
2026
2027 /* maybe we are approaching crossing now, after reversal */
2028 crossing = TrainApproachingCrossingTile(v);
2029 if (crossing != INVALID_TILE) MaybeBarCrossingWithSound(crossing);
2030
2031 /* If we are inside a depot after reversing, don't bother with path reserving. */
2032 if (v->track == TRACK_BIT_DEPOT) {
2033 /* Can't be stuck here as inside a depot is always a safe tile. */
2034 if (v->flags.Test(VehicleRailFlag::Stuck)) SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
2035 v->flags.Reset(VehicleRailFlag::Stuck);
2036 return;
2037 }
2038
2039 /* VehicleExitDir does not always produce the desired dir for depots and
2040 * tunnels/bridges that is needed for UpdateSignalsOnSegment. */
2041 DiagDirection dir = VehicleExitDir(v->direction, v->track);
2042 if (IsRailDepotTile(v->tile) || IsTileType(v->tile, MP_TUNNELBRIDGE)) dir = INVALID_DIAGDIR;

Callers 4

CmdReverseTrainDirectionFunction · 0.85
TrainControllerFunction · 0.85
TrainApproachingLineEndFunction · 0.85
TrainLocoHandlerFunction · 0.85

Calls 15

IsRailDepotTileFunction · 0.85
IsWholeTrainInsideDepotFunction · 0.85
CountVehiclesInChainFunction · 0.85
AdvanceWagonsBeforeSwapFunction · 0.85
ReverseTrainSwapVehFunction · 0.85
AdvanceWagonsAfterSwapFunction · 0.85
UpdateLevelCrossingFunction · 0.85
SetWindowWidgetDirtyFunction · 0.85
VehicleExitDirFunction · 0.85

Tested by

no test coverage detected