1
0
Fork 0

Codechange: Remove `m_` prefix from pathfinders.

pull/13030/head
Peter Nelson 2024-10-14 21:43:04 +01:00 committed by Peter Nelson
parent a496e9397c
commit a171939ec3
20 changed files with 793 additions and 793 deletions

View File

@ -1229,7 +1229,7 @@ static int32_t River_CalculateG(AyStar *, AyStarNode *, PathNode *)
/* AyStar callback for getting the estimated cost to the destination. */ /* AyStar callback for getting the estimated cost to the destination. */
static int32_t River_CalculateH(AyStar *aystar, AyStarNode *current, PathNode *) static int32_t River_CalculateH(AyStar *aystar, AyStarNode *current, PathNode *)
{ {
return DistanceManhattan(*(TileIndex*)aystar->user_target, current->m_tile); return DistanceManhattan(*(TileIndex*)aystar->user_target, current->tile);
} }
/* AyStar callback for getting the neighbouring nodes of the given node. */ /* AyStar callback for getting the neighbouring nodes of the given node. */
@ -1242,8 +1242,8 @@ static void River_GetNeighbours(AyStar *aystar, PathNode *current)
TileIndex t2 = tile + TileOffsByDiagDir(d); TileIndex t2 = tile + TileOffsByDiagDir(d);
if (IsValidTile(t2) && FlowsDown(tile, t2)) { if (IsValidTile(t2) && FlowsDown(tile, t2)) {
auto &neighbour = aystar->neighbours.emplace_back(); auto &neighbour = aystar->neighbours.emplace_back();
neighbour.m_tile = t2; neighbour.tile = t2;
neighbour.m_td = INVALID_TRACKDIR; neighbour.td = INVALID_TRACKDIR;
} }
} }
} }
@ -1255,7 +1255,7 @@ static void River_FoundEndNode(AyStar *aystar, PathNode *current)
/* First, build the river without worrying about its width. */ /* First, build the river without worrying about its width. */
uint cur_pos = 0; uint cur_pos = 0;
for (PathNode *path = current->m_parent; path != nullptr; path = path->m_parent, cur_pos++) { for (PathNode *path = current->parent; path != nullptr; path = path->parent, cur_pos++) {
TileIndex tile = path->GetTile(); TileIndex tile = path->GetTile();
if (!IsWaterTile(tile)) { if (!IsWaterTile(tile)) {
MakeRiverAndModifyDesertZoneAround(tile); MakeRiverAndModifyDesertZoneAround(tile);
@ -1271,14 +1271,14 @@ static void River_FoundEndNode(AyStar *aystar, PathNode *current)
uint radius; uint radius;
cur_pos = 0; cur_pos = 0;
for (PathNode *path = current->m_parent; path != nullptr; path = path->m_parent, cur_pos++) { for (PathNode *path = current->parent; path != nullptr; path = path->parent, cur_pos++) {
TileIndex tile = path->GetTile(); TileIndex tile = path->GetTile();
/* Check if we should widen river depending on how far we are away from the source. */ /* Check if we should widen river depending on how far we are away from the source. */
current_river_length = DistanceManhattan(data->spring, tile); current_river_length = DistanceManhattan(data->spring, tile);
radius = std::min(3u, (current_river_length / (long_river_length / 3u)) + 1u); radius = std::min(3u, (current_river_length / (long_river_length / 3u)) + 1u);
if (radius > 1) CircularTileSearch(&tile, radius, RiverMakeWider, (void *)&path->m_key.m_tile); if (radius > 1) CircularTileSearch(&tile, radius, RiverMakeWider, (void *)&path->key.tile);
} }
} }
} }
@ -1304,8 +1304,8 @@ static void BuildRiver(TileIndex begin, TileIndex end, TileIndex spring, bool ma
finder.user_data = &user_data; finder.user_data = &user_data;
AyStarNode start; AyStarNode start;
start.m_tile = begin; start.tile = begin;
start.m_td = INVALID_TRACKDIR; start.td = INVALID_TRACKDIR;
finder.AddStartNode(&start, 0); finder.AddStartNode(&start, 0);
finder.Main(); finder.Main();
} }

View File

