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"
25 TrackBits
GetReservedTrackbits(TileIndex t
);
27 bool HasReservedMapPos (const RailPathPos
&pos
);
30 * Check whether a position is reserved.
31 * @param pos the position
32 * @return true if the track is reserved
34 static inline bool HasReservedPos(const RailPathPos
&pos
)
36 return !pos
.in_wormhole() ? HasReservedMapPos (pos
) :
37 IsRailwayTile (pos
.wormhole
) ? HasBridgeMiddleReservation (pos
.wormhole
) : HasTunnelMiddleReservation (pos
.wormhole
);
40 void SetRailStationPlatformReservation(TileIndex start
, DiagDirection dir
, bool b
);
41 void SetRailStationPlatformReservation(const RailPathPos
&pos
, bool b
);
43 bool TryReserveRailTrack(TileIndex tile
, Track t
, bool trigger_stations
= true);
44 void UnreserveRailTrack(TileIndex tile
, Track t
);
46 static inline bool TryReserveRailTrack(const RailPathPos
&pos
)
48 if (!pos
.in_wormhole()) {
49 return TryReserveRailTrack(pos
.tile
, TrackdirToTrack(pos
.td
));
50 } else if (IsRailwayTile(pos
.wormhole
)) {
51 if (HasBridgeMiddleReservation(pos
.wormhole
)) return false;
52 SetBridgeMiddleReservation(pos
.wormhole
, true);
53 TileIndex end
= GetOtherBridgeEnd (pos
.wormhole
);
54 SetBridgeMiddleReservation(end
, true);
55 MarkBridgeTilesDirty (pos
.wormhole
, end
, GetTunnelBridgeDirection (pos
.wormhole
), false);
58 if (HasTunnelMiddleReservation(pos
.wormhole
)) return false;
59 SetTunnelMiddleReservation(pos
.wormhole
, true);
60 SetTunnelMiddleReservation(GetOtherTunnelEnd(pos
.wormhole
), true);
65 static inline void UnreserveRailTrack(const RailPathPos
&pos
)
67 if (!pos
.in_wormhole()) {
68 UnreserveRailTrack(pos
.tile
, TrackdirToTrack(pos
.td
));
69 } else if (IsRailwayTile(pos
.wormhole
)) {
70 SetBridgeMiddleReservation(pos
.wormhole
, false);
71 TileIndex end
= GetOtherBridgeEnd (pos
.wormhole
);
72 SetBridgeMiddleReservation(end
, false);
73 MarkBridgeTilesDirty (pos
.wormhole
, end
, GetTunnelBridgeDirection (pos
.wormhole
), false);
75 SetTunnelMiddleReservation(pos
.wormhole
, false);
76 SetTunnelMiddleReservation(GetOtherTunnelEnd(pos
.wormhole
), false);
80 bool FollowTrainReservation (const Train
*v
, RailPathPos
*pos
, bool check
= false);
82 /** State of a waiting position wrt PBS. */
83 enum PBSPositionState
{
84 PBS_UNSAFE
, ///< Not a safe waiting position
85 PBS_BUSY
, ///< Waiting position safe but busy
86 PBS_FREE
, ///< Waiting position safe and free
89 /** Checking behaviour for CheckWaitingPosition. */
90 enum PBSCheckingBehaviour
{
91 PBS_CHECK_FULL
, ///< Do a full check of the waiting position
92 PBS_CHECK_SAFE
, ///< Only check if the waiting position is safe
93 PBS_CHECK_FREE
, ///< Assume that the waiting position is safe, and check if it is free
94 PBS_CHECK_SAFE_FREE
, ///< Check if the waiting position is both safe and free
97 PBSPositionState
CheckWaitingPosition(const Train
*v
, const RailPathPos
&pos
, bool forbid_90deg
= false, PBSCheckingBehaviour cb
= PBS_CHECK_FULL
);
99 static inline bool IsSafeWaitingPosition(const Train
*v
, const RailPathPos
&pos
, bool forbid_90deg
= false)
101 return CheckWaitingPosition(v
, pos
, forbid_90deg
, PBS_CHECK_SAFE
) != PBS_UNSAFE
;
104 static inline bool IsWaitingPositionFree(const Train
*v
, const RailPathPos
&pos
, bool forbid_90deg
= false)
106 return CheckWaitingPosition(v
, pos
, forbid_90deg
, PBS_CHECK_FREE
) == PBS_FREE
;
109 static inline bool IsFreeSafeWaitingPosition(const Train
*v
, const RailPathPos
&pos
, bool forbid_90deg
= false)
111 return CheckWaitingPosition(v
, pos
, forbid_90deg
, PBS_CHECK_SAFE_FREE
) == PBS_FREE
;
114 Train
*GetTrainForReservation (TileIndex tile
, Track track
, bool free
= false);
117 * Check whether some of tracks is reserved on a tile.
119 * @param tile the tile
120 * @param tracks the tracks to test
121 * @return true if at least on of tracks is reserved
123 static inline bool HasReservedTracks(TileIndex tile
, TrackBits tracks
)
125 return (GetReservedTrackbits(tile
) & tracks
) != TRACK_BIT_NONE
;
129 * Check whether a track is reserved on a tile.
131 * @param tile the tile
132 * @param track the track to test
133 * @return true if the track is reserved
135 static inline bool HasReservedTrack(TileIndex tile
, Track track
)
137 return HasReservedTracks(tile
, TrackToTrackBits(track
));