mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-06-20 15:39:25 +02:00
fix(Core/Travel): Map-wide node scan in GetFullPath candidate pick (was zone-restricted)
This commit is contained in:
parent
8efe3a4321
commit
0cbee1621d
@ -1679,7 +1679,7 @@ TravelNodeRoute TravelNodeMap::FindRouteNearestNodes(WorldPosition startPos, Wor
|
|||||||
return TravelNodeRoute();
|
return TravelNodeRoute();
|
||||||
}
|
}
|
||||||
|
|
||||||
TravelPath TravelNodeMap::GetFullPath(WorldPosition botPos, uint32 botZoneId,
|
TravelPath TravelNodeMap::GetFullPath(WorldPosition botPos, [[maybe_unused]] uint32 botZoneId,
|
||||||
WorldPosition destination, Unit* bot)
|
WorldPosition destination, Unit* bot)
|
||||||
{
|
{
|
||||||
TravelPath path;
|
TravelPath path;
|
||||||
@ -1709,33 +1709,28 @@ TravelPath TravelNodeMap::GetFullPath(WorldPosition botPos, uint32 botZoneId,
|
|||||||
|
|
||||||
std::shared_lock<std::shared_timed_mutex> guard(m_nMapMtx);
|
std::shared_lock<std::shared_timed_mutex> guard(m_nMapMtx);
|
||||||
|
|
||||||
// K-nearest start + end node candidates (cmangos parity: K=5).
|
// K-nearest start + end node candidates (K=5). Map-wide scan to
|
||||||
// Iterate combinations — first pair with a graph route wins. The
|
// mirror reference `getNodes(pos, -1)` — restricting to bot's zone
|
||||||
// single-nearest may have no route while the 2nd/3rd does.
|
// misses nodes that sit just across a zone boundary (e.g. a cave
|
||||||
|
// whose interior node is in a different zone than its entrance).
|
||||||
constexpr uint32 K = 5;
|
constexpr uint32 K = 5;
|
||||||
auto pickKNearest = [&](WorldPosition pos, uint32 zoneId) -> std::vector<TravelNode*>
|
auto pickKNearest = [&](WorldPosition pos) -> std::vector<TravelNode*>
|
||||||
{
|
{
|
||||||
std::vector<TravelNode*> const& zoneNodes = GetNodesInZone(zoneId);
|
std::vector<TravelNode*> candidates;
|
||||||
std::vector<TravelNode*> candidates(zoneNodes.begin(), zoneNodes.end());
|
|
||||||
if (candidates.empty())
|
|
||||||
{
|
|
||||||
// Fallback to per-map scan
|
|
||||||
for (TravelNode* n : nodes)
|
for (TravelNode* n : nodes)
|
||||||
if (n && n->getPosition()->GetMapId() == pos.GetMapId())
|
if (n && n->getPosition()->GetMapId() == pos.GetMapId())
|
||||||
candidates.push_back(n);
|
candidates.push_back(n);
|
||||||
}
|
|
||||||
if (candidates.empty())
|
if (candidates.empty())
|
||||||
return {};
|
return {};
|
||||||
uint32 n = std::min<uint32>(K, candidates.size());
|
uint32 const n = std::min<uint32>(K, (uint32)candidates.size());
|
||||||
std::partial_sort(candidates.begin(), candidates.begin() + n, candidates.end(),
|
std::partial_sort(candidates.begin(), candidates.begin() + n, candidates.end(),
|
||||||
[pos](TravelNode* i, TravelNode* j) { return i->fDist(pos) < j->fDist(pos); });
|
[pos](TravelNode* i, TravelNode* j) { return i->fDist(pos) < j->fDist(pos); });
|
||||||
candidates.resize(n);
|
candidates.resize(n);
|
||||||
return candidates;
|
return candidates;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32 destZone = sMapMgr->GetZoneId(PHASEMASK_NORMAL, destination);
|
std::vector<TravelNode*> startCandidates = pickKNearest(botPos);
|
||||||
std::vector<TravelNode*> startCandidates = pickKNearest(botPos, botZoneId);
|
std::vector<TravelNode*> endCandidates = pickKNearest(destination);
|
||||||
std::vector<TravelNode*> endCandidates = pickKNearest(destination, destZone);
|
|
||||||
|
|
||||||
if (startCandidates.empty() || endCandidates.empty())
|
if (startCandidates.empty() || endCandidates.empty())
|
||||||
return path; // empty
|
return path; // empty
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user