@ -26,9 +26,9 @@ void AyStar::OpenListAdd(PathNode *parent, const AyStarNode *node, int f, int g)
{ {
/* Add a new Node to the OpenList */ /* Add a new Node to the OpenList */
PathNode *new_node = this->nodes.CreateNewNode(); PathNode *new_node = this->nodes.CreateNewNode();
new_node->Set(parent, node->m_tile, node->m_td, true); new_node->Set(parent, node->tile, node->td, true);
new_node->m_estimate = f; new_node->estimate = f;
new_node->m_cost = g; new_node->cost = g;
this->nodes.InsertOpenNode(*new_node); this->nodes.InsertOpenNode(*new_node);
} }
@ -48,7 +48,7 @@ void AyStar::CheckTile(AyStarNode *current, PathNode *parent)
/* There should not be given any other error-code.. */ /* There should not be given any other error-code.. */
assert(new_g >= 0); assert(new_g >= 0);
/* Add the parent g-value to the new g-value */ /* Add the parent g-value to the new g-value */
new_g += parent->m_cost; new_g += parent->cost;
if (this->max_path_cost != 0 && new_g > this->max_path_cost) return; if (this->max_path_cost != 0 && new_g > this->max_path_cost) return;
/* Calculate the h-value */ /* Calculate the h-value */
@ -60,18 +60,18 @@ void AyStar::CheckTile(AyStarNode *current, PathNode *parent)
int new_f = new_g + new_h; int new_f = new_g + new_h;
/* Get the pointer to the parent in the ClosedList (the current one is to a copy of the one in the OpenList) */ /* Get the pointer to the parent in the ClosedList (the current one is to a copy of the one in the OpenList) */
PathNode *closedlist_parent = this->nodes.FindClosedNode(parent->m_key); PathNode *closedlist_parent = this->nodes.FindClosedNode(parent->key);
/* Check if this item is already in the OpenList */ /* Check if this item is already in the OpenList */
PathNode *check = this->nodes.FindOpenNode(*current); PathNode *check = this->nodes.FindOpenNode(*current);
if (check != nullptr) { if (check != nullptr) {
/* Yes, check if this g value is lower.. */ /* Yes, check if this g value is lower.. */
if (new_g > check->m_cost) return; if (new_g > check->cost) return;
this->nodes.PopOpenNode(check->m_key); this->nodes.PopOpenNode(check->key);
/* It is lower, so change it to this item */ /* It is lower, so change it to this item */
check->m_estimate = new_f; check->estimate = new_f;
check->m_cost = new_g; check->cost = new_g;
check->m_parent = closedlist_parent; check->parent = closedlist_parent;
/* Re-add it in the openlist_queue. */ /* Re-add it in the openlist_queue. */
this->nodes.InsertOpenNode(*check); this->nodes.InsertOpenNode(*check);
} else { } else {
@ -97,7 +97,7 @@ int AyStar::Loop()
if (current == nullptr) return AYSTAR_EMPTY_OPENLIST; if (current == nullptr) return AYSTAR_EMPTY_OPENLIST;
/* Check for end node and if found, return that code */ /* Check for end node and if found, return that code */
if (this->EndNodeCheck(this, current) == AYSTAR_FOUND_END_NODE && current->m_parent != nullptr) { if (this->EndNodeCheck(this, current) == AYSTAR_FOUND_END_NODE && current->parent != nullptr) {
if (this->FoundEndNode != nullptr) { if (this->FoundEndNode != nullptr) {
this->FoundEndNode(this, current); this->FoundEndNode(this, current);
} }

View File

@ -36,19 +36,19 @@ struct CFollowTrackT
EC_RESERVED, EC_RESERVED,
}; };
const VehicleType *m_veh; ///< moving vehicle const VehicleType *veh; ///< moving vehicle
Owner m_veh_owner; ///< owner of the vehicle Owner veh_owner; ///< owner of the vehicle
TileIndex m_old_tile; ///< the origin (vehicle moved from) before move TileIndex old_tile; ///< the origin (vehicle moved from) before move
Trackdir m_old_td; ///< the trackdir (the vehicle was on) before move Trackdir old_td; ///< the trackdir (the vehicle was on) before move
TileIndex m_new_tile; ///< the new tile (the vehicle has entered) TileIndex new_tile; ///< the new tile (the vehicle has entered)
TrackdirBits m_new_td_bits; ///< the new set of available trackdirs TrackdirBits new_td_bits; ///< the new set of available trackdirs
DiagDirection m_exitdir; ///< exit direction (leaving the old tile) DiagDirection exitdir; ///< exit direction (leaving the old tile)
bool m_is_tunnel; ///< last turn passed tunnel bool is_tunnel; ///< last turn passed tunnel
bool m_is_bridge; ///< last turn passed bridge ramp bool is_bridge; ///< last turn passed bridge ramp
bool m_is_station; ///< last turn passed station bool is_station; ///< last turn passed station
int m_tiles_skipped; ///< number of skipped tunnel or station tiles int tiles_skipped; ///< number of skipped tunnel or station tiles
ErrorCode m_err; ErrorCode err;
RailTypes m_railtypes; RailTypes railtypes;
inline CFollowTrackT(const VehicleType *v = nullptr, RailTypes railtype_override = INVALID_RAILTYPES) inline CFollowTrackT(const VehicleType *v = nullptr, RailTypes railtype_override = INVALID_RAILTYPES)
{ {
@ -58,40 +58,40 @@ struct CFollowTrackT
inline CFollowTrackT(Owner o, RailTypes railtype_override = INVALID_RAILTYPES) inline CFollowTrackT(Owner o, RailTypes railtype_override = INVALID_RAILTYPES)
{ {
assert(IsRailTT()); assert(IsRailTT());
this->m_veh = nullptr; this->veh = nullptr;
Init(o, railtype_override); Init(o, railtype_override);
} }
inline void Init(const VehicleType *v, RailTypes railtype_override) inline void Init(const VehicleType *v, RailTypes railtype_override)
{ {
assert(!IsRailTT() || (v != nullptr && v->type == VEH_TRAIN)); assert(!IsRailTT() || (v != nullptr && v->type == VEH_TRAIN));
this->m_veh = v; this->veh = v;
Init(v != nullptr ? v->owner : INVALID_OWNER, IsRailTT() && railtype_override == INVALID_RAILTYPES ? Train::From(v)->compatible_railtypes : railtype_override); Init(v != nullptr ? v->owner : INVALID_OWNER, IsRailTT() && railtype_override == INVALID_RAILTYPES ? Train::From(v)->compatible_railtypes : railtype_override);
} }
inline void Init(Owner o, RailTypes railtype_override) inline void Init(Owner o, RailTypes railtype_override)
{ {
assert(!IsRoadTT() || this->m_veh != nullptr); assert(!IsRoadTT() || this->veh != nullptr);
assert(!IsRailTT() || railtype_override != INVALID_RAILTYPES); assert(!IsRailTT() || railtype_override != INVALID_RAILTYPES);
this->m_veh_owner = o; this->veh_owner = o;
/* don't worry, all is inlined so compiler should remove unnecessary initializations */ /* don't worry, all is inlined so compiler should remove unnecessary initializations */
this->m_old_tile = INVALID_TILE; this->old_tile = INVALID_TILE;
this->m_old_td = INVALID_TRACKDIR; this->old_td = INVALID_TRACKDIR;
this->m_new_tile = INVALID_TILE; this->new_tile = INVALID_TILE;
this->m_new_td_bits = TRACKDIR_BIT_NONE; this->new_td_bits = TRACKDIR_BIT_NONE;
this->m_exitdir = INVALID_DIAGDIR; this->exitdir = INVALID_DIAGDIR;
this->m_is_station = false; this->is_station = false;
this->m_is_bridge = false; this->is_bridge = false;
this->m_is_tunnel = false; this->is_tunnel = false;
this->m_tiles_skipped = 0; this->tiles_skipped = 0;
this->m_err = EC_NONE; this->err = EC_NONE;
this->m_railtypes = railtype_override; this->railtypes = railtype_override;
} }
debug_inline static TransportType TT() { return Ttr_type_; } debug_inline static TransportType TT() { return Ttr_type_; }
debug_inline static bool IsWaterTT() { return TT() == TRANSPORT_WATER; } debug_inline static bool IsWaterTT() { return TT() == TRANSPORT_WATER; }
debug_inline static bool IsRailTT() { return TT() == TRANSPORT_RAIL; } debug_inline static bool IsRailTT() { return TT() == TRANSPORT_RAIL; }
inline bool IsTram() { return IsRoadTT() && RoadTypeIsTram(RoadVehicle::From(this->m_veh)->roadtype); } inline bool IsTram() { return IsRoadTT() && RoadTypeIsTram(RoadVehicle::From(this->veh)->roadtype); }
debug_inline static bool IsRoadTT() { return TT() == TRANSPORT_ROAD; } debug_inline static bool IsRoadTT() { return TT() == TRANSPORT_ROAD; }
inline static bool Allow90degTurns() { return T90deg_turns_allowed_; } inline static bool Allow90degTurns() { return T90deg_turns_allowed_; }
inline static bool DoTrackMasking() { return Tmask_reserved_tracks; } inline static bool DoTrackMasking() { return Tmask_reserved_tracks; }
@ -120,24 +120,24 @@ struct CFollowTrackT
*/ */
inline bool Follow(TileIndex old_tile, Trackdir old_td) inline bool Follow(TileIndex old_tile, Trackdir old_td)
{ {
this->m_old_tile = old_tile; this->old_tile = old_tile;
this->m_old_td = old_td; this->old_td = old_td;
this->m_err = EC_NONE; this->err = EC_NONE;
assert([&]() { assert([&]() {
if (this->IsTram() && this->GetSingleTramBit(this->m_old_tile) != INVALID_DIAGDIR) return true; // Skip the check for single tram bits if (this->IsTram() && this->GetSingleTramBit(this->old_tile) != INVALID_DIAGDIR) return true; // Skip the check for single tram bits
const uint sub_mode = (IsRoadTT() && this->m_veh != nullptr) ? (this->IsTram() ? RTT_TRAM : RTT_ROAD) : 0; const uint sub_mode = (IsRoadTT() && this->veh != nullptr) ? (this->IsTram() ? RTT_TRAM : RTT_ROAD) : 0;
const TrackdirBits old_tile_valid_dirs = TrackStatusToTrackdirBits(GetTileTrackStatus(this->m_old_tile, TT(), sub_mode)); const TrackdirBits old_tile_valid_dirs = TrackStatusToTrackdirBits(GetTileTrackStatus(this->old_tile, TT(), sub_mode));
return (old_tile_valid_dirs & TrackdirToTrackdirBits(this->m_old_td)) != TRACKDIR_BIT_NONE; return (old_tile_valid_dirs & TrackdirToTrackdirBits(this->old_td)) != TRACKDIR_BIT_NONE;
}()); }());
this->m_exitdir = TrackdirToExitdir(this->m_old_td); this->exitdir = TrackdirToExitdir(this->old_td);
if (this->ForcedReverse()) return true; if (this->ForcedReverse()) return true;
if (!this->CanExitOldTile()) return false; if (!this->CanExitOldTile()) return false;
this->FollowTileExit(); this->FollowTileExit();
if (!this->QueryNewTileTrackStatus()) return TryReverse(); if (!this->QueryNewTileTrackStatus()) return TryReverse();
this->m_new_td_bits &= DiagdirReachesTrackdirs(this->m_exitdir); this->new_td_bits &= DiagdirReachesTrackdirs(this->exitdir);
if (this->m_new_td_bits == TRACKDIR_BIT_NONE || !this->CanEnterNewTile()) { if (this->new_td_bits == TRACKDIR_BIT_NONE || !this->CanEnterNewTile()) {
/* In case we can't enter the next tile, but are /* In case we can't enter the next tile, but are
* a normal road vehicle, then we can actually * a normal road vehicle, then we can actually
* try to reverse as this is the end of the road. * try to reverse as this is the end of the road.
@ -154,14 +154,14 @@ struct CFollowTrackT
/* CanEnterNewTile already set a reason. /* CanEnterNewTile already set a reason.
* Do NOT overwrite it (important for example for EC_RAIL_ROAD_TYPE). * Do NOT overwrite it (important for example for EC_RAIL_ROAD_TYPE).
* Only set a reason if CanEnterNewTile was not called */ * Only set a reason if CanEnterNewTile was not called */
if (this->m_new_td_bits == TRACKDIR_BIT_NONE) this->m_err = EC_NO_WAY; if (this->new_td_bits == TRACKDIR_BIT_NONE) this->err = EC_NO_WAY;
return false; return false;
} }
if ((!IsRailTT() && !Allow90degTurns()) || (IsRailTT() && Rail90DegTurnDisallowed(GetTileRailType(this->m_old_tile), GetTileRailType(this->m_new_tile), !Allow90degTurns()))) { if ((!IsRailTT() && !Allow90degTurns()) || (IsRailTT() && Rail90DegTurnDisallowed(GetTileRailType(this->old_tile), GetTileRailType(this->new_tile), !Allow90degTurns()))) {
this->m_new_td_bits &= (TrackdirBits)~(int)TrackdirCrossesTrackdirs(this->m_old_td); this->new_td_bits &= (TrackdirBits)~(int)TrackdirCrossesTrackdirs(this->old_td);
if (this->m_new_td_bits == TRACKDIR_BIT_NONE) { if (this->new_td_bits == TRACKDIR_BIT_NONE) {
this->m_err = EC_90DEG; this->err = EC_90DEG;
return false; return false;
} }
} }
@ -172,200 +172,200 @@ struct CFollowTrackT
{ {
if (!DoTrackMasking()) return true; if (!DoTrackMasking()) return true;
if (this->m_is_station) { if (this->is_station) {
/* Check skipped station tiles as well. */ /* Check skipped station tiles as well. */
TileIndexDiff diff = TileOffsByDiagDir(this->m_exitdir); TileIndexDiff diff = TileOffsByDiagDir(this->exitdir);
for (TileIndex tile = this->m_new_tile - diff * this->m_tiles_skipped; tile != this->m_new_tile; tile += diff) { for (TileIndex tile = this->new_tile - diff * this->tiles_skipped; tile != this->new_tile; tile += diff) {
if (HasStationReservation(tile)) { if (HasStationReservation(tile)) {
this->m_new_td_bits = TRACKDIR_BIT_NONE; this->new_td_bits = TRACKDIR_BIT_NONE;
this->m_err = EC_RESERVED; this->err = EC_RESERVED;
return false; return false;
} }
} }
} }
TrackBits reserved = GetReservedTrackbits(this->m_new_tile); TrackBits reserved = GetReservedTrackbits(this->new_tile);
/* Mask already reserved trackdirs. */ /* Mask already reserved trackdirs. */
this->m_new_td_bits &= ~TrackBitsToTrackdirBits(reserved); this->new_td_bits &= ~TrackBitsToTrackdirBits(reserved);
/* Mask out all trackdirs that conflict with the reservation. */ /* Mask out all trackdirs that conflict with the reservation. */
for (Track t : SetTrackBitIterator(TrackdirBitsToTrackBits(this->m_new_td_bits))) { for (Track t : SetTrackBitIterator(TrackdirBitsToTrackBits(this->new_td_bits))) {
if (TracksOverlap(reserved | TrackToTrackBits(t))) this->m_new_td_bits &= ~TrackToTrackdirBits(t); if (TracksOverlap(reserved | TrackToTrackBits(t))) this->new_td_bits &= ~TrackToTrackdirBits(t);
} }
if (this->m_new_td_bits == TRACKDIR_BIT_NONE) { if (this->new_td_bits == TRACKDIR_BIT_NONE) {
this->m_err = EC_RESERVED; this->err = EC_RESERVED;
return false; return false;
} }
return true; return true;
} }
protected: protected:
/** Follow the m_exitdir from m_old_tile and fill m_new_tile and m_tiles_skipped */ /** Follow the exitdir from old_tile and fill new_tile and tiles_skipped */
inline void FollowTileExit() inline void FollowTileExit()
{ {
this->m_is_station = false; this->is_station = false;
this->m_is_bridge = false; this->is_bridge = false;
this->m_is_tunnel = false; this->is_tunnel = false;
this->m_tiles_skipped = 0; this->tiles_skipped = 0;
/* extra handling for tunnels and bridges in our direction */ /* extra handling for tunnels and bridges in our direction */
if (IsTileType(this->m_old_tile, MP_TUNNELBRIDGE)) { if (IsTileType(this->old_tile, MP_TUNNELBRIDGE)) {
DiagDirection enterdir = GetTunnelBridgeDirection(this->m_old_tile); DiagDirection enterdir = GetTunnelBridgeDirection(this->old_tile);
if (enterdir == this->m_exitdir) { if (enterdir == this->exitdir) {
/* we are entering the tunnel / bridge */ /* we are entering the tunnel / bridge */
if (IsTunnel(this->m_old_tile)) { if (IsTunnel(this->old_tile)) {
this->m_is_tunnel = true; this->is_tunnel = true;
this->m_new_tile = GetOtherTunnelEnd(this->m_old_tile); this->new_tile = GetOtherTunnelEnd(this->old_tile);
} else { // IsBridge(m_old_tile) } else { // IsBridge(old_tile)
this->m_is_bridge = true; this->is_bridge = true;
this->m_new_tile = GetOtherBridgeEnd(this->m_old_tile); this->new_tile = GetOtherBridgeEnd(this->old_tile);
} }
this->m_tiles_skipped = GetTunnelBridgeLength(this->m_new_tile, this->m_old_tile); this->tiles_skipped = GetTunnelBridgeLength(this->new_tile, this->old_tile);
return; return;
} }
assert(ReverseDiagDir(enterdir) == this->m_exitdir); assert(ReverseDiagDir(enterdir) == this->exitdir);
} }
/* normal or station tile, do one step */ /* normal or station tile, do one step */
this->m_new_tile = TileAddByDiagDir(this->m_old_tile, this->m_exitdir); this->new_tile = TileAddByDiagDir(this->old_tile, this->exitdir);
/* special handling for stations */ /* special handling for stations */
if (IsRailTT() && HasStationTileRail(this->m_new_tile)) { if (IsRailTT() && HasStationTileRail(this->new_tile)) {
this->m_is_station = true; this->is_station = true;
} else if (IsRoadTT() && IsStationRoadStopTile(this->m_new_tile)) { } else if (IsRoadTT() && IsStationRoadStopTile(this->new_tile)) {
this->m_is_station = true; this->is_station = true;
} }
} }
/** stores track status (available trackdirs) for the new tile into m_new_td_bits */ /** stores track status (available trackdirs) for the new tile into new_td_bits */
inline bool QueryNewTileTrackStatus() inline bool QueryNewTileTrackStatus()
{ {
if (IsRailTT() && IsPlainRailTile(this->m_new_tile)) { if (IsRailTT() && IsPlainRailTile(this->new_tile)) {
this->m_new_td_bits = (TrackdirBits)(GetTrackBits(this->m_new_tile) * 0x101); this->new_td_bits = (TrackdirBits)(GetTrackBits(this->new_tile) * 0x101);
} else if (IsRoadTT()) { } else if (IsRoadTT()) {
this->m_new_td_bits = GetTrackdirBitsForRoad(this->m_new_tile, this->IsTram() ? RTT_TRAM : RTT_ROAD); this->new_td_bits = GetTrackdirBitsForRoad(this->new_tile, this->IsTram() ? RTT_TRAM : RTT_ROAD);
} else { } else {
this->m_new_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(this->m_new_tile, TT(), 0)); this->new_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(this->new_tile, TT(), 0));
} }
return (this->m_new_td_bits != TRACKDIR_BIT_NONE); return (this->new_td_bits != TRACKDIR_BIT_NONE);
} }
/** return true if we can leave m_old_tile in m_exitdir */ /** return true if we can leave old_tile in exitdir */
inline bool CanExitOldTile() inline bool CanExitOldTile()
{ {
/* road stop can be left at one direction only unless it's a drive-through stop */ /* road stop can be left at one direction only unless it's a drive-through stop */
if (IsRoadTT() && IsBayRoadStopTile(this->m_old_tile)) { if (IsRoadTT() && IsBayRoadStopTile(this->old_tile)) {
DiagDirection exitdir = GetBayRoadStopDir(this->m_old_tile); DiagDirection exitdir = GetBayRoadStopDir(this->old_tile);
if (exitdir != this->m_exitdir) { if (exitdir != this->exitdir) {
this->m_err = EC_NO_WAY; this->err = EC_NO_WAY;
return false; return false;
} }
} }
/* single tram bits can only be left in one direction */ /* single tram bits can only be left in one direction */
if (this->IsTram()) { if (this->IsTram()) {
DiagDirection single_tram = GetSingleTramBit(this->m_old_tile); DiagDirection single_tram = GetSingleTramBit(this->old_tile);
if (single_tram != INVALID_DIAGDIR && single_tram != this->m_exitdir) { if (single_tram != INVALID_DIAGDIR && single_tram != this->exitdir) {
this->m_err = EC_NO_WAY; this->err = EC_NO_WAY;
return false; return false;
} }
} }
/* road depots can be also left in one direction only */ /* road depots can be also left in one direction only */
if (IsRoadTT() && IsDepotTypeTile(this->m_old_tile, TT())) { if (IsRoadTT() && IsDepotTypeTile(this->old_tile, TT())) {
DiagDirection exitdir = GetRoadDepotDirection(this->m_old_tile); DiagDirection exitdir = GetRoadDepotDirection(this->old_tile);
if (exitdir != this->m_exitdir) { if (exitdir != this->exitdir) {
this->m_err = EC_NO_WAY; this->err = EC_NO_WAY;
return false; return false;
} }
} }
return true; return true;
} }
/** return true if we can enter m_new_tile from m_exitdir */ /** return true if we can enter new_tile from exitdir */
inline bool CanEnterNewTile() inline bool CanEnterNewTile()
{ {
if (IsRoadTT() && IsBayRoadStopTile(this->m_new_tile)) { if (IsRoadTT() && IsBayRoadStopTile(this->new_tile)) {
/* road stop can be entered from one direction only unless it's a drive-through stop */ /* road stop can be entered from one direction only unless it's a drive-through stop */
DiagDirection exitdir = GetBayRoadStopDir(this->m_new_tile); DiagDirection exitdir = GetBayRoadStopDir(this->new_tile);
if (ReverseDiagDir(exitdir) != this->m_exitdir) { if (ReverseDiagDir(exitdir) != this->exitdir) {
this->m_err = EC_NO_WAY; this->err = EC_NO_WAY;
return false; return false;
} }
} }
/* single tram bits can only be entered from one direction */ /* single tram bits can only be entered from one direction */
if (this->IsTram()) { if (this->IsTram()) {
DiagDirection single_tram = this->GetSingleTramBit(this->m_new_tile); DiagDirection single_tram = this->GetSingleTramBit(this->new_tile);
if (single_tram != INVALID_DIAGDIR && single_tram != ReverseDiagDir(this->m_exitdir)) { if (single_tram != INVALID_DIAGDIR && single_tram != ReverseDiagDir(this->exitdir)) {
this->m_err = EC_NO_WAY; this->err = EC_NO_WAY;
return false; return false;
} }
} }
/* road and rail depots can also be entered from one direction only */ /* road and rail depots can also be entered from one direction only */
if (IsRoadTT() && IsDepotTypeTile(this->m_new_tile, TT())) { if (IsRoadTT() && IsDepotTypeTile(this->new_tile, TT())) {
DiagDirection exitdir = GetRoadDepotDirection(this->m_new_tile); DiagDirection exitdir = GetRoadDepotDirection(this->new_tile);
if (ReverseDiagDir(exitdir) != this->m_exitdir) { if (ReverseDiagDir(exitdir) != this->exitdir) {
this->m_err = EC_NO_WAY; this->err = EC_NO_WAY;
return false; return false;
} }
/* don't try to enter other company's depots */ /* don't try to enter other company's depots */
if (GetTileOwner(this->m_new_tile) != this->m_veh_owner) { if (GetTileOwner(this->new_tile) != this->veh_owner) {
this->m_err = EC_OWNER; this->err = EC_OWNER;
return false; return false;
} }
} }
if (IsRailTT() && IsDepotTypeTile(this->m_new_tile, TT())) { if (IsRailTT() && IsDepotTypeTile(this->new_tile, TT())) {
DiagDirection exitdir = GetRailDepotDirection(this->m_new_tile); DiagDirection exitdir = GetRailDepotDirection(this->new_tile);
if (ReverseDiagDir(exitdir) != this->m_exitdir) { if (ReverseDiagDir(exitdir) != this->exitdir) {
this->m_err = EC_NO_WAY; this->err = EC_NO_WAY;
return false; return false;
} }
} }
/* rail transport is possible only on tiles with the same owner as vehicle */ /* rail transport is possible only on tiles with the same owner as vehicle */
if (IsRailTT() && GetTileOwner(this->m_new_tile) != this->m_veh_owner) { if (IsRailTT() && GetTileOwner(this->new_tile) != this->veh_owner) {
/* different owner */ /* different owner */
this->m_err = EC_NO_WAY; this->err = EC_NO_WAY;
return false; return false;
} }
/* rail transport is possible only on compatible rail types */ /* rail transport is possible only on compatible rail types */
if (IsRailTT()) { if (IsRailTT()) {
RailType rail_type = GetTileRailType(this->m_new_tile); RailType rail_type = GetTileRailType(this->new_tile);
if (!HasBit(this->m_railtypes, rail_type)) { if (!HasBit(this->railtypes, rail_type)) {
/* incompatible rail type */ /* incompatible rail type */
this->m_err = EC_RAIL_ROAD_TYPE; this->err = EC_RAIL_ROAD_TYPE;
return false; return false;
} }
} }
/* road transport is possible only on compatible road types */ /* road transport is possible only on compatible road types */
if (IsRoadTT()) { if (IsRoadTT()) {
const RoadVehicle *v = RoadVehicle::From(this->m_veh); const RoadVehicle *v = RoadVehicle::From(this->veh);
RoadType roadtype = GetRoadType(this->m_new_tile, GetRoadTramType(v->roadtype)); RoadType roadtype = GetRoadType(this->new_tile, GetRoadTramType(v->roadtype));
if (!HasBit(v->compatible_roadtypes, roadtype)) { if (!HasBit(v->compatible_roadtypes, roadtype)) {
/* incompatible road type */ /* incompatible road type */
this->m_err = EC_RAIL_ROAD_TYPE; this->err = EC_RAIL_ROAD_TYPE;
return false; return false;
} }
} }
/* tunnel holes and bridge ramps can be entered only from proper direction */ /* tunnel holes and bridge ramps can be entered only from proper direction */
if (IsTileType(this->m_new_tile, MP_TUNNELBRIDGE)) { if (IsTileType(this->new_tile, MP_TUNNELBRIDGE)) {
if (IsTunnel(this->m_new_tile)) { if (IsTunnel(this->new_tile)) {
if (!this->m_is_tunnel) { if (!this->is_tunnel) {
DiagDirection tunnel_enterdir = GetTunnelBridgeDirection(this->m_new_tile); DiagDirection tunnel_enterdir = GetTunnelBridgeDirection(this->new_tile);
if (tunnel_enterdir != this->m_exitdir) { if (tunnel_enterdir != this->exitdir) {
this->m_err = EC_NO_WAY; this->err = EC_NO_WAY;
return false; return false;
} }
} }
} else { // IsBridge(m_new_tile) } else { // IsBridge(new_tile)
if (!this->m_is_bridge) { if (!this->is_bridge) {
DiagDirection ramp_enderdir = GetTunnelBridgeDirection(this->m_new_tile); DiagDirection ramp_enderdir = GetTunnelBridgeDirection(this->new_tile);
if (ramp_enderdir != this->m_exitdir) { if (ramp_enderdir != this->exitdir) {
this->m_err = EC_NO_WAY; this->err = EC_NO_WAY;
return false; return false;
} }
} }
@ -373,16 +373,16 @@ protected:
} }
/* special handling for rail stations - get to the end of platform */ /* special handling for rail stations - get to the end of platform */
if (IsRailTT() && this->m_is_station) { if (IsRailTT() && this->is_station) {
/* entered railway station /* entered railway station
* get platform length */ * get platform length */
uint length = BaseStation::GetByTile(this->m_new_tile)->GetPlatformLength(this->m_new_tile, TrackdirToExitdir(this->m_old_td)); uint length = BaseStation::GetByTile(this->new_tile)->GetPlatformLength(this->new_tile, TrackdirToExitdir(this->old_td));
/* how big step we must do to get to the last platform tile? */ /* how big step we must do to get to the last platform tile? */
this->m_tiles_skipped = length - 1; this->tiles_skipped = length - 1;
/* move to the platform end */ /* move to the platform end */
TileIndexDiff diff = TileOffsByDiagDir(this->m_exitdir); TileIndexDiff diff = TileOffsByDiagDir(this->exitdir);
diff *= this->m_tiles_skipped; diff *= this->tiles_skipped;
this->m_new_tile = TileAdd(this->m_new_tile, diff); this->new_tile = TileAdd(this->new_tile, diff);
return true; return true;
} }
@ -393,32 +393,32 @@ protected:
inline bool ForcedReverse() inline bool ForcedReverse()
{ {
/* rail and road depots cause reversing */ /* rail and road depots cause reversing */
if (!IsWaterTT() && IsDepotTypeTile(this->m_old_tile, TT())) { if (!IsWaterTT() && IsDepotTypeTile(this->old_tile, TT())) {
DiagDirection exitdir = IsRailTT() ? GetRailDepotDirection(this->m_old_tile) : GetRoadDepotDirection(this->m_old_tile); DiagDirection exitdir = IsRailTT() ? GetRailDepotDirection(this->old_tile) : GetRoadDepotDirection(this->old_tile);
if (exitdir != this->m_exitdir) { if (exitdir != this->exitdir) {
/* reverse */ /* reverse */
this->m_new_tile = this->m_old_tile; this->new_tile = this->old_tile;
this->m_new_td_bits = TrackdirToTrackdirBits(ReverseTrackdir(this->m_old_td)); this->new_td_bits = TrackdirToTrackdirBits(ReverseTrackdir(this->old_td));
this->m_exitdir = exitdir; this->exitdir = exitdir;
this->m_tiles_skipped = 0; this->tiles_skipped = 0;
this->m_is_tunnel = false; this->is_tunnel = false;
this->m_is_bridge = false; this->is_bridge = false;
this->m_is_station = false; this->is_station = false;
return true; return true;
} }
} }
/* Single tram bits and standard road stops cause reversing. */ /* Single tram bits and standard road stops cause reversing. */
if (IsRoadTT() && ((this->IsTram() && GetSingleTramBit(this->m_old_tile) == ReverseDiagDir(this->m_exitdir)) || if (IsRoadTT() && ((this->IsTram() && GetSingleTramBit(this->old_tile) == ReverseDiagDir(this->exitdir)) ||
(IsBayRoadStopTile(this->m_old_tile) && GetBayRoadStopDir(this->m_old_tile) == ReverseDiagDir(this->m_exitdir)))) { (IsBayRoadStopTile(this->old_tile) && GetBayRoadStopDir(this->old_tile) == ReverseDiagDir(this->exitdir)))) {
/* reverse */ /* reverse */
this->m_new_tile = this->m_old_tile; this->new_tile = this->old_tile;
this->m_new_td_bits = TrackdirToTrackdirBits(ReverseTrackdir(this->m_old_td)); this->new_td_bits = TrackdirToTrackdirBits(ReverseTrackdir(this->old_td));
this->m_exitdir = ReverseDiagDir(this->m_exitdir); this->exitdir = ReverseDiagDir(this->exitdir);
this->m_tiles_skipped = 0; this->tiles_skipped = 0;
this->m_is_tunnel = false; this->is_tunnel = false;
this->m_is_bridge = false; this->is_bridge = false;
this->m_is_station = false; this->is_station = false;
return true; return true;
} }
@ -430,42 +430,42 @@ protected:
{ {
if (IsRoadTT() && !this->IsTram()) { if (IsRoadTT() && !this->IsTram()) {
/* if we reached the end of road, we can reverse the RV and continue moving */ /* if we reached the end of road, we can reverse the RV and continue moving */
this->m_exitdir = ReverseDiagDir(this->m_exitdir); this->exitdir = ReverseDiagDir(this->exitdir);
/* new tile will be the same as old one */ /* new tile will be the same as old one */
this->m_new_tile = this->m_old_tile; this->new_tile = this->old_tile;
/* set new trackdir bits to all reachable trackdirs */ /* set new trackdir bits to all reachable trackdirs */
QueryNewTileTrackStatus(); QueryNewTileTrackStatus();
this->m_new_td_bits &= DiagdirReachesTrackdirs(this->m_exitdir); this->new_td_bits &= DiagdirReachesTrackdirs(this->exitdir);
if (this->m_new_td_bits != TRACKDIR_BIT_NONE) { if (this->new_td_bits != TRACKDIR_BIT_NONE) {
/* we have some trackdirs reachable after reversal */ /* we have some trackdirs reachable after reversal */
return true; return true;
} }
} }
this->m_err = EC_NO_WAY; this->err = EC_NO_WAY;
return false; return false;
} }
public: public:
/** Helper for pathfinders - get min/max speed on the m_old_tile/m_old_td */ /** Helper for pathfinders - get min/max speed on the old_tile/old_td */
int GetSpeedLimit(int *pmin_speed = nullptr) const int GetSpeedLimit(int *pmin_speed = nullptr) const
{ {
int min_speed = 0; int min_speed = 0;
int max_speed = INT_MAX; // no limit int max_speed = INT_MAX; // no limit
/* Check for on-bridge speed limit */ /* Check for on-bridge speed limit */
if (!IsWaterTT() && IsBridgeTile(this->m_old_tile)) { if (!IsWaterTT() && IsBridgeTile(this->old_tile)) {
int spd = GetBridgeSpec(GetBridgeType(this->m_old_tile))->speed; int spd = GetBridgeSpec(GetBridgeType(this->old_tile))->speed;
if (IsRoadTT()) spd *= 2; if (IsRoadTT()) spd *= 2;
max_speed = std::min(max_speed, spd); max_speed = std::min(max_speed, spd);
} }
/* Check for speed limit imposed by railtype */ /* Check for speed limit imposed by railtype */
if (IsRailTT()) { if (IsRailTT()) {
uint16_t rail_speed = GetRailTypeInfo(GetRailType(this->m_old_tile))->max_speed; uint16_t rail_speed = GetRailTypeInfo(GetRailType(this->old_tile))->max_speed;
if (rail_speed > 0) max_speed = std::min<int>(max_speed, rail_speed); if (rail_speed > 0) max_speed = std::min<int>(max_speed, rail_speed);
} }
if (IsRoadTT()) { if (IsRoadTT()) {
/* max_speed is already in roadvehicle units, no need to further modify (divide by 2) */ /* max_speed is already in roadvehicle units, no need to further modify (divide by 2) */
uint16_t road_speed = GetRoadTypeInfo(GetRoadType(this->m_old_tile, GetRoadTramType(RoadVehicle::From(this->m_veh)->roadtype)))->max_speed; uint16_t road_speed = GetRoadTypeInfo(GetRoadType(this->old_tile, GetRoadTramType(RoadVehicle::From(this->veh)->roadtype)))->max_speed;
if (road_speed > 0) max_speed = std::min<int>(max_speed, road_speed); if (road_speed > 0) max_speed = std::min<int>(max_speed, road_speed);
} }

View File

@ -165,11 +165,11 @@ public:
/* By using a TrackFollower we "play by the same rules" as the actual ship pathfinder */ /* By using a TrackFollower we "play by the same rules" as the actual ship pathfinder */
CFollowTrackWater ft; CFollowTrackWater ft;
if (ft.Follow(tile, dir)) { if (ft.Follow(tile, dir)) {
if (this->tile_area.Contains(ft.m_new_tile)) { if (this->tile_area.Contains(ft.new_tile)) {
tiles_to_check.push_back(ft.m_new_tile); tiles_to_check.push_back(ft.new_tile);
} else if (!ft.m_is_bridge) { } else if (!ft.is_bridge) {
assert(DistanceManhattan(ft.m_new_tile, tile) == 1); assert(DistanceManhattan(ft.new_tile, tile) == 1);
const auto side = DiagdirBetweenTiles(tile, ft.m_new_tile); const auto side = DiagdirBetweenTiles(tile, ft.new_tile);
const int local_x_or_y = DiagDirToAxis(side) == AXIS_X ? TileY(tile) - TileY(this->tile_area.tile) : TileX(tile) - TileX(this->tile_area.tile); const int local_x_or_y = DiagDirToAxis(side) == AXIS_X ? TileY(tile) - TileY(this->tile_area.tile) : TileX(tile) - TileX(this->tile_area.tile);
SetBit(this->data.edge_traversability_bits[side], local_x_or_y); SetBit(this->data.edge_traversability_bits[side], local_x_or_y);
} else { } else {

View File

@ -29,17 +29,17 @@ public:
typedef CBinaryHeapT<Titem_> CPriorityQueue; ///< How the priority queue will be managed. typedef CBinaryHeapT<Titem_> CPriorityQueue; ///< How the priority queue will be managed.
protected: protected:
CItemArray m_arr; ///< Here we store full item data (Titem_). CItemArray items; ///< Here we store full item data (Titem_).
COpenList m_open; ///< Hash table of pointers to open item data. COpenList open_nodes; ///< Hash table of pointers to open item data.
CClosedList m_closed; ///< Hash table of pointers to closed item data. CClosedList closed_nodes; ///< Hash table of pointers to closed item data.
CPriorityQueue m_open_queue; ///< Priority queue of pointers to open item data. CPriorityQueue open_queue; ///< Priority queue of pointers to open item data.
Titem *m_new_node; ///< New open node under construction. Titem *new_node; ///< New open node under construction.
public: public:
/** default constructor */ /** default constructor */
CNodeList_HashTableT() : m_open_queue(2048) CNodeList_HashTableT() : open_queue(2048)
{ {
this->m_new_node = nullptr; this->new_node = nullptr;
} }
/** destructor */ /** destructor */
@ -50,28 +50,28 @@ public:
/** return number of open nodes */ /** return number of open nodes */
inline int OpenCount() inline int OpenCount()
{ {
return this->m_open.Count(); return this->open_nodes.Count();
} }
/** return number of closed nodes */ /** return number of closed nodes */
inline int ClosedCount() inline int ClosedCount()
{ {
return this->m_closed.Count(); return this->closed_nodes.Count();
} }
/** allocate new data item from m_arr */ /** allocate new data item from items */
inline Titem_ *CreateNewNode() inline Titem_ *CreateNewNode()
{ {
if (this->m_new_node == nullptr) this->m_new_node = &this->m_arr.emplace_back(); if (this->new_node == nullptr) this->new_node = &this->items.emplace_back();
return this->m_new_node; return this->new_node;
} }
/** Notify the nodelist that we don't want to discard the given node. */ /** Notify the nodelist that we don't want to discard the given node. */
inline void FoundBestNode(Titem_ &item) inline void FoundBestNode(Titem_ &item)
{ {
/* for now it is enough to invalidate m_new_node if it is our given node */ /* for now it is enough to invalidate m_new_node if it is our given node */
if (&item == this->m_new_node) { if (&item == this->new_node) {
this->m_new_node = nullptr; this->new_node = nullptr;
} }
/* TODO: do we need to store best nodes found in some extra list/array? Probably not now. */ /* TODO: do we need to store best nodes found in some extra list/array? Probably not now. */
} }
@ -79,19 +79,19 @@ public:
/** insert given item as open node (into m_open and m_open_queue) */ /** insert given item as open node (into m_open and m_open_queue) */
inline void InsertOpenNode(Titem_ &item) inline void InsertOpenNode(Titem_ &item)
{ {
assert(this->m_closed.Find(item.GetKey()) == nullptr); assert(this->closed_nodes.Find(item.GetKey()) == nullptr);
this->m_open.Push(item); this->open_nodes.Push(item);
this->m_open_queue.Include(&item); this->open_queue.Include(&item);
if (&item == this->m_new_node) { if (&item == this->new_node) {
this->m_new_node = nullptr; this->new_node = nullptr;
} }
} }
/** return the best open node */ /** return the best open node */
inline Titem_ *GetBestOpenNode() inline Titem_ *GetBestOpenNode()
{ {
if (!this->m_open_queue.IsEmpty()) { if (!this->open_queue.IsEmpty()) {
return this->m_open_queue.Begin(); return this->open_queue.Begin();
} }
return nullptr; return nullptr;
} }
@ -99,9 +99,9 @@ public:
/** remove and return the best open node */ /** remove and return the best open node */
inline Titem_ *PopBestOpenNode() inline Titem_ *PopBestOpenNode()
{ {
if (!this->m_open_queue.IsEmpty()) { if (!this->open_queue.IsEmpty()) {
Titem_ *item = this->m_open_queue.Shift(); Titem_ *item = this->open_queue.Shift();
this->m_open.Pop(*item); this->open_nodes.Pop(*item);
return item; return item;
} }
return nullptr; return nullptr;
@ -110,49 +110,49 @@ public:
/** return the open node specified by a key or nullptr if not found */ /** return the open node specified by a key or nullptr if not found */
inline Titem_ *FindOpenNode(const Key &key) inline Titem_ *FindOpenNode(const Key &key)
{ {
Titem_ *item = this->m_open.Find(key); Titem_ *item = this->open_nodes.Find(key);
return item; return item;
} }
/** remove and return the open node specified by a key */ /** remove and return the open node specified by a key */
inline Titem_ &PopOpenNode(const Key &key) inline Titem_ &PopOpenNode(const Key &key)
{ {
Titem_ &item = this->m_open.Pop(key); Titem_ &item = this->open_nodes.Pop(key);
size_t idxPop = this->m_open_queue.FindIndex(item); size_t idxPop = this->open_queue.FindIndex(item);
this->m_open_queue.Remove(idxPop); this->open_queue.Remove(idxPop);
return item; return item;
} }
/** close node */ /** close node */
inline void InsertClosedNode(Titem_ &item) inline void InsertClosedNode(Titem_ &item)
{ {
assert(this->m_open.Find(item.GetKey()) == nullptr); assert(this->open_nodes.Find(item.GetKey()) == nullptr);
this->m_closed.Push(item); this->closed_nodes.Push(item);
} }
/** return the closed node specified by a key or nullptr if not found */ /** return the closed node specified by a key or nullptr if not found */
inline Titem_ *FindClosedNode(const Key &key) inline Titem_ *FindClosedNode(const Key &key)
{ {
Titem_ *item = this->m_closed.Find(key); Titem_ *item = this->closed_nodes.Find(key);
return item; return item;
} }
/** The number of items. */ /** The number of items. */
inline int TotalCount() inline int TotalCount()
{ {
return this->m_arr.Length(); return this->items.Length();
} }
/** Get a particular item. */ /** Get a particular item. */
inline Titem_ &ItemAt(int idx) inline Titem_ &ItemAt(int idx)
{ {
return this->m_arr[idx]; return this->items[idx];
} }
/** Helper for creating output of this array. */ /** Helper for creating output of this array. */
template <class D> void Dump(D &dmp) const template <class D> void Dump(D &dmp) const
{ {
dmp.WriteStructT("m_arr", &this->m_arr); dmp.WriteStructT("data", &this->items);
} }
}; };

View File

@ -56,24 +56,24 @@ public:
typedef typename Node::Key Key; ///< key to hash tables typedef typename Node::Key Key; ///< key to hash tables
NodeList m_nodes; ///< node list multi-container NodeList nodes; ///< node list multi-container
protected: protected:
Node *m_pBestDestNode = nullptr; ///< pointer to the destination node found at last round Node *best_dest_node = nullptr; ///< pointer to the destination node found at last round
Node *m_pBestIntermediateNode = nullptr; ///< here should be node closest to the destination if path not found Node *best_intermediate_node = nullptr; ///< here should be node closest to the destination if path not found
const YAPFSettings *m_settings; ///< current settings (_settings_game.yapf) const YAPFSettings *settings; ///< current settings (_settings_game.yapf)
int m_max_search_nodes; ///< maximum number of nodes we are allowed to visit before we give up int max_search_nodes; ///< maximum number of nodes we are allowed to visit before we give up
const VehicleType *m_veh = nullptr; ///< vehicle that we are trying to drive const VehicleType *vehicle = nullptr; ///< vehicle that we are trying to drive
int m_stats_cost_calcs = 0; ///< stats - how many node's costs were calculated int stats_cost_calcs = 0; ///< stats - how many node's costs were calculated
int m_stats_cache_hits = 0; ///< stats - how many node's costs were reused from cache int stats_cache_hits = 0; ///< stats - how many node's costs were reused from cache
public: public:
int m_num_steps = 0; ///< this is there for debugging purposes (hope it doesn't hurt) int num_steps = 0; ///< this is there for debugging purposes (hope it doesn't hurt)
public: public:
/** default constructor */ /** default constructor */
inline CYapfBaseT() : m_settings(&_settings_game.pf.yapf), m_max_search_nodes(PfGetSettings().max_search_nodes) {} inline CYapfBaseT() : settings(&_settings_game.pf.yapf), max_search_nodes(PfGetSettings().max_search_nodes) {}
/** default destructor */ /** default destructor */
~CYapfBaseT() {} ~CYapfBaseT() {}
@ -89,7 +89,7 @@ public:
/** return current settings (can be custom - company based - but later) */ /** return current settings (can be custom - company based - but later) */
inline const YAPFSettings &PfGetSettings() const inline const YAPFSettings &PfGetSettings() const
{ {
return *this->m_settings; return *this->settings;
} }
/** /**
@ -98,43 +98,43 @@ public:
* - main loop that stops if: * - main loop that stops if:
* - the destination was found * - the destination was found
* - or the open list is empty (no route to destination). * - or the open list is empty (no route to destination).
* - or the maximum amount of loops reached - m_max_search_nodes (default = 10000) * - or the maximum amount of loops reached - max_search_nodes (default = 10000)
* @return true if the path was found * @return true if the path was found
*/ */
inline bool FindPath(const VehicleType *v) inline bool FindPath(const VehicleType *v)
{ {
this->m_veh = v; this->vehicle = v;
Yapf().PfSetStartupNodes(); Yapf().PfSetStartupNodes();
for (;;) { for (;;) {
this->m_num_steps++; this->num_steps++;
Node *best_open_node = this->m_nodes.GetBestOpenNode(); Node *best_open_node = this->nodes.GetBestOpenNode();
if (best_open_node == nullptr) break; if (best_open_node == nullptr) break;
if (Yapf().PfDetectDestination(*best_open_node)) { if (Yapf().PfDetectDestination(*best_open_node)) {
this->m_pBestDestNode = best_open_node; this->best_dest_node = best_open_node;
break; break;
} }
Yapf().PfFollowNode(*best_open_node); Yapf().PfFollowNode(*best_open_node);
if (this->m_max_search_nodes != 0 && this->m_nodes.ClosedCount() >= this->m_max_search_nodes) break; if (this->max_search_nodes != 0 && this->nodes.ClosedCount() >= this->max_search_nodes) break;
this->m_nodes.PopOpenNode(best_open_node->GetKey()); this->nodes.PopOpenNode(best_open_node->GetKey());
this->m_nodes.InsertClosedNode(*best_open_node); this->nodes.InsertClosedNode(*best_open_node);
} }
const bool destination_found = (this->m_pBestDestNode != nullptr); const bool destination_found = (this->best_dest_node != nullptr);
if (_debug_yapf_level >= 3) { if (_debug_yapf_level >= 3) {
const UnitID veh_idx = (this->m_veh != nullptr) ? this->m_veh->unitnumber : 0; const UnitID veh_idx = (this->vehicle != nullptr) ? this->vehicle->unitnumber : 0;
const char ttc = Yapf().TransportTypeChar(); const char ttc = Yapf().TransportTypeChar();
const float cache_hit_ratio = (this->m_stats_cache_hits == 0) ? 0.0f : ((float)this->m_stats_cache_hits / (float)(this->m_stats_cache_hits + this->m_stats_cost_calcs) * 100.0f); const float cache_hit_ratio = (this->stats_cache_hits == 0) ? 0.0f : ((float)this->stats_cache_hits / (float)(this->stats_cache_hits + this->stats_cost_calcs) * 100.0f);
const int cost = destination_found ? this->m_pBestDestNode->m_cost : -1; const int cost = destination_found ? this->best_dest_node->cost : -1;
const int dist = destination_found ? this->m_pBestDestNode->m_estimate - this->m_pBestDestNode->m_cost : -1; const int dist = destination_found ? this->best_dest_node->estimate - this->best_dest_node->cost : -1;
Debug(yapf, 3, "[YAPF{}]{}{:4d} - {} rounds - {} open - {} closed - CHR {:4.1f}% - C {} D {}", Debug(yapf, 3, "[YAPF{}]{}{:4d} - {} rounds - {} open - {} closed - CHR {:4.1f}% - C {} D {}",
ttc, destination_found ? '-' : '!', veh_idx, this->m_num_steps, this->m_nodes.OpenCount(), this->m_nodes.ClosedCount(), cache_hit_ratio, cost, dist ttc, destination_found ? '-' : '!', veh_idx, this->num_steps, this->nodes.OpenCount(), this->nodes.ClosedCount(), cache_hit_ratio, cost, dist
); );
} }
@ -147,7 +147,7 @@ public:
*/ */
inline Node *GetBestNode() inline Node *GetBestNode()
{ {
return (this->m_pBestDestNode != nullptr) ? this->m_pBestDestNode : this->m_pBestIntermediateNode; return (this->best_dest_node != nullptr) ? this->best_dest_node : this->best_intermediate_node;
} }
/** /**
@ -156,7 +156,7 @@ public:
*/ */
inline Node &CreateNewNode() inline Node &CreateNewNode()
{ {
Node &node = *this->m_nodes.CreateNewNode(); Node &node = *this->nodes.CreateNewNode();
return node; return node;
} }
@ -165,8 +165,8 @@ public:
{ {
Yapf().PfNodeCacheFetch(n); Yapf().PfNodeCacheFetch(n);
/* insert the new node only if it is not there */ /* insert the new node only if it is not there */
if (this->m_nodes.FindOpenNode(n.m_key) == nullptr) { if (this->nodes.FindOpenNode(n.key) == nullptr) {
this->m_nodes.InsertOpenNode(n); this->nodes.InsertOpenNode(n);
} else { } else {
/* if we are here, it means that node is already there - how it is possible? /* if we are here, it means that node is already there - how it is possible?
* probably the train is in the position that both its ends point to the same tile/exit-dir * probably the train is in the position that both its ends point to the same tile/exit-dir
@ -177,11 +177,11 @@ public:
/** add multiple nodes - direct children of the given node */ /** add multiple nodes - direct children of the given node */
inline void AddMultipleNodes(Node *parent, const TrackFollower &tf) inline void AddMultipleNodes(Node *parent, const TrackFollower &tf)
{ {
bool is_choice = (KillFirstBit(tf.m_new_td_bits) != TRACKDIR_BIT_NONE); bool is_choice = (KillFirstBit(tf.new_td_bits) != TRACKDIR_BIT_NONE);
for (TrackdirBits rtds = tf.m_new_td_bits; rtds != TRACKDIR_BIT_NONE; rtds = KillFirstBit(rtds)) { for (TrackdirBits rtds = tf.new_td_bits; rtds != TRACKDIR_BIT_NONE; rtds = KillFirstBit(rtds)) {
Trackdir td = (Trackdir)FindFirstBit(rtds); Trackdir td = (Trackdir)FindFirstBit(rtds);
Node &n = Yapf().CreateNewNode(); Node &n = Yapf().CreateNewNode();
n.Set(parent, tf.m_new_tile, td, is_choice); n.Set(parent, tf.new_tile, td, is_choice);
Yapf().AddNewNode(n, tf); Yapf().AddNewNode(n, tf);
} }
} }
@ -197,11 +197,11 @@ public:
void PruneIntermediateNodeBranch(Node *n) void PruneIntermediateNodeBranch(Node *n)
{ {
bool intermediate_on_branch = false; bool intermediate_on_branch = false;
while (n != nullptr && (n->m_segment->m_end_segment_reason & ESRB_CHOICE_FOLLOWS) == 0) { while (n != nullptr && (n->segment->end_segment_reason & ESRB_CHOICE_FOLLOWS) == 0) {
if (n == Yapf().m_pBestIntermediateNode) intermediate_on_branch = true; if (n == Yapf().best_intermediate_node) intermediate_on_branch = true;
n = n->m_parent; n = n->parent;
} }
if (intermediate_on_branch) Yapf().m_pBestIntermediateNode = n; if (intermediate_on_branch) Yapf().best_intermediate_node = n;
} }
/** /**
@ -211,47 +211,47 @@ public:
void AddNewNode(Node &n, const TrackFollower &tf) void AddNewNode(Node &n, const TrackFollower &tf)
{ {
/* evaluate the node */ /* evaluate the node */
bool bCached = Yapf().PfNodeCacheFetch(n); bool cached = Yapf().PfNodeCacheFetch(n);
if (!bCached) { if (!cached) {
this->m_stats_cost_calcs++; this->stats_cost_calcs++;
} else { } else {
this->m_stats_cache_hits++; this->stats_cache_hits++;
} }
bool bValid = Yapf().PfCalcCost(n, &tf); bool valid = Yapf().PfCalcCost(n, &tf);
if (bValid) bValid = Yapf().PfCalcEstimate(n); if (valid) valid = Yapf().PfCalcEstimate(n);
/* have the cost or estimate callbacks marked this node as invalid? */ /* have the cost or estimate callbacks marked this node as invalid? */
if (!bValid) return; if (!valid) return;
/* The new node can be set as the best intermediate node only once we're /* The new node can be set as the best intermediate node only once we're
* certain it will be finalized by being inserted into the open list. */ * certain it will be finalized by being inserted into the open list. */
bool set_intermediate = this->m_max_search_nodes > 0 && (this->m_pBestIntermediateNode == nullptr || (this->m_pBestIntermediateNode->GetCostEstimate() - this->m_pBestIntermediateNode->GetCost()) > (n.GetCostEstimate() - n.GetCost())); bool set_intermediate = this->max_search_nodes > 0 && (this->best_intermediate_node == nullptr || (this->best_intermediate_node->GetCostEstimate() - this->best_intermediate_node->GetCost()) > (n.GetCostEstimate() - n.GetCost()));
/* check new node against open list */ /* check new node against open list */
Node *openNode = this->m_nodes.FindOpenNode(n.GetKey()); Node *open_node = this->nodes.FindOpenNode(n.GetKey());
if (openNode != nullptr) { if (open_node != nullptr) {
/* another node exists with the same key in the open list /* another node exists with the same key in the open list
* is it better than new one? */ * is it better than new one? */
if (n.GetCostEstimate() < openNode->GetCostEstimate()) { if (n.GetCostEstimate() < open_node->GetCostEstimate()) {
/* update the old node by value from new one */ /* update the old node by value from new one */
this->m_nodes.PopOpenNode(n.GetKey()); this->nodes.PopOpenNode(n.GetKey());
*openNode = n; *open_node = n;
/* add the updated old node back to open list */ /* add the updated old node back to open list */
this->m_nodes.InsertOpenNode(*openNode); this->nodes.InsertOpenNode(*open_node);
if (set_intermediate) this->m_pBestIntermediateNode = openNode; if (set_intermediate) this->best_intermediate_node = open_node;
} }
return; return;
} }
/* check new node against closed list */ /* check new node against closed list */
Node *closedNode = this->m_nodes.FindClosedNode(n.GetKey()); Node *closed_node = this->nodes.FindClosedNode(n.GetKey());
if (closedNode != nullptr) { if (closed_node != nullptr) {
/* another node exists with the same key in the closed list /* another node exists with the same key in the closed list
* is it better than new one? */ * is it better than new one? */
int node_est = n.GetCostEstimate(); int node_est = n.GetCostEstimate();
int closed_est = closedNode->GetCostEstimate(); int closed_est = closed_node->GetCostEstimate();
if (node_est < closed_est) { if (node_est < closed_est) {
/* If this assert occurs, you have probably problem in /* If this assert occurs, you have probably problem in
* your Tderived::PfCalcCost() or Tderived::PfCalcEstimate(). * your Tderived::PfCalcCost() or Tderived::PfCalcEstimate().
@ -265,19 +265,19 @@ public:
} }
/* the new node is really new /* the new node is really new
* add it to the open list */ * add it to the open list */
this->m_nodes.InsertOpenNode(n); this->nodes.InsertOpenNode(n);
if (set_intermediate) this->m_pBestIntermediateNode = &n; if (set_intermediate) this->best_intermediate_node = &n;
} }
const VehicleType * GetVehicle() const const VehicleType * GetVehicle() const
{ {
return this->m_veh; return this->vehicle;
} }
void DumpBase(DumpTarget &dmp) const void DumpBase(DumpTarget &dmp) const
{ {
dmp.WriteStructT("m_nodes", &this->m_nodes); dmp.WriteStructT("nodes", &this->nodes);
dmp.WriteValue("m_num_steps", this->m_num_steps); dmp.WriteValue("num_steps", this->num_steps);
} }
}; };

View File

@ -27,8 +27,8 @@ public:
typedef typename Node::Key Key; ///< key to hash tables typedef typename Node::Key Key; ///< key to hash tables
protected: protected:
TileIndex m_orgTile; ///< origin tile TileIndex origin_tile; ///< origin tile
TrackdirBits m_orgTrackdirs; ///< origin trackdir mask TrackdirBits origin_trackdirs; ///< origin trackdir mask
/** to access inherited path finder */ /** to access inherited path finder */
inline Tpf &Yapf() inline Tpf &Yapf()
@ -40,18 +40,18 @@ public:
/** Set origin tile / trackdir mask */ /** Set origin tile / trackdir mask */
void SetOrigin(TileIndex tile, TrackdirBits trackdirs) void SetOrigin(TileIndex tile, TrackdirBits trackdirs)
{ {
this->m_orgTile = tile; this->origin_tile = tile;
this->m_orgTrackdirs = trackdirs; this->origin_trackdirs = trackdirs;
} }
/** Called when YAPF needs to place origin nodes into open list */ /** Called when YAPF needs to place origin nodes into open list */
void PfSetStartupNodes() void PfSetStartupNodes()
{ {
bool is_choice = (KillFirstBit(this->m_orgTrackdirs) != TRACKDIR_BIT_NONE); bool is_choice = (KillFirstBit(this->origin_trackdirs) != TRACKDIR_BIT_NONE);
for (TrackdirBits tdb = this->m_orgTrackdirs; tdb != TRACKDIR_BIT_NONE; tdb = KillFirstBit(tdb)) { for (TrackdirBits tdb = this->origin_trackdirs; tdb != TRACKDIR_BIT_NONE; tdb = KillFirstBit(tdb)) {
Trackdir td = (Trackdir)FindFirstBit(tdb); Trackdir td = (Trackdir)FindFirstBit(tdb);
Node &n1 = Yapf().CreateNewNode(); Node &n1 = Yapf().CreateNewNode();
n1.Set(nullptr, this->m_orgTile, td, is_choice); n1.Set(nullptr, this->origin_tile, td, is_choice);
Yapf().AddStartupNode(n1); Yapf().AddStartupNode(n1);
} }
} }
@ -67,12 +67,12 @@ public:
typedef typename Node::Key Key; ///< key to hash tables typedef typename Node::Key Key; ///< key to hash tables
protected: protected:
TileIndex m_orgTile; ///< first origin tile TileIndex origin_tile; ///< first origin tile
Trackdir m_orgTd; ///< first origin trackdir Trackdir origin_td; ///< first origin trackdir
TileIndex m_revTile; ///< second (reversed) origin tile TileIndex reverse_tile; ///< second (reverse) origin tile
Trackdir m_revTd; ///< second (reversed) origin trackdir Trackdir reverse_td; ///< second (reverse) origin trackdir
int m_reverse_penalty; ///< penalty to be added for using the reversed origin int reverse_penalty; ///< penalty to be added for using the reverse origin
bool m_treat_first_red_two_way_signal_as_eol; ///< in some cases (leaving station) we need to handle first two-way signal differently bool treat_first_red_two_way_signal_as_eol; ///< in some cases (leaving station) we need to handle first two-way signal differently
/** to access inherited path finder */ /** to access inherited path finder */
inline Tpf &Yapf() inline Tpf &Yapf()
@ -84,26 +84,26 @@ public:
/** set origin (tiles, trackdirs, etc.) */ /** set origin (tiles, trackdirs, etc.) */
void SetOrigin(TileIndex tile, Trackdir td, TileIndex tiler = INVALID_TILE, Trackdir tdr = INVALID_TRACKDIR, int reverse_penalty = 0, bool treat_first_red_two_way_signal_as_eol = true) void SetOrigin(TileIndex tile, Trackdir td, TileIndex tiler = INVALID_TILE, Trackdir tdr = INVALID_TRACKDIR, int reverse_penalty = 0, bool treat_first_red_two_way_signal_as_eol = true)
{ {
this->m_orgTile = tile; this->origin_tile = tile;
this->m_orgTd = td; this->origin_td = td;
this->m_revTile = tiler; this->reverse_tile = tiler;
this->m_revTd = tdr; this->reverse_td = tdr;
this->m_reverse_penalty = reverse_penalty; this->reverse_penalty = reverse_penalty;
this->m_treat_first_red_two_way_signal_as_eol = treat_first_red_two_way_signal_as_eol; this->treat_first_red_two_way_signal_as_eol = treat_first_red_two_way_signal_as_eol;
} }
/** Called when YAPF needs to place origin nodes into open list */ /** Called when YAPF needs to place origin nodes into open list */
void PfSetStartupNodes() void PfSetStartupNodes()
{ {
if (this->m_orgTile != INVALID_TILE && this->m_orgTd != INVALID_TRACKDIR) { if (this->origin_tile != INVALID_TILE && this->origin_td != INVALID_TRACKDIR) {
Node &n1 = Yapf().CreateNewNode(); Node &n1 = Yapf().CreateNewNode();
n1.Set(nullptr, this->m_orgTile, this->m_orgTd, false); n1.Set(nullptr, this->origin_tile, this->origin_td, false);
Yapf().AddStartupNode(n1); Yapf().AddStartupNode(n1);
} }
if (this->m_revTile != INVALID_TILE && this->m_revTd != INVALID_TRACKDIR) { if (this->reverse_tile != INVALID_TILE && this->reverse_td != INVALID_TRACKDIR) {
Node &n2 = Yapf().CreateNewNode(); Node &n2 = Yapf().CreateNewNode();
n2.Set(nullptr, this->m_revTile, this->m_revTd, false); n2.Set(nullptr, this->reverse_tile, this->reverse_td, false);
n2.m_cost = this->m_reverse_penalty; n2.cost = this->reverse_penalty;
Yapf().AddStartupNode(n2); Yapf().AddStartupNode(n2);
} }
} }
@ -111,7 +111,7 @@ public:
/** return true if first two-way signal should be treated as dead end */ /** return true if first two-way signal should be treated as dead end */
inline bool TreatFirstRedTwoWaySignalAsEOL() inline bool TreatFirstRedTwoWaySignalAsEOL()
{ {
return Yapf().PfGetSettings().rail_firstred_twoway_eol && this->m_treat_first_red_two_way_signal_as_eol; return Yapf().PfGetSettings().rail_firstred_twoway_eol && this->treat_first_red_two_way_signal_as_eol;
} }
}; };
@ -125,15 +125,15 @@ public:
typedef typename Node::Key Key; ///< key to hash tables typedef typename Node::Key Key; ///< key to hash tables
protected: protected:
TileIndex m_destTile; ///< destination tile TileIndex dest_tile; ///< destination tile
TrackdirBits m_destTrackdirs; ///< destination trackdir mask TrackdirBits dest_trackdirs; ///< destination trackdir mask
public: public:
/** set the destination tile / more trackdirs */ /** set the destination tile / more trackdirs */
void SetDestination(TileIndex tile, TrackdirBits trackdirs) void SetDestination(TileIndex tile, TrackdirBits trackdirs)
{ {
this->m_destTile = tile; this->dest_tile = tile;
this->m_destTrackdirs = trackdirs; this->dest_trackdirs = trackdirs;
} }
protected: protected:
@ -147,19 +147,19 @@ public:
/** Called by YAPF to detect if node ends in the desired destination */ /** Called by YAPF to detect if node ends in the desired destination */
inline bool PfDetectDestination(Node &n) inline bool PfDetectDestination(Node &n)
{ {
return (n.m_key.m_tile == this->m_destTile) && HasTrackdir(this->m_destTrackdirs, n.GetTrackdir()); return (n.key.tile == this->dest_tile) && HasTrackdir(this->dest_trackdirs, n.GetTrackdir());
} }
/** /**
* Called by YAPF to calculate cost estimate. Calculates distance to the destination * Called by YAPF to calculate cost estimate. Calculates distance to the destination
* adds it to the actual cost from origin and stores the sum to the Node::m_estimate * adds it to the actual cost from origin and stores the sum to the Node::estimate
*/ */
inline bool PfCalcEstimate(Node &n) inline bool PfCalcEstimate(Node &n)
{ {
static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0}; static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
static const int dg_dir_to_y_offs[] = {0, 1, 0, -1}; static const int dg_dir_to_y_offs[] = {0, 1, 0, -1};
if (this->PfDetectDestination(n)) { if (this->PfDetectDestination(n)) {
n.m_estimate = n.m_cost; n.estimate = n.cost;
return true; return true;
} }
@ -167,15 +167,15 @@ public:
DiagDirection exitdir = TrackdirToExitdir(n.GetTrackdir()); DiagDirection exitdir = TrackdirToExitdir(n.GetTrackdir());
int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir]; int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir]; int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
int x2 = 2 * TileX(this->m_destTile); int x2 = 2 * TileX(this->dest_tile);
int y2 = 2 * TileY(this->m_destTile); int y2 = 2 * TileY(this->dest_tile);
int dx = abs(x1 - x2); int dx = abs(x1 - x2);
int dy = abs(y1 - y2); int dy = abs(y1 - y2);
int dmin = std::min(dx, dy); int dmin = std::min(dx, dy);
int dxy = abs(dx - dy); int dxy = abs(dx - dy);
int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2); int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
n.m_estimate = n.m_cost + d; n.estimate = n.cost + d;
assert(n.m_estimate >= n.m_parent->m_estimate); assert(n.estimate >= n.parent->estimate);
return true; return true;
} }
}; };

View File

@ -73,25 +73,25 @@ struct CSegmentCostCacheT : public CSegmentCostCacheBase {
using Heap = std::deque<Tsegment>; using Heap = std::deque<Tsegment>;
typedef typename Tsegment::Key Key; ///< key to hash table typedef typename Tsegment::Key Key; ///< key to hash table
HashTable m_map; HashTable map;
Heap m_heap; Heap heap;
inline CSegmentCostCacheT() {} inline CSegmentCostCacheT() {}
/** flush (clear) the cache */ /** flush (clear) the cache */
inline void Flush() inline void Flush()
{ {
this->m_map.Clear(); this->map.Clear();
this->m_heap.clear(); this->heap.clear();
} }
inline Tsegment &Get(Key &key, bool *found) inline Tsegment &Get(Key &key, bool *found)
{ {
Tsegment *item = this->m_map.Find(key); Tsegment *item = this->map.Find(key);
if (item == nullptr) { if (item == nullptr) {
*found = false; *found = false;
item = &m_heap.emplace_back(key); item = &heap.emplace_back(key);
this->m_map.Push(*item); this->map.Push(*item);
} else { } else {
*found = true; *found = true;
} }
@ -116,10 +116,10 @@ public:
using LocalCache = std::deque<CachedData>; using LocalCache = std::deque<CachedData>;
protected: protected:
Cache &m_global_cache; Cache &global_cache;
LocalCache m_local_cache; LocalCache local_cache;
inline CYapfSegmentCostCacheGlobalT() : m_global_cache(stGetGlobalCache()) {}; inline CYapfSegmentCostCacheGlobalT() : global_cache(stGetGlobalCache()) {};
/** to access inherited path finder */ /** to access inherited path finder */
inline Tpf &Yapf() inline Tpf &Yapf()
@ -150,12 +150,12 @@ public:
CacheKey key(n.GetKey()); CacheKey key(n.GetKey());
if (!Yapf().CanUseGlobalCache(n)) { if (!Yapf().CanUseGlobalCache(n)) {
Yapf().ConnectNodeToCachedData(n, this->m_local_cache.emplace_back(key)); Yapf().ConnectNodeToCachedData(n, this->local_cache.emplace_back(key));
return false; return false;
} }
bool found; bool found;
CachedData &item = this->m_global_cache.Get(key, &found); CachedData &item = this->global_cache.Get(key, &found);
Yapf().ConnectNodeToCachedData(n, item); Yapf().ConnectNodeToCachedData(n, item);
return found; return found;
} }

View File

@ -45,26 +45,26 @@ protected:
* @note maximum cost doesn't work with caching enabled * @note maximum cost doesn't work with caching enabled
* @todo fix maximum cost failing with caching (e.g. FS#2900) * @todo fix maximum cost failing with caching (e.g. FS#2900)
*/ */
int m_max_cost; int max_cost;
bool m_disable_cache; bool disable_cache;
std::vector<int> m_sig_look_ahead_costs; std::vector<int> sig_look_ahead_costs;
public: public:
bool m_stopped_on_first_two_way_signal; bool stopped_on_first_two_way_signal;
protected:
protected:
static const int s_max_segment_cost = 10000; static const int s_max_segment_cost = 10000;
CYapfCostRailT() : m_max_cost(0), m_disable_cache(false), m_stopped_on_first_two_way_signal(false) CYapfCostRailT() : max_cost(0), disable_cache(false), stopped_on_first_two_way_signal(false)
{ {
/* pre-compute look-ahead penalties into array */ /* pre-compute look-ahead penalties into array */
int p0 = Yapf().PfGetSettings().rail_look_ahead_signal_p0; int p0 = Yapf().PfGetSettings().rail_look_ahead_signal_p0;
int p1 = Yapf().PfGetSettings().rail_look_ahead_signal_p1; int p1 = Yapf().PfGetSettings().rail_look_ahead_signal_p1;
int p2 = Yapf().PfGetSettings().rail_look_ahead_signal_p2; int p2 = Yapf().PfGetSettings().rail_look_ahead_signal_p2;
this->m_sig_look_ahead_costs.clear(); this->sig_look_ahead_costs.clear();
this->m_sig_look_ahead_costs.reserve(Yapf().PfGetSettings().rail_look_ahead_max_signals); this->sig_look_ahead_costs.reserve(Yapf().PfGetSettings().rail_look_ahead_max_signals);
for (uint i = 0; i < Yapf().PfGetSettings().rail_look_ahead_max_signals; i++) { for (uint i = 0; i < Yapf().PfGetSettings().rail_look_ahead_max_signals; i++) {
this->m_sig_look_ahead_costs.push_back(p0 + i * (p1 + i * p2)); this->sig_look_ahead_costs.push_back(p0 + i * (p1 + i * p2));
} }
} }
@ -145,8 +145,8 @@ public:
/** The cost for reserved tiles, including skipped ones. */ /** The cost for reserved tiles, including skipped ones. */
inline int ReservationCost(Node &n, TileIndex tile, Trackdir trackdir, int skipped) inline int ReservationCost(Node &n, TileIndex tile, Trackdir trackdir, int skipped)
{ {
if (n.m_num_signals_passed >= this->m_sig_look_ahead_costs.size() / 2) return 0; if (n.num_signals_passed >= this->sig_look_ahead_costs.size() / 2) return 0;
if (!IsPbsSignal(n.m_last_signal_type)) return 0; if (!IsPbsSignal(n.last_signal_type)) return 0;
if (IsRailStationTile(tile) && IsAnyStationTileReserved(tile, trackdir, skipped)) { if (IsRailStationTile(tile) && IsAnyStationTileReserved(tile, trackdir, skipped)) {
return Yapf().PfGetSettings().rail_pbs_station_penalty * (skipped + 1); return Yapf().PfGetSettings().rail_pbs_station_penalty * (skipped + 1);
@ -167,19 +167,19 @@ public:
bool has_signal_along = HasSignalOnTrackdir(tile, trackdir); bool has_signal_along = HasSignalOnTrackdir(tile, trackdir);
if (has_signal_against && !has_signal_along && IsOnewaySignal(tile, TrackdirToTrack(trackdir))) { if (has_signal_against && !has_signal_along && IsOnewaySignal(tile, TrackdirToTrack(trackdir))) {
/* one-way signal in opposite direction */ /* one-way signal in opposite direction */
n.m_segment->m_end_segment_reason |= ESRB_DEAD_END; n.segment->end_segment_reason |= ESRB_DEAD_END;
} else { } else {
if (has_signal_along) { if (has_signal_along) {
SignalState sig_state = GetSignalStateByTrackdir(tile, trackdir); SignalState sig_state = GetSignalStateByTrackdir(tile, trackdir);
SignalType sig_type = GetSignalType(tile, TrackdirToTrack(trackdir)); SignalType sig_type = GetSignalType(tile, TrackdirToTrack(trackdir));
n.m_last_signal_type = sig_type; n.last_signal_type = sig_type;
/* cache the look-ahead polynomial constant only if we didn't pass more signals than the look-ahead limit is */ /* cache the look-ahead polynomial constant only if we didn't pass more signals than the look-ahead limit is */
int look_ahead_cost = (n.m_num_signals_passed < this->m_sig_look_ahead_costs.size()) ? this->m_sig_look_ahead_costs[n.m_num_signals_passed] : 0; int look_ahead_cost = (n.num_signals_passed < this->sig_look_ahead_costs.size()) ? this->sig_look_ahead_costs[n.num_signals_passed] : 0;
if (sig_state != SIGNAL_STATE_RED) { if (sig_state != SIGNAL_STATE_RED) {
/* green signal */ /* green signal */
n.flags_u.flags_s.m_last_signal_was_red = false; n.flags_u.flags_s.last_signal_was_red = false;
/* negative look-ahead red-signal penalties would cause problems later, so use them as positive penalties for green signal */ /* negative look-ahead red-signal penalties would cause problems later, so use them as positive penalties for green signal */
if (look_ahead_cost < 0) { if (look_ahead_cost < 0) {
/* add its negation to the cost */ /* add its negation to the cost */
@ -188,15 +188,15 @@ public:
} else { } else {
/* we have a red signal in our direction /* we have a red signal in our direction
* was it first signal which is two-way? */ * was it first signal which is two-way? */
if (!IsPbsSignal(sig_type) && Yapf().TreatFirstRedTwoWaySignalAsEOL() && n.flags_u.flags_s.m_choice_seen && has_signal_against && n.m_num_signals_passed == 0) { if (!IsPbsSignal(sig_type) && Yapf().TreatFirstRedTwoWaySignalAsEOL() && n.flags_u.flags_s.choice_seen && has_signal_against && n.num_signals_passed == 0) {
/* yes, the first signal is two-way red signal => DEAD END. Prune this branch... */ /* yes, the first signal is two-way red signal => DEAD END. Prune this branch... */
Yapf().PruneIntermediateNodeBranch(&n); Yapf().PruneIntermediateNodeBranch(&n);
n.m_segment->m_end_segment_reason |= ESRB_DEAD_END; n.segment->end_segment_reason |= ESRB_DEAD_END;
Yapf().m_stopped_on_first_two_way_signal = true; Yapf().stopped_on_first_two_way_signal = true;
return -1; return -1;
} }
n.m_last_red_signal_type = sig_type; n.last_red_signal_type = sig_type;
n.flags_u.flags_s.m_last_signal_was_red = true; n.flags_u.flags_s.last_signal_was_red = true;
/* look-ahead signal penalty */ /* look-ahead signal penalty */
if (!IsPbsSignal(sig_type) && look_ahead_cost > 0) { if (!IsPbsSignal(sig_type) && look_ahead_cost > 0) {
@ -205,7 +205,7 @@ public:
} }
/* special signal penalties */ /* special signal penalties */
if (n.m_num_signals_passed == 0) { if (n.num_signals_passed == 0) {
switch (sig_type) { switch (sig_type) {
case SIGTYPE_COMBO: case SIGTYPE_COMBO:
case SIGTYPE_EXIT: cost += Yapf().PfGetSettings().rail_firstred_exit_penalty; break; // first signal is red pre-signal-exit case SIGTYPE_EXIT: cost += Yapf().PfGetSettings().rail_firstred_exit_penalty; break; // first signal is red pre-signal-exit
@ -216,13 +216,13 @@ public:
} }
} }
n.m_num_signals_passed++; n.num_signals_passed++;
n.m_segment->m_last_signal_tile = tile; n.segment->last_signal_tile = tile;
n.m_segment->m_last_signal_td = trackdir; n.segment->last_signal_td = trackdir;
} }
if (has_signal_against && IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) { if (has_signal_against && IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) {
cost += n.m_num_signals_passed < Yapf().PfGetSettings().rail_look_ahead_max_signals ? Yapf().PfGetSettings().rail_pbs_signal_back_penalty : 0; cost += n.num_signals_passed < Yapf().PfGetSettings().rail_look_ahead_max_signals ? Yapf().PfGetSettings().rail_pbs_signal_back_penalty : 0;
} }
} }
} }
@ -250,7 +250,7 @@ public:
public: public:
inline void SetMaxCost(int max_cost) inline void SetMaxCost(int max_cost)
{ {
this->m_max_cost = max_cost; this->max_cost = max_cost;
} }
/** /**
@ -260,18 +260,18 @@ public:
*/ */
inline bool PfCalcCost(Node &n, const TrackFollower *tf) inline bool PfCalcCost(Node &n, const TrackFollower *tf)
{ {
assert(!n.flags_u.flags_s.m_targed_seen); assert(!n.flags_u.flags_s.target_seen);
assert(tf->m_new_tile == n.m_key.m_tile); assert(tf->new_tile == n.key.tile);
assert((HasTrackdir(tf->m_new_td_bits, n.m_key.m_td))); assert((HasTrackdir(tf->new_td_bits, n.key.td)));
/* Does the node have some parent node? */ /* Does the node have some parent node? */
bool has_parent = (n.m_parent != nullptr); bool has_parent = (n.parent != nullptr);
/* Do we already have a cached segment? */ /* Do we already have a cached segment? */
CachedData &segment = *n.m_segment; CachedData &segment = *n.segment;
bool is_cached_segment = (segment.m_cost >= 0); bool is_cached_segment = (segment.cost >= 0);
int parent_cost = has_parent ? n.m_parent->m_cost : 0; int parent_cost = has_parent ? n.parent->cost : 0;
/* Each node cost contains 2 or 3 main components: /* Each node cost contains 2 or 3 main components:
* 1. Transition cost - cost of the move from previous node (tile): * 1. Transition cost - cost of the move from previous node (tile):
@ -305,11 +305,11 @@ public:
const Train *v = Yapf().GetVehicle(); const Train *v = Yapf().GetVehicle();
/* start at n.m_key.m_tile / n.m_key.m_td and walk to the end of segment */ /* start at n.key.tile / n.key.td and walk to the end of segment */
TILE cur(n.m_key.m_tile, n.m_key.m_td); TILE cur(n.key.tile, n.key.td);
/* the previous tile will be needed for transition cost calculations */ /* the previous tile will be needed for transition cost calculations */
TILE prev = !has_parent ? TILE() : TILE(n.m_parent->GetLastTile(), n.m_parent->GetLastTrackdir()); TILE prev = !has_parent ? TILE() : TILE(n.parent->GetLastTile(), n.parent->GetLastTrackdir());
EndSegmentReasonBits end_segment_reason = ESRB_NONE; EndSegmentReasonBits end_segment_reason = ESRB_NONE;
@ -337,17 +337,17 @@ public:
/* It is the right time now to look if we can reuse the cached segment cost. */ /* It is the right time now to look if we can reuse the cached segment cost. */
if (is_cached_segment) { if (is_cached_segment) {
/* Yes, we already know the segment cost. */ /* Yes, we already know the segment cost. */
segment_cost = segment.m_cost; segment_cost = segment.cost;
/* We know also the reason why the segment ends. */ /* We know also the reason why the segment ends. */
end_segment_reason = segment.m_end_segment_reason; end_segment_reason = segment.end_segment_reason;
/* We will need also some information about the last signal (if it was red). */ /* We will need also some information about the last signal (if it was red). */
if (segment.m_last_signal_tile != INVALID_TILE) { if (segment.last_signal_tile != INVALID_TILE) {
assert(HasSignalOnTrackdir(segment.m_last_signal_tile, segment.m_last_signal_td)); assert(HasSignalOnTrackdir(segment.last_signal_tile, segment.last_signal_td));
SignalState sig_state = GetSignalStateByTrackdir(segment.m_last_signal_tile, segment.m_last_signal_td); SignalState sig_state = GetSignalStateByTrackdir(segment.last_signal_tile, segment.last_signal_td);
bool is_red = (sig_state == SIGNAL_STATE_RED); bool is_red = (sig_state == SIGNAL_STATE_RED);
n.flags_u.flags_s.m_last_signal_was_red = is_red; n.flags_u.flags_s.last_signal_was_red = is_red;
if (is_red) { if (is_red) {
n.m_last_red_signal_type = GetSignalType(segment.m_last_signal_tile, TrackdirToTrack(segment.m_last_signal_td)); n.last_red_signal_type = GetSignalType(segment.last_signal_tile, TrackdirToTrack(segment.last_signal_td));
} }
} }
/* No further calculation needed. */ /* No further calculation needed. */
@ -365,7 +365,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
segment_cost += Yapf().OneTileCost(cur.tile, cur.td); segment_cost += Yapf().OneTileCost(cur.tile, cur.td);
/* If we skipped some tunnel/bridge/station tiles, add their base cost */ /* If we skipped some tunnel/bridge/station tiles, add their base cost */
segment_cost += YAPF_TILE_LENGTH * tf->m_tiles_skipped; segment_cost += YAPF_TILE_LENGTH * tf->tiles_skipped;
/* Slope cost. */ /* Slope cost. */
segment_cost += Yapf().SlopeCost(cur.tile, cur.td); segment_cost += Yapf().SlopeCost(cur.tile, cur.td);
@ -374,9 +374,9 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
segment_cost += Yapf().SignalCost(n, cur.tile, cur.td); segment_cost += Yapf().SignalCost(n, cur.tile, cur.td);
/* Reserved tiles. */ /* Reserved tiles. */
segment_cost += Yapf().ReservationCost(n, cur.tile, cur.td, tf->m_tiles_skipped); segment_cost += Yapf().ReservationCost(n, cur.tile, cur.td, tf->tiles_skipped);
end_segment_reason = segment.m_end_segment_reason; end_segment_reason = segment.end_segment_reason;
/* Tests for 'potential target' reasons to close the segment. */ /* Tests for 'potential target' reasons to close the segment. */
if (cur.tile == prev.tile) { if (cur.tile == prev.tile) {
@ -401,21 +401,21 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
/* Arbitrary maximum tiles to follow to avoid infinite loops. */ /* Arbitrary maximum tiles to follow to avoid infinite loops. */
uint max_tiles = 20; uint max_tiles = 20;
while (ft.Follow(t, td)) { while (ft.Follow(t, td)) {
assert(t != ft.m_new_tile); assert(t != ft.new_tile);
t = ft.m_new_tile; t = ft.new_tile;
if (t == cur.tile || --max_tiles == 0) { if (t == cur.tile || --max_tiles == 0) {
/* We looped back on ourself or found another loop, bail out. */ /* We looped back on ourself or found another loop, bail out. */
td = INVALID_TRACKDIR; td = INVALID_TRACKDIR;
break; break;
} }
if (KillFirstBit(ft.m_new_td_bits) != TRACKDIR_BIT_NONE) { if (KillFirstBit(ft.new_td_bits) != TRACKDIR_BIT_NONE) {
/* We encountered a junction; it's going to be too complex to /* We encountered a junction; it's going to be too complex to
* handle this perfectly, so just bail out. There is no simple * handle this perfectly, so just bail out. There is no simple
* free path, so try the other possibilities. */ * free path, so try the other possibilities. */
td = INVALID_TRACKDIR; td = INVALID_TRACKDIR;
break; break;
} }
td = RemoveFirstTrackdir(&ft.m_new_td_bits); td = RemoveFirstTrackdir(&ft.new_td_bits);
/* If this is a safe waiting position we're done searching for it */ /* If this is a safe waiting position we're done searching for it */
if (IsSafeWaitingPosition(v, t, td, true, _settings_game.pf.forbid_90_deg)) break; if (IsSafeWaitingPosition(v, t, td, true, _settings_game.pf.forbid_90_deg)) break;
} }
@ -432,9 +432,9 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
/* Waypoint is also a good reason to finish. */ /* Waypoint is also a good reason to finish. */
end_segment_reason |= ESRB_WAYPOINT; end_segment_reason |= ESRB_WAYPOINT;
} else if (tf->m_is_station) { } else if (tf->is_station) {
/* Station penalties. */ /* Station penalties. */
uint platform_length = tf->m_tiles_skipped + 1; uint platform_length = tf->tiles_skipped + 1;
/* We don't know yet if the station is our target or not. Act like /* We don't know yet if the station is our target or not. Act like
* if it is pass-through station (not our destination). */ * if it is pass-through station (not our destination). */
segment_cost += Yapf().PfGetSettings().rail_station_penalty * platform_length; segment_cost += Yapf().PfGetSettings().rail_station_penalty * platform_length;
@ -450,13 +450,13 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
/* Apply min/max speed penalties only when inside the look-ahead radius. Otherwise /* Apply min/max speed penalties only when inside the look-ahead radius. Otherwise
* it would cause desync in MP. */ * it would cause desync in MP. */
if (n.m_num_signals_passed < this->m_sig_look_ahead_costs.size()) if (n.num_signals_passed < this->sig_look_ahead_costs.size())
{ {
int min_speed = 0; int min_speed = 0;
int max_speed = tf->GetSpeedLimit(&min_speed); int max_speed = tf->GetSpeedLimit(&min_speed);
int max_veh_speed = std::min<int>(v->GetDisplayMaxSpeed(), v->current_order.GetMaxSpeed()); int max_veh_speed = std::min<int>(v->GetDisplayMaxSpeed(), v->current_order.GetMaxSpeed());
if (max_speed < max_veh_speed) { if (max_speed < max_veh_speed) {
extra_cost += YAPF_TILE_LENGTH * (max_veh_speed - max_speed) * (4 + tf->m_tiles_skipped) / max_veh_speed; extra_cost += YAPF_TILE_LENGTH * (max_veh_speed - max_speed) * (4 + tf->tiles_skipped) / max_veh_speed;
} }
if (min_speed > max_veh_speed) { if (min_speed > max_veh_speed) {
extra_cost += YAPF_TILE_LENGTH * (min_speed - max_veh_speed); extra_cost += YAPF_TILE_LENGTH * (min_speed - max_veh_speed);
@ -465,7 +465,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
/* Finish if we already exceeded the maximum path cost (i.e. when /* Finish if we already exceeded the maximum path cost (i.e. when
* searching for the nearest depot). */ * searching for the nearest depot). */
if (this->m_max_cost > 0 && (parent_cost + segment_entry_cost + segment_cost) > this->m_max_cost) { if (this->max_cost > 0 && (parent_cost + segment_entry_cost + segment_cost) > this->max_cost) {
end_segment_reason |= ESRB_PATH_TOO_LONG; end_segment_reason |= ESRB_PATH_TOO_LONG;
} }
@ -474,9 +474,9 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
tf_local.Init(v, Yapf().GetCompatibleRailTypes()); tf_local.Init(v, Yapf().GetCompatibleRailTypes());
if (!tf_local.Follow(cur.tile, cur.td)) { if (!tf_local.Follow(cur.tile, cur.td)) {
assert(tf_local.m_err != TrackFollower::EC_NONE); assert(tf_local.err != TrackFollower::EC_NONE);
/* Can't move to the next tile (EOL?). */ /* Can't move to the next tile (EOL?). */
if (tf_local.m_err == TrackFollower::EC_RAIL_ROAD_TYPE) { if (tf_local.err == TrackFollower::EC_RAIL_ROAD_TYPE) {
end_segment_reason |= ESRB_RAIL_TYPE; end_segment_reason |= ESRB_RAIL_TYPE;
} else { } else {
end_segment_reason |= ESRB_DEAD_END; end_segment_reason |= ESRB_DEAD_END;
@ -489,14 +489,14 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
} }
/* Check if the next tile is not a choice. */ /* Check if the next tile is not a choice. */
if (KillFirstBit(tf_local.m_new_td_bits) != TRACKDIR_BIT_NONE) { if (KillFirstBit(tf_local.new_td_bits) != TRACKDIR_BIT_NONE) {
/* More than one segment will follow. Close this one. */ /* More than one segment will follow. Close this one. */
end_segment_reason |= ESRB_CHOICE_FOLLOWS; end_segment_reason |= ESRB_CHOICE_FOLLOWS;
break; break;
} }
/* Gather the next tile/trackdir/tile_type/rail_type. */ /* Gather the next tile/trackdir/tile_type/rail_type. */
TILE next(tf_local.m_new_tile, (Trackdir)FindFirstBit(tf_local.m_new_td_bits)); TILE next(tf_local.new_tile, (Trackdir)FindFirstBit(tf_local.new_td_bits));
if (TrackFollower::DoTrackMasking() && IsTileType(next.tile, MP_RAILWAY)) { if (TrackFollower::DoTrackMasking() && IsTileType(next.tile, MP_RAILWAY)) {
if (HasSignalOnTrackdir(next.tile, next.td) && IsPbsSignal(GetSignalType(next.tile, TrackdirToTrack(next.td)))) { if (HasSignalOnTrackdir(next.tile, next.td) && IsPbsSignal(GetSignalType(next.tile, TrackdirToTrack(next.td)))) {
@ -517,7 +517,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
} }
/* Avoid infinite looping. */ /* Avoid infinite looping. */
if (next.tile == n.m_key.m_tile && next.td == n.m_key.m_td) { if (next.tile == n.key.tile && next.td == n.key.td) {
end_segment_reason |= ESRB_INFINITE_LOOP; end_segment_reason |= ESRB_INFINITE_LOOP;
break; break;
} }
@ -525,7 +525,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
if (segment_cost > s_max_segment_cost) { if (segment_cost > s_max_segment_cost) {
/* Potentially in the infinite loop (or only very long segment?). We should /* Potentially in the infinite loop (or only very long segment?). We should
* not force it to finish prematurely unless we are on a regular tile. */ * not force it to finish prematurely unless we are on a regular tile. */
if (IsTileType(tf->m_new_tile, MP_RAILWAY)) { if (IsTileType(tf->new_tile, MP_RAILWAY)) {
end_segment_reason |= ESRB_SEGMENT_TOO_LONG; end_segment_reason |= ESRB_SEGMENT_TOO_LONG;
break; break;
} }
@ -557,8 +557,8 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
/* Update the segment if needed. */ /* Update the segment if needed. */
if (!is_cached_segment) { if (!is_cached_segment) {
/* Write back the segment information so it can be reused the next time. */ /* Write back the segment information so it can be reused the next time. */
segment.m_cost = segment_cost; segment.cost = segment_cost;
segment.m_end_segment_reason = end_segment_reason & ESRB_CACHED_MASK; segment.end_segment_reason = end_segment_reason & ESRB_CACHED_MASK;
/* Save end of segment back to the node. */ /* Save end of segment back to the node. */
n.SetLastTileTrackdir(cur.tile, cur.td); n.SetLastTileTrackdir(cur.tile, cur.td);
} }
@ -571,13 +571,13 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
/* Special costs for the case we have reached our target. */ /* Special costs for the case we have reached our target. */
if (target_seen) { if (target_seen) {
n.flags_u.flags_s.m_targed_seen = true; n.flags_u.flags_s.target_seen = true;
/* Last-red and last-red-exit penalties. */ /* Last-red and last-red-exit penalties. */
if (n.flags_u.flags_s.m_last_signal_was_red) { if (n.flags_u.flags_s.last_signal_was_red) {
if (n.m_last_red_signal_type == SIGTYPE_EXIT) { if (n.last_red_signal_type == SIGTYPE_EXIT) {
/* last signal was red pre-signal-exit */ /* last signal was red pre-signal-exit */
extra_cost += Yapf().PfGetSettings().rail_lastred_exit_penalty; extra_cost += Yapf().PfGetSettings().rail_lastred_exit_penalty;
} else if (!IsPbsSignal(n.m_last_red_signal_type)) { } else if (!IsPbsSignal(n.last_red_signal_type)) {
/* Last signal was red, but not exit or path signal. */ /* Last signal was red, but not exit or path signal. */
extra_cost += Yapf().PfGetSettings().rail_lastred_penalty; extra_cost += Yapf().PfGetSettings().rail_lastred_penalty;
} }
@ -596,30 +596,30 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
} }
/* total node cost */ /* total node cost */
n.m_cost = parent_cost + segment_entry_cost + segment_cost + extra_cost; n.cost = parent_cost + segment_entry_cost + segment_cost + extra_cost;
return true; return true;
} }
inline bool CanUseGlobalCache(Node &n) const inline bool CanUseGlobalCache(Node &n) const
{ {
return !this->m_disable_cache return !this->disable_cache
&& (n.m_parent != nullptr) && (n.parent != nullptr)
&& (n.m_parent->m_num_signals_passed >= this->m_sig_look_ahead_costs.size()); && (n.parent->num_signals_passed >= this->sig_look_ahead_costs.size());
} }
inline void ConnectNodeToCachedData(Node &n, CachedData &ci) inline void ConnectNodeToCachedData(Node &n, CachedData &ci)
{ {
n.m_segment = &ci; n.segment = &ci;
if (n.m_segment->m_cost < 0) { if (n.segment->cost < 0) {
n.m_segment->m_last_tile = n.m_key.m_tile; n.segment->last_tile = n.key.tile;
n.m_segment->m_last_td = n.m_key.m_td; n.segment->last_td = n.key.td;
} }
} }
void DisableCache(bool disable) void DisableCache(bool disable)
{ {
this->m_disable_cache = disable; this->disable_cache = disable;
} }
}; };

View File

@ -16,23 +16,23 @@
class CYapfDestinationRailBase { class CYapfDestinationRailBase {
protected: protected:
RailTypes m_compatible_railtypes; RailTypes compatible_railtypes;
public: public:
void SetDestination(const Train *v, bool override_rail_type = false) void SetDestination(const Train *v, bool override_rail_type = false)
{ {
this->m_compatible_railtypes = v->compatible_railtypes; this->compatible_railtypes = v->compatible_railtypes;
if (override_rail_type) this->m_compatible_railtypes |= GetRailTypeInfo(v->railtype)->compatible_railtypes; if (override_rail_type) this->compatible_railtypes |= GetRailTypeInfo(v->railtype)->compatible_railtypes;
} }
bool IsCompatibleRailType(RailType rt) bool IsCompatibleRailType(RailType rt)
{ {
return HasBit(this->m_compatible_railtypes, rt); return HasBit(this->compatible_railtypes, rt);
} }
RailTypes GetCompatibleRailTypes() const RailTypes GetCompatibleRailTypes() const
{ {
return this->m_compatible_railtypes; return this->compatible_railtypes;
} }
}; };
@ -64,11 +64,11 @@ public:
/** /**
* Called by YAPF to calculate cost estimate. Calculates distance to the destination * Called by YAPF to calculate cost estimate. Calculates distance to the destination
* adds it to the actual cost from origin and stores the sum to the Node::m_estimate * adds it to the actual cost from origin and stores the sum to the Node::estimate
*/ */
inline bool PfCalcEstimate(Node &n) inline bool PfCalcEstimate(Node &n)
{ {
n.m_estimate = n.m_cost; n.estimate = n.cost;
return true; return true;
} }
}; };
@ -102,11 +102,11 @@ public:
/** /**
* Called by YAPF to calculate cost estimate. Calculates distance to the destination * Called by YAPF to calculate cost estimate. Calculates distance to the destination
* adds it to the actual cost from origin and stores the sum to the Node::m_estimate. * adds it to the actual cost from origin and stores the sum to the Node::estimate.
*/ */
inline bool PfCalcEstimate(Node &n) inline bool PfCalcEstimate(Node &n)
{ {
n.m_estimate = n.m_cost; n.estimate = n.cost;
return true; return true;
} }
}; };
@ -119,10 +119,10 @@ public:
typedef typename Node::Key Key; ///< key to hash tables typedef typename Node::Key Key; ///< key to hash tables
protected: protected:
TileIndex m_destTile; TileIndex dest_tile;
TrackdirBits m_destTrackdirs; TrackdirBits dest_trackdirs;
StationID m_dest_station_id; StationID dest_station_id;
bool m_any_depot; bool any_depot;
/** to access inherited path finder */ /** to access inherited path finder */
Tpf &Yapf() Tpf &Yapf()
@ -133,7 +133,7 @@ protected:
public: public:
void SetDestination(const Train *v) void SetDestination(const Train *v)
{ {
this->m_any_depot = false; this->any_depot = false;
switch (v->current_order.GetType()) { switch (v->current_order.GetType()) {
case OT_GOTO_WAYPOINT: case OT_GOTO_WAYPOINT:
if (!Waypoint::Get(v->current_order.GetDestination())->IsSingleTile()) { if (!Waypoint::Get(v->current_order.GetDestination())->IsSingleTile()) {
@ -147,21 +147,21 @@ public:
[[fallthrough]]; [[fallthrough]];
case OT_GOTO_STATION: case OT_GOTO_STATION:
this->m_destTile = CalcClosestStationTile(v->current_order.GetDestination(), v->tile, v->current_order.IsType(OT_GOTO_STATION) ? STATION_RAIL : STATION_WAYPOINT); this->dest_tile = CalcClosestStationTile(v->current_order.GetDestination(), v->tile, v->current_order.IsType(OT_GOTO_STATION) ? STATION_RAIL : STATION_WAYPOINT);
this->m_dest_station_id = v->current_order.GetDestination(); this->dest_station_id = v->current_order.GetDestination();
this->m_destTrackdirs = INVALID_TRACKDIR_BIT; this->dest_trackdirs = INVALID_TRACKDIR_BIT;
break; break;
case OT_GOTO_DEPOT: case OT_GOTO_DEPOT:
if (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) { if (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
this->m_any_depot = true; this->any_depot = true;
} }
[[fallthrough]]; [[fallthrough]];
default: default:
this->m_destTile = v->dest_tile; this->dest_tile = v->dest_tile;
this->m_dest_station_id = INVALID_STATION; this->dest_station_id = INVALID_STATION;
this->m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL, 0)); this->dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL, 0));
break; break;
} }
this->CYapfDestinationRailBase::SetDestination(v); this->CYapfDestinationRailBase::SetDestination(v);
@ -176,29 +176,29 @@ public:
/** Called by YAPF to detect if node ends in the desired destination */ /** Called by YAPF to detect if node ends in the desired destination */
inline bool PfDetectDestination(TileIndex tile, Trackdir td) inline bool PfDetectDestination(TileIndex tile, Trackdir td)
{ {
if (this->m_dest_station_id != INVALID_STATION) { if (this->dest_station_id != INVALID_STATION) {
return HasStationTileRail(tile) return HasStationTileRail(tile)
&& (GetStationIndex(tile) == this->m_dest_station_id) && (GetStationIndex(tile) == this->dest_station_id)
&& (GetRailStationTrack(tile) == TrackdirToTrack(td)); && (GetRailStationTrack(tile) == TrackdirToTrack(td));
} }
if (this->m_any_depot) { if (this->any_depot) {
return IsRailDepotTile(tile); return IsRailDepotTile(tile);
} }
return (tile == this->m_destTile) && HasTrackdir(this->m_destTrackdirs, td); return (tile == this->dest_tile) && HasTrackdir(this->dest_trackdirs, td);
} }
/** /**
* Called by YAPF to calculate cost estimate. Calculates distance to the destination * Called by YAPF to calculate cost estimate. Calculates distance to the destination
* adds it to the actual cost from origin and stores the sum to the Node::m_estimate * adds it to the actual cost from origin and stores the sum to the Node::estimate
*/ */
inline bool PfCalcEstimate(Node &n) inline bool PfCalcEstimate(Node &n)
{ {
static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0}; static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
static const int dg_dir_to_y_offs[] = {0, 1, 0, -1}; static const int dg_dir_to_y_offs[] = {0, 1, 0, -1};
if (this->PfDetectDestination(n)) { if (this->PfDetectDestination(n)) {
n.m_estimate = n.m_cost; n.estimate = n.cost;
return true; return true;
} }
@ -206,15 +206,15 @@ public:
DiagDirection exitdir = TrackdirToExitdir(n.GetLastTrackdir()); DiagDirection exitdir = TrackdirToExitdir(n.GetLastTrackdir());
int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir]; int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir]; int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
int x2 = 2 * TileX(this->m_destTile); int x2 = 2 * TileX(this->dest_tile);
int y2 = 2 * TileY(this->m_destTile); int y2 = 2 * TileY(this->dest_tile);
int dx = abs(x1 - x2); int dx = abs(x1 - x2);
int dy = abs(y1 - y2); int dy = abs(y1 - y2);
int dmin = std::min(dx, dy); int dmin = std::min(dx, dy);
int dxy = abs(dx - dy); int dxy = abs(dx - dy);
int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2); int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
n.m_estimate = n.m_cost + d; n.estimate = n.cost + d;
assert(n.m_estimate >= n.m_parent->m_estimate); assert(n.estimate >= n.parent->estimate);
return true; return true;
} }
}; };

View File

@ -15,32 +15,32 @@
/** Yapf Node Key that evaluates hash from (and compares) tile & exit dir. */ /** Yapf Node Key that evaluates hash from (and compares) tile & exit dir. */
struct CYapfNodeKeyExitDir { struct CYapfNodeKeyExitDir {
TileIndex m_tile; TileIndex tile;
Trackdir m_td; Trackdir td;
DiagDirection m_exitdir; DiagDirection exitdir;
inline void Set(TileIndex tile, Trackdir td) inline void Set(TileIndex tile, Trackdir td)
{ {
this->m_tile = tile; this->tile = tile;
this->m_td = td; this->td = td;
this->m_exitdir = (this->m_td == INVALID_TRACKDIR) ? INVALID_DIAGDIR : TrackdirToExitdir(this->m_td); this->exitdir = (this->td == INVALID_TRACKDIR) ? INVALID_DIAGDIR : TrackdirToExitdir(this->td);
} }
inline int CalcHash() const inline int CalcHash() const
{ {
return this->m_exitdir | (this->m_tile.base() << 2); return this->exitdir | (this->tile.base() << 2);
} }
inline bool operator==(const CYapfNodeKeyExitDir &other) const inline bool operator==(const CYapfNodeKeyExitDir &other) const
{ {
return this->m_tile == other.m_tile && this->m_exitdir == other.m_exitdir; return this->tile == other.tile && this->exitdir == other.exitdir;
} }
void Dump(DumpTarget &dmp) const void Dump(DumpTarget &dmp) const
{ {
dmp.WriteTile("m_tile", this->m_tile); dmp.WriteTile("tile", this->tile);
dmp.WriteEnumT("m_td", this->m_td); dmp.WriteEnumT("td", this->td);
dmp.WriteEnumT("m_exitdir", this->m_exitdir); dmp.WriteEnumT("exitdir", this->exitdir);
} }
}; };
@ -48,12 +48,12 @@ struct CYapfNodeKeyTrackDir : public CYapfNodeKeyExitDir
{ {
inline int CalcHash() const inline int CalcHash() const
{ {
return this->m_td | (this->m_tile.base() << 4); return this->td | (this->tile.base() << 4);
} }
inline bool operator==(const CYapfNodeKeyTrackDir &other) const inline bool operator==(const CYapfNodeKeyTrackDir &other) const
{ {
return this->m_tile == other.m_tile && this->m_td == other.m_td; return this->tile == other.tile && this->td == other.td;
} }
}; };
@ -63,74 +63,74 @@ struct CYapfNodeT {
typedef Tkey_ Key; typedef Tkey_ Key;
typedef Tnode Node; typedef Tnode Node;
Tkey_ m_key; Tkey_ key;
Node *m_hash_next; Node *hash_next;
Node *m_parent; Node *parent;
int m_cost; int cost;
int m_estimate; int estimate;
bool m_is_choice; bool is_choice;
inline void Set(Node *parent, TileIndex tile, Trackdir td, bool is_choice) inline void Set(Node *parent, TileIndex tile, Trackdir td, bool is_choice)
{ {
this->m_key.Set(tile, td); this->key.Set(tile, td);
this->m_hash_next = nullptr; this->hash_next = nullptr;
this->m_parent = parent; this->parent = parent;
this->m_cost = 0; this->cost = 0;
this->m_estimate = 0; this->estimate = 0;
this->m_is_choice = is_choice; this->is_choice = is_choice;
} }
inline Node *GetHashNext() inline Node *GetHashNext()
{ {
return this->m_hash_next; return this->hash_next;
} }
inline void SetHashNext(Node *pNext) inline void SetHashNext(Node *pNext)
{ {
this->m_hash_next = pNext; this->hash_next = pNext;
} }
inline TileIndex GetTile() const inline TileIndex GetTile() const
{ {
return this->m_key.m_tile; return this->key.tile;
} }
inline Trackdir GetTrackdir() const inline Trackdir GetTrackdir() const
{ {
return this->m_key.m_td; return this->key.td;
} }
inline const Tkey_ &GetKey() const inline const Tkey_ &GetKey() const
{ {
return this->m_key; return this->key;
} }
inline int GetCost() const inline int GetCost() const
{ {
return this->m_cost; return this->cost;
} }
inline int GetCostEstimate() const inline int GetCostEstimate() const
{ {
return this->m_estimate; return this->estimate;
} }
inline bool GetIsChoice() const inline bool GetIsChoice() const
{ {
return this->m_is_choice; return this->is_choice;
} }
inline bool operator<(const Node &other) const inline bool operator<(const Node &other) const
{ {
return this->m_estimate < other.m_estimate; return this->estimate < other.estimate;
} }
void Dump(DumpTarget &dmp) const void Dump(DumpTarget &dmp) const
{ {
dmp.WriteStructT("m_key", &this->m_key); dmp.WriteStructT("key", &this->key);
dmp.WriteStructT("m_parent", this->m_parent); dmp.WriteStructT("parent", this->parent);
dmp.WriteValue("m_cost", this->m_cost); dmp.WriteValue("cost", this->cost);
dmp.WriteValue("m_estimate", this->m_estimate); dmp.WriteValue("estimate", this->estimate);
} }
}; };

View File

@ -19,7 +19,7 @@
/** key for cached segment cost for rail YAPF */ /** key for cached segment cost for rail YAPF */
struct CYapfRailSegmentKey struct CYapfRailSegmentKey
{ {
uint32_t m_value; uint32_t value;
inline CYapfRailSegmentKey(const CYapfNodeKeyTrackDir &node_key) inline CYapfRailSegmentKey(const CYapfNodeKeyTrackDir &node_key)
{ {
@ -28,32 +28,32 @@ struct CYapfRailSegmentKey
inline void Set(const CYapfRailSegmentKey &src) inline void Set(const CYapfRailSegmentKey &src)
{ {
this->m_value = src.m_value; this->value = src.value;
} }
inline void Set(const CYapfNodeKeyTrackDir &node_key) inline void Set(const CYapfNodeKeyTrackDir &node_key)
{ {
this->m_value = (node_key.m_tile.base() << 4) | node_key.m_td; this->value = (node_key.tile.base() << 4) | node_key.td;
} }
inline int32_t CalcHash() const inline int32_t CalcHash() const
{ {
return this->m_value; return this->value;
} }
inline TileIndex GetTile() const inline TileIndex GetTile() const
{ {
return (TileIndex)(this->m_value >> 4); return (TileIndex)(this->value >> 4);
} }
inline Trackdir GetTrackdir() const inline Trackdir GetTrackdir() const
{ {
return (Trackdir)(this->m_value & 0x0F); return (Trackdir)(this->value & 0x0F);
} }
inline bool operator==(const CYapfRailSegmentKey &other) const inline bool operator==(const CYapfRailSegmentKey &other) const
{ {
return this->m_value == other.m_value; return this->value == other.value;
} }
void Dump(DumpTarget &dmp) const void Dump(DumpTarget &dmp) const
@ -68,46 +68,46 @@ struct CYapfRailSegment
{ {
typedef CYapfRailSegmentKey Key; typedef CYapfRailSegmentKey Key;
CYapfRailSegmentKey m_key; CYapfRailSegmentKey key;
TileIndex m_last_tile = INVALID_TILE; TileIndex last_tile = INVALID_TILE;
Trackdir m_last_td = INVALID_TRACKDIR; Trackdir last_td = INVALID_TRACKDIR;
int m_cost = -1; int cost = -1;
TileIndex m_last_signal_tile = INVALID_TILE; TileIndex last_signal_tile = INVALID_TILE;
Trackdir m_last_signal_td = INVALID_TRACKDIR; Trackdir last_signal_td = INVALID_TRACKDIR;
EndSegmentReasonBits m_end_segment_reason = ESRB_NONE; EndSegmentReasonBits end_segment_reason = ESRB_NONE;
CYapfRailSegment *m_hash_next = nullptr; CYapfRailSegment *hash_next = nullptr;
inline CYapfRailSegment(const CYapfRailSegmentKey &key) : m_key(key) {} inline CYapfRailSegment(const CYapfRailSegmentKey &key) : key(key) {}
inline const Key &GetKey() const inline const Key &GetKey() const
{ {
return this->m_key; return this->key;
} }
inline TileIndex GetTile() const inline TileIndex GetTile() const
{ {
return this->m_key.GetTile(); return this->key.GetTile();
} }
inline CYapfRailSegment *GetHashNext() inline CYapfRailSegment *GetHashNext()
{ {
return this->m_hash_next; return this->hash_next;
} }
inline void SetHashNext(CYapfRailSegment *next) inline void SetHashNext(CYapfRailSegment *next)
{ {
this->m_hash_next = next; this->hash_next = next;
} }
void Dump(DumpTarget &dmp) const void Dump(DumpTarget &dmp) const
{ {
dmp.WriteStructT("m_key", &this->m_key); dmp.WriteStructT("key", &this->key);
dmp.WriteTile("m_last_tile", this->m_last_tile); dmp.WriteTile("last_tile", this->last_tile);
dmp.WriteEnumT("m_last_td", this->m_last_td); dmp.WriteEnumT("last_td", this->last_td);
dmp.WriteValue("m_cost", this->m_cost); dmp.WriteValue("cost", this->cost);
dmp.WriteTile("m_last_signal_tile", this->m_last_signal_tile); dmp.WriteTile("last_signal_tile", this->last_signal_tile);
dmp.WriteEnumT("m_last_signal_td", this->m_last_signal_td); dmp.WriteEnumT("last_signal_td", this->last_signal_td);
dmp.WriteEnumT("m_end_segment_reason", this->m_end_segment_reason); dmp.WriteEnumT("end_segment_reason", this->end_segment_reason);
} }
}; };
@ -119,27 +119,27 @@ struct CYapfRailNodeT
typedef CYapfNodeT<Tkey_, CYapfRailNodeT<Tkey_> > base; typedef CYapfNodeT<Tkey_, CYapfRailNodeT<Tkey_> > base;
typedef CYapfRailSegment CachedData; typedef CYapfRailSegment CachedData;
CYapfRailSegment *m_segment; CYapfRailSegment *segment;
uint16_t m_num_signals_passed; uint16_t num_signals_passed;
union { union {
uint32_t m_inherited_flags; uint32_t inherited_flags;
struct { struct {
bool m_targed_seen; bool target_seen;
bool m_choice_seen; bool choice_seen;
bool m_last_signal_was_red; bool last_signal_was_red;
} flags_s; } flags_s;
} flags_u; } flags_u;
SignalType m_last_red_signal_type; SignalType last_red_signal_type;
SignalType m_last_signal_type; SignalType last_signal_type;
inline void Set(CYapfRailNodeT *parent, TileIndex tile, Trackdir td, bool is_choice) inline void Set(CYapfRailNodeT *parent, TileIndex tile, Trackdir td, bool is_choice)
{ {
this->base::Set(parent, tile, td, is_choice); this->base::Set(parent, tile, td, is_choice);
this->m_segment = nullptr; this->segment = nullptr;
if (parent == nullptr) { if (parent == nullptr) {
this->m_num_signals_passed = 0; this->num_signals_passed = 0;
this->flags_u.m_inherited_flags = 0; this->flags_u.inherited_flags = 0;
this->m_last_red_signal_type = SIGTYPE_BLOCK; this->last_red_signal_type = SIGTYPE_BLOCK;
/* We use PBS as initial signal type because if we are in /* We use PBS as initial signal type because if we are in
* a PBS section and need to route, i.e. we're at a safe * a PBS section and need to route, i.e. we're at a safe
* waiting point of a station, we need to account for the * waiting point of a station, we need to account for the
@ -150,33 +150,33 @@ struct CYapfRailNodeT
* then avoiding that train with help of the reservation * then avoiding that train with help of the reservation
* costs is not a bad thing, actually it would probably * costs is not a bad thing, actually it would probably
* be a good thing to do. */ * be a good thing to do. */
this->m_last_signal_type = SIGTYPE_PBS; this->last_signal_type = SIGTYPE_PBS;
} else { } else {
this->m_num_signals_passed = parent->m_num_signals_passed; this->num_signals_passed = parent->num_signals_passed;
this->flags_u.m_inherited_flags = parent->flags_u.m_inherited_flags; this->flags_u.inherited_flags = parent->flags_u.inherited_flags;
this->m_last_red_signal_type = parent->m_last_red_signal_type; this->last_red_signal_type = parent->last_red_signal_type;
this->m_last_signal_type = parent->m_last_signal_type; this->last_signal_type = parent->last_signal_type;
} }
this->flags_u.flags_s.m_choice_seen |= is_choice; this->flags_u.flags_s.choice_seen |= is_choice;
} }
inline TileIndex GetLastTile() const inline TileIndex GetLastTile() const
{ {
assert(this->m_segment != nullptr); assert(this->segment != nullptr);
return this->m_segment->m_last_tile; return this->segment->last_tile;
} }
inline Trackdir GetLastTrackdir() const inline Trackdir GetLastTrackdir() const
{ {
assert(this->m_segment != nullptr); assert(this->segment != nullptr);
return this->m_segment->m_last_td; return this->segment->last_td;
} }
inline void SetLastTileTrackdir(TileIndex tile, Trackdir td) inline void SetLastTileTrackdir(TileIndex tile, Trackdir td)
{ {
assert(this->m_segment != nullptr); assert(this->segment != nullptr);
this->m_segment->m_last_tile = tile; this->segment->last_tile = tile;
this->m_segment->m_last_td = td; this->segment->last_td = td;
} }
template <class Tbase, class Tfunc, class Tpf> template <class Tbase, class Tfunc, class Tpf>
@ -190,9 +190,9 @@ struct CYapfRailNodeT
if (!((obj.*func)(cur, cur_td))) return false; if (!((obj.*func)(cur, cur_td))) return false;
if (!ft.Follow(cur, cur_td)) break; if (!ft.Follow(cur, cur_td)) break;
cur = ft.m_new_tile; cur = ft.new_tile;
assert(KillFirstBit(ft.m_new_td_bits) == TRACKDIR_BIT_NONE); assert(KillFirstBit(ft.new_td_bits) == TRACKDIR_BIT_NONE);
cur_td = FindFirstTrackdir(ft.m_new_td_bits); cur_td = FindFirstTrackdir(ft.new_td_bits);
} }
return (obj.*func)(cur, cur_td); return (obj.*func)(cur, cur_td);
@ -201,12 +201,12 @@ struct CYapfRailNodeT
void Dump(DumpTarget &dmp) const void Dump(DumpTarget &dmp) const
{ {
this->base::Dump(dmp); this->base::Dump(dmp);
dmp.WriteStructT("m_segment", this->m_segment); dmp.WriteStructT("segment", this->segment);
dmp.WriteValue("m_num_signals_passed", this->m_num_signals_passed); dmp.WriteValue("num_signals_passed", this->num_signals_passed);
dmp.WriteValue("m_targed_seen", this->flags_u.flags_s.m_targed_seen ? "Yes" : "No"); dmp.WriteValue("target_seen", this->flags_u.flags_s.target_seen ? "Yes" : "No");
dmp.WriteValue("m_choice_seen", this->flags_u.flags_s.m_choice_seen ? "Yes" : "No"); dmp.WriteValue("choice_seen", this->flags_u.flags_s.choice_seen ? "Yes" : "No");
dmp.WriteValue("m_last_signal_was_red", this->flags_u.flags_s.m_last_signal_was_red ? "Yes" : "No"); dmp.WriteValue("last_signal_was_red", this->flags_u.flags_s.last_signal_was_red ? "Yes" : "No");
dmp.WriteEnumT("m_last_red_signal_type", this->m_last_red_signal_type); dmp.WriteEnumT("last_red_signal_type", this->last_red_signal_type);
} }
}; };

View File

@ -20,14 +20,14 @@ template <class Tkey_>
struct CYapfRoadNodeT : CYapfNodeT<Tkey_, CYapfRoadNodeT<Tkey_> > { struct CYapfRoadNodeT : CYapfNodeT<Tkey_, CYapfRoadNodeT<Tkey_> > {
typedef CYapfNodeT<Tkey_, CYapfRoadNodeT<Tkey_> > base; typedef CYapfNodeT<Tkey_, CYapfRoadNodeT<Tkey_> > base;
TileIndex m_segment_last_tile; TileIndex segment_last_tile;
Trackdir m_segment_last_td; Trackdir segment_last_td;
void Set(CYapfRoadNodeT *parent, TileIndex tile, Trackdir td, bool is_choice) void Set(CYapfRoadNodeT *parent, TileIndex tile, Trackdir td, bool is_choice)
{ {
this->base::Set(parent, tile, td, is_choice); this->base::Set(parent, tile, td, is_choice);
this->m_segment_last_tile = tile; this->segment_last_tile = tile;
this->m_segment_last_td = td; this->segment_last_td = td;
} }
}; };

View File

@ -20,14 +20,14 @@ template <class Tkey_>
struct CYapfShipNodeT : CYapfNodeT<Tkey_, CYapfShipNodeT<Tkey_> > { struct CYapfShipNodeT : CYapfNodeT<Tkey_, CYapfShipNodeT<Tkey_> > {
typedef CYapfNodeT<Tkey_, CYapfShipNodeT<Tkey_> > base; typedef CYapfNodeT<Tkey_, CYapfShipNodeT<Tkey_> > base;
TileIndex m_segment_last_tile; TileIndex segment_last_tile;
Trackdir m_segment_last_td; Trackdir segment_last_td;
void Set(CYapfShipNodeT *parent, TileIndex tile, Trackdir td, bool is_choice) void Set(CYapfShipNodeT *parent, TileIndex tile, Trackdir td, bool is_choice)
{ {
this->base::Set(parent, tile, td, is_choice); this->base::Set(parent, tile, td, is_choice);
this->m_segment_last_tile = tile; this->segment_last_tile = tile;
this->m_segment_last_td = td; this->segment_last_td = td;
} }
}; };

View File

@ -48,20 +48,20 @@ protected:
} }
private: private:
TileIndex m_res_dest; ///< The reservation target tile TileIndex res_dest_tile; ///< The reservation target tile
Trackdir m_res_dest_td; ///< The reservation target trackdir Trackdir res_dest_td; ///< The reservation target trackdir
Node *m_res_node; ///< The reservation target node Node *res_dest_node; ///< The reservation target node
TileIndex m_res_fail_tile; ///< The tile where the reservation failed TileIndex res_fail_tile; ///< The tile where the reservation failed
Trackdir m_res_fail_td; ///< The trackdir where the reservation failed Trackdir res_fail_td; ///< The trackdir where the reservation failed
TileIndex m_origin_tile; ///< Tile our reservation will originate from TileIndex origin_tile; ///< Tile our reservation will originate from
std::vector<std::pair<TileIndex, Trackdir>> m_signals_set_to_red; ///< List of signals turned red during a path reservation. std::vector<std::pair<TileIndex, Trackdir>> signals_set_to_red; ///< List of signals turned red during a path reservation.
bool FindSafePositionProc(TileIndex tile, Trackdir td) bool FindSafePositionProc(TileIndex tile, Trackdir td)
{ {
if (IsSafeWaitingPosition(Yapf().GetVehicle(), tile, td, true, !TrackFollower::Allow90degTurns())) { if (IsSafeWaitingPosition(Yapf().GetVehicle(), tile, td, true, !TrackFollower::Allow90degTurns())) {
this->m_res_dest = tile; this->res_dest_tile = tile;
this->m_res_dest_td = td; this->res_dest_td = td;
return false; // Stop iterating segment return false; // Stop iterating segment
} }
return true; return true;
@ -78,7 +78,7 @@ private:
SetRailStationReservation(tile, true); SetRailStationReservation(tile, true);
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
tile = TileAdd(tile, diff); tile = TileAdd(tile, diff);
} while (IsCompatibleTrainStationTile(tile, start) && tile != this->m_origin_tile); } while (IsCompatibleTrainStationTile(tile, start) && tile != this->origin_tile);
TriggerStationRandomisation(nullptr, start, SRT_PATH_RESERVATION); TriggerStationRandomisation(nullptr, start, SRT_PATH_RESERVATION);
@ -92,26 +92,26 @@ private:
if (IsRailStationTile(tile)) { if (IsRailStationTile(tile)) {
if (!ReserveRailStationPlatform(tile, TrackdirToExitdir(rev_td))) { if (!ReserveRailStationPlatform(tile, TrackdirToExitdir(rev_td))) {
/* Platform could not be reserved, undo. */ /* Platform could not be reserved, undo. */
this->m_res_fail_tile = tile; this->res_fail_tile = tile;
this->m_res_fail_td = td; this->res_fail_td = td;
} }
} else { } else {
if (!TryReserveRailTrack(tile, TrackdirToTrack(td))) { if (!TryReserveRailTrack(tile, TrackdirToTrack(td))) {
/* Tile couldn't be reserved, undo. */ /* Tile couldn't be reserved, undo. */
this->m_res_fail_tile = tile; this->res_fail_tile = tile;
this->m_res_fail_td = td; this->res_fail_td = td;
return false; return false;
} }
/* Green path signal opposing the path? Turn to red. */ /* Green path signal opposing the path? Turn to red. */
if (HasPbsSignalOnTrackdir(tile, rev_td) && GetSignalStateByTrackdir(tile, rev_td) == SIGNAL_STATE_GREEN) { if (HasPbsSignalOnTrackdir(tile, rev_td) && GetSignalStateByTrackdir(tile, rev_td) == SIGNAL_STATE_GREEN) {
this->m_signals_set_to_red.emplace_back(tile, rev_td); this->signals_set_to_red.emplace_back(tile, rev_td);
SetSignalStateByTrackdir(tile, rev_td, SIGNAL_STATE_RED); SetSignalStateByTrackdir(tile, rev_td, SIGNAL_STATE_RED);
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
} }
} }
return tile != this->m_res_dest || td != this->m_res_dest_td; return tile != this->res_dest_tile || td != this->res_dest_td;
} }
/** Unreserve a single track/platform. Stops when the previous failer is reached. */ /** Unreserve a single track/platform. Stops when the previous failer is reached. */
@ -120,68 +120,68 @@ private:
if (IsRailStationTile(tile)) { if (IsRailStationTile(tile)) {
TileIndex start = tile; TileIndex start = tile;
TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(ReverseTrackdir(td))); TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(ReverseTrackdir(td)));
while ((tile != this->m_res_fail_tile || td != this->m_res_fail_td) && IsCompatibleTrainStationTile(tile, start)) { while ((tile != this->res_fail_tile || td != this->res_fail_td) && IsCompatibleTrainStationTile(tile, start)) {
SetRailStationReservation(tile, false); SetRailStationReservation(tile, false);
tile = TileAdd(tile, diff); tile = TileAdd(tile, diff);
} }
} else if (tile != this->m_res_fail_tile || td != this->m_res_fail_td) { } else if (tile != this->res_fail_tile || td != this->res_fail_td) {
UnreserveRailTrack(tile, TrackdirToTrack(td)); UnreserveRailTrack(tile, TrackdirToTrack(td));
} }
return (tile != this->m_res_dest || td != this->m_res_dest_td) && (tile != this->m_res_fail_tile || td != this->m_res_fail_td); return (tile != this->res_dest_tile || td != this->res_dest_td) && (tile != this->res_fail_tile || td != this->res_fail_td);
} }
public: public:
/** Set the target to where the reservation should be extended. */ /** Set the target to where the reservation should be extended. */
inline void SetReservationTarget(Node *node, TileIndex tile, Trackdir td) inline void SetReservationTarget(Node *node, TileIndex tile, Trackdir td)
{ {
this->m_res_node = node; this->res_dest_node = node;
this->m_res_dest = tile; this->res_dest_tile = tile;
this->m_res_dest_td = td; this->res_dest_td = td;
} }
/** Check the node for a possible reservation target. */ /** Check the node for a possible reservation target. */
inline void FindSafePositionOnNode(Node *node) inline void FindSafePositionOnNode(Node *node)
{ {
assert(node->m_parent != nullptr); assert(node->parent != nullptr);
/* We will never pass more than two signals, no need to check for a safe tile. */ /* We will never pass more than two signals, no need to check for a safe tile. */
if (node->m_parent->m_num_signals_passed >= 2) return; if (node->parent->num_signals_passed >= 2) return;
if (!node->IterateTiles(Yapf().GetVehicle(), Yapf(), *this, &CYapfReserveTrack<Types>::FindSafePositionProc)) { if (!node->IterateTiles(Yapf().GetVehicle(), Yapf(), *this, &CYapfReserveTrack<Types>::FindSafePositionProc)) {
this->m_res_node = node; this->res_dest_node = node;
} }
} }
/** Try to reserve the path till the reservation target. */ /** Try to reserve the path till the reservation target. */
bool TryReservePath(PBSTileInfo *target, TileIndex origin) bool TryReservePath(PBSTileInfo *target, TileIndex origin)
{ {
this->m_res_fail_tile = INVALID_TILE; this->res_fail_tile = INVALID_TILE;
this->m_origin_tile = origin; this->origin_tile = origin;
if (target != nullptr) { if (target != nullptr) {
target->tile = this->m_res_dest; target->tile = this->res_dest_tile;
target->trackdir = this->m_res_dest_td; target->trackdir = this->res_dest_td;
target->okay = false; target->okay = false;
} }
/* Don't bother if the target is reserved. */ /* Don't bother if the target is reserved. */
if (!IsWaitingPositionFree(Yapf().GetVehicle(), this->m_res_dest, this->m_res_dest_td)) return false; if (!IsWaitingPositionFree(Yapf().GetVehicle(), this->res_dest_tile, this->res_dest_td)) return false;
this->m_signals_set_to_red.clear(); this->signals_set_to_red.clear();
for (Node *node = this->m_res_node; node->m_parent != nullptr; node = node->m_parent) { for (Node *node = this->res_dest_node; node->parent != nullptr; node = node->parent) {
node->IterateTiles(Yapf().GetVehicle(), Yapf(), *this, &CYapfReserveTrack<Types>::ReserveSingleTrack); node->IterateTiles(Yapf().GetVehicle(), Yapf(), *this, &CYapfReserveTrack<Types>::ReserveSingleTrack);
if (this->m_res_fail_tile != INVALID_TILE) { if (this->res_fail_tile != INVALID_TILE) {
/* Reservation failed, undo. */ /* Reservation failed, undo. */
Node *fail_node = this->m_res_node; Node *fail_node = this->res_dest_node;
TileIndex stop_tile = this->m_res_fail_tile; TileIndex stop_tile = this->res_fail_tile;
do { do {
/* If this is the node that failed, stop at the failed tile. */ /* If this is the node that failed, stop at the failed tile. */
this->m_res_fail_tile = fail_node == node ? stop_tile : INVALID_TILE; this->res_fail_tile = fail_node == node ? stop_tile : INVALID_TILE;
fail_node->IterateTiles(Yapf().GetVehicle(), Yapf(), *this, &CYapfReserveTrack<Types>::UnreserveSingleTrack); fail_node->IterateTiles(Yapf().GetVehicle(), Yapf(), *this, &CYapfReserveTrack<Types>::UnreserveSingleTrack);
} while (fail_node != node && (fail_node = fail_node->m_parent) != nullptr); } while (fail_node != node && (fail_node = fail_node->parent) != nullptr);
/* Re-instate green path signals we turned to red. */ /* Re-instate green path signals we turned to red. */
for (auto [sig_tile, td] : this->m_signals_set_to_red) { for (auto [sig_tile, td] : this->signals_set_to_red) {
SetSignalStateByTrackdir(sig_tile, td, SIGNAL_STATE_GREEN); SetSignalStateByTrackdir(sig_tile, td, SIGNAL_STATE_GREEN);
} }
@ -191,7 +191,7 @@ public:
if (target != nullptr) target->okay = true; if (target != nullptr) target->okay = true;
if (Yapf().CanUseGlobalCache(*this->m_res_node)) { if (Yapf().CanUseGlobalCache(*this->res_dest_node)) {
YapfNotifyTrackLayoutChange(INVALID_TILE, INVALID_TRACK); YapfNotifyTrackLayoutChange(INVALID_TILE, INVALID_TRACK);
} }
@ -280,13 +280,13 @@ public:
/* walk through the path back to the origin */ /* walk through the path back to the origin */
Node *pNode = n; Node *pNode = n;
while (pNode->m_parent != nullptr) { while (pNode->parent != nullptr) {
pNode = pNode->m_parent; pNode = pNode->parent;
} }
/* if the origin node is our front vehicle tile/Trackdir then we didn't reverse /* if the origin node is our front vehicle tile/Trackdir then we didn't reverse
* but we can also look at the cost (== 0 -> not reversed, == reverse_penalty -> reversed) */ * but we can also look at the cost (== 0 -> not reversed, == reverse_penalty -> reversed) */
return FindDepotData(n->GetLastTile(), n->m_cost, pNode->m_cost != 0); return FindDepotData(n->GetLastTile(), n->cost, pNode->cost != 0);
} }
}; };
@ -362,9 +362,9 @@ public:
/* Walk through the path back to the origin. */ /* Walk through the path back to the origin. */
Node *pPrev = nullptr; Node *pPrev = nullptr;
while (pNode->m_parent != nullptr) { while (pNode->parent != nullptr) {
pPrev = pNode; pPrev = pNode;
pNode = pNode->m_parent; pNode = pNode->parent;
this->FindSafePositionOnNode(pPrev); this->FindSafePositionOnNode(pPrev);
} }
@ -454,9 +454,9 @@ public:
/* path was found or at least suggested /* path was found or at least suggested
* walk through the path back to the origin */ * walk through the path back to the origin */
Node *pPrev = nullptr; Node *pPrev = nullptr;
while (pNode->m_parent != nullptr) { while (pNode->parent != nullptr) {
pPrev = pNode; pPrev = pNode;
pNode = pNode->m_parent; pNode = pNode->parent;
this->FindSafePositionOnNode(pPrev); this->FindSafePositionOnNode(pPrev);
} }
@ -476,7 +476,7 @@ public:
} }
/* Treat the path as found if stopped on the first two way signal(s). */ /* Treat the path as found if stopped on the first two way signal(s). */
path_found |= Yapf().m_stopped_on_first_two_way_signal; path_found |= Yapf().stopped_on_first_two_way_signal;
return next_trackdir; return next_trackdir;
} }
@ -513,13 +513,13 @@ public:
/* path was found /* path was found
* walk through the path back to the origin */ * walk through the path back to the origin */
Node *pNode = Yapf().GetBestNode(); Node *pNode = Yapf().GetBestNode();
while (pNode->m_parent != nullptr) { while (pNode->parent != nullptr) {
pNode = pNode->m_parent; pNode = pNode->parent;
} }
/* check if it was reversed origin */ /* check if it was reversed origin */
Node &best_org_node = *pNode; Node &best_org_node = *pNode;
bool reversed = (best_org_node.m_cost != 0); bool reversed = (best_org_node.cost != 0);
return reversed; return reversed;
} }
}; };

View File

@ -25,9 +25,9 @@ public:
typedef typename Node::Key Key; ///< key to hash tables typedef typename Node::Key Key; ///< key to hash tables
protected: protected:
int m_max_cost; int max_cost;
CYapfCostRoadT() : m_max_cost(0) {}; CYapfCostRoadT() : max_cost(0) {};
/** to access inherited path finder */ /** to access inherited path finder */
Tpf &Yapf() Tpf &Yapf()
@ -103,7 +103,7 @@ protected:
public: public:
inline void SetMaxCost(int max_cost) inline void SetMaxCost(int max_cost)
{ {
this->m_max_cost = max_cost; this->max_cost = max_cost;
} }
/** /**
@ -115,10 +115,10 @@ public:
{ {
int segment_cost = 0; int segment_cost = 0;
uint tiles = 0; uint tiles = 0;
/* start at n.m_key.m_tile / n.m_key.m_td and walk to the end of segment */ /* start at n.key.tile / n.key.td and walk to the end of segment */
TileIndex tile = n.m_key.m_tile; TileIndex tile = n.key.tile;
Trackdir trackdir = n.m_key.m_td; Trackdir trackdir = n.key.td;
int parent_cost = (n.m_parent != nullptr) ? n.m_parent->m_cost : 0; int parent_cost = (n.parent != nullptr) ? n.parent->cost : 0;
for (;;) { for (;;) {
/* base tile cost depending on distance between edges */ /* base tile cost depending on distance between edges */
@ -130,7 +130,7 @@ public:
/* Finish if we already exceeded the maximum path cost (i.e. when /* Finish if we already exceeded the maximum path cost (i.e. when
* searching for the nearest depot). */ * searching for the nearest depot). */
if (this->m_max_cost > 0 && (parent_cost + segment_cost) > this->m_max_cost) { if (this->max_cost > 0 && (parent_cost + segment_cost) > this->max_cost) {
return false; return false;
} }
@ -145,39 +145,39 @@ public:
if (!F.Follow(tile, trackdir)) break; if (!F.Follow(tile, trackdir)) break;
/* if there are more trackdirs available & reachable, we are at the end of segment */ /* if there are more trackdirs available & reachable, we are at the end of segment */
if (KillFirstBit(F.m_new_td_bits) != TRACKDIR_BIT_NONE) break; if (KillFirstBit(F.new_td_bits) != TRACKDIR_BIT_NONE) break;
Trackdir new_td = (Trackdir)FindFirstBit(F.m_new_td_bits); Trackdir new_td = (Trackdir)FindFirstBit(F.new_td_bits);
/* stop if RV is on simple loop with no junctions */ /* stop if RV is on simple loop with no junctions */
if (F.m_new_tile == n.m_key.m_tile && new_td == n.m_key.m_td) return false; if (F.new_tile == n.key.tile && new_td == n.key.td) return false;
/* if we skipped some tunnel tiles, add their cost */ /* if we skipped some tunnel tiles, add their cost */
segment_cost += F.m_tiles_skipped * YAPF_TILE_LENGTH; segment_cost += F.tiles_skipped * YAPF_TILE_LENGTH;
tiles += F.m_tiles_skipped + 1; tiles += F.tiles_skipped + 1;
/* add hilly terrain penalty */ /* add hilly terrain penalty */
segment_cost += Yapf().SlopeCost(tile, F.m_new_tile, trackdir); segment_cost += Yapf().SlopeCost(tile, F.new_tile, trackdir);
/* add min/max speed penalties */ /* add min/max speed penalties */
int min_speed = 0; int min_speed = 0;
int max_veh_speed = std::min<int>(v->GetDisplayMaxSpeed(), v->current_order.GetMaxSpeed() * 2); int max_veh_speed = std::min<int>(v->GetDisplayMaxSpeed(), v->current_order.GetMaxSpeed() * 2);
int max_speed = F.GetSpeedLimit(&min_speed); int max_speed = F.GetSpeedLimit(&min_speed);
if (max_speed < max_veh_speed) segment_cost += YAPF_TILE_LENGTH * (max_veh_speed - max_speed) * (4 + F.m_tiles_skipped) / max_veh_speed; if (max_speed < max_veh_speed) segment_cost += YAPF_TILE_LENGTH * (max_veh_speed - max_speed) * (4 + F.tiles_skipped) / max_veh_speed;
if (min_speed > max_veh_speed) segment_cost += YAPF_TILE_LENGTH * (min_speed - max_veh_speed); if (min_speed > max_veh_speed) segment_cost += YAPF_TILE_LENGTH * (min_speed - max_veh_speed);
/* move to the next tile */ /* move to the next tile */
tile = F.m_new_tile; tile = F.new_tile;
trackdir = new_td; trackdir = new_td;
if (tiles > MAX_MAP_SIZE) break; if (tiles > MAX_MAP_SIZE) break;
} }
/* save end of segment back to the node */ /* save end of segment back to the node */
n.m_segment_last_tile = tile; n.segment_last_tile = tile;
n.m_segment_last_td = trackdir; n.segment_last_td = trackdir;
/* save also tile cost */ /* save also tile cost */
n.m_cost = parent_cost + segment_cost; n.cost = parent_cost + segment_cost;
return true; return true;
} }
}; };
@ -201,7 +201,7 @@ public:
/** Called by YAPF to detect if node ends in the desired destination */ /** Called by YAPF to detect if node ends in the desired destination */
inline bool PfDetectDestination(Node &n) inline bool PfDetectDestination(Node &n)
{ {
return IsRoadDepotTile(n.m_segment_last_tile); return IsRoadDepotTile(n.segment_last_tile);
} }
inline bool PfDetectDestinationTile(TileIndex tile, Trackdir) inline bool PfDetectDestinationTile(TileIndex tile, Trackdir)
@ -215,7 +215,7 @@ public:
*/ */
inline bool PfCalcEstimate(Node &n) inline bool PfCalcEstimate(Node &n)
{ {
n.m_estimate = n.m_cost; n.estimate = n.cost;
return true; return true;
} }
}; };
@ -231,37 +231,37 @@ public:
typedef typename Node::Key Key; ///< key to hash tables typedef typename Node::Key Key; ///< key to hash tables
protected: protected:
TileIndex m_destTile; TileIndex dest_tile;
TrackdirBits m_destTrackdirs; TrackdirBits dest_trackdirs;
StationID m_dest_station; StationID dest_station;
StationType m_station_type; StationType station_type;
bool m_non_artic; bool non_artic;
public: public:
void SetDestination(const RoadVehicle *v) void SetDestination(const RoadVehicle *v)
{ {
if (v->current_order.IsType(OT_GOTO_STATION)) { if (v->current_order.IsType(OT_GOTO_STATION)) {
this->m_dest_station = v->current_order.GetDestination(); this->dest_station = v->current_order.GetDestination();
this->m_station_type = v->IsBus() ? STATION_BUS : STATION_TRUCK; this->station_type = v->IsBus() ? STATION_BUS : STATION_TRUCK;
this->m_destTile = CalcClosestStationTile(this->m_dest_station, v->tile, this->m_station_type); this->dest_tile = CalcClosestStationTile(this->dest_station, v->tile, this->station_type);
this->m_non_artic = !v->HasArticulatedPart(); this->non_artic = !v->HasArticulatedPart();
this->m_destTrackdirs = INVALID_TRACKDIR_BIT; this->dest_trackdirs = INVALID_TRACKDIR_BIT;
} else if (v->current_order.IsType(OT_GOTO_WAYPOINT)) { } else if (v->current_order.IsType(OT_GOTO_WAYPOINT)) {
this->m_dest_station = v->current_order.GetDestination(); this->dest_station = v->current_order.GetDestination();
this->m_station_type = STATION_ROADWAYPOINT; this->station_type = STATION_ROADWAYPOINT;
this->m_destTile = CalcClosestStationTile(this->m_dest_station, v->tile, this->m_station_type); this->dest_tile = CalcClosestStationTile(this->dest_station, v->tile, this->station_type);
this->m_non_artic = !v->HasArticulatedPart(); this->non_artic = !v->HasArticulatedPart();
this->m_destTrackdirs = INVALID_TRACKDIR_BIT; this->dest_trackdirs = INVALID_TRACKDIR_BIT;
} else { } else {
this->m_dest_station = INVALID_STATION; this->dest_station = INVALID_STATION;
this->m_destTile = v->dest_tile; this->dest_tile = v->dest_tile;
this->m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype))); this->dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype)));
} }
} }
const Station *GetDestinationStation() const const Station *GetDestinationStation() const
{ {
return this->m_dest_station != INVALID_STATION ? Station::GetIfValid(this->m_dest_station) : nullptr; return this->dest_station != INVALID_STATION ? Station::GetIfValid(this->dest_station) : nullptr;
} }
protected: protected:
@ -275,19 +275,19 @@ public:
/** Called by YAPF to detect if node ends in the desired destination */ /** Called by YAPF to detect if node ends in the desired destination */
inline bool PfDetectDestination(Node &n) inline bool PfDetectDestination(Node &n)
{ {
return this->PfDetectDestinationTile(n.m_segment_last_tile, n.m_segment_last_td); return this->PfDetectDestinationTile(n.segment_last_tile, n.segment_last_td);
} }
inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir) inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir)
{ {
if (this->m_dest_station != INVALID_STATION) { if (this->dest_station != INVALID_STATION) {
return IsTileType(tile, MP_STATION) && return IsTileType(tile, MP_STATION) &&
GetStationIndex(tile) == this->m_dest_station && GetStationIndex(tile) == this->dest_station &&
(this->m_station_type == GetStationType(tile)) && (this->station_type == GetStationType(tile)) &&
(this->m_non_artic || IsDriveThroughStopTile(tile)); (this->non_artic || IsDriveThroughStopTile(tile));
} }
return tile == this->m_destTile && HasTrackdir(this->m_destTrackdirs, trackdir); return tile == this->dest_tile && HasTrackdir(this->dest_trackdirs, trackdir);
} }
/** /**
@ -299,23 +299,23 @@ public:
static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0}; static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
static const int dg_dir_to_y_offs[] = {0, 1, 0, -1}; static const int dg_dir_to_y_offs[] = {0, 1, 0, -1};
if (this->PfDetectDestination(n)) { if (this->PfDetectDestination(n)) {
n.m_estimate = n.m_cost; n.estimate = n.cost;
return true; return true;
} }
TileIndex tile = n.m_segment_last_tile; TileIndex tile = n.segment_last_tile;
DiagDirection exitdir = TrackdirToExitdir(n.m_segment_last_td); DiagDirection exitdir = TrackdirToExitdir(n.segment_last_td);
int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir]; int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir]; int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
int x2 = 2 * TileX(this->m_destTile); int x2 = 2 * TileX(this->dest_tile);
int y2 = 2 * TileY(this->m_destTile); int y2 = 2 * TileY(this->dest_tile);
int dx = abs(x1 - x2); int dx = abs(x1 - x2);
int dy = abs(y1 - y2); int dy = abs(y1 - y2);
int dmin = std::min(dx, dy); int dmin = std::min(dx, dy);
int dxy = abs(dx - dy); int dxy = abs(dx - dy);
int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2); int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
n.m_estimate = n.m_cost + d; n.estimate = n.cost + d;
assert(n.m_estimate >= n.m_parent->m_estimate); assert(n.estimate >= n.parent->estimate);
return true; return true;
} }
}; };
@ -348,7 +348,7 @@ public:
inline void PfFollowNode(Node &old_node) inline void PfFollowNode(Node &old_node)
{ {
TrackFollower F(Yapf().GetVehicle()); TrackFollower F(Yapf().GetVehicle());
if (F.Follow(old_node.m_segment_last_tile, old_node.m_segment_last_td)) { if (F.Follow(old_node.segment_last_tile, old_node.segment_last_td)) {
Yapf().AddMultipleNodes(&old_node, F); Yapf().AddMultipleNodes(&old_node, F);
} }
} }
@ -394,17 +394,17 @@ public:
Node *pNode = Yapf().GetBestNode(); Node *pNode = Yapf().GetBestNode();
if (pNode != nullptr) { if (pNode != nullptr) {
uint steps = 0; uint steps = 0;
for (Node *n = pNode; n->m_parent != nullptr; n = n->m_parent) steps++; for (Node *n = pNode; n->parent != nullptr; n = n->parent) steps++;
/* path was found or at least suggested /* path was found or at least suggested
* walk through the path back to its origin */ * walk through the path back to its origin */
while (pNode->m_parent != nullptr) { while (pNode->parent != nullptr) {
steps--; steps--;
if (pNode->GetIsChoice() && steps < YAPF_ROADVEH_PATH_CACHE_SEGMENTS) { if (pNode->GetIsChoice() && steps < YAPF_ROADVEH_PATH_CACHE_SEGMENTS) {
path_cache.td.push_front(pNode->GetTrackdir()); path_cache.td.push_front(pNode->GetTrackdir());
path_cache.tile.push_front(pNode->GetTile()); path_cache.tile.push_front(pNode->GetTile());
} }
pNode = pNode->m_parent; pNode = pNode->parent;
} }
/* return trackdir from the best origin node (one of start nodes) */ /* return trackdir from the best origin node (one of start nodes) */
Node &best_next_node = *pNode; Node &best_next_node = *pNode;
@ -503,7 +503,7 @@ public:
/* Return the cost of the best path and its depot. */ /* Return the cost of the best path and its depot. */
Node *n = Yapf().GetBestNode(); Node *n = Yapf().GetBestNode();
return FindDepotData(n->m_segment_last_tile, n->m_cost); return FindDepotData(n->segment_last_tile, n->cost);
} }
}; };

