* Check if a safe position is free. * * @param v the vehicle to test for * @param tile The tile * @param trackdir The trackdir to test * @param forbid_90deg Don't allow trains to make 90 degree turns * @return True if the position is free */
| 425 | * @return True if the position is free |
| 426 | */ |
| 427 | bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bool forbid_90deg) |
| 428 | { |
| 429 | Track track = TrackdirToTrack(trackdir); |
| 430 | TrackBits reserved = GetReservedTrackbits(tile); |
| 431 | |
| 432 | /* Tile reserved? Can never be a free waiting position. */ |
| 433 | if (TrackOverlapsTracks(reserved, track)) return false; |
| 434 | |
| 435 | /* Not reserved and depot or not a pbs signal -> free. */ |
| 436 | if (IsRailDepotTile(tile)) return true; |
| 437 | if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, trackdir) && !IsPbsSignal(GetSignalType(tile, track))) return true; |
| 438 | |
| 439 | /* Check the next tile, it has to be free as well. Do not filter for compatible railtypes |
| 440 | * to make sure we never accidentally join up reservations. */ |
| 441 | CFollowTrackRail ft(v, RailTypes{}); |
| 442 | |
| 443 | if (!ft.Follow(tile, trackdir)) return true; |
| 444 | |
| 445 | /* Check for reachable tracks. */ |
| 446 | ft.new_td_bits &= DiagdirReachesTrackdirs(ft.exitdir); |
| 447 | if (Rail90DegTurnDisallowed(GetTileRailType(ft.old_tile), GetTileRailType(ft.new_tile), forbid_90deg)) ft.new_td_bits &= ~TrackdirCrossesTrackdirs(trackdir); |
| 448 | |
| 449 | return !HasReservedTracks(ft.new_tile, TrackdirBitsToTrackBits(ft.new_td_bits)); |
| 450 | } |
no test coverage detected