OpenTTD Source 20241224-master-gf74b0cf984
follow_track.hpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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/>.
6 */
7
10#ifndef FOLLOW_TRACK_HPP
11#define FOLLOW_TRACK_HPP
12
13#include "../pbs.h"
14#include "../roadveh.h"
15#include "../station_base.h"
16#include "../train.h"
17#include "../tunnelbridge.h"
18#include "../tunnelbridge_map.h"
19#include "../depot_map.h"
20#include "pathfinder_func.h"
21
27template <TransportType Ttr_type_, typename VehicleType, bool T90deg_turns_allowed_ = true, bool Tmask_reserved_tracks = false>
29{
30 enum ErrorCode {
31 EC_NONE,
32 EC_OWNER,
33 EC_RAIL_ROAD_TYPE,
34 EC_90DEG,
35 EC_NO_WAY,
36 EC_RESERVED,
37 };
38
46 bool is_tunnel;
47 bool is_bridge;
50 ErrorCode err;
51 RailTypes railtypes;
52
53 inline CFollowTrackT(const VehicleType *v = nullptr, RailTypes railtype_override = INVALID_RAILTYPES)
54 {
55 Init(v, railtype_override);
56 }
57
58 inline CFollowTrackT(Owner o, RailTypes railtype_override = INVALID_RAILTYPES)
59 {
60 assert(IsRailTT());
61 this->veh = nullptr;
62 Init(o, railtype_override);
63 }
64
65 inline void Init(const VehicleType *v, RailTypes railtype_override)
66 {
67 assert(!IsRailTT() || (v != nullptr && v->type == VEH_TRAIN));
68 this->veh = v;
69 Init(v != nullptr ? v->owner : INVALID_OWNER, IsRailTT() && railtype_override == INVALID_RAILTYPES ? Train::From(v)->compatible_railtypes : railtype_override);
70 }
71
72 inline void Init(Owner o, RailTypes railtype_override)
73 {
74 assert(!IsRoadTT() || this->veh != nullptr);
75 assert(!IsRailTT() || railtype_override != INVALID_RAILTYPES);
76 this->veh_owner = o;
77 /* don't worry, all is inlined so compiler should remove unnecessary initializations */
78 this->old_tile = INVALID_TILE;
79 this->old_td = INVALID_TRACKDIR;
80 this->new_tile = INVALID_TILE;
81 this->new_td_bits = TRACKDIR_BIT_NONE;
82 this->exitdir = INVALID_DIAGDIR;
83 this->is_station = false;
84 this->is_bridge = false;
85 this->is_tunnel = false;
86 this->tiles_skipped = 0;
87 this->err = EC_NONE;
88 this->railtypes = railtype_override;
89 }
90
91 debug_inline static TransportType TT() { return Ttr_type_; }
92 debug_inline static bool IsWaterTT() { return TT() == TRANSPORT_WATER; }
93 debug_inline static bool IsRailTT() { return TT() == TRANSPORT_RAIL; }
94 inline bool IsTram() { return IsRoadTT() && RoadTypeIsTram(RoadVehicle::From(this->veh)->roadtype); }
95 debug_inline static bool IsRoadTT() { return TT() == TRANSPORT_ROAD; }
96 inline static bool Allow90degTurns() { return T90deg_turns_allowed_; }
97 inline static bool DoTrackMasking() { return Tmask_reserved_tracks; }
98
101 {
102 assert(this->IsTram()); // this function shouldn't be called in other cases
103
104 if (IsNormalRoadTile(tile)) {
105 RoadBits rb = GetRoadBits(tile, RTT_TRAM);
106 switch (rb) {
107 case ROAD_NW: return DIAGDIR_NW;
108 case ROAD_SW: return DIAGDIR_SW;
109 case ROAD_SE: return DIAGDIR_SE;
110 case ROAD_NE: return DIAGDIR_NE;
111 default: break;
112 }
113 }
114 return INVALID_DIAGDIR;
115 }
116
122 {
123 this->old_tile = old_tile;
124 this->old_td = old_td;
125 this->err = EC_NONE;
126
127 assert([&]() {
128 if (this->IsTram() && this->GetSingleTramBit(this->old_tile) != INVALID_DIAGDIR) return true; // Skip the check for single tram bits
129 const uint sub_mode = (IsRoadTT() && this->veh != nullptr) ? (this->IsTram() ? RTT_TRAM : RTT_ROAD) : 0;
130 const TrackdirBits old_tile_valid_dirs = TrackStatusToTrackdirBits(GetTileTrackStatus(this->old_tile, TT(), sub_mode));
131 return (old_tile_valid_dirs & TrackdirToTrackdirBits(this->old_td)) != TRACKDIR_BIT_NONE;
132 }());
133
134 this->exitdir = TrackdirToExitdir(this->old_td);
135 if (this->ForcedReverse()) return true;
136 if (!this->CanExitOldTile()) return false;
137 this->FollowTileExit();
138 if (!this->QueryNewTileTrackStatus()) return TryReverse();
139 this->new_td_bits &= DiagdirReachesTrackdirs(this->exitdir);
140 if (this->new_td_bits == TRACKDIR_BIT_NONE || !this->CanEnterNewTile()) {
141 /* In case we can't enter the next tile, but are
142 * a normal road vehicle, then we can actually
143 * try to reverse as this is the end of the road.
144 * Trams can only turn on the appropriate bits in
145 * which case reaching this would mean a dead end
146 * near a building and in that case there would
147 * a "false" QueryNewTileTrackStatus result and
148 * as such reversing is already tried. The fact
149 * that function failed can have to do with a
150 * missing road bit, or inability to connect the
151 * different bits due to slopes. */
152 if (IsRoadTT() && !this->IsTram() && this->TryReverse()) return true;
153
154 /* CanEnterNewTile already set a reason.
155 * Do NOT overwrite it (important for example for EC_RAIL_ROAD_TYPE).
156 * Only set a reason if CanEnterNewTile was not called */
157 if (this->new_td_bits == TRACKDIR_BIT_NONE) this->err = EC_NO_WAY;
158
159 return false;
160 }
161 if ((!IsRailTT() && !Allow90degTurns()) || (IsRailTT() && Rail90DegTurnDisallowed(GetTileRailType(this->old_tile), GetTileRailType(this->new_tile), !Allow90degTurns()))) {
162 this->new_td_bits &= (TrackdirBits)~(int)TrackdirCrossesTrackdirs(this->old_td);
163 if (this->new_td_bits == TRACKDIR_BIT_NONE) {
164 this->err = EC_90DEG;
165 return false;
166 }
167 }
168 return true;
169 }
170
171 inline bool MaskReservedTracks()
172 {
173 if (!DoTrackMasking()) return true;
174
175 if (this->is_station) {
176 /* Check skipped station tiles as well. */
177 TileIndexDiff diff = TileOffsByDiagDir(this->exitdir);
178 for (TileIndex tile = this->new_tile - diff * this->tiles_skipped; tile != this->new_tile; tile += diff) {
179 if (HasStationReservation(tile)) {
180 this->new_td_bits = TRACKDIR_BIT_NONE;
181 this->err = EC_RESERVED;
182 return false;
183 }
184 }
185 }
186
187 TrackBits reserved = GetReservedTrackbits(this->new_tile);
188 /* Mask already reserved trackdirs. */
189 this->new_td_bits &= ~TrackBitsToTrackdirBits(reserved);
190 /* Mask out all trackdirs that conflict with the reservation. */
192 if (TracksOverlap(reserved | TrackToTrackBits(t))) this->new_td_bits &= ~TrackToTrackdirBits(t);
193 }
194 if (this->new_td_bits == TRACKDIR_BIT_NONE) {
195 this->err = EC_RESERVED;
196 return false;
197 }
198 return true;
199 }
200
201protected:
203 inline void FollowTileExit()
204 {
205 this->is_station = false;
206 this->is_bridge = false;
207 this->is_tunnel = false;
208 this->tiles_skipped = 0;
209
210 /* extra handling for tunnels and bridges in our direction */
211 if (IsTileType(this->old_tile, MP_TUNNELBRIDGE)) {
212 DiagDirection enterdir = GetTunnelBridgeDirection(this->old_tile);
213 if (enterdir == this->exitdir) {
214 /* we are entering the tunnel / bridge */
215 if (IsTunnel(this->old_tile)) {
216 this->is_tunnel = true;
217 this->new_tile = GetOtherTunnelEnd(this->old_tile);
218 } else { // IsBridge(old_tile)
219 this->is_bridge = true;
220 this->new_tile = GetOtherBridgeEnd(this->old_tile);
221 }
222 this->tiles_skipped = GetTunnelBridgeLength(this->new_tile, this->old_tile);
223 return;
224 }
225 assert(ReverseDiagDir(enterdir) == this->exitdir);
226 }
227
228 /* normal or station tile, do one step */
229 this->new_tile = TileAddByDiagDir(this->old_tile, this->exitdir);
230
231 /* special handling for stations */
232 if (IsRailTT() && HasStationTileRail(this->new_tile)) {
233 this->is_station = true;
234 } else if (IsRoadTT() && IsStationRoadStopTile(this->new_tile)) {
235 this->is_station = true;
236 }
237 }
238
241 {
242 if (IsRailTT() && IsPlainRailTile(this->new_tile)) {
243 this->new_td_bits = (TrackdirBits)(GetTrackBits(this->new_tile) * 0x101);
244 } else if (IsRoadTT()) {
245 this->new_td_bits = GetTrackdirBitsForRoad(this->new_tile, this->IsTram() ? RTT_TRAM : RTT_ROAD);
246 } else {
247 this->new_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(this->new_tile, TT(), 0));
248 }
249 return (this->new_td_bits != TRACKDIR_BIT_NONE);
250 }
251
253 inline bool CanExitOldTile()
254 {
255 /* road stop can be left at one direction only unless it's a drive-through stop */
256 if (IsRoadTT() && IsBayRoadStopTile(this->old_tile)) {
257 DiagDirection exitdir = GetBayRoadStopDir(this->old_tile);
258 if (exitdir != this->exitdir) {
259 this->err = EC_NO_WAY;
260 return false;
261 }
262 }
263
264 /* single tram bits can only be left in one direction */
265 if (this->IsTram()) {
266 DiagDirection single_tram = GetSingleTramBit(this->old_tile);
267 if (single_tram != INVALID_DIAGDIR && single_tram != this->exitdir) {
268 this->err = EC_NO_WAY;
269 return false;
270 }
271 }
272
273 /* road depots can be also left in one direction only */
274 if (IsRoadTT() && IsDepotTypeTile(this->old_tile, TT())) {
276 if (exitdir != this->exitdir) {
277 this->err = EC_NO_WAY;
278 return false;
279 }
280 }
281 return true;
282 }
283
285 inline bool CanEnterNewTile()
286 {
287 if (IsRoadTT() && IsBayRoadStopTile(this->new_tile)) {
288 /* road stop can be entered from one direction only unless it's a drive-through stop */
289 DiagDirection exitdir = GetBayRoadStopDir(this->new_tile);
290 if (ReverseDiagDir(exitdir) != this->exitdir) {
291 this->err = EC_NO_WAY;
292 return false;
293 }
294 }
295
296 /* single tram bits can only be entered from one direction */
297 if (this->IsTram()) {
298 DiagDirection single_tram = this->GetSingleTramBit(this->new_tile);
299 if (single_tram != INVALID_DIAGDIR && single_tram != ReverseDiagDir(this->exitdir)) {
300 this->err = EC_NO_WAY;
301 return false;
302 }
303 }
304
305 /* road and rail depots can also be entered from one direction only */
306 if (IsRoadTT() && IsDepotTypeTile(this->new_tile, TT())) {
308 if (ReverseDiagDir(exitdir) != this->exitdir) {
309 this->err = EC_NO_WAY;
310 return false;
311 }
312 /* don't try to enter other company's depots */
313 if (GetTileOwner(this->new_tile) != this->veh_owner) {
314 this->err = EC_OWNER;
315 return false;
316 }
317 }
318 if (IsRailTT() && IsDepotTypeTile(this->new_tile, TT())) {
320 if (ReverseDiagDir(exitdir) != this->exitdir) {
321 this->err = EC_NO_WAY;
322 return false;
323 }
324 }
325
326 /* rail transport is possible only on tiles with the same owner as vehicle */
327 if (IsRailTT() && GetTileOwner(this->new_tile) != this->veh_owner) {
328 /* different owner */
329 this->err = EC_NO_WAY;
330 return false;
331 }
332
333 /* rail transport is possible only on compatible rail types */
334 if (IsRailTT()) {
335 RailType rail_type = GetTileRailType(this->new_tile);
336 if (!HasBit(this->railtypes, rail_type)) {
337 /* incompatible rail type */
338 this->err = EC_RAIL_ROAD_TYPE;
339 return false;
340 }
341 }
342
343 /* road transport is possible only on compatible road types */
344 if (IsRoadTT()) {
345 const RoadVehicle *v = RoadVehicle::From(this->veh);
346 RoadType roadtype = GetRoadType(this->new_tile, GetRoadTramType(v->roadtype));
347 if (!HasBit(v->compatible_roadtypes, roadtype)) {
348 /* incompatible road type */
349 this->err = EC_RAIL_ROAD_TYPE;
350 return false;
351 }
352 }
353
354 /* tunnel holes and bridge ramps can be entered only from proper direction */
355 if (IsTileType(this->new_tile, MP_TUNNELBRIDGE)) {
356 if (IsTunnel(this->new_tile)) {
357 if (!this->is_tunnel) {
358 DiagDirection tunnel_enterdir = GetTunnelBridgeDirection(this->new_tile);
359 if (tunnel_enterdir != this->exitdir) {
360 this->err = EC_NO_WAY;
361 return false;
362 }
363 }
364 } else { // IsBridge(new_tile)
365 if (!this->is_bridge) {
366 DiagDirection ramp_enderdir = GetTunnelBridgeDirection(this->new_tile);
367 if (ramp_enderdir != this->exitdir) {
368 this->err = EC_NO_WAY;
369 return false;
370 }
371 }
372 }
373 }
374
375 /* special handling for rail stations - get to the end of platform */
376 if (IsRailTT() && this->is_station) {
377 /* entered railway station
378 * get platform length */
379 uint length = BaseStation::GetByTile(this->new_tile)->GetPlatformLength(this->new_tile, TrackdirToExitdir(this->old_td));
380 /* how big step we must do to get to the last platform tile? */
381 this->tiles_skipped = length - 1;
382 /* move to the platform end */
383 TileIndexDiff diff = TileOffsByDiagDir(this->exitdir);
384 diff *= this->tiles_skipped;
385 this->new_tile = TileAdd(this->new_tile, diff);
386 return true;
387 }
388
389 return true;
390 }
391
393 inline bool ForcedReverse()
394 {
395 /* rail and road depots cause reversing */
396 if (!IsWaterTT() && IsDepotTypeTile(this->old_tile, TT())) {
397 DiagDirection exitdir = IsRailTT() ? GetRailDepotDirection(this->old_tile) : GetRoadDepotDirection(this->old_tile);
398 if (exitdir != this->exitdir) {
399 /* reverse */
400 this->new_tile = this->old_tile;
401 this->new_td_bits = TrackdirToTrackdirBits(ReverseTrackdir(this->old_td));
402 this->exitdir = exitdir;
403 this->tiles_skipped = 0;
404 this->is_tunnel = false;
405 this->is_bridge = false;
406 this->is_station = false;
407 return true;
408 }
409 }
410
411 /* Single tram bits and standard road stops cause reversing. */
412 if (IsRoadTT() && ((this->IsTram() && GetSingleTramBit(this->old_tile) == ReverseDiagDir(this->exitdir)) ||
413 (IsBayRoadStopTile(this->old_tile) && GetBayRoadStopDir(this->old_tile) == ReverseDiagDir(this->exitdir)))) {
414 /* reverse */
415 this->new_tile = this->old_tile;
416 this->new_td_bits = TrackdirToTrackdirBits(ReverseTrackdir(this->old_td));
417 this->exitdir = ReverseDiagDir(this->exitdir);
418 this->tiles_skipped = 0;
419 this->is_tunnel = false;
420 this->is_bridge = false;
421 this->is_station = false;
422 return true;
423 }
424
425 return false;
426 }
427
429 inline bool TryReverse()
430 {
431 if (IsRoadTT() && !this->IsTram()) {
432 /* if we reached the end of road, we can reverse the RV and continue moving */
433 this->exitdir = ReverseDiagDir(this->exitdir);
434 /* new tile will be the same as old one */
435 this->new_tile = this->old_tile;
436 /* set new trackdir bits to all reachable trackdirs */
438 this->new_td_bits &= DiagdirReachesTrackdirs(this->exitdir);
439 if (this->new_td_bits != TRACKDIR_BIT_NONE) {
440 /* we have some trackdirs reachable after reversal */
441 return true;
442 }
443 }
444 this->err = EC_NO_WAY;
445 return false;
446 }
447
448public:
450 int GetSpeedLimit(int *pmin_speed = nullptr) const
451 {
452 int min_speed = 0;
453 int max_speed = INT_MAX; // no limit
454
455 /* Check for on-bridge speed limit */
456 if (!IsWaterTT() && IsBridgeTile(this->old_tile)) {
457 int spd = GetBridgeSpec(GetBridgeType(this->old_tile))->speed;
458 if (IsRoadTT()) spd *= 2;
459 max_speed = std::min(max_speed, spd);
460 }
461 /* Check for speed limit imposed by railtype */
462 if (IsRailTT()) {
463 uint16_t rail_speed = GetRailTypeInfo(GetRailType(this->old_tile))->max_speed;
464 if (rail_speed > 0) max_speed = std::min<int>(max_speed, rail_speed);
465 }
466 if (IsRoadTT()) {
467 /* max_speed is already in roadvehicle units, no need to further modify (divide by 2) */
468 uint16_t road_speed = GetRoadTypeInfo(GetRoadType(this->old_tile, GetRoadTramType(RoadVehicle::From(this->veh)->roadtype)))->max_speed;
469 if (road_speed > 0) max_speed = std::min<int>(max_speed, road_speed);
470 }
471
472 /* if min speed was requested, return it */
473 if (pmin_speed != nullptr) *pmin_speed = min_speed;
474 return max_speed;
475 }
476};
477
481
483
486
487#endif /* FOLLOW_TRACK_HPP */
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
const BridgeSpec * GetBridgeSpec(BridgeType i)
Get the specification of a bridge type.
Definition bridge.h:67
TileIndex GetOtherBridgeEnd(TileIndex tile)
Starting at one bridge end finds the other bridge end.
bool IsBridgeTile(Tile t)
checks if there is a bridge on this tile
Definition bridge_map.h:35
BridgeType GetBridgeType(Tile t)
Determines the type of bridge on a tile.
Definition bridge_map.h:56
uint16_t max_speed
Maximum speed for vehicles travelling on this rail type.
Definition rail.h:231
uint16_t max_speed
Maximum speed for vehicles travelling on this road type.
Definition road.h:142
Owner
Enum for all companies/owners.
@ INVALID_OWNER
An invalid owner.
bool IsDepotTypeTile(Tile tile, TransportType type)
Check if a tile is a depot and it is a depot of the given type.
Definition depot_map.h:18
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
DiagDirection
Enumeration for diagonal directions.
@ DIAGDIR_NE
Northeast, upper right on your monitor.
@ DIAGDIR_NW
Northwest.
@ DIAGDIR_SE
Southeast.
@ INVALID_DIAGDIR
Flag for an invalid DiagDirection.
@ DIAGDIR_SW
Southwest.
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition map_func.h:608
constexpr TileIndex TileAdd(TileIndex tile, TileIndexDiff offset)
Adds a given offset to a tile.
Definition map_func.h:454
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:567
int32_t TileIndexDiff
An offset value between two tiles.
Definition map_type.h:23
General functions related to pathfinders.
TrackdirBits GetTrackdirBitsForRoad(TileIndex tile, RoadTramType rtt)
Wrapper around GetTileTrackStatus() and TrackStatusToTrackdirBits(), as for single tram bits GetTileT...
TrackBits GetReservedTrackbits(TileIndex t)
Get the reserved trackbits for any tile, regardless of type.
Definition pbs.cpp:24
RailType GetTileRailType(Tile tile)
Return the rail type of tile, or INVALID_RAILTYPE if this is no rail tile.
Definition rail.cpp:155
bool Rail90DegTurnDisallowed(RailType rt1, RailType rt2, bool def=_settings_game.pf.forbid_90_deg)
Test if 90 degree turns are disallowed between two railtypes.
Definition rail.h:357
const RailTypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition rail.h:307
RailType GetRailType(Tile t)
Gets the rail type of the given tile.
Definition rail_map.h:115
TrackBits GetTrackBits(Tile tile)
Gets the track bits of the given tile.
Definition rail_map.h:136
DiagDirection GetRailDepotDirection(Tile t)
Returns the direction the depot is facing to.
Definition rail_map.h:171
static debug_inline bool IsPlainRailTile(Tile t)
Checks whether the tile is a rail tile or rail tile with signals.
Definition rail_map.h:60
RailTypes
Allow incrementing of Track variables.
Definition rail_type.h:44
@ INVALID_RAILTYPES
Invalid railtypes.
Definition rail_type.h:50
RailType
Enumeration for all possible railtypes.
Definition rail_type.h:27
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:227
static debug_inline bool IsNormalRoadTile(Tile t)
Return whether a tile is a normal road tile.
Definition road_map.h:74
RoadBits GetRoadBits(Tile t, RoadTramType rtt)
Get the present road bits for a specific road type.
Definition road_map.h:128
DiagDirection GetRoadDepotDirection(Tile t)
Get the direction of the exit of a road depot.
Definition road_map.h:565
RoadBits
Enumeration for the road parts on a tile.
Definition road_type.h:52
@ ROAD_SW
South-west part.
Definition road_type.h:55
@ ROAD_NE
North-east part.
Definition road_type.h:57
@ ROAD_SE
South-east part.
Definition road_type.h:56
@ ROAD_NW
North-west part.
Definition road_type.h:54
RoadType
The different roadtypes we support.
Definition road_type.h:25
bool IsStationRoadStopTile(Tile t)
Is tile t a road stop station?
bool IsBayRoadStopTile(Tile t)
Is tile t a bay (non-drive through) road stop station?
bool HasStationTileRail(Tile t)
Has this station tile a rail? In other words, is this station tile a rail station or rail waypoint?
bool HasStationReservation(Tile t)
Get the reservation state of the rail station.
DiagDirection GetBayRoadStopDir(Tile t)
Gets the direction the bay road stop entrance points towards.
virtual uint GetPlatformLength(TileIndex tile) const =0
Obtain the length of a platform.
static BaseStation * GetByTile(TileIndex tile)
Get the base station belonging to a specific tile.
uint16_t speed
maximum travel speed (1 unit = 1/1.6 mph = 1 km-ish/h)
Definition bridge.h:48
Track follower helper template class (can serve pathfinders and vehicle controllers).
bool CanExitOldTile()
return true if we can leave old_tile in exitdir
bool Follow(TileIndex old_tile, Trackdir old_td)
main follower routine.
bool CanEnterNewTile()
return true if we can enter new_tile from exitdir
bool is_tunnel
last turn passed tunnel
bool QueryNewTileTrackStatus()
stores track status (available trackdirs) for the new tile into new_td_bits
bool TryReverse()
return true if we successfully reversed at end of road/track
bool is_bridge
last turn passed bridge ramp
int GetSpeedLimit(int *pmin_speed=nullptr) const
Helper for pathfinders - get min/max speed on the old_tile/old_td.
const VehicleType * veh
moving vehicle
bool ForcedReverse()
return true if we must reverse (in depots and single tram bits)
int tiles_skipped
number of skipped tunnel or station tiles
DiagDirection exitdir
exit direction (leaving the old tile)
TrackdirBits new_td_bits
the new set of available trackdirs
void FollowTileExit()
Follow the exitdir from old_tile and fill new_tile and tiles_skipped.
TileIndex new_tile
the new tile (the vehicle has entered)
Trackdir old_td
the trackdir (the vehicle was on) before move
bool is_station
last turn passed station
DiagDirection GetSingleTramBit(TileIndex tile)
Tests if a tile is a road tile with a single tramtrack (tram can reverse)
Owner veh_owner
owner of the vehicle
TileIndex old_tile
the origin (vehicle moved from) before move
Buses, trucks and trams belong to this class.
Definition roadveh.h:98
RoadTypes compatible_roadtypes
NOSAVE: Roadtypes this consist is powered on.
Definition roadveh.h:110
RoadType roadtype
NOSAVE: Roadtype of this vehicle.
Definition roadveh.h:108
Iterable ensemble of each set bit in a value.
static T * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
'Train' is either a loco or a wagon.
Definition train.h:89
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
Definition tile_map.h:178
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95
@ MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition tile_type.h:57
TrackBits TrackToTrackBits(Track track)
Maps a Track to the corresponding TrackBits value.
Definition track_func.h:77
TrackdirBits TrackStatusToTrackdirBits(TrackStatus ts)
Returns the present-trackdir-information of a TrackStatus.
Definition track_func.h:352
Trackdir ReverseTrackdir(Trackdir trackdir)
Maps a trackdir to the reverse trackdir.
Definition track_func.h:247
bool TracksOverlap(TrackBits bits)
Checks if the given tracks overlap, ie form a crossing.
Definition track_func.h:645
TrackdirBits TrackdirCrossesTrackdirs(Trackdir trackdir)
Maps a trackdir to all trackdirs that make 90 deg turns with it.
Definition track_func.h:606
TrackdirBits DiagdirReachesTrackdirs(DiagDirection diagdir)
Returns all trackdirs that can be reached when entering a tile from a given (diagonal) direction.
Definition track_func.h:555
TrackdirBits TrackdirToTrackdirBits(Trackdir trackdir)
Maps a Trackdir to the corresponding TrackdirBits value.
Definition track_func.h:111
DiagDirection TrackdirToExitdir(Trackdir trackdir)
Maps a trackdir to the (4-way) direction the tile is exited when following that trackdir.
Definition track_func.h:439
TrackBits TrackdirBitsToTrackBits(TrackdirBits bits)
Discards all directional information from a TrackdirBits value.
Definition track_func.h:308
TrackBits
Allow incrementing of Track variables.
Definition track_type.h:35
Trackdir
Enumeration for tracks and directions.
Definition track_type.h:67
@ INVALID_TRACKDIR
Flag for an invalid trackdir.
Definition track_type.h:86
TrackdirBits
Allow incrementing of Trackdir variables.
Definition track_type.h:98
@ TRACKDIR_BIT_NONE
No track build.
Definition track_type.h:99
Track
These are used to specify a single track.
Definition track_type.h:19
TransportType
Available types of transport.
@ TRANSPORT_RAIL
Transport by train.
@ TRANSPORT_ROAD
Transport by road vehicle.
@ TRANSPORT_WATER
Transport over water.
TileIndex GetOtherTunnelEnd(TileIndex tile)
Gets the other end of the tunnel.
bool IsTunnel(Tile t)
Is this a tunnel (entrance)?
Definition tunnel_map.h:23
uint GetTunnelBridgeLength(TileIndex begin, TileIndex end)
Calculates the length of a tunnel or a bridge (without end tiles)
DiagDirection GetTunnelBridgeDirection(Tile t)
Get the direction pointing to the other end.
VehicleType
Available vehicle types.
@ VEH_TRAIN
Train vehicle type.