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 roadstop_base.h Base class for roadstops. */
12 #ifndef ROADSTOP_BASE_H
13 #define ROADSTOP_BASE_H
15 #include "core/pool_type.hpp"
16 #include "core/bitmath_func.hpp"
17 #include "map/station.h"
19 /** A Stop for a Road Vehicle */
20 struct RoadStop
: PooledItem
<RoadStop
, RoadStopID
, 32, 64000> {
21 enum RoadStopStatusFlags
{
22 RSSFB_BAY0_FREE
= 0, ///< Non-zero when bay 0 is free
23 RSSFB_BAY1_FREE
= 1, ///< Non-zero when bay 1 is free
24 RSSFB_BAY_COUNT
= 2, ///< Max. number of bays
25 RSSFB_BASE_ENTRY
= 6, ///< Non-zero when the entries on this road stop are the primary, i.e. the ones to delete
26 RSSFB_ENTRY_BUSY
= 7, ///< Non-zero when roadstop entry is busy
29 /** Container for both entry points of a drive-through road stop. */
32 uint length
; ///< The length of the stop in tile 'units'
33 uint occupied_east
; ///< The amount of occupied stop in tile 'units' to the east
34 uint occupied_west
; ///< The amount of occupied stop in tile 'units' to the west
37 friend struct RoadStop
; ///< Oh yeah, the road stop may play with me.
39 /** Create a platform. */
41 : length(0), occupied_east(), occupied_west()
46 * Get the length of this drive through stop.
47 * @return the length in tile units.
49 inline uint
GetLength() const
55 * Get the amount of occupied space in a given direction.
56 * @param dir The direction to get the occupied space for.
57 * @return the occupied space in tile units.
59 inline uint
GetOccupied (DiagDirection dir
) const
61 return HasBit ((int)dir
, 1) ? this->occupied_west
: this->occupied_east
;
66 * Get a pointer to the occupied field in a given direction.
67 * @param dir The direction to get the occupied pointer for.
68 * @return A pointer to the occupied field in the given direction.
70 inline uint
*GetOccupiedPtr (DiagDirection dir
)
72 return HasBit ((int)dir
, 1) ? &this->occupied_west
: &this->occupied_east
;
76 void Rebuild (TileIndex tile
);
79 TileIndex xy
; ///< Position on the map
80 byte status
; ///< Current status of the Stop, @see RoadStopSatusFlag. Access using *Bay and *Busy functions.
81 struct RoadStop
*next
; ///< Next stop of the given type at this station
83 Platform
*platform
; ///< Platform data for drive-through stops
86 /** Initializes a RoadStop */
87 inline RoadStop(TileIndex tile
= INVALID_TILE
) :
89 status((1 << RSSFB_BAY_COUNT
) - 1)
95 * Checks whether there is a free bay in this road stop
96 * @return is at least one bay free?
98 inline bool HasFreeBay() const
100 return GB(this->status
, 0, RSSFB_BAY_COUNT
) != 0;
104 * Checks whether the given bay is free in this road stop
105 * @param nr bay to check
106 * @return is given bay free?
108 inline bool IsFreeBay(uint nr
) const
110 assert(nr
< RSSFB_BAY_COUNT
);
111 return HasBit(this->status
, nr
);
115 * Checks whether the entrance of the road stop is occupied by a vehicle
116 * @return is entrance busy?
118 inline bool IsEntranceBusy() const
120 return HasBit(this->status
, RSSFB_ENTRY_BUSY
);
124 * Makes an entrance occupied or free
125 * @param busy If true, marks busy; free otherwise.
127 inline void SetEntranceBusy(bool busy
)
129 SB(this->status
, RSSFB_ENTRY_BUSY
, 1, busy
);
133 * Get the drive through road stop platform struct.
134 * @return the platform
136 inline const Platform
*GetPlatform (void) const
138 return this->platform
;
141 void MakeDriveThrough();
142 void ClearDriveThrough();
145 * Add the length of a vehicle to the occupied length in the platform.
146 * @param dir The direction of the vehicle.
147 * @param length The vehicle length to add.
149 void EnterDriveThrough (DiagDirection dir
, uint length
)
151 assert (IsDriveThroughStopTile (this->xy
));
153 /* We cannot assert on occupied < length because of the
154 * remote possibility that RVs are running through each
155 * other when trying to prevent an infinite jam. */
156 *this->platform
->GetOccupiedPtr(dir
) += length
;
160 * Subtract the length of a vehicle from the occupied length in the platform.
161 * @param dir The direction of the vehicle.
162 * @param length The vehicle length to subtract.
164 void LeaveDriveThrough (DiagDirection dir
, uint length
)
166 assert (IsDriveThroughStopTile (this->xy
));
168 uint
*p
= this->platform
->GetOccupiedPtr (dir
);
169 assert (*p
>= length
);
173 static RoadStop
*GetByTile(TileIndex tile
, RoadStopType type
);
175 static bool IsDriveThroughRoadStopContinuation(TileIndex rs
, TileIndex next
);
177 /** Rebuild the vehicles and other metadata on this stop. */
180 assert (HasBit (this->status
, RSSFB_BASE_ENTRY
));
182 this->platform
->Rebuild (this->xy
);
185 void CheckIntegrity (void) const;
189 * @return the allocated bay number, or -1 if all are busy
191 inline int AllocateBay()
193 /* Find the first free bay. If the bit is set, the bay is free. */
194 for (uint bay
= 0; bay
< RSSFB_BAY_COUNT
; bay
++) {
195 if (HasBit (this->status
, bay
)) {
196 ClrBit (this->status
, bay
);
205 * Frees the given bay
206 * @param nr the number of the bay to free
208 inline void FreeBay(uint nr
)
210 assert(nr
< RSSFB_BAY_COUNT
);
211 SetBit(this->status
, nr
);
215 #define FOR_ALL_ROADSTOPS_FROM(var, start) FOR_ALL_ITEMS_FROM(RoadStop, roadstop_index, var, start)
216 #define FOR_ALL_ROADSTOPS(var) FOR_ALL_ROADSTOPS_FROM(var, 0)
218 #endif /* ROADSTOP_BASE_H */