View File

@ -34,33 +34,33 @@ public:
typedef typename Node::Key Key; ///< key to hash tables. typedef typename Node::Key Key; ///< key to hash tables.
protected: protected:
TileIndex m_destTile; TileIndex dest_tile;
TrackdirBits m_destTrackdirs; TrackdirBits dest_trackdirs;
StationID m_destStation; StationID dest_station;
bool m_has_intermediate_dest = false; bool has_intermediate_dest = false;
TileIndex m_intermediate_dest_tile; TileIndex intermediate_dest_tile;
WaterRegionPatchDesc m_intermediate_dest_region_patch; WaterRegionPatchDesc intermediate_dest_region_patch;
public: public:
void SetDestination(const Ship *v) void SetDestination(const Ship *v)
{ {
if (v->current_order.IsType(OT_GOTO_STATION)) { if (v->current_order.IsType(OT_GOTO_STATION)) {
this->m_destStation = v->current_order.GetDestination(); this->dest_station = v->current_order.GetDestination();
this->m_destTile = CalcClosestStationTile(this->m_destStation, v->tile, STATION_DOCK); this->dest_tile = CalcClosestStationTile(this->dest_station, v->tile, STATION_DOCK);
this->m_destTrackdirs = INVALID_TRACKDIR_BIT; this->dest_trackdirs = INVALID_TRACKDIR_BIT;
} else { } else {
this->m_destStation = INVALID_STATION; this->dest_station = INVALID_STATION;
this->m_destTile = v->dest_tile; this->dest_tile = v->dest_tile;
this->m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_WATER, 0)); this->dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_WATER, 0));
} }
} }
void SetIntermediateDestination(const WaterRegionPatchDesc &water_region_patch) void SetIntermediateDestination(const WaterRegionPatchDesc &water_region_patch)
{ {
this->m_has_intermediate_dest = true; this->has_intermediate_dest = true;
this->m_intermediate_dest_tile = GetWaterRegionCenterTile(water_region_patch); this->intermediate_dest_tile = GetWaterRegionCenterTile(water_region_patch);
this->m_intermediate_dest_region_patch = water_region_patch; this->intermediate_dest_region_patch = water_region_patch;
} }
protected: protected:
@ -74,20 +74,20 @@ public:
/** Called by YAPF to detect if node ends in the desired destination. */ /** Called by YAPF to detect if node ends in the desired destination. */
inline bool PfDetectDestination(Node &n) inline bool PfDetectDestination(Node &n)
{ {
return this->PfDetectDestinationTile(n.m_segment_last_tile, n.m_segment_last_td); return this->PfDetectDestinationTile(n.segment_last_tile, n.segment_last_td);
} }
inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir) inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir)
{ {
if (this->m_has_intermediate_dest) { if (this->has_intermediate_dest) {
/* GetWaterRegionInfo is much faster than GetWaterRegionPatchInfo so we try that first. */ /* GetWaterRegionInfo is much faster than GetWaterRegionPatchInfo so we try that first. */
if (GetWaterRegionInfo(tile) != this->m_intermediate_dest_region_patch) return false; if (GetWaterRegionInfo(tile) != this->intermediate_dest_region_patch) return false;
return GetWaterRegionPatchInfo(tile) == this->m_intermediate_dest_region_patch; return GetWaterRegionPatchInfo(tile) == this->intermediate_dest_region_patch;
} }
if (this->m_destStation != INVALID_STATION) return IsDockingTile(tile) && IsShipDestinationTile(tile, this->m_destStation); if (this->dest_station != INVALID_STATION) return IsDockingTile(tile) && IsShipDestinationTile(tile, this->dest_station);
return tile == this->m_destTile && ((this->m_destTrackdirs & TrackdirToTrackdirBits(trackdir)) != TRACKDIR_BIT_NONE); return tile == this->dest_tile && ((this->dest_trackdirs & TrackdirToTrackdirBits(trackdir)) != TRACKDIR_BIT_NONE);
} }
/** /**
@ -96,17 +96,17 @@ public:
*/ */
inline bool PfCalcEstimate(Node &n) inline bool PfCalcEstimate(Node &n)
{ {
const TileIndex destination_tile = this->m_has_intermediate_dest ? this->m_intermediate_dest_tile : this->m_destTile; const TileIndex destination_tile = this->has_intermediate_dest ? this->intermediate_dest_tile : this->dest_tile;
static const int dg_dir_to_x_offs[] = { -1, 0, 1, 0 }; static const int dg_dir_to_x_offs[] = { -1, 0, 1, 0 };
static const int dg_dir_to_y_offs[] = { 0, 1, 0, -1 }; static const int dg_dir_to_y_offs[] = { 0, 1, 0, -1 };
if (this->PfDetectDestination(n)) { if (this->PfDetectDestination(n)) {
n.m_estimate = n.m_cost; n.estimate = n.cost;
return true; return true;
} }
TileIndex tile = n.m_segment_last_tile; TileIndex tile = n.segment_last_tile;
DiagDirection exitdir = TrackdirToExitdir(n.m_segment_last_td); DiagDirection exitdir = TrackdirToExitdir(n.segment_last_td);
int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir]; int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir]; int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
int x2 = 2 * TileX(destination_tile); int x2 = 2 * TileX(destination_tile);
@ -116,8 +116,8 @@ public:
int dmin = std::min(dx, dy); int dmin = std::min(dx, dy);
int dxy = abs(dx - dy); int dxy = abs(dx - dy);
int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2); int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
n.m_estimate = n.m_cost + d; n.estimate = n.cost + d;
assert(n.m_estimate >= n.m_parent->m_estimate); assert(n.estimate >= n.parent->estimate);
return true; return true;
} }
}; };
@ -139,7 +139,7 @@ protected:
return *static_cast<Tpf*>(this); return *static_cast<Tpf*>(this);
} }
std::vector<WaterRegionDesc> m_water_region_corridor; std::vector<WaterRegionDesc> water_region_corridor;
public: public:
/** /**
@ -150,10 +150,10 @@ public:
inline void PfFollowNode(Node &old_node) inline void PfFollowNode(Node &old_node)
{ {
TrackFollower F(Yapf().GetVehicle()); TrackFollower F(Yapf().GetVehicle());
if (F.Follow(old_node.m_key.m_tile, old_node.m_key.m_td)) { if (F.Follow(old_node.key.tile, old_node.key.td)) {
if (this->m_water_region_corridor.empty() if (this->water_region_corridor.empty()
|| std::find(this->m_water_region_corridor.begin(), this->m_water_region_corridor.end(), || std::find(this->water_region_corridor.begin(), this->water_region_corridor.end(),
GetWaterRegionInfo(F.m_new_tile)) != this->m_water_region_corridor.end()) { GetWaterRegionInfo(F.new_tile)) != this->water_region_corridor.end()) {
Yapf().AddMultipleNodes(&old_node, F); Yapf().AddMultipleNodes(&old_node, F);
} }
} }
@ -162,8 +162,8 @@ public:
/** Restricts the search by creating corridor or water regions through which the ship is allowed to travel. */ /** Restricts the search by creating corridor or water regions through which the ship is allowed to travel. */
inline void RestrictSearch(const std::vector<WaterRegionPatchDesc> &path) inline void RestrictSearch(const std::vector<WaterRegionPatchDesc> &path)
{ {
this->m_water_region_corridor.clear(); this->water_region_corridor.clear();
for (const WaterRegionPatchDesc &path_entry : path) this->m_water_region_corridor.push_back(path_entry); for (const WaterRegionPatchDesc &path_entry : path) this->water_region_corridor.push_back(path_entry);
} }
/** Return debug report character to identify the transportation type. */ /** Return debug report character to identify the transportation type. */
@ -185,12 +185,12 @@ public:
{ {
TrackFollower follower(v); TrackFollower follower(v);
if (follower.Follow(tile, dir)) { if (follower.Follow(tile, dir)) {
TrackdirBits dirs = follower.m_new_td_bits; TrackdirBits dirs = follower.new_td_bits;
const TrackdirBits dirs_without_90_degree = dirs & ~TrackdirCrossesTrackdirs(dir); const TrackdirBits dirs_without_90_degree = dirs & ~TrackdirCrossesTrackdirs(dir);
if (dirs_without_90_degree != TRACKDIR_BIT_NONE) dirs = dirs_without_90_degree; if (dirs_without_90_degree != TRACKDIR_BIT_NONE) dirs = dirs_without_90_degree;
return { follower.m_new_tile, GetRandomTrackdir(dirs) }; return { follower.new_tile, GetRandomTrackdir(dirs) };
} }
return { follower.m_new_tile, INVALID_TRACKDIR }; return { follower.new_tile, INVALID_TRACKDIR };
} }
/** Creates a random path, avoids 90 degree turns. */ /** Creates a random path, avoids 90 degree turns. */
@ -250,7 +250,7 @@ public:
const WaterRegionPatchDesc end_water_patch = GetWaterRegionPatchInfo(node->GetTile()); const WaterRegionPatchDesc end_water_patch = GetWaterRegionPatchInfo(node->GetTile());
assert(GetWaterRegionPatchInfo(tile) == high_level_path.front()); assert(GetWaterRegionPatchInfo(tile) == high_level_path.front());
const WaterRegionPatchDesc start_water_patch = high_level_path.front(); const WaterRegionPatchDesc start_water_patch = high_level_path.front();
while (node->m_parent) { while (node->parent) {
const WaterRegionPatchDesc node_water_patch = GetWaterRegionPatchInfo(node->GetTile()); const WaterRegionPatchDesc node_water_patch = GetWaterRegionPatchInfo(node->GetTile());
const bool node_water_patch_on_high_level_path = std::find(high_level_path.begin(), high_level_path.end(), node_water_patch) != high_level_path.end(); const bool node_water_patch_on_high_level_path = std::find(high_level_path.begin(), high_level_path.end(), node_water_patch) != high_level_path.end();
@ -263,7 +263,7 @@ public:
} else { } else {
path_cache.clear(); path_cache.clear();
} }
node = node->m_parent; node = node->parent;
} }
assert(node->GetTile() == v->tile); assert(node->GetTile() == v->tile);
@ -373,7 +373,7 @@ public:
/* Base tile cost depending on distance. */ /* Base tile cost depending on distance. */
int c = IsDiagonalTrackdir(n.GetTrackdir()) ? YAPF_TILE_LENGTH : YAPF_TILE_CORNER_LENGTH; int c = IsDiagonalTrackdir(n.GetTrackdir()) ? YAPF_TILE_LENGTH : YAPF_TILE_CORNER_LENGTH;
/* Additional penalty for curves. */ /* Additional penalty for curves. */
c += this->CurveCost(n.m_parent->GetTrackdir(), n.GetTrackdir()); c += this->CurveCost(n.parent->GetTrackdir(), n.GetTrackdir());
if (IsDockingTile(n.GetTile())) { if (IsDockingTile(n.GetTile())) {
/* Check docking tile for occupancy. */ /* Check docking tile for occupancy. */
@ -383,15 +383,15 @@ public:
} }
/* Skipped tile cost for aqueducts. */ /* Skipped tile cost for aqueducts. */
c += YAPF_TILE_LENGTH * tf->m_tiles_skipped; c += YAPF_TILE_LENGTH * tf->tiles_skipped;
/* Ocean/canal speed penalty. */ /* Ocean/canal speed penalty. */
const ShipVehicleInfo *svi = ShipVehInfo(Yapf().GetVehicle()->engine_type); const ShipVehicleInfo *svi = ShipVehInfo(Yapf().GetVehicle()->engine_type);
uint8_t speed_frac = (GetEffectiveWaterClass(n.GetTile()) == WATER_CLASS_SEA) ? svi->ocean_speed_frac : svi->canal_speed_frac; uint8_t speed_frac = (GetEffectiveWaterClass(n.GetTile()) == WATER_CLASS_SEA) ? svi->ocean_speed_frac : svi->canal_speed_frac;
if (speed_frac > 0) c += YAPF_TILE_LENGTH * (1 + tf->m_tiles_skipped) * speed_frac / (256 - speed_frac); if (speed_frac > 0) c += YAPF_TILE_LENGTH * (1 + tf->tiles_skipped) * speed_frac / (256 - speed_frac);
/* Apply it. */ /* Apply it. */
n.m_cost = n.m_parent->m_cost + c; n.cost = n.parent->cost + c;
return true; return true;
} }
}; };
@ -420,7 +420,7 @@ struct CYapfShip_TypesT
struct CYapfShip : CYapfT<CYapfShip_TypesT<CYapfShip, CFollowTrackWater, CShipNodeListExitDir > > struct CYapfShip : CYapfT<CYapfShip_TypesT<CYapfShip, CFollowTrackWater, CShipNodeListExitDir > >
{ {
explicit CYapfShip(int max_nodes) { this->m_max_search_nodes = max_nodes; } explicit CYapfShip(int max_nodes) { this->max_search_nodes = max_nodes; }
}; };
/** Ship controller helper - path finder invoker. */ /** Ship controller helper - path finder invoker. */

