* Determine whether a certain track on a tile is a safe position to end a path. * * @param v the vehicle to test for * @param tile The tile * @param trackdir The trackdir to test * @param include_line_end Should end-of-line tiles be considered safe? * @param forbid_90deg Don't allow trains to make 90 degree turns * @return True if it is a safe position */
| 379 | * @return True if it is a safe position |
| 380 | */ |
| 381 | bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bool include_line_end, bool forbid_90deg) |
| 382 | { |
| 383 | if (IsRailDepotTile(tile)) return true; |
| 384 | |
| 385 | if (IsTileType(tile, MP_RAILWAY)) { |
| 386 | /* For non-pbs signals, stop on the signal tile. */ |
| 387 | if (HasSignalOnTrackdir(tile, trackdir) && !IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) return true; |
| 388 | } |
| 389 | |
| 390 | /* Check next tile. For performance reasons, we check for 90 degree turns ourself. */ |
| 391 | CFollowTrackRail ft(v, GetAllCompatibleRailTypes(v->railtypes)); |
| 392 | |
| 393 | /* End of track? */ |
| 394 | if (!ft.Follow(tile, trackdir)) { |
| 395 | /* Last tile of a terminus station is a safe position. */ |
| 396 | if (include_line_end) return true; |
| 397 | } |
| 398 | |
| 399 | /* Check for reachable tracks. */ |
| 400 | ft.new_td_bits &= DiagdirReachesTrackdirs(ft.exitdir); |
| 401 | if (Rail90DegTurnDisallowed(GetTileRailType(ft.old_tile), GetTileRailType(ft.new_tile), forbid_90deg)) ft.new_td_bits &= ~TrackdirCrossesTrackdirs(trackdir); |
| 402 | if (ft.new_td_bits == TRACKDIR_BIT_NONE) return include_line_end; |
| 403 | |
| 404 | if (ft.new_td_bits != TRACKDIR_BIT_NONE && KillFirstBit(ft.new_td_bits) == TRACKDIR_BIT_NONE) { |
| 405 | Trackdir td = FindFirstTrackdir(ft.new_td_bits); |
| 406 | /* PBS signal on next trackdir? Safe position. */ |
| 407 | if (HasPbsSignalOnTrackdir(ft.new_tile, td)) return true; |
| 408 | /* One-way PBS signal against us? Safe if end-of-line is allowed. */ |
| 409 | if (IsTileType(ft.new_tile, MP_RAILWAY) && HasSignalOnTrackdir(ft.new_tile, ReverseTrackdir(td)) && |
| 410 | GetSignalType(ft.new_tile, TrackdirToTrack(td)) == SIGTYPE_PBS_ONEWAY) { |
| 411 | return include_line_end; |
| 412 | } |
| 413 | } |
| 414 | |
| 415 | return false; |
| 416 | } |
| 417 | |
| 418 | /** |
| 419 | * Check if a safe position is free. |
no test coverage detected