fix(Core/Travel): Port cmangos makeShortCut walkability filter and bot context

This commit is contained in:
bash 2026-05-08 23:25:43 +02:00
parent 6021e397f5
commit 0e053d456a
3 changed files with 26 additions and 10 deletions

View File

@ -101,7 +101,7 @@ bool NewRpgBaseAction::MoveFarTo(WorldPosition dest)
if (lastBack.distance(dest) < maxDistChange && distFromBotToBack > 10.0f) if (lastBack.distance(dest) < maxDistChange && distFromBotToBack > 10.0f)
{ {
WorldPosition botPos(bot); WorldPosition botPos(bot);
lastMove.lastPath.makeShortCut(botPos, sPlayerbotAIConfig.reactDistance); lastMove.lastPath.makeShortCut(botPos, sPlayerbotAIConfig.reactDistance, bot);
// makeShortCut may clear the path if the bot drifted // makeShortCut may clear the path if the bot drifted
// too far off (>reactDistance from any waypoint). In // too far off (>reactDistance from any waypoint). In

View File

@ -678,7 +678,7 @@ void TravelNode::print([[maybe_unused]] bool printFailed)
} }
// Attempts to move ahead of the path. // Attempts to move ahead of the path.
bool TravelPath::makeShortCut(WorldPosition startPos, float maxDist) bool TravelPath::makeShortCut(WorldPosition startPos, float maxDist, Unit* bot)
{ {
if (GetPath().empty()) if (GetPath().empty())
return false; return false;
@ -691,10 +691,10 @@ bool TravelPath::makeShortCut(WorldPosition startPos, float maxDist)
for (auto& p : fullPath) // cycle over the full path for (auto& p : fullPath) // cycle over the full path
{ {
// if (p.point.GetMapId() != startPos.GetMapId()) // Walkability filter (cmangos parity): portals/transports/taxis
// continue; // aren't valid anchor points — picking one as the new start of
// the trimmed path would leave the bot anchored on a hop.
if (p.point.GetMapId() == startPos.GetMapId()) if (p.point.GetMapId() == startPos.GetMapId() && p.isWalkable())
{ {
float curDist = p.point.sqDistance(startPos); float curDist = p.point.sqDistance(startPos);
@ -737,8 +737,10 @@ bool TravelPath::makeShortCut(WorldPosition startPos, float maxDist)
WorldPosition beginPos = newPath.begin()->point; WorldPosition beginPos = newPath.begin()->point;
// The old path seems to be the best. // The old path seems to be the best — either the closest walkable
if (beginPos.distance(firstNode) < sPlayerbotAIConfig.tooCloseDistance) // point IS the original front, or it's within tooCloseDistance.
if (newPath.front() == fullPath.front() ||
beginPos.distance(firstNode) < sPlayerbotAIConfig.tooCloseDistance)
return false; return false;
// We are (nearly) on the new path. Just follow the rest. // We are (nearly) on the new path. Just follow the rest.
@ -748,7 +750,11 @@ bool TravelPath::makeShortCut(WorldPosition startPos, float maxDist)
return true; return true;
} }
std::vector<WorldPosition> toPath = startPos.getPathTo(beginPos, nullptr); // Pass the bot into getPathTo so PathGenerator picks up its
// collision / swimming / flying flags. cmangos parity — passing
// nullptr here drops to a default mover and can produce a path
// the bot itself can't actually walk.
std::vector<WorldPosition> toPath = startPos.getPathTo(beginPos, bot);
// We can not reach the new begin position. Follow the complete path. // We can not reach the new begin position. Follow the complete path.
if (!beginPos.isPathTo(toPath)) if (!beginPos.isPathTo(toPath))

View File

@ -427,6 +427,16 @@ struct PathNodePoint
WorldPosition point; WorldPosition point;
PathNodeType type = PathNodeType::NODE_PATH; PathNodeType type = PathNodeType::NODE_PATH;
uint32 entry = 0; uint32 entry = 0;
bool operator==(const PathNodePoint& p1) const
{
return point == p1.point && type == p1.type && entry == p1.entry;
}
// A "walkable" node is one we traverse on foot. Portals/transports/
// taxis/teleports are entry/exit hops, not points to anchor a
// shortcut on. Used by makeShortCut to skip them when picking the
// closest-point-on-path to the bot.
bool isWalkable() const { return (uint8)type <= (uint8)PathNodeType::NODE_NODE; }
}; };
// A complete list of points the bots has to walk to or teleport to. // A complete list of points the bots has to walk to or teleport to.
@ -481,7 +491,7 @@ public:
return retVec; return retVec;
} }
bool makeShortCut(WorldPosition startPos, float maxDist); bool makeShortCut(WorldPosition startPos, float maxDist, Unit* bot = nullptr);
std::ostringstream const print(); std::ostringstream const print();