* Find the train which has reserved a specific path. * * @param tile A tile on the path. * @param track A reserved track on the tile. * @return The vehicle holding the reservation or nullptr if the path is stray. */
| 329 | * @return The vehicle holding the reservation or nullptr if the path is stray. |
| 330 | */ |
| 331 | Train *GetTrainForReservation(TileIndex tile, Track track) |
| 332 | { |
| 333 | assert(HasReservedTracks(tile, TrackToTrackBits(track))); |
| 334 | Trackdir trackdir = TrackToTrackdir(track); |
| 335 | |
| 336 | RailTypes rts = GetRailTypeInfo(GetTileRailType(tile))->compatible_railtypes; |
| 337 | |
| 338 | /* Follow the path from tile to both ends, one of the end tiles should |
| 339 | * have a train on it. We need FollowReservation to ignore one-way signals |
| 340 | * here, as one of the two search directions will be the "wrong" way. */ |
| 341 | for (int i = 0; i < 2; ++i, trackdir = ReverseTrackdir(trackdir)) { |
| 342 | /* If the tile has a one-way block signal in the current trackdir, skip the |
| 343 | * search in this direction as the reservation can't come from this side.*/ |
| 344 | if (HasOnewaySignalBlockingTrackdir(tile, ReverseTrackdir(trackdir)) && !HasPbsSignalOnTrackdir(tile, trackdir)) continue; |
| 345 | |
| 346 | FindTrainOnTrackInfo ftoti; |
| 347 | ftoti.res = FollowReservation(GetTileOwner(tile), rts, tile, trackdir, true); |
| 348 | |
| 349 | CheckTrainsOnTrack(ftoti, ftoti.res.tile); |
| 350 | if (ftoti.best != nullptr) return ftoti.best; |
| 351 | |
| 352 | /* Special case for stations: check the whole platform for a vehicle. */ |
| 353 | if (IsRailStationTile(ftoti.res.tile)) { |
| 354 | TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(ReverseTrackdir(ftoti.res.trackdir))); |
| 355 | for (TileIndex st_tile = ftoti.res.tile + diff; IsCompatibleTrainStationTile(st_tile, ftoti.res.tile); st_tile += diff) { |
| 356 | CheckTrainsOnTrack(ftoti, st_tile); |
| 357 | if (ftoti.best != nullptr) return ftoti.best; |
| 358 | } |
| 359 | } |
| 360 | |
| 361 | /* Special case for bridges/tunnels: check the other end as well. */ |
| 362 | if (IsTileType(ftoti.res.tile, MP_TUNNELBRIDGE)) { |
| 363 | CheckTrainsOnTrack(ftoti, GetOtherTunnelBridgeEnd(ftoti.res.tile)); |
| 364 | if (ftoti.best != nullptr) return ftoti.best; |
| 365 | } |
| 366 | } |
| 367 | |
| 368 | return nullptr; |
| 369 | } |
| 370 | |
| 371 | /** |
| 372 | * Determine whether a certain track on a tile is a safe position to end a path. |
no test coverage detected