10#include "../../stdafx.h"
13#include "../../roadstop_base.h"
15#include "../../safeguards.h"
21 typedef typename Types::Tpf
Tpf;
23 typedef typename Types::NodeList::Item
Node;
24 typedef typename Node::Key
Key;
34 return *
static_cast<Tpf *
>(
this);
51 return Yapf().PfGetSettings().road_slope_penalty;
67 cost +=
Yapf().PfGetSettings().road_crossing_penalty;
77 cost +=
Yapf().PfGetSettings().road_stop_penalty;
87 cost +=
Yapf().PfGetSettings().road_stop_bay_occupied_penalty * (!rs->
IsFreeBay(0) + !rs->
IsFreeBay(1)) / 2;
103 inline void SetMaxCost(
int max_cost)
105 this->max_cost = max_cost;
115 int segment_cost = 0;
120 int parent_cost = (n.parent !=
nullptr) ? n.parent->cost : 0;
124 segment_cost +=
Yapf().OneTileCost(tile, trackdir);
128 if (
Yapf().PfDetectDestinationTile(tile, trackdir))
break;
132 if (this->max_cost > 0 && (parent_cost + segment_cost) > this->max_cost) {
144 if (!F.Follow(tile, trackdir))
break;
152 if (F.new_tile == n.key.tile && new_td == n.key.td)
return false;
156 tiles += F.tiles_skipped + 1;
159 segment_cost +=
Yapf().SlopeCost(tile, F.new_tile, trackdir);
164 int max_speed = F.GetSpeedLimit(&min_speed);
165 if (max_speed < max_veh_speed) segment_cost +=
YAPF_TILE_LENGTH * (max_veh_speed - max_speed) * (4 + F.tiles_skipped) / max_veh_speed;
166 if (min_speed > max_veh_speed) segment_cost +=
YAPF_TILE_LENGTH * (min_speed - max_veh_speed);
175 n.segment_last_tile = tile;
176 n.segment_last_td = trackdir;
179 n.cost = parent_cost + segment_cost;
185template <
class Types>
188 typedef typename Types::Tpf
Tpf;
189 typedef typename Types::TrackFollower TrackFollower;
190 typedef typename Types::NodeList::Item
Node;
191 typedef typename Node::Key
Key;
196 return *
static_cast<Tpf *
>(
this);
222template <
class Types>
225 typedef typename Types::Tpf
Tpf;
226 typedef typename Types::TrackFollower TrackFollower;
227 typedef typename Types::NodeList::Item
Node;
228 typedef typename Node::Key
Key;
242 this->station_type = v->
IsBus() ? StationType::Bus : StationType::Truck;
248 this->station_type = StationType::RoadWaypoint;
253 this->dest_station = StationID::Invalid();
259 const Station *GetDestinationStation()
const
261 return this->dest_station != StationID::Invalid() ?
Station::GetIfValid(this->dest_station) : nullptr;
268 return *
static_cast<Tpf *
>(
this);
275 return this->PfDetectDestinationTile(n.segment_last_tile, n.segment_last_td);
280 if (this->dest_station != StationID::Invalid()) {
287 return tile == this->dest_tile &&
HasTrackdir(this->dest_trackdirs, trackdir);
296 static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
297 static const int dg_dir_to_y_offs[] = {0, 1, 0, -1};
305 int x1 = 2 *
TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
306 int y1 = 2 *
TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
307 int x2 = 2 *
TileX(this->dest_tile);
308 int y2 = 2 *
TileY(this->dest_tile);
309 int dx =
abs(x1 - x2);
310 int dy =
abs(y1 - y2);
311 int dmin = std::min(dx, dy);
312 int dxy =
abs(dx - dy);
314 n.estimate = n.cost + d;
315 assert(n.estimate >= n.parent->estimate);
322template <
class Types>
325 typedef typename Types::Tpf
Tpf;
326 typedef typename Types::TrackFollower TrackFollower;
327 typedef typename Types::NodeList::Item
Node;
328 typedef typename Node::Key
Key;
334 return *
static_cast<Tpf *
>(
this);
346 TrackFollower F(
Yapf().GetVehicle());
347 if (F.Follow(old_node.segment_last_tile, old_node.segment_last_td)) {
348 Yapf().AddMultipleNodes(&old_node, F);
361 return pf.ChooseRoadTrack(v, tile, enterdir, path_found, path_cache);
382 Yapf().SetOrigin(src_tile, src_trackdirs);
383 Yapf().SetDestination(v);
386 path_found =
Yapf().FindPath(v);
391 if (node !=
nullptr) {
393 for (
Node *n = node; n->parent !=
nullptr; n = n->parent) steps++;
397 while (node->parent !=
nullptr) {
400 path_cache.emplace_back(node->GetTrackdir(), node->GetTile());
405 Node &best_next_node = *node;
406 assert(best_next_node.GetTile() == tile);
407 next_trackdir = best_next_node.GetTrackdir();
411 const Station *st =
Yapf().GetDestinationStation();
413 const RoadStop *stop = st->GetPrimaryRoadStop(v);
421 auto it = std::find_if(std::begin(path_cache), std::end(path_cache), [&non_cached_area](
const auto &pc) {
return !non_cached_area.
Contains(pc.tile); });
422 path_cache.erase(std::begin(path_cache), it);
426 return next_trackdir;
432 if (dst_tile == v->
tile) {
440 Yapf().SetDestination(v);
443 uint dist = UINT_MAX;
446 if (!
Yapf().FindPath(v))
return dist;
449 if (node !=
nullptr) {
452 dist = node->GetCostEstimate();
476 return pf.FindNearestDepot(v, tile, td, max_distance);
490 Yapf().SetMaxCost(max_distance);
501template <
class Tpf_,
class Tnode_list,
template <
class Types>
class Tdestination>
512 typedef Tdestination<Types> PfDestination;
517struct CYapfRoad1 :
CYapfT<CYapfRoad_TypesT<CYapfRoad1 , CRoadNodeListTrackDir, CYapfDestinationTileRoadT>> {};
518struct CYapfRoad2 :
CYapfT<CYapfRoad_TypesT<CYapfRoad2 , CRoadNodeListExitDir , CYapfDestinationTileRoadT>> {};
527 ? CYapfRoad1::stChooseRoadTrack(v, tile, enterdir, path_found, path_cache)
528 : CYapfRoad2::stChooseRoadTrack(v, tile, enterdir, path_found, path_cache);
543 ? CYapfRoadAnyDepot1::stFindNearestDepot(v, tile, trackdir, max_distance)
544 : CYapfRoadAnyDepot2::stFindNearestDepot(v, tile, trackdir, max_distance);
constexpr uint8_t FindFirstBit(T x)
Search the first set bit in a value.
constexpr T KillFirstBit(T value)
Clear the first bit in an integer.
CYapfBaseT - A-star type path finder base class.
Types::TrackFollower TrackFollower
track follower helper
Types::NodeList::Item Node
this will be our node type
Node::Key Key
key to hash tables
Tpf & Yapf()
to access inherited path finder
int OneTileCost(TileIndex tile, Trackdir trackdir)
return one tile cost
bool PfCalcCost(Node &n, const TrackFollower *)
Called by YAPF to calculate the cost from the origin to the given node.
Types::Tpf Tpf
pathfinder (derived from THIS class)
Tpf & Yapf()
to access inherited path finder
Types::NodeList::Item Node
this will be our node type
bool PfCalcEstimate(Node &n)
Called by YAPF to calculate cost estimate.
bool PfDetectDestination(Node &n)
Called by YAPF to detect if node ends in the desired destination.
Node::Key Key
key to hash tables
Types::Tpf Tpf
the pathfinder class (derived from THIS class)
bool PfCalcEstimate(Node &n)
Called by YAPF to calculate cost estimate.
Types::Tpf Tpf
the pathfinder class (derived from THIS class)
Node::Key Key
key to hash tables
Tpf & Yapf()
to access inherited path finder
Types::NodeList::Item Node
this will be our node type
bool PfDetectDestination(Node &n)
Called by YAPF to detect if node ends in the desired destination.
Types::NodeList::Item Node
this will be our node type
FindDepotData FindNearestDepot(const RoadVehicle *v, TileIndex tile, Trackdir td, int max_distance)
Find the best depot for a road vehicle.
Tpf & Yapf()
to access inherited path finder
void PfFollowNode(Node &old_node)
Called by YAPF to move from the given node to the next tile.
Node::Key Key
key to hash tables
char TransportTypeChar() const
return debug report character to identify the transportation type
bool SetOriginFromVehiclePos(const RoadVehicle *v)
Return true if the valid origin (tile/trackdir) was set from the current vehicle position.
Types::Tpf Tpf
the pathfinder class (derived from THIS class)
YAPF origin provider base class - used when origin is one tile / multiple trackdirs.
CYapfSegmentCostCacheNoneT - the formal only yapf cost cache provider that implements PfNodeCacheFetc...
YAPF template that uses Ttypes template argument to determine all YAPF components (base classes) from...
Hash table based node list multi-container class.
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
DiagDirection
Enumeration for diagonal directions.
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
int GetSlopePixelZ(int x, int y, bool ground_vehicle)
Return world Z coordinate of a given point of a tile.
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
static const uint MAX_MAP_SIZE
Maximal map size = 4096.
constexpr T abs(const T a)
Returns the absolute value of (scalar) variable.
TrackdirBits GetTrackdirBitsForRoad(TileIndex tile, RoadTramType rtt)
Wrapper around GetTileTrackStatus() and TrackStatusToTrackdirBits(), as for single tram bits GetTileT...
TileIndex CalcClosestStationTile(StationID station, TileIndex tile, StationType station_type)
Calculates the tile of given station that is closest to a given tile for this we assume the station i...
static const int YAPF_TILE_CORNER_LENGTH
Length (penalty) of a corner with YAPF.
static const int YAPF_ROADVEH_PATH_CACHE_SEGMENTS
Maximum segments of road vehicle path cache.
static const int YAPF_ROADVEH_PATH_CACHE_DESTINATION_LIMIT
Distance from destination road stops to not cache any further.
static const int YAPF_TILE_LENGTH
Length (penalty) of one tile with YAPF.
DiagDirection GetRoadDepotDirection(Tile t)
Get the direction of the exit of a road depot.
static debug_inline bool IsRoadDepotTile(Tile t)
Return whether a tile is a road depot tile.
bool IsLevelCrossing(Tile t)
Return whether a tile is a level crossing.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
StationType GetStationType(Tile t)
Get the station type of this tile.
bool IsRoadWaypoint(Tile t)
Is the station at t a road waypoint?
bool IsDriveThroughStopTile(Tile t)
Is tile t a drive through road stop station or waypoint?
StationID GetStationIndex(Tile t)
Get StationID from a tile.
RoadStopType GetRoadStopType(Tile t)
Get the road stop type of this tile.
StationType
Station types.
Track follower helper template class (can serve pathfinders and vehicle controllers).
Helper container to find a depot.
PathfinderSettings pf
settings for all pathfinders
uint16_t GetMaxSpeed() const
Get the maxmimum speed in km-ish/h a vehicle is allowed to reach on the way to the destination.
DestinationID GetDestination() const
Gets the destination of this order.
bool IsType(OrderType type) const
Check whether this order is of the given type.
Represents the covered area of e.g.
bool Contains(TileIndex tile) const
Does this tile area contain a tile?
OrthogonalTileArea & Expand(int rad)
Expand a tile area by rad tiles in each direction, keeping within map bounds.
YAPFSettings yapf
pathfinder settings for the yet another pathfinder
Container for each entry point of a drive through road stop.
int GetOccupied() const
Get the amount of occupied space in this drive through stop.
int GetLength() const
Get the length of this drive through stop.
A Stop for a Road Vehicle.
bool IsFreeBay(uint nr) const
Checks whether the given bay is free in this road stop.
RoadStop * GetNextRoadStop(const struct RoadVehicle *v) const
Get the next road stop accessible by this vehicle.
TileIndex xy
Position on the map.
const Entry & GetEntry(DiagDirection dir) const
Get the drive through road stop entry struct for the given direction.
static bool IsDriveThroughRoadStopContinuation(TileIndex rs, TileIndex next)
Checks whether the 'next' tile is still part of the road same drive through stop 'rs' in the same dir...
static RoadStop * GetByTile(TileIndex tile, RoadStopType type)
Find a roadstop at given tile.
Buses, trucks and trams belong to this class.
bool IsBus() const
Check whether a roadvehicle is a bus.
int GetDisplayMaxSpeed() const override
Gets the maximum speed in km-ish/h that can be sent into string parameters for string processing.
Trackdir GetVehicleTrackdir() const override
Returns the Trackdir on which the vehicle is currently located.
RoadType roadtype
NOSAVE: Roadtype of this vehicle.
static Station * GetIfValid(auto index)
Returns station if the index is a valid index for this station type.
TileArea bus_station
Tile area the bus 'station' part covers.
TileArea truck_station
Tile area the truck 'station' part covers.
bool HasArticulatedPart() const
Check if an engine has an articulated part.
Order current_order
The current order (+ status, like: loading)
TileIndex tile
Current tile index.
TileIndex dest_tile
Heading for this tile.
bool disable_node_optimization
whether to use exit-dir instead of trackdir in node key
static debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
static constexpr uint TILE_SIZE
Tile size in world coordinates.
@ MP_ROAD
A tile with road (or tram tracks)
@ MP_STATION
A tile of a station.
TrackdirBits TrackStatusToTrackdirBits(TrackStatus ts)
Returns the present-trackdir-information of a TrackStatus.
TrackdirBits DiagdirReachesTrackdirs(DiagDirection diagdir)
Returns all trackdirs that can be reached when entering a tile from a given (diagonal) direction.
bool IsDiagonalTrackdir(Trackdir trackdir)
Checks if a given Trackdir is diagonal.
bool HasTrackdir(TrackdirBits trackdirs, Trackdir trackdir)
Checks whether a TrackdirBits has a given Trackdir.
Trackdir DiagDirToDiagTrackdir(DiagDirection diagdir)
Maps a (4-way) direction to the diagonal trackdir that runs in that 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.
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.
@ INVALID_TRACKDIR_BIT
Flag for an invalid trackdirbit value.
@ TRANSPORT_ROAD
Transport by road vehicle.
Base includes/functions for YAPF.
Node tailored for road pathfinding.
FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_distance)
Used when user sends road vehicle to the nearest depot or if road vehicle needs servicing using YAPF.
Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found, RoadVehPathCache &path_cache)
Finds the best path for given road vehicle using YAPF.