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

Function FreeTrainTrackReservation

src/train_cmd.cpp:2419–2478  ·  view source on GitHub ↗

* Free the reserved path in front of a vehicle. * @param v %Train owning the reserved path. */

Source from the content-addressed store, hash-verified

2417 * @param v %Train owning the reserved path.
2418 */
2419void FreeTrainTrackReservation(const Train *v)
2420{
2421 assert(v->IsFrontEngine());
2422
2423 TileIndex tile = v->tile;
2424 Trackdir td = v->GetVehicleTrackdir();
2425 bool free_tile = !(IsRailStationTile(v->tile) || IsTileType(v->tile, MP_TUNNELBRIDGE));
2426 StationID station_id = IsRailStationTile(v->tile) ? GetStationIndex(v->tile) : StationID::Invalid();
2427
2428 /* Can't be holding a reservation if we enter a depot. */
2429 if (IsRailDepotTile(tile) && TrackdirToExitdir(td) != GetRailDepotDirection(tile)) return;
2430 if (v->track == TRACK_BIT_DEPOT) {
2431 /* Front engine is in a depot. We enter if some part is not in the depot. */
2432 for (const Train *u = v; u != nullptr; u = u->Next()) {
2433 if (u->track != TRACK_BIT_DEPOT || u->tile != v->tile) return;
2434 }
2435 }
2436 /* Don't free reservation if it's not ours. */
2437 if (TracksOverlap(GetReservedTrackbits(tile) | TrackToTrackBits(TrackdirToTrack(td)))) return;
2438
2439 CFollowTrackRail ft(v, GetAllCompatibleRailTypes(v->railtypes));
2440 while (ft.Follow(tile, td)) {
2441 tile = ft.new_tile;
2442 TrackdirBits bits = ft.new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(tile));
2443 td = RemoveFirstTrackdir(&bits);
2444 assert(bits == TRACKDIR_BIT_NONE);
2445
2446 if (!IsValidTrackdir(td)) break;
2447
2448 if (IsTileType(tile, MP_RAILWAY)) {
2449 if (HasSignalOnTrackdir(tile, td) && !IsPbsSignal(GetSignalType(tile, TrackdirToTrack(td)))) {
2450 /* Conventional signal along trackdir: remove reservation and stop. */
2451 UnreserveRailTrack(tile, TrackdirToTrack(td));
2452 break;
2453 }
2454 if (HasPbsSignalOnTrackdir(tile, td)) {
2455 if (GetSignalStateByTrackdir(tile, td) == SIGNAL_STATE_RED) {
2456 /* Red PBS signal? Can't be our reservation, would be green then. */
2457 break;
2458 } else {
2459 /* Turn the signal back to red. */
2460 SetSignalStateByTrackdir(tile, td, SIGNAL_STATE_RED);
2461 MarkTileDirtyByTile(tile);
2462 }
2463 } else if (HasPbsSignalOnTrackdir(tile, ReverseTrackdir(td))) {
2464 /* Reservation passes an opposing path signal. Mark signal for update to re-establish the proper default state. */
2465 AddSideToSignalBuffer(tile, TrackdirToExitdir(ReverseTrackdir(td)), v->owner);
2466 } else if (HasSignalOnTrackdir(tile, ReverseTrackdir(td)) && IsOnewaySignal(tile, TrackdirToTrack(td))) {
2467 break;
2468 }
2469 }
2470
2471 /* Don't free first station/bridge/tunnel if we are on it. */
2472 if (free_tile || (!(ft.is_station && GetStationIndex(ft.new_tile) == station_id) && !ft.is_tunnel && !ft.is_bridge)) ClearPathReservation(v, tile, td);
2473
2474 free_tile = true;
2475 }
2476

Callers 10

CmdRemoveSingleRailFunction · 0.85
CmdBuildSingleSignalFunction · 0.85
CmdConvertRailFunction · 0.85
RemoveTrainDepotFunction · 0.85
DoClearTunnelFunction · 0.85
DoClearBridgeFunction · 0.85
ReverseTrainDirectionFunction · 0.85
ChooseTrainTrackFunction · 0.85
CrashMethod · 0.85
FreeTrainReservationFunction · 0.85

Calls 15

IsRailStationTileFunction · 0.85
IsTileTypeFunction · 0.85
GetStationIndexFunction · 0.85
InvalidFunction · 0.85
IsRailDepotTileFunction · 0.85
TrackdirToExitdirFunction · 0.85
GetRailDepotDirectionFunction · 0.85
TracksOverlapFunction · 0.85
GetReservedTrackbitsFunction · 0.85
TrackToTrackBitsFunction · 0.85
TrackdirToTrackFunction · 0.85

Tested by

no test coverage detected