View File

@ -22,20 +22,20 @@ constexpr int MAX_NUMBER_OF_NODES = 65536;
/** Yapf Node Key that represents a single patch of interconnected water within a water region. */ /** Yapf Node Key that represents a single patch of interconnected water within a water region. */
struct CYapfRegionPatchNodeKey { struct CYapfRegionPatchNodeKey {
WaterRegionPatchDesc m_water_region_patch; WaterRegionPatchDesc water_region_patch;
inline void Set(const WaterRegionPatchDesc &water_region_patch) inline void Set(const WaterRegionPatchDesc &water_region_patch)
{ {
this->m_water_region_patch = water_region_patch; this->water_region_patch = water_region_patch;
} }
inline int CalcHash() const { return CalculateWaterRegionPatchHash(this->m_water_region_patch); } inline int CalcHash() const { return CalculateWaterRegionPatchHash(this->water_region_patch); }
inline bool operator==(const CYapfRegionPatchNodeKey &other) const { return this->CalcHash() == other.CalcHash(); } inline bool operator==(const CYapfRegionPatchNodeKey &other) const { return this->CalcHash() == other.CalcHash(); }
}; };
inline uint ManhattanDistance(const CYapfRegionPatchNodeKey &a, const CYapfRegionPatchNodeKey &b) inline uint ManhattanDistance(const CYapfRegionPatchNodeKey &a, const CYapfRegionPatchNodeKey &b)
{ {
return (std::abs(a.m_water_region_patch.x - b.m_water_region_patch.x) + std::abs(a.m_water_region_patch.y - b.m_water_region_patch.y)) * DIRECT_NEIGHBOR_COST; return (std::abs(a.water_region_patch.x - b.water_region_patch.x) + std::abs(a.water_region_patch.y - b.water_region_patch.y)) * DIRECT_NEIGHBOR_COST;
} }
/** Yapf Node for water regions. */ /** Yapf Node for water regions. */
@ -44,31 +44,31 @@ struct CYapfRegionNodeT {
typedef Tkey_ Key; typedef Tkey_ Key;
typedef CYapfRegionNodeT<Tkey_> Node; typedef CYapfRegionNodeT<Tkey_> Node;
Tkey_ m_key; Tkey_ key;
Node *m_hash_next; Node *hash_next;
Node *m_parent; Node *parent;
int m_cost; int cost;
int m_estimate; int estimate;
inline void Set(Node *parent, const WaterRegionPatchDesc &water_region_patch) inline void Set(Node *parent, const WaterRegionPatchDesc &water_region_patch)
{ {
this->m_key.Set(water_region_patch); this->key.Set(water_region_patch);
this->m_hash_next = nullptr; this->hash_next = nullptr;
this->m_parent = parent; this->parent = parent;
this->m_cost = 0; this->cost = 0;
this->m_estimate = 0; this->estimate = 0;
} }
inline void Set(Node *parent, const Key &key) inline void Set(Node *parent, const Key &key)
{ {
this->Set(parent, key.m_water_region_patch); this->Set(parent, key.water_region_patch);
} }
DiagDirection GetDiagDirFromParent() const DiagDirection GetDiagDirFromParent() const
{ {
if (!this->m_parent) return INVALID_DIAGDIR; if (!this->parent) return INVALID_DIAGDIR;
const int dx = this->m_key.m_water_region_patch.x - this->m_parent->m_key.m_water_region_patch.x; const int dx = this->key.water_region_patch.x - this->parent->key.water_region_patch.x;
const int dy = this->m_key.m_water_region_patch.y - this->m_parent->m_key.m_water_region_patch.y; const int dy = this->key.water_region_patch.y - this->parent->key.water_region_patch.y;
if (dx > 0 && dy == 0) return DIAGDIR_SW; if (dx > 0 && dy == 0) return DIAGDIR_SW;
if (dx < 0 && dy == 0) return DIAGDIR_NE; if (dx < 0 && dy == 0) return DIAGDIR_NE;
if (dx == 0 && dy > 0) return DIAGDIR_SE; if (dx == 0 && dy > 0) return DIAGDIR_SE;
@ -76,12 +76,12 @@ struct CYapfRegionNodeT {
return INVALID_DIAGDIR; return INVALID_DIAGDIR;
} }
inline Node *GetHashNext() { return this->m_hash_next; } inline Node *GetHashNext() { return this->hash_next; }
inline void SetHashNext(Node *pNext) { this->m_hash_next = pNext; } inline void SetHashNext(Node *pNext) { this->hash_next = pNext; }
inline const Tkey_ &GetKey() const { return this->m_key; } inline const Tkey_ &GetKey() const { return this->key; }
inline int GetCost() { return this->m_cost; } inline int GetCost() { return this->cost; }
inline int GetCostEstimate() { return this->m_estimate; } inline int GetCostEstimate() { return this->estimate; }
inline bool operator<(const Node &other) const { return this->m_estimate < other.m_estimate; } inline bool operator<(const Node &other) const { return this->estimate < other.estimate; }
}; };
/** YAPF origin for water regions. */ /** YAPF origin for water regions. */
@ -97,23 +97,23 @@ protected:
inline Tpf &Yapf() { return *static_cast<Tpf*>(this); } inline Tpf &Yapf() { return *static_cast<Tpf*>(this); }
private: private:
std::vector<CYapfRegionPatchNodeKey> m_origin_keys; std::vector<CYapfRegionPatchNodeKey> origin_keys;
public: public:
void AddOrigin(const WaterRegionPatchDesc &water_region_patch) void AddOrigin(const WaterRegionPatchDesc &water_region_patch)
{ {
if (water_region_patch.label == INVALID_WATER_REGION_PATCH) return; if (water_region_patch.label == INVALID_WATER_REGION_PATCH) return;
if (!HasOrigin(water_region_patch)) this->m_origin_keys.push_back(CYapfRegionPatchNodeKey{ water_region_patch }); if (!HasOrigin(water_region_patch)) this->origin_keys.push_back(CYapfRegionPatchNodeKey{ water_region_patch });
} }
bool HasOrigin(const WaterRegionPatchDesc &water_region_patch) bool HasOrigin(const WaterRegionPatchDesc &water_region_patch)
{ {
return std::find(this->m_origin_keys.begin(), this->m_origin_keys.end(), CYapfRegionPatchNodeKey{ water_region_patch }) != this->m_origin_keys.end(); return std::find(this->origin_keys.begin(), this->origin_keys.end(), CYapfRegionPatchNodeKey{ water_region_patch }) != this->origin_keys.end();
} }
void PfSetStartupNodes() void PfSetStartupNodes()
{ {
for (const CYapfRegionPatchNodeKey &origin_key : this->m_origin_keys) { for (const CYapfRegionPatchNodeKey &origin_key : this->origin_keys) {
Node &node = Yapf().CreateNewNode(); Node &node = Yapf().CreateNewNode();
node.Set(nullptr, origin_key); node.Set(nullptr, origin_key);
Yapf().AddStartupNode(node); Yapf().AddStartupNode(node);
@ -131,12 +131,12 @@ public:
typedef typename Node::Key Key; ///< Key to hash tables. typedef typename Node::Key Key; ///< Key to hash tables.
protected: protected:
Key m_dest; Key dest;
public: public:
void SetDestination(const WaterRegionPatchDesc &water_region_patch) void SetDestination(const WaterRegionPatchDesc &water_region_patch)
{ {
this->m_dest.Set(water_region_patch); this->dest.Set(water_region_patch);
} }
protected: protected:
@ -145,17 +145,17 @@ protected:
public: public:
inline bool PfDetectDestination(Node &n) const inline bool PfDetectDestination(Node &n) const
{ {
return n.m_key == this->m_dest; return n.key == this->dest;
} }
inline bool PfCalcEstimate(Node &n) inline bool PfCalcEstimate(Node &n)
{ {
if (this->PfDetectDestination(n)) { if (this->PfDetectDestination(n)) {
n.m_estimate = n.m_cost; n.estimate = n.cost;
return true; return true;
} }
n.m_estimate = n.m_cost + ManhattanDistance(n.m_key, this->m_dest); n.estimate = n.cost + ManhattanDistance(n.key, this->dest);
return true; return true;
} }
@ -183,7 +183,7 @@ public:
node.Set(&old_node, water_region_patch); node.Set(&old_node, water_region_patch);
Yapf().AddNewNode(node, TrackFollower{}); Yapf().AddNewNode(node, TrackFollower{});
}; };
VisitWaterRegionPatchNeighbors(old_node.m_key.m_water_region_patch, visitFunc); VisitWaterRegionPatchNeighbors(old_node.key.water_region_patch, visitFunc);
} }
inline char TransportTypeChar() const { return '^'; } inline char TransportTypeChar() const { return '^'; }
@ -223,8 +223,8 @@ public:
Node *node = pf.GetBestNode(); Node *node = pf.GetBestNode();
for (int i = 0; i < max_returned_path_length - 1; ++i) { for (int i = 0; i < max_returned_path_length - 1; ++i) {
if (node != nullptr) { if (node != nullptr) {
node = node->m_parent; node = node->parent;
if (node != nullptr) path.push_back(node->m_key.m_water_region_patch); if (node != nullptr) path.push_back(node->key.water_region_patch);
} }
} }
@ -255,13 +255,13 @@ public:
*/ */
inline bool PfCalcCost(Node &n, const TrackFollower *) inline bool PfCalcCost(Node &n, const TrackFollower *)
{ {
n.m_cost = n.m_parent->m_cost + ManhattanDistance(n.m_key, n.m_parent->m_key); n.cost = n.parent->cost + ManhattanDistance(n.key, n.parent->key);
/* Incentivise zigzagging by adding a slight penalty when the search continues in the same direction. */ /* Incentivise zigzagging by adding a slight penalty when the search continues in the same direction. */
Node *grandparent = n.m_parent->m_parent; Node *grandparent = n.parent->parent;
if (grandparent != nullptr) { if (grandparent != nullptr) {
const DiagDirDiff dir_diff = DiagDirDifference(n.m_parent->GetDiagDirFromParent(), n.GetDiagDirFromParent()); const DiagDirDiff dir_diff = DiagDirDifference(n.parent->GetDiagDirFromParent(), n.GetDiagDirFromParent());
if (dir_diff != DIAGDIRDIFF_90LEFT && dir_diff != DIAGDIRDIFF_90RIGHT) n.m_cost += 1; if (dir_diff != DIAGDIRDIFF_90LEFT && dir_diff != DIAGDIRDIFF_90RIGHT) n.cost += 1;
} }
return true; return true;
@ -297,7 +297,7 @@ typedef CNodeList_HashTableT<CYapfRegionNodeT<CYapfRegionPatchNodeKey>, 12, 12>
struct CYapfRegionWater : CYapfT<CYapfRegion_TypesT<CYapfRegionWater, CRegionNodeListWater>> struct CYapfRegionWater : CYapfT<CYapfRegion_TypesT<CYapfRegionWater, CRegionNodeListWater>>
{ {
explicit CYapfRegionWater(int max_nodes) { this->m_max_search_nodes = max_nodes; } explicit CYapfRegionWater(int max_nodes) { this->max_search_nodes = max_nodes; }
}; };
/** /**

View File

@ -198,18 +198,18 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra
/* Do not disallow 90 deg turns as the setting might have changed between reserving and now. */ /* Do not disallow 90 deg turns as the setting might have changed between reserving and now. */
CFollowTrackRail ft(o, rts); CFollowTrackRail ft(o, rts);
while (ft.Follow(tile, trackdir)) { while (ft.Follow(tile, trackdir)) {
TrackdirBits reserved = ft.m_new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(ft.m_new_tile)); TrackdirBits reserved = ft.new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(ft.new_tile));
/* No reservation --> path end found */ /* No reservation --> path end found */
if (reserved == TRACKDIR_BIT_NONE) { if (reserved == TRACKDIR_BIT_NONE) {
if (ft.m_is_station) { if (ft.is_station) {
/* Check skipped station tiles as well, maybe our reservation ends inside the station. */ /* Check skipped station tiles as well, maybe our reservation ends inside the station. */
TileIndexDiff diff = TileOffsByDiagDir(ft.m_exitdir); TileIndexDiff diff = TileOffsByDiagDir(ft.exitdir);
while (ft.m_tiles_skipped-- > 0) { while (ft.tiles_skipped-- > 0) {
ft.m_new_tile -= diff; ft.new_tile -= diff;
if (HasStationReservation(ft.m_new_tile)) { if (HasStationReservation(ft.new_tile)) {
tile = ft.m_new_tile; tile = ft.new_tile;
trackdir = DiagDirToDiagTrackdir(ft.m_exitdir); trackdir = DiagDirToDiagTrackdir(ft.exitdir);
break; break;
} }
} }
@ -222,9 +222,9 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra
/* One-way signal against us. The reservation can't be ours as it is not /* One-way signal against us. The reservation can't be ours as it is not
* a safe position from our direction and we can never pass the signal. */ * a safe position from our direction and we can never pass the signal. */
if (!ignore_oneway && HasOnewaySignalBlockingTrackdir(ft.m_new_tile, new_trackdir)) break; if (!ignore_oneway && HasOnewaySignalBlockingTrackdir(ft.new_tile, new_trackdir)) break;
tile = ft.m_new_tile; tile = ft.new_tile;
trackdir = new_trackdir; trackdir = new_trackdir;
if (first_loop) { if (first_loop) {
@ -396,17 +396,17 @@ bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bo
} }
/* Check for reachable tracks. */ /* Check for reachable tracks. */
ft.m_new_td_bits &= DiagdirReachesTrackdirs(ft.m_exitdir); ft.new_td_bits &= DiagdirReachesTrackdirs(ft.exitdir);
if (Rail90DegTurnDisallowed(GetTileRailType(ft.m_old_tile), GetTileRailType(ft.m_new_tile), forbid_90deg)) ft.m_new_td_bits &= ~TrackdirCrossesTrackdirs(trackdir); if (Rail90DegTurnDisallowed(GetTileRailType(ft.old_tile), GetTileRailType(ft.new_tile), forbid_90deg)) ft.new_td_bits &= ~TrackdirCrossesTrackdirs(trackdir);
if (ft.m_new_td_bits == TRACKDIR_BIT_NONE) return include_line_end; if (ft.new_td_bits == TRACKDIR_BIT_NONE) return include_line_end;
if (ft.m_new_td_bits != TRACKDIR_BIT_NONE && KillFirstBit(ft.m_new_td_bits) == TRACKDIR_BIT_NONE) { if (ft.new_td_bits != TRACKDIR_BIT_NONE && KillFirstBit(ft.new_td_bits) == TRACKDIR_BIT_NONE) {
Trackdir td = FindFirstTrackdir(ft.m_new_td_bits); Trackdir td = FindFirstTrackdir(ft.new_td_bits);
/* PBS signal on next trackdir? Safe position. */ /* PBS signal on next trackdir? Safe position. */
if (HasPbsSignalOnTrackdir(ft.m_new_tile, td)) return true; if (HasPbsSignalOnTrackdir(ft.new_tile, td)) return true;
/* One-way PBS signal against us? Safe if end-of-line is allowed. */ /* One-way PBS signal against us? Safe if end-of-line is allowed. */
if (IsTileType(ft.m_new_tile, MP_RAILWAY) && HasSignalOnTrackdir(ft.m_new_tile, ReverseTrackdir(td)) && if (IsTileType(ft.new_tile, MP_RAILWAY) && HasSignalOnTrackdir(ft.new_tile, ReverseTrackdir(td)) &&
GetSignalType(ft.m_new_tile, TrackdirToTrack(td)) == SIGTYPE_PBS_ONEWAY) { GetSignalType(ft.new_tile, TrackdirToTrack(td)) == SIGTYPE_PBS_ONEWAY) {
return include_line_end; return include_line_end;
} }
} }
@ -441,8 +441,8 @@ bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bo
if (!ft.Follow(tile, trackdir)) return true; if (!ft.Follow(tile, trackdir)) return true;
/* Check for reachable tracks. */ /* Check for reachable tracks. */
ft.m_new_td_bits &= DiagdirReachesTrackdirs(ft.m_exitdir); ft.new_td_bits &= DiagdirReachesTrackdirs(ft.exitdir);
if (Rail90DegTurnDisallowed(GetTileRailType(ft.m_old_tile), GetTileRailType(ft.m_new_tile), forbid_90deg)) ft.m_new_td_bits &= ~TrackdirCrossesTrackdirs(trackdir); if (Rail90DegTurnDisallowed(GetTileRailType(ft.old_tile), GetTileRailType(ft.new_tile), forbid_90deg)) ft.new_td_bits &= ~TrackdirCrossesTrackdirs(trackdir);
return !HasReservedTracks(ft.m_new_tile, TrackdirBitsToTrackBits(ft.m_new_td_bits)); return !HasReservedTracks(ft.new_tile, TrackdirBitsToTrackBits(ft.new_td_bits));
} }

View File

@ -2245,16 +2245,16 @@ static void CheckNextTrainTile(Train *v)
CFollowTrackRail ft(v); CFollowTrackRail ft(v);
if (!ft.Follow(v->tile, td)) return; if (!ft.Follow(v->tile, td)) return;
if (!HasReservedTracks(ft.m_new_tile, TrackdirBitsToTrackBits(ft.m_new_td_bits))) { if (!HasReservedTracks(ft.new_tile, TrackdirBitsToTrackBits(ft.new_td_bits))) {
/* Next tile is not reserved. */ /* Next tile is not reserved. */
if (KillFirstBit(ft.m_new_td_bits) == TRACKDIR_BIT_NONE) { if (KillFirstBit(ft.new_td_bits) == TRACKDIR_BIT_NONE) {
if (HasPbsSignalOnTrackdir(ft.m_new_tile, FindFirstTrackdir(ft.m_new_td_bits))) { if (HasPbsSignalOnTrackdir(ft.new_tile, FindFirstTrackdir(ft.new_td_bits))) {
/* If the next tile is a PBS signal, try to make a reservation. */ /* If the next tile is a PBS signal, try to make a reservation. */
TrackBits tracks = TrackdirBitsToTrackBits(ft.m_new_td_bits); TrackBits tracks = TrackdirBitsToTrackBits(ft.new_td_bits);
if (Rail90DegTurnDisallowed(GetTileRailType(ft.m_old_tile), GetTileRailType(ft.m_new_tile))) { if (Rail90DegTurnDisallowed(GetTileRailType(ft.old_tile), GetTileRailType(ft.new_tile))) {
tracks &= ~TrackCrossesTracks(TrackdirToTrack(ft.m_old_td)); tracks &= ~TrackCrossesTracks(TrackdirToTrack(ft.old_td));
} }
ChooseTrainTrack(v, ft.m_new_tile, ft.m_exitdir, tracks, false, nullptr, false); ChooseTrainTrack(v, ft.new_tile, ft.exitdir, tracks, false, nullptr, false);
} }
} }
} }
@ -2410,8 +2410,8 @@ void FreeTrainTrackReservation(const Train *v)
CFollowTrackRail ft(v, GetRailTypeInfo(v->railtype)->compatible_railtypes); CFollowTrackRail ft(v, GetRailTypeInfo(v->railtype)->compatible_railtypes);
while (ft.Follow(tile, td)) { while (ft.Follow(tile, td)) {
tile = ft.m_new_tile; tile = ft.new_tile;
TrackdirBits bits = ft.m_new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(tile)); TrackdirBits bits = ft.new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(tile));
td = RemoveFirstTrackdir(&bits); td = RemoveFirstTrackdir(&bits);
assert(bits == TRACKDIR_BIT_NONE); assert(bits == TRACKDIR_BIT_NONE);
@ -2441,7 +2441,7 @@ void FreeTrainTrackReservation(const Train *v)
} }
/* Don't free first station/bridge/tunnel if we are on it. */ /* Don't free first station/bridge/tunnel if we are on it. */
if (free_tile || (!(ft.m_is_station && GetStationIndex(ft.m_new_tile) == station_id) && !ft.m_is_tunnel && !ft.m_is_bridge)) ClearPathReservation(v, tile, td); if (free_tile || (!(ft.is_station && GetStationIndex(ft.new_tile) == station_id) && !ft.is_tunnel && !ft.is_bridge)) ClearPathReservation(v, tile, td);
free_tile = true; free_tile = true;
} }
@ -2493,39 +2493,39 @@ static PBSTileInfo ExtendTrainReservation(const Train *v, TrackBits *new_tracks,
TileIndex tile = origin.tile; TileIndex tile = origin.tile;
Trackdir cur_td = origin.trackdir; Trackdir cur_td = origin.trackdir;
while (ft.Follow(tile, cur_td)) { while (ft.Follow(tile, cur_td)) {
if (KillFirstBit(ft.m_new_td_bits) == TRACKDIR_BIT_NONE) { if (KillFirstBit(ft.new_td_bits) == TRACKDIR_BIT_NONE) {
/* Possible signal tile. */ /* Possible signal tile. */
if (HasOnewaySignalBlockingTrackdir(ft.m_new_tile, FindFirstTrackdir(ft.m_new_td_bits))) break; if (HasOnewaySignalBlockingTrackdir(ft.new_tile, FindFirstTrackdir(ft.new_td_bits))) break;
} }
if (Rail90DegTurnDisallowed(GetTileRailType(ft.m_old_tile), GetTileRailType(ft.m_new_tile))) { if (Rail90DegTurnDisallowed(GetTileRailType(ft.old_tile), GetTileRailType(ft.new_tile))) {
ft.m_new_td_bits &= ~TrackdirCrossesTrackdirs(ft.m_old_td); ft.new_td_bits &= ~TrackdirCrossesTrackdirs(ft.old_td);
if (ft.m_new_td_bits == TRACKDIR_BIT_NONE) break; if (ft.new_td_bits == TRACKDIR_BIT_NONE) break;
} }
/* Station, depot or waypoint are a possible target. */ /* Station, depot or waypoint are a possible target. */
bool target_seen = ft.m_is_station || (IsTileType(ft.m_new_tile, MP_RAILWAY) && !IsPlainRail(ft.m_new_tile)); bool target_seen = ft.is_station || (IsTileType(ft.new_tile, MP_RAILWAY) && !IsPlainRail(ft.new_tile));
if (target_seen || KillFirstBit(ft.m_new_td_bits) != TRACKDIR_BIT_NONE) { if (target_seen || KillFirstBit(ft.new_td_bits) != TRACKDIR_BIT_NONE) {
/* Choice found or possible target encountered. /* Choice found or possible target encountered.
* On finding a possible target, we need to stop and let the pathfinder handle the * On finding a possible target, we need to stop and let the pathfinder handle the
* remaining path. This is because we don't know if this target is in one of our * remaining path. This is because we don't know if this target is in one of our
* orders, so we might cause pathfinding to fail later on if we find a choice. * orders, so we might cause pathfinding to fail later on if we find a choice.
* This failure would cause a bogous call to TryReserveSafePath which might reserve * This failure would cause a bogous call to TryReserveSafePath which might reserve
* a wrong path not leading to our next destination. */ * a wrong path not leading to our next destination. */
if (HasReservedTracks(ft.m_new_tile, TrackdirBitsToTrackBits(TrackdirReachesTrackdirs(ft.m_old_td)))) break; if (HasReservedTracks(ft.new_tile, TrackdirBitsToTrackBits(TrackdirReachesTrackdirs(ft.old_td)))) break;
/* If we did skip some tiles, backtrack to the first skipped tile so the pathfinder /* If we did skip some tiles, backtrack to the first skipped tile so the pathfinder
* actually starts its search at the first unreserved tile. */ * actually starts its search at the first unreserved tile. */
if (ft.m_tiles_skipped != 0) ft.m_new_tile -= TileOffsByDiagDir(ft.m_exitdir) * ft.m_tiles_skipped; if (ft.tiles_skipped != 0) ft.new_tile -= TileOffsByDiagDir(ft.exitdir) * ft.tiles_skipped;
/* Choice found, path valid but not okay. Save info about the choice tile as well. */ /* Choice found, path valid but not okay. Save info about the choice tile as well. */
if (new_tracks != nullptr) *new_tracks = TrackdirBitsToTrackBits(ft.m_new_td_bits); if (new_tracks != nullptr) *new_tracks = TrackdirBitsToTrackBits(ft.new_td_bits);
if (enterdir != nullptr) *enterdir = ft.m_exitdir; if (enterdir != nullptr) *enterdir = ft.exitdir;
return PBSTileInfo(ft.m_new_tile, ft.m_old_td, false); return PBSTileInfo(ft.new_tile, ft.old_td, false);
} }
tile = ft.m_new_tile; tile = ft.new_tile;
cur_td = FindFirstTrackdir(ft.m_new_td_bits); cur_td = FindFirstTrackdir(ft.new_td_bits);
Trackdir rev_td = ReverseTrackdir(cur_td); Trackdir rev_td = ReverseTrackdir(cur_td);
if (IsSafeWaitingPosition(v, tile, cur_td, true, _settings_game.pf.forbid_90_deg)) { if (IsSafeWaitingPosition(v, tile, cur_td, true, _settings_game.pf.forbid_90_deg)) {
@ -2551,27 +2551,27 @@ static PBSTileInfo ExtendTrainReservation(const Train *v, TrackBits *new_tracks,
} }
} }
if (ft.m_err == CFollowTrackRail::EC_OWNER || ft.m_err == CFollowTrackRail::EC_NO_WAY) { if (ft.err == CFollowTrackRail::EC_OWNER || ft.err == CFollowTrackRail::EC_NO_WAY) {
/* End of line, path valid and okay. */ /* End of line, path valid and okay. */
return PBSTileInfo(ft.m_old_tile, ft.m_old_td, true); return PBSTileInfo(ft.old_tile, ft.old_td, true);
} }
/* Sorry, can't reserve path, back out. */ /* Sorry, can't reserve path, back out. */
tile = origin.tile; tile = origin.tile;
cur_td = origin.trackdir; cur_td = origin.trackdir;
TileIndex stopped = ft.m_old_tile; TileIndex stopped = ft.old_tile;
Trackdir stopped_td = ft.m_old_td; Trackdir stopped_td = ft.old_td;
while (tile != stopped || cur_td != stopped_td) { while (tile != stopped || cur_td != stopped_td) {
if (!ft.Follow(tile, cur_td)) break; if (!ft.Follow(tile, cur_td)) break;
if (Rail90DegTurnDisallowed(GetTileRailType(ft.m_old_tile), GetTileRailType(ft.m_new_tile))) { if (Rail90DegTurnDisallowed(GetTileRailType(ft.old_tile), GetTileRailType(ft.new_tile))) {
ft.m_new_td_bits &= ~TrackdirCrossesTrackdirs(ft.m_old_td); ft.new_td_bits &= ~TrackdirCrossesTrackdirs(ft.old_td);
assert(ft.m_new_td_bits != TRACKDIR_BIT_NONE); assert(ft.new_td_bits != TRACKDIR_BIT_NONE);
} }
assert(KillFirstBit(ft.m_new_td_bits) == TRACKDIR_BIT_NONE); assert(KillFirstBit(ft.new_td_bits) == TRACKDIR_BIT_NONE);
tile = ft.m_new_tile; tile = ft.new_tile;
cur_td = FindFirstTrackdir(ft.m_new_td_bits); cur_td = FindFirstTrackdir(ft.new_td_bits);
UnreserveRailTrack(tile, TrackdirToTrack(cur_td)); UnreserveRailTrack(tile, TrackdirToTrack(cur_td));
} }