10#ifndef FOLLOW_TRACK_HPP
11#define FOLLOW_TRACK_HPP
14#include "../roadveh.h"
15#include "../station_base.h"
17#include "../tunnelbridge.h"
18#include "../tunnelbridge_map.h"
19#include "../depot_map.h"
27template <TransportType Ttr_type_,
typename VehicleType,
bool T90deg_turns_allowed_ = true,
bool Tmask_reserved_tracks = false>
55 Init(v, railtype_override);
62 Init(o, railtype_override);
67 assert(!IsRailTT() || (v !=
nullptr && v->type ==
VEH_TRAIN));
74 assert(!IsRoadTT() || this->veh !=
nullptr);
83 this->is_station =
false;
84 this->is_bridge =
false;
85 this->is_tunnel =
false;
86 this->tiles_skipped = 0;
88 this->railtypes = railtype_override;
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; }
102 assert(this->IsTram());
129 const uint sub_mode = (IsRoadTT() && this->veh !=
nullptr) ? (this->IsTram() ? RTT_TRAM : RTT_ROAD) : 0;
152 if (IsRoadTT() && !this->IsTram() && this->
TryReverse())
return true;
164 this->err = EC_90DEG;
171 inline bool MaskReservedTracks()
173 if (!DoTrackMasking())
return true;
175 if (this->is_station) {
178 for (
TileIndex tile = this->new_tile - diff * this->tiles_skipped; tile != this->
new_tile; tile += diff) {
181 this->err = EC_RESERVED;
189 this->new_td_bits &= ~TrackBitsToTrackdirBits(reserved);
195 this->err = EC_RESERVED;
205 this->is_station =
false;
206 this->is_bridge =
false;
207 this->is_tunnel =
false;
208 this->tiles_skipped = 0;
213 if (enterdir == this->exitdir) {
216 this->is_tunnel =
true;
219 this->is_bridge =
true;
233 this->is_station =
true;
235 this->is_station =
true;
244 }
else if (IsRoadTT()) {
258 if (
exitdir != this->exitdir) {
259 this->err = EC_NO_WAY;
265 if (this->IsTram()) {
268 this->err = EC_NO_WAY;
276 if (
exitdir != this->exitdir) {
277 this->err = EC_NO_WAY;
291 this->err = EC_NO_WAY;
297 if (this->IsTram()) {
300 this->err = EC_NO_WAY;
309 this->err = EC_NO_WAY;
314 this->err = EC_OWNER;
321 this->err = EC_NO_WAY;
327 if (IsRailTT() &&
GetTileOwner(this->new_tile) != this->veh_owner) {
329 this->err = EC_NO_WAY;
336 if (!
HasBit(this->railtypes, rail_type)) {
338 this->err = EC_RAIL_ROAD_TYPE;
346 RoadType roadtype = GetRoadType(this->new_tile, GetRoadTramType(v->
roadtype));
349 this->err = EC_RAIL_ROAD_TYPE;
357 if (!this->is_tunnel) {
359 if (tunnel_enterdir != this->exitdir) {
360 this->err = EC_NO_WAY;
365 if (!this->is_bridge) {
367 if (ramp_enderdir != this->exitdir) {
368 this->err = EC_NO_WAY;
376 if (IsRailTT() && this->is_station) {
381 this->tiles_skipped = length - 1;
385 this->new_tile =
TileAdd(this->new_tile, diff);
398 if (
exitdir != this->exitdir) {
403 this->tiles_skipped = 0;
404 this->is_tunnel =
false;
405 this->is_bridge =
false;
406 this->is_station =
false;
418 this->tiles_skipped = 0;
419 this->is_tunnel =
false;
420 this->is_bridge =
false;
421 this->is_station =
false;
431 if (IsRoadTT() && !this->IsTram()) {
444 this->err = EC_NO_WAY;
453 int max_speed = INT_MAX;
458 if (IsRoadTT()) spd *= 2;
459 max_speed = std::min(max_speed, spd);
464 if (rail_speed > 0) max_speed = std::min<int>(max_speed, rail_speed);
469 if (road_speed > 0) max_speed = std::min<int>(max_speed, road_speed);
473 if (pmin_speed !=
nullptr) *pmin_speed = min_speed;
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.
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.
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.
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.
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, uint 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.
DiagDirection GetRailDepotDirection(Tile t)
Returns the direction the depot is facing to.
static debug_inline bool IsPlainRailTile(Tile t)
Checks whether the tile is a rail tile or rail tile with signals.
RailTypes
Allow incrementing of Track variables.
@ INVALID_RAILTYPES
Invalid railtypes.
RailType
Enumeration for all possible railtypes.
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
static debug_inline bool IsNormalRoadTile(Tile t)
Return whether a tile is a normal road tile.
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.
RoadBits
Enumeration for the road parts on a tile.
@ ROAD_SW
South-west part.
@ ROAD_NE
North-east part.
@ ROAD_SE
South-east part.
@ ROAD_NW
North-west part.
RoadType
The different roadtypes we support.
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)
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.
RoadTypes compatible_roadtypes
NOSAVE: Roadtypes this consist is powered on.
RoadType roadtype
NOSAVE: Roadtype of this vehicle.
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.
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
@ MP_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.
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)?
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.