4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
10 /** @file pbs.h PBS support routines */
15 #include "map/coord.h"
16 #include "direction_type.h"
17 #include "track_type.h"
18 #include "track_func.h"
19 #include "vehicle_type.h"
20 #include "pathfinder/railpos.h"
21 #include "map/bridge.h"
22 #include "map/tunnelbridge.h"
23 #include "signal_map.h"
25 TrackBits
GetReservedTrackbits(TileIndex t
);
27 void SetRailStationPlatformReservation(TileIndex start
, DiagDirection dir
, bool b
);
28 void SetRailStationPlatformReservation(const RailPathPos
&pos
, bool b
);
30 bool TryReserveRailTrack(TileIndex tile
, Track t
, bool trigger_stations
= true);
31 void UnreserveRailTrack(TileIndex tile
, Track t
);
33 static inline bool TryReserveRailTrack(const RailPathPos
&pos
)
35 if (!pos
.in_wormhole()) {
36 return TryReserveRailTrack(pos
.tile
, TrackdirToTrack(pos
.td
));
37 } else if (IsRailwayTile(pos
.wormhole
)) {
38 if (HasBridgeMiddleReservation(pos
.wormhole
)) return false;
39 SetBridgeMiddleReservation(pos
.wormhole
, true);
40 SetBridgeMiddleReservation(GetOtherBridgeEnd(pos
.wormhole
), true);
43 if (HasTunnelMiddleReservation(pos
.wormhole
)) return false;
44 SetTunnelMiddleReservation(pos
.wormhole
, true);
45 SetTunnelMiddleReservation(GetOtherTunnelEnd(pos
.wormhole
), true);
50 static inline void UnreserveRailTrack(const RailPathPos
&pos
)
52 if (!pos
.in_wormhole()) {
53 UnreserveRailTrack(pos
.tile
, TrackdirToTrack(pos
.td
));
54 } else if (IsRailwayTile(pos
.wormhole
)) {
55 SetBridgeMiddleReservation(pos
.wormhole
, false);
56 SetBridgeMiddleReservation(GetOtherBridgeEnd(pos
.wormhole
), false);
58 SetTunnelMiddleReservation(pos
.wormhole
, false);
59 SetTunnelMiddleReservation(GetOtherTunnelEnd(pos
.wormhole
), false);
63 bool FollowTrainReservation(const Train
*v
, RailPathPos
*pos
, Vehicle
**train_on_res
= NULL
);
65 /** State of a waiting position wrt PBS. */
66 enum PBSPositionState
{
67 PBS_UNSAFE
, ///< Not a safe waiting position
68 PBS_BUSY
, ///< Waiting position safe but busy
69 PBS_FREE
, ///< Waiting position safe and free
72 /** Checking behaviour for CheckWaitingPosition. */
73 enum PBSCheckingBehaviour
{
74 PBS_CHECK_FULL
, ///< Do a full check of the waiting position
75 PBS_CHECK_SAFE
, ///< Only check if the waiting position is safe
76 PBS_CHECK_FREE
, ///< Assume that the waiting position is safe, and check if it is free
77 PBS_CHECK_SAFE_FREE
, ///< Check if the waiting position is both safe and free
80 PBSPositionState
CheckWaitingPosition(const Train
*v
, const RailPathPos
&pos
, bool forbid_90deg
= false, PBSCheckingBehaviour cb
= PBS_CHECK_FULL
);
82 static inline bool IsSafeWaitingPosition(const Train
*v
, const RailPathPos
&pos
, bool forbid_90deg
= false)
84 return CheckWaitingPosition(v
, pos
, forbid_90deg
, PBS_CHECK_SAFE
) != PBS_UNSAFE
;
87 static inline bool IsWaitingPositionFree(const Train
*v
, const RailPathPos
&pos
, bool forbid_90deg
= false)
89 return CheckWaitingPosition(v
, pos
, forbid_90deg
, PBS_CHECK_FREE
) == PBS_FREE
;
92 static inline bool IsFreeSafeWaitingPosition(const Train
*v
, const RailPathPos
&pos
, bool forbid_90deg
= false)
94 return CheckWaitingPosition(v
, pos
, forbid_90deg
, PBS_CHECK_SAFE_FREE
) == PBS_FREE
;
97 Train
*GetTrainForReservation(TileIndex tile
, Track track
);
100 * Check whether some of tracks is reserved on a tile.
102 * @param tile the tile
103 * @param tracks the tracks to test
104 * @return true if at least on of tracks is reserved
106 static inline bool HasReservedTracks(TileIndex tile
, TrackBits tracks
)
108 return (GetReservedTrackbits(tile
) & tracks
) != TRACK_BIT_NONE
;
112 * Check whether a track is reserved on a tile.
114 * @param tile the tile
115 * @param track the track to test
116 * @return true if the track is reserved
118 static inline bool HasReservedTrack(TileIndex tile
, Track track
)
120 return HasReservedTracks(tile
, TrackToTrackBits(track
));
124 * Check whether a position is reserved.
126 * @param pos the position
127 * @return true if the track is reserved
129 static inline bool HasReservedPos(const RailPathPos
&pos
)
131 return !pos
.in_wormhole() ? HasReservedTrack(pos
.tile
, TrackdirToTrack(pos
.td
)) :
132 IsRailwayTile(pos
.wormhole
) ? HasBridgeMiddleReservation(pos
.wormhole
) : HasTunnelMiddleReservation(pos
.wormhole
);