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 base_station_base.h Base classes/functions for base stations. */
12 #ifndef BASE_STATION_BASE_H
13 #define BASE_STATION_BASE_H
15 #include "core/pool_type.hpp"
16 #include "command_type.h"
17 #include "viewport_type.h"
18 #include "station_map.h"
20 typedef Pool
<BaseStation
, StationID
, 32, 64000> StationPool
;
21 extern StationPool _station_pool
;
23 struct StationSpecList
{
24 const StationSpec
*spec
;
25 uint32 grfid
; ///< GRF ID of this custom station
26 uint8 localidx
; ///< Station ID within GRF of station
30 /** StationRect - used to track station spread out rectangle - cheaper than scanning whole map */
31 struct StationRect
: public Rect
{
41 bool PtInExtendedRect(int x
, int y
, int distance
= 0) const;
43 CommandCost
BeforeAddTile(TileIndex tile
, StationRectMode mode
);
44 CommandCost
BeforeAddRect(TileIndex tile
, int w
, int h
, StationRectMode mode
);
45 bool AfterRemoveTile(BaseStation
*st
, TileIndex tile
);
46 bool AfterRemoveRect(BaseStation
*st
, TileArea ta
);
48 static bool ScanForStationTiles(StationID st_id
, int left_a
, int top_a
, int right_a
, int bottom_a
);
50 StationRect
& operator = (const Rect
&src
);
53 /** Base class for all station-ish types */
54 struct BaseStation
: StationPool::PoolItem
<&_station_pool
> {
55 TileIndex xy
; ///< Base tile of the station
56 ViewportSign sign
; ///< NOSAVE: Dimensions of sign
57 byte delete_ctr
; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted.
59 char *name
; ///< Custom name
60 StringID string_id
; ///< Default name (town area) of station
62 Town
*town
; ///< The town this station is associated with
63 OwnerByte owner
; ///< The owner of this station
64 StationFacilityByte facilities
; ///< The facilities that this station has
66 uint8 num_specs
; ///< Number of specs in the speclist
67 StationSpecList
*speclist
; ///< List of station specs of this station
69 Date build_date
; ///< Date of construction
71 uint16 random_bits
; ///< Random bits assigned to this station
72 byte waiting_triggers
; ///< Waiting triggers (NewGRF) for this station
73 uint8 cached_anim_triggers
; ///< NOSAVE: Combined animation trigger bitmask, used to determine if trigger processing should happen.
74 uint32 cached_cargo_triggers
; ///< NOSAVE: Combined cargo trigger bitmask
76 TileArea train_station
; ///< Tile area the train 'station' part covers
77 StationRect rect
; ///< NOSAVE: Station spread out rectangle maintained by StationRect::xxx() functions
80 * Initialize the base station.
81 * @param tile The location of the station sign
83 BaseStation(TileIndex tile
) :
85 train_station(INVALID_TILE
, 0, 0)
89 virtual ~BaseStation();
92 * Check whether a specific tile belongs to this station.
93 * @param tile the tile to check
94 * @return true if the tile belongs to this station
96 virtual bool TileBelongsToRailStation(TileIndex tile
) const = 0;
99 * Helper function to get a NewGRF variable that isn't implemented by the base class.
100 * @param object the resolver object related to this query
101 * @param variable that is queried
102 * @param parameter parameter for that variable
103 * @param available will return false if ever the variable asked for does not exist
104 * @return the value stored in the corresponding variable
106 virtual uint32
GetNewGRFVariable(const struct ResolverObject
&object
, byte variable
, byte parameter
, bool *available
) const = 0;
109 * Update the coordinated of the sign (as shown in the viewport).
111 virtual void UpdateVirtCoord() = 0;
114 * Get the tile area for a given station type.
115 * @param ta tile area to fill.
116 * @param type the type of the area
118 virtual void GetTileArea(TileArea
*ta
, StationType type
) const = 0;
122 * Obtain the length of a platform
123 * @pre tile must be a rail station tile
124 * @param tile A tile that contains the platform in question
125 * @return The length of the platform
127 virtual uint
GetPlatformLength(TileIndex tile
) const = 0;
130 * Determines the REMAINING length of a platform, starting at (and including)
132 * @param tile the tile from which to start searching. Must be a rail station tile
133 * @param dir The direction in which to search.
134 * @return The platform length
136 virtual uint
GetPlatformLength(TileIndex tile
, DiagDirection dir
) const = 0;
139 * Get the base station belonging to a specific tile.
140 * @param tile The tile to get the base station from.
141 * @return the station associated with that tile.
143 static inline BaseStation
*GetByTile(TileIndex tile
)
145 return BaseStation::Get(GetStationIndex(tile
));
149 * Check whether the base station currently is in use; in use means
150 * that it is not scheduled for deletion and that it still has some
152 * @return true if still in use
154 inline bool IsInUse() const
156 return (this->facilities
& ~FACIL_WAYPOINT
) != 0;
160 * Check whether the base station has given facilities.
161 * @param facilities The facilities to check.
162 * @return True if station has at least one of the given \a facilities.
164 inline bool HasFacilities(StationFacility facilities
) const
166 return (this->facilities
& facilities
) != 0;
169 static void PostDestructor(size_t index
);
172 #define FOR_ALL_BASE_STATIONS(var) FOR_ALL_ITEMS_FROM(BaseStation, station_index, var, 0)
175 * Class defining several overloaded accessors so we don't
176 * have to cast base stations that often
178 template <class T
, bool Tis_waypoint
>
179 struct SpecializedStation
: public BaseStation
{
180 static const StationFacility EXPECTED_FACIL
= Tis_waypoint
? FACIL_WAYPOINT
: FACIL_NONE
; ///< Specialized type
183 * Set station type correctly
184 * @param tile The base tile of the station.
186 inline SpecializedStation
<T
, Tis_waypoint
>(TileIndex tile
) :
189 this->facilities
= EXPECTED_FACIL
;
193 * Helper for checking whether the given station is of this type.
194 * @param st the station to check.
195 * @return true if the station is the type we expect it to be.
197 static inline bool IsExpected(const BaseStation
*st
)
199 return (st
->facilities
& FACIL_WAYPOINT
) == EXPECTED_FACIL
;
203 * Tests whether given index is a valid index for station of this type
204 * @param index tested index
205 * @return is this index valid index of T?
207 static inline bool IsValidID(size_t index
)
209 return BaseStation::IsValidID(index
) && IsExpected(BaseStation::Get(index
));
213 * Gets station with given index
214 * @return pointer to station with given index casted to T *
216 static inline T
*Get(size_t index
)
218 return (T
*)BaseStation::Get(index
);
222 * Returns station if the index is a valid index for this station type
223 * @return pointer to station with given index if it's a station of this type
225 static inline T
*GetIfValid(size_t index
)
227 return IsValidID(index
) ? Get(index
) : nullptr;
231 * Get the station belonging to a specific tile.
232 * @param tile The tile to get the station from.
233 * @return the station associated with that tile.
235 static inline T
*GetByTile(TileIndex tile
)
237 return GetIfValid(GetStationIndex(tile
));
241 * Converts a BaseStation to SpecializedStation with type checking.
242 * @param st BaseStation pointer
243 * @return pointer to SpecializedStation
245 static inline T
*From(BaseStation
*st
)
247 assert(IsExpected(st
));
252 * Converts a const BaseStation to const SpecializedStation with type checking.
253 * @param st BaseStation pointer
254 * @return pointer to SpecializedStation
256 static inline const T
*From(const BaseStation
*st
)
258 assert(IsExpected(st
));
259 return (const T
*)st
;
263 #define FOR_ALL_BASE_STATIONS_OF_TYPE(name, var) \
264 for (size_t station_index = 0; var = nullptr, station_index < name::GetPoolSize(); station_index++) \
265 if ((var = name::GetIfValid(station_index)) != nullptr)
267 #endif /* BASE_STATION_BASE_H */