mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-06-20 15:39:25 +02:00
feat(Core/Movement): Add MovementAction::ResolveMovePath unified resolver
This commit is contained in:
parent
bf5d4cf047
commit
665f2a3e56
@ -3260,6 +3260,55 @@ bool MovementAction::GetTravelPlan(TravelPlan& plan, WorldPosition destination)
|
||||
return sTravelNodeMap.GetFullPath(plan, botPos, bot->GetZoneId(), destination, bot);
|
||||
}
|
||||
|
||||
TravelPath MovementAction::ResolveMovePath(WorldPosition const& startPos,
|
||||
WorldPosition const& endPos,
|
||||
LastMovement& lastMove)
|
||||
{
|
||||
float const totalDistance = startPos.distance(endPos);
|
||||
float const maxDistChange = totalDistance * 0.1f;
|
||||
|
||||
// 10% reuse: cached path's tail close enough to new dest? Return as-is.
|
||||
if (!lastMove.lastPath.empty() &&
|
||||
lastMove.lastPath.getBack().distance(endPos) < maxDistChange)
|
||||
return lastMove.lastPath;
|
||||
|
||||
// Long path = cross-map or beyond sight; otherwise pure mmap probe.
|
||||
bool const needsLongPath =
|
||||
startPos.GetMapId() != endPos.GetMapId() ||
|
||||
totalDistance > sPlayerbotAIConfig.sightDistance;
|
||||
|
||||
TravelPath out;
|
||||
|
||||
if (needsLongPath && !sTravelNodeMap.getNodes().empty() && !bot->InBattleground())
|
||||
{
|
||||
// Wrap the legacy TravelPlan-populating call; the steps field on
|
||||
// TravelPlan IS a TravelPath, so extract it directly.
|
||||
TravelPlan tmp;
|
||||
if (sTravelNodeMap.GetFullPath(tmp, startPos, bot->GetZoneId(), endPos, bot))
|
||||
out = tmp.steps;
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldPosition mutableStart = startPos;
|
||||
std::vector<WorldPosition> probe = mutableStart.getPathTo(endPos, bot);
|
||||
out.addPath(probe);
|
||||
}
|
||||
|
||||
// Regression guard: if cached path's tail is no worse than the new
|
||||
// path's tail, keep the cached one (catches probes blocked by geometry).
|
||||
if (!lastMove.lastPath.empty() && !out.empty() &&
|
||||
lastMove.lastPath.getBack().distance(endPos) <=
|
||||
out.getBack().distance(endPos))
|
||||
out = lastMove.lastPath;
|
||||
|
||||
// Last-ditch fallback: a single point at the destination, so the
|
||||
// caller has at least something to dispatch.
|
||||
if (out.empty())
|
||||
out.addPoint(endPos);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
bool MovementAction::ExecuteTravelPlan(TravelPlan& state)
|
||||
{
|
||||
if (!state.IsActive())
|
||||
|
||||
@ -92,6 +92,15 @@ protected:
|
||||
bool GetTravelPlan(TravelPlan& plan, WorldPosition destination);
|
||||
bool ExecuteTravelPlan(TravelPlan& state);
|
||||
|
||||
// Returns a unified TravelPath for the move. Mirror of the reference
|
||||
// ResolveMovePath shape: 10% lastPath reuse short-circuit, choose
|
||||
// graph (cross-map / >sightDistance) or live mmap probe, regression
|
||||
// guard preferring cached path when no better, fall back to a
|
||||
// single-point path on dest. Stateless — does not dispatch.
|
||||
TravelPath ResolveMovePath(WorldPosition const& startPos,
|
||||
WorldPosition const& endPos,
|
||||
LastMovement& lastMove);
|
||||
|
||||
// Transport boarding helpers (shared by FollowAction and travel plan)
|
||||
static Transport* GetTransportForPosTolerant(Map* map, WorldObject* ref,
|
||||
uint32 phaseMask, float x, float y, float z);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user