10#ifndef FOLLOW_TRACK_HPP
11#define FOLLOW_TRACK_HPP
27template <TransportType Ttr_type_,
typename VehicleType,
bool T90deg_turns_allowed_ = true,
bool Tmask_reserved_tracks = false>
29 enum ErrorCode : uint8_t {
52 inline CFollowTrackT(
const VehicleType *v =
nullptr,
RailTypes railtype_override = INVALID_RAILTYPES)
54 Init(v, railtype_override);
61 Init(o, railtype_override);
66 assert(!IsRailTT() || (v !=
nullptr && v->type ==
VEH_TRAIN));
68 Init(v !=
nullptr ? v->owner :
INVALID_OWNER, IsRailTT() && railtype_override == INVALID_RAILTYPES ?
Train::From(v)->compatible_railtypes : railtype_override);
71 inline void Init(Owner o,
RailTypes railtype_override)
73 assert(!IsRoadTT() || this->
veh !=
nullptr);
74 assert(!IsRailTT() || railtype_override != INVALID_RAILTYPES);
87 this->railtypes = railtype_override;
93 inline bool IsTram() {
return IsRoadTT() && RoadTypeIsTram(
RoadVehicle::From(this->
veh)->roadtype); }
95 static inline bool Allow90degTurns() {
return T90deg_turns_allowed_; }
96 static inline bool DoTrackMasking() {
return Tmask_reserved_tracks; }
105 assert(this->IsTram());
158 if (IsRoadTT() && !this->IsTram() && this->
TryReverse())
return true;
170 this->err = EC_90DEG;
177 inline bool MaskReservedTracks()
179 if (!DoTrackMasking())
return true;
181 if (this->is_station) {
184 for (
TileIndex tile = this->new_tile - diff * this->tiles_skipped; tile != this->new_tile; tile += diff) {
187 this->err = EC_RESERVED;
195 this->
new_td_bits &= ~TrackBitsToTrackdirBits(reserved);
201 this->err = EC_RESERVED;
211 this->is_station =
false;
212 this->is_bridge =
false;
213 this->is_tunnel =
false;
214 this->tiles_skipped = 0;
219 if (enterdir == this->exitdir) {
222 this->is_tunnel =
true;
225 this->is_bridge =
true;
239 this->is_station =
true;
241 this->is_station =
true;
253 }
else if (IsRoadTT()) {
270 if (
exitdir != this->exitdir) {
271 this->err = EC_NO_WAY;
277 if (this->IsTram()) {
280 this->err = EC_NO_WAY;
288 if (
exitdir != this->exitdir) {
289 this->err = EC_NO_WAY;
306 this->err = EC_NO_WAY;
312 if (this->IsTram()) {
315 this->err = EC_NO_WAY;
324 this->err = EC_NO_WAY;
329 this->err = EC_OWNER;
336 this->err = EC_NO_WAY;
342 if (IsRailTT() &&
GetTileOwner(this->new_tile) != this->veh_owner) {
344 this->err = EC_NO_WAY;
349 if (IsRailTT() && this->railtypes.
Any()) {
351 if (!this->railtypes.
Test(rail_type)) {
353 this->err = EC_RAIL_ROAD_TYPE;
364 this->err = EC_RAIL_ROAD_TYPE;
372 if (!this->is_tunnel) {
374 if (tunnel_enterdir != this->exitdir) {
375 this->err = EC_NO_WAY;
380 if (!this->is_bridge) {
382 if (ramp_enderdir != this->exitdir) {
383 this->err = EC_NO_WAY;
391 if (IsRailTT() && this->is_station) {
396 this->tiles_skipped = length - 1;
399 diff *= this->tiles_skipped;
400 this->new_tile =
TileAdd(this->new_tile, diff);
416 if (
exitdir != this->exitdir) {
418 this->new_tile = this->old_tile;
421 this->tiles_skipped = 0;
422 this->is_tunnel =
false;
423 this->is_bridge =
false;
424 this->is_station =
false;
433 this->new_tile = this->old_tile;
436 this->tiles_skipped = 0;
437 this->is_tunnel =
false;
438 this->is_bridge =
false;
439 this->is_station =
false;
452 if (IsRoadTT() && !this->IsTram()) {
456 this->new_tile = this->old_tile;
465 this->err = EC_NO_WAY;
478 int max_speed = INT_MAX;
483 if (IsRoadTT()) spd *= 2;
484 max_speed = std::min(max_speed, spd);
489 if (rail_speed > 0) max_speed = std::min<int>(max_speed, rail_speed);
494 if (road_speed > 0) max_speed = std::min<int>(max_speed, road_speed);
498 if (pmin_speed !=
nullptr) *pmin_speed = min_speed;
const BridgeSpec * GetBridgeSpec(BridgeType i)
Get the specification of a bridge type.
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
BridgeType GetBridgeType(Tile t)
Determines the type of bridge on a tile.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Tstorage base() const noexcept
Retrieve the raw value behind this bit set.
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
uint16_t max_speed
Maximum speed for vehicles travelling on this rail type.
uint16_t max_speed
Maximum speed for vehicles travelling on this road type.
static constexpr Owner INVALID_OWNER
An invalid owner.
Map related accessors for depots.
bool IsDepotTypeTile(Tile tile, TransportType type)
Check if a tile is a depot and it is a depot of the given type.
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.
@ INVALID_DIAGDIR
Flag for an invalid DiagDirection.
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, RoadTramType sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
constexpr TileIndex TileAdd(TileIndex tile, TileIndexDiff offset)
Adds a given offset to a tile.
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
int32_t TileIndexDiff
An offset value between two tiles.
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.
RailType GetTileRailType(Tile tile)
Return the rail type of tile, or INVALID_RAILTYPE if this is no rail tile.
bool Rail90DegTurnDisallowed(RailType rt1, RailType rt2, bool def=_settings_game.pf.forbid_90_deg)
Test if 90 degree turns are disallowed between two railtypes.
const RailTypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
RailType GetRailType(Tile t)
Gets the rail type of the given tile.
TrackBits GetTrackBits(Tile tile)
Gets the track bits of the given tile.
static bool IsPlainRailTile(Tile t)
Checks whether the tile is a rail tile or rail tile with signals.
DiagDirection GetRailDepotDirection(Tile t)
Returns the direction the depot is facing to.
EnumBitSet< RailType, uint64_t > RailTypes
Allow incrementing of Track variables.
RailType
Enumeration for all possible railtypes.
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
RoadBits GetRoadBits(Tile t, RoadTramType rtt)
Get the present road bits for a specific road type.
DiagDirection GetRoadDepotDirection(Tile t)
Get the direction of the exit of a road depot.
RoadType GetRoadType(Tile t, RoadTramType rtt)
Get the road type for the given RoadTramType.
static bool IsNormalRoadTile(Tile t)
Return whether a tile is a normal road tile.
EnumBitSet< RoadBit, uint8_t > RoadBits
Bitset of RoadBit elements.
RoadType
The different roadtypes we support.
RoadTramType
The different types of road type.
Base classes/functions for stations.
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?
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.
#define debug_inline
When making a (pure) debug build, the compiler will by default disable inlining of functions.
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)
Track follower helper template class (can serve pathfinders and vehicle controllers).
bool CanExitOldTile()
Check whether we can leave the old tile.
bool Follow(TileIndex old_tile, Trackdir old_td)
Main follower routine.
bool CanEnterNewTile()
Checks whether we can enter the next tile.
bool QueryNewTileTrackStatus()
Stores track status (available trackdirs) for the new tile into new_td_bits.
bool TryReverse()
Try whether we can reverse our road vehicle.
int GetSpeedLimit(int *pmin_speed=nullptr) const
Helper for pathfinders - get min/max speed on the old_tile/old_td.
bool ForcedReverse()
Are we forced to reverse the vehicle?
void FollowTileExit()
Follow the exitdir from old_tile and fill new_tile and tiles_skipped.
DiagDirection GetSingleTramBit(TileIndex tile)
Tests if a tile is a road tile with a single tramtrack (tram can reverse).
Buses, trucks and trams belong to this class.
RoadTypes compatible_roadtypes
NOSAVE: Roadtypes this consist is powered on.
RoadType roadtype
NOSAVE: Roadtype of this vehicle.
static Train * From(Vehicle *v)
static bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
@ TunnelBridge
Tunnel entry/exit and bridge heads.
TrackBits TrackToTrackBits(Track track)
Maps a Track to the corresponding TrackBits value.
TrackdirBits TrackStatusToTrackdirBits(TrackStatus ts)
Returns the present-trackdir-information of a TrackStatus.
Trackdir ReverseTrackdir(Trackdir trackdir)
Maps a trackdir to the reverse trackdir.
bool TracksOverlap(TrackBits bits)
Checks if the given tracks overlap, ie form a crossing.
TrackdirBits TrackdirCrossesTrackdirs(Trackdir trackdir)
Maps a trackdir to all trackdirs that make 90 deg turns with it.
TrackdirBits DiagdirReachesTrackdirs(DiagDirection diagdir)
Returns all trackdirs that can be reached when entering a tile from a given (diagonal) direction.
TrackdirBits TrackdirToTrackdirBits(Trackdir trackdir)
Maps a Trackdir to the corresponding TrackdirBits value.
DiagDirection TrackdirToExitdir(Trackdir trackdir)
Maps a trackdir to the (4-way) direction the tile is exited when following that trackdir.
TrackBits TrackdirBitsToTrackBits(TrackdirBits bits)
Discards all directional information from a TrackdirBits value.
TrackBits
Allow incrementing of Track variables.
Trackdir
Enumeration for tracks and directions.
@ INVALID_TRACKDIR
Flag for an invalid trackdir.
TrackdirBits
Allow incrementing of Trackdir variables.
@ TRACKDIR_BIT_NONE
No track build.
Track
These are used to specify a single track.
Base for the train class.
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)?
Header file for things common for tunnels and bridges.
uint GetTunnelBridgeLength(TileIndex begin, TileIndex end)
Calculates the length of a tunnel or a bridge (without end tiles).
Functions that have tunnels and bridges in common.
DiagDirection GetTunnelBridgeDirection(Tile t)
Get the direction pointing to the other end.
VehicleType
Available vehicle types.
@ VEH_TRAIN
Train vehicle type.