OpenTTD Source
20240917-master-g9ab0a47812
|
Go to the documentation of this file.
10 #include "../../stdafx.h"
17 #include "../../viewport_func.h"
18 #include "../../newgrf_station.h"
20 #include "../../safeguards.h"
22 template <
typename Tpf>
void DumpState(Tpf &pf1, Tpf &pf2)
29 assert(f1.has_value());
30 assert(f2.has_value());
31 fwrite(dmp1.
m_out.c_str(), 1, dmp1.
m_out.size(), *f1);
32 fwrite(dmp2.
m_out.c_str(), 1, dmp2.
m_out.size(), *f2);
35 template <
class Types>
39 typedef typename Types::Tpf
Tpf;
40 typedef typename Types::TrackFollower TrackFollower;
41 typedef typename Types::NodeList::Titem
Node;
47 return *
static_cast<Tpf *
>(
this);
145 assert(node->m_parent !=
nullptr);
148 if (node->m_parent->m_num_signals_passed >= 2)
return;
161 if (target !=
nullptr) {
164 target->
okay =
false;
171 for (
Node *node =
m_res_node; node->m_parent !=
nullptr; node = node->m_parent) {
181 }
while (fail_node != node && (fail_node = fail_node->m_parent) !=
nullptr);
192 if (target !=
nullptr) target->
okay =
true;
202 template <
class Types>
206 typedef typename Types::Tpf
Tpf;
207 typedef typename Types::TrackFollower TrackFollower;
208 typedef typename Types::NodeList::Titem
Node;
209 typedef typename Node::Key
Key;
215 return *
static_cast<Tpf *
>(
this);
226 TrackFollower F(
Yapf().GetVehicle());
227 if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir())) {
228 Yapf().AddMultipleNodes(&old_node, F);
250 if (max_penalty != 0) pf1.DisableCache(
true);
251 FindDepotData result1 = pf1.FindNearestDepotTwoWay(v, t1, td1, t2, td2, max_penalty, reverse_penalty);
253 if (_debug_desync_level >= 2) {
255 pf2.DisableCache(
true);
256 FindDepotData result2 = pf2.FindNearestDepotTwoWay(v, t1, td1, t2, td2, max_penalty, reverse_penalty);
258 Debug(desync, 2,
"warning: FindNearestDepotTwoWay cache mismatch: {} vs {}",
271 Yapf().SetOrigin(t1, td1, t2, td2, reverse_penalty,
true);
272 Yapf().SetDestination(v);
273 Yapf().SetMaxCost(max_penalty);
283 while (pNode->m_parent !=
nullptr) {
284 pNode = pNode->m_parent;
289 return FindDepotData(n->GetLastTile(), n->m_cost, pNode->m_cost != 0);
293 template <
class Types>
297 typedef typename Types::Tpf
Tpf;
298 typedef typename Types::TrackFollower TrackFollower;
299 typedef typename Types::NodeList::Titem
Node;
300 typedef typename Node::Key
Key;
306 return *
static_cast<Tpf *
>(
this);
317 TrackFollower F(
Yapf().GetVehicle(),
Yapf().GetCompatibleRailTypes());
318 if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir()) && F.MaskReservedTracks()) {
319 Yapf().AddMultipleNodes(&old_node, F);
334 if (_debug_desync_level < 2) {
335 result1 = pf1.FindNearestSafeTile(v, t1, td, override_railtype,
false);
337 bool result2 = pf1.FindNearestSafeTile(v, t1, td, override_railtype,
true);
339 pf2.DisableCache(
true);
340 result1 = pf2.FindNearestSafeTile(v, t1, td, override_railtype,
false);
341 if (result1 != result2) {
342 Debug(desync, 2,
"warning: FindSafeTile cache mismatch: {} vs {}", result2 ?
"T" :
"F", result1 ?
"T" :
"F");
350 bool FindNearestSafeTile(
const Train *v,
TileIndex t1,
Trackdir td,
bool override_railtype,
bool dont_reserve)
353 Yapf().SetOrigin(t1, td);
354 Yapf().SetDestination(v, override_railtype);
356 bool bFound =
Yapf().FindPath(v);
357 if (!bFound)
return false;
364 Node *pPrev =
nullptr;
365 while (pNode->m_parent !=
nullptr) {
367 pNode = pNode->m_parent;
372 return dont_reserve || this->
TryReservePath(
nullptr, pNode->GetLastTile());
376 template <
class Types>
380 typedef typename Types::Tpf
Tpf;
381 typedef typename Types::TrackFollower TrackFollower;
382 typedef typename Types::NodeList::Titem
Node;
383 typedef typename Node::Key
Key;
389 return *
static_cast<Tpf *
>(
this);
400 TrackFollower F(
Yapf().GetVehicle());
401 if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir())) {
402 Yapf().AddMultipleNodes(&old_node, F);
418 if (_debug_desync_level < 2) {
419 result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target, dest);
421 result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found,
false,
nullptr,
nullptr);
423 pf2.DisableCache(
true);
424 Trackdir result2 = pf2.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target, dest);
425 if (result1 != result2) {
426 Debug(desync, 2,
"warning: ChooseRailTrack cache mismatch: {} vs {}", result1, result2);
442 Yapf().SetDestination(v);
445 path_found =
Yapf().FindPath(v);
450 if (pNode !=
nullptr) {
456 Node *pPrev =
nullptr;
457 while (pNode->m_parent !=
nullptr) {
459 pNode = pNode->m_parent;
469 Node &best_next_node = *pPrev;
470 next_trackdir = best_next_node.GetTrackdir();
472 if (reserve_track && path_found) {
473 if (dest !=
nullptr) *dest =
Yapf().GetBestNode()->GetLastTile();
479 path_found |=
Yapf().m_stopped_on_first_two_way_signal;
480 return next_trackdir;
486 bool result1 = pf1.CheckReverseTrain(v, t1, td1, t2, td2, reverse_penalty);
488 if (_debug_desync_level >= 2) {
490 pf2.DisableCache(
true);
491 bool result2 = pf2.CheckReverseTrain(v, t1, td1, t2, td2, reverse_penalty);
492 if (result1 != result2) {
493 Debug(desync, 2,
"warning: CheckReverseTrain cache mismatch: {} vs {}", result1 ?
"T" :
"F", result2 ?
"T" :
"F");
505 Yapf().SetOrigin(t1, td1, t2, td2, reverse_penalty,
false);
506 Yapf().SetDestination(v);
509 bool bFound =
Yapf().FindPath(v);
511 if (!bFound)
return false;
516 while (pNode->m_parent !=
nullptr) {
517 pNode = pNode->m_parent;
521 Node &best_org_node = *pNode;
522 bool reversed = (best_org_node.m_cost != 0);
527 template <
class Tpf_,
class Ttrack_follower,
class Tnode_list,
template <
class Types>
class TdestinationT,
template <
class Types>
class TfollowT>
533 typedef Ttrack_follower TrackFollower;
534 typedef Tnode_list NodeList;
537 typedef TfollowT<Types> PfFollow;
539 typedef TdestinationT<Types> PfDestination;
544 struct CYapfRail1 :
CYapfT<CYapfRail_TypesT<CYapfRail1 , CFollowTrackRail , CRailNodeListTrackDir, CYapfDestinationTileOrStationRailT, CYapfFollowRailT> > {};
545 struct CYapfRail2 :
CYapfT<CYapfRail_TypesT<CYapfRail2 , CFollowTrackRailNo90, CRailNodeListTrackDir, CYapfDestinationTileOrStationRailT, CYapfFollowRailT> > {};
547 struct CYapfAnyDepotRail1 :
CYapfT<CYapfRail_TypesT<CYapfAnyDepotRail1, CFollowTrackRail , CRailNodeListTrackDir, CYapfDestinationAnyDepotRailT , CYapfFollowAnyDepotRailT> > {};
548 struct CYapfAnyDepotRail2 :
CYapfT<CYapfRail_TypesT<CYapfAnyDepotRail2, CFollowTrackRailNo90, CRailNodeListTrackDir, CYapfDestinationAnyDepotRailT , CYapfFollowAnyDepotRailT> > {};
550 struct CYapfAnySafeTileRail1 :
CYapfT<CYapfRail_TypesT<CYapfAnySafeTileRail1, CFollowTrackFreeRail , CRailNodeListTrackDir, CYapfDestinationAnySafeTileRailT , CYapfFollowAnySafeTileRailT> > {};
551 struct CYapfAnySafeTileRail2 :
CYapfT<CYapfRail_TypesT<CYapfAnySafeTileRail2, CFollowTrackFreeRailNo90, CRailNodeListTrackDir, CYapfDestinationAnySafeTileRailT , CYapfFollowAnySafeTileRailT> > {};
558 PfnChooseRailTrack pfnChooseRailTrack = &CYapfRail1::stChooseRailTrack;
562 pfnChooseRailTrack = &CYapfRail2::stChooseRailTrack;
565 Trackdir td_ret = pfnChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target, dest);
581 int reverse_penalty = 0;
613 PfnCheckReverseTrain pfnCheckReverseTrain = CYapfRail1::stCheckReverseTrain;
617 pfnCheckReverseTrain = &CYapfRail2::stCheckReverseTrain;
621 if (reverse_penalty == 0) reverse_penalty = 1;
623 bool reverse = pfnCheckReverseTrain(v, tile, td, tile_rev, td_rev, reverse_penalty);
637 PfnFindNearestDepotTwoWay pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail1::stFindNearestDepotTwoWay;
641 pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail2::stFindNearestDepotTwoWay;
650 PfnFindNearestSafeTile pfnFindNearestSafeTile = CYapfAnySafeTileRail1::stFindNearestSafeTile;
654 pfnFindNearestSafeTile = &CYapfAnySafeTileRail2::stFindNearestSafeTile;
657 return pfnFindNearestSafeTile(v, tile, td, override_railtype);
665 CSegmentCostCacheBase::NotifyTrackLayoutChange(tile, track);
bool okay
True if tile is a safe waiting position, false otherwise.
Trackdir m_res_dest_td
The reservation target trackdir.
Track FindFirstTrack(TrackBits tracks)
Returns first Track from TrackBits or INVALID_TRACK.
constexpr TileIndex TileAdd(TileIndex tile, TileIndexDiff offset)
Adds a given offset to a tile.
Types::NodeList::Titem Node
this will be our node type
Tpf & Yapf()
to access inherited pathfinder
Tpf & Yapf()
to access inherited path finder
Helper container to find a depot.
bool forbid_90_deg
forbid trains to make 90 deg turns
bool ReserveRailStationPlatform(TileIndex &tile, DiagDirection dir)
Reserve a railway platform.
Types::Tpf Tpf
the pathfinder class (derived from THIS class)
Node * m_res_node
The reservation target node.
void YapfNotifyTrackLayoutChange(TileIndex tile, Track track)
Use this function to notify YAPF that track layout (or signal configuration) has change.
Track TrackdirToTrack(Trackdir trackdir)
Returns the Track that a given Trackdir represents.
DiagDirection TrackdirToExitdir(Trackdir trackdir)
Maps a trackdir to the (4-way) direction the tile is exited when following that trackdir.
bool reverse
True if reversing is necessary for the train to get to this depot.
Types::Tpf Tpf
the pathfinder class (derived from THIS class)
PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res)
Follow a train reservation to the last tile.
void FindSafePositionOnNode(Node *node)
Check the node for a possible reservation target.
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
@ SIGNAL_STATE_GREEN
The signal is green.
bool IsCompatibleTrainStationTile(Tile test_tile, Tile station_tile)
Check if a tile is a valid continuation to a railstation tile.
bool IsRailStationTile(Tile t)
Is this tile a station tile and a rail station?
DiagDirection
Enumeration for diagonal directions.
YAPF template that uses Ttypes template argument to determine all YAPF components (base classes) from...
static std::optional< FileHandle > Open(const std::string &filename, const std::string &mode)
Open an RAII file handle if possible.
void PfFollowNode(Node &old_node)
Called by YAPF to move from the given node to the next tile.
char TransportTypeChar() const
return debug report character to identify the transportation type
Trackdir m_res_fail_td
The trackdir where the reservation failed.
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
bool TryReserveRailTrack(TileIndex tile, Track t, bool trigger_stations)
Try to reserve a specific track on a tile.
int32_t x_pos
x coordinate.
Node::Key Key
key to hash tables
char TransportTypeChar() const
return debug report character to identify the transportation type
PathfinderSettings pf
settings for all pathfinders
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
void UnreserveRailTrack(TileIndex tile, Track t)
Lift the reservation of a specific track on a tile.
bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bool forbid_90deg)
Check if a safe position is free.
YAPF origin provider base class - used when there are two tile/trackdir origins.
TileIndex m_origin_tile
Tile our reservation will originate from.
Trackdir GetVehicleTrackdir() const override
Get the tracks of the train vehicle.
TrackBits
Allow incrementing of Track variables.
static const int YAPF_TILE_LENGTH
Length (penalty) of one tile with YAPF.
TileIndex tile
Current tile index.
@ SIGNAL_STATE_RED
The signal is red.
This struct contains information about the end of a reserved path.
Node::Key Key
key to hash tables
Trackdir trackdir
The reserved trackdir on the tile.
CYapfSegmentCostCacheGlobalT - the yapf cost cache provider that adds the segment cost caching functi...
Trackdir ReverseTrackdir(Trackdir trackdir)
Maps a trackdir to the reverse trackdir.
Class that represents the dump-into-string target.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
'Train' is either a loco or a wagon.
bool UnreserveSingleTrack(TileIndex tile, Trackdir td)
Unreserve a single track/platform.
void SetReservationTarget(Node *node, TileIndex tile, Trackdir td)
Set the target to where the reservation should be extended.
bool TryReservePath(PBSTileInfo *target, TileIndex origin)
Try to reserve the path till the reservation target.
bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bool include_line_end, bool forbid_90deg)
Determine whether a certain track on a tile is a safe position to end a path.
SignalState GetSignalStateByTrackdir(Tile tile, Trackdir trackdir)
Gets the state of the signal along the given trackdir.
Types::Tpf Tpf
the pathfinder class (derived from THIS class)
int32_t TileIndexDiff
An offset value between two tiles.
void SetRailStationReservation(Tile t, bool b)
Set the reservation state of the rail station.
FindDepotData YapfTrainFindNearestDepot(const Train *v, int max_penalty)
Used when user sends train to the nearest depot or if train needs servicing using YAPF.
char TransportTypeChar() const
Return debug report character to identify the transportation type.
static int s_rail_change_counter
if any track changes, this counter is incremented - that will invalidate segment cost cache
@ TRACK_BIT_WORMHOLE
Bitflag for a wormhole (used for tunnels)
TileIndex m_res_fail_tile
The tile where the reservation failed.
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Types::Tpf Tpf
the pathfinder class (derived from THIS class)
Tpf & Yapf()
to access inherited path finder
TileIndex m_res_dest
The reservation target tile.
TileIndex tile
Tile the path ends, INVALID_TILE if no valid path was found.
Track
These are used to specify a single track.
Track YapfTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, PBSTileInfo *target, TileIndex *dest)
Finds the best path for given train using YAPF.
Trackdir
Enumeration for tracks and directions.
bool HasStationReservation(Tile t)
Get the reservation state of the rail station.
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
std::string m_out
the output string
void PfFollowNode(Node &old_node)
Called by YAPF to move from the given node to the next tile.
TileIndex tile
The tile of the depot.
static const int YAPF_INFINITE_PENALTY
This penalty is the equivalent of "infinite", which means that paths that get this penalty will be ch...
std::vector< std::pair< TileIndex, Trackdir > > m_signals_set_to_red
List of signals turned red during a path reservation.
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.
bool YapfTrainCheckReverse(const Train *v)
Returns true if it is better to reverse the train before leaving station using YAPF.
TileIndex GetOtherTunnelBridgeEnd(Tile t)
Determines type of the wormhole and returns its other end.
int32_t y_pos
y coordinate.
void TriggerStationRandomisation(Station *st, TileIndex trigger_tile, StationRandomTrigger trigger, CargoID cargo_type)
Trigger station randomisation.
@ SRT_PATH_RESERVATION
Trigger platform when train reserves path.
void PfFollowNode(Node &old_node)
Called by YAPF to move from the given node to the next tile.
static debug_inline TileIndex TileVirtXY(uint x, uint y)
Get a tile from the virtual XY-coordinate.
Types::NodeList::Titem Node
this will be our node type
CYapfBaseT - A-star type path finder base class.
Types::NodeList::Titem Node
this will be our node type
bool HasPbsSignalOnTrackdir(Tile tile, Trackdir td)
Is a pbs signal present along the trackdir?
Node::Key Key
key to hash tables
T * Last()
Get the last vehicle in the chain.
@ INVALID_TRACK
Flag for an invalid track.
Tpf & Yapf()
to access inherited path finder
void SetSignalStateByTrackdir(Tile tile, Trackdir trackdir, SignalState state)
Sets the state of the signal along the given trackdir.
@ INVALID_TRACKDIR
Flag for an invalid trackdir.
Types::NodeList::Titem Node
this will be our node type
bool YapfTrainFindNearestSafeTile(const Train *v, TileIndex tile, Trackdir td, bool override_railtype)
Try to extend the reserved path of a train to the nearest safe tile using YAPF.
bool ReserveSingleTrack(TileIndex tile, Trackdir td)
Try to reserve a single track/platform.
DiagDirection GetTunnelBridgeDirection(Tile t)
Get the direction pointing to the other end.