mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-06-20 15:39:25 +02:00
Compare commits
4 Commits
b8adda0a90
...
3837425cad
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3837425cad | ||
|
|
9ce874269d | ||
|
|
b703a83679 | ||
|
|
9f3a8a49f8 |
@ -3221,34 +3221,26 @@ bool MovementAction::RefineWalkPoints(std::vector<G3D::Vector3>& walkPoints)
|
|||||||
WorldPosition aPos(mapId, a.x, a.y, a.z);
|
WorldPosition aPos(mapId, a.x, a.y, a.z);
|
||||||
WorldPosition bPos(mapId, b.x, b.y, b.z);
|
WorldPosition bPos(mapId, b.x, b.y, b.z);
|
||||||
|
|
||||||
// Per-segment mmap query against the live navmesh. The
|
// Per-segment mmap query: routes around geometry the offline
|
||||||
// travel-node graph stores offline-baked waypoints; if the
|
// graph didn't account for, or returns empty if unreachable.
|
||||||
// straight line A->B crosses geometry the live navmesh has
|
|
||||||
// (mountain, ledge, model edit since offline gen), this
|
|
||||||
// returns either an mmap-routed path around it (NORMAL/
|
|
||||||
// INCOMPLETE) or empty (NOT_USING_PATH was rejected as
|
|
||||||
// "would walk through walls").
|
|
||||||
std::vector<WorldPosition> segPath = bPos.getPathStepFrom(aPos, bot);
|
std::vector<WorldPosition> segPath = bPos.getPathStepFrom(aPos, bot);
|
||||||
|
|
||||||
if (segPath.empty())
|
// Trust the raw waypoint pair when mmap can't validate it —
|
||||||
|
// navmesh gaps/tile-edge artifacts on short segments shouldn't
|
||||||
|
// kill an active plan. Travelnode waypoints are authoritative.
|
||||||
|
bool const trustRaw = segPath.empty() ||
|
||||||
|
TravelPath::IsPathCheating(segPath, aPos.distance(bPos));
|
||||||
|
|
||||||
|
if (trustRaw)
|
||||||
{
|
{
|
||||||
// Live mmap refuses A->B. Caller should abort the plan
|
if (i == 0)
|
||||||
// and let MoveFarTo's own probe re-derive a route.
|
refined.emplace_back(a);
|
||||||
return false;
|
refined.emplace_back(b);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reject "pathfinder cheating" — same checks the offline gen
|
// Include the first segment's start; skip subsequent starts
|
||||||
// applies to BuildPath. Catches cached segments where the
|
// to avoid duplicating the prior segment's tail.
|
||||||
// live navmesh still produces a near-vertical hop or a
|
|
||||||
// 2-point straight line through geometry.
|
|
||||||
if (TravelPath::IsPathCheating(segPath, aPos.distance(bPos)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// First segment: include its start point so the spline
|
|
||||||
// begins from the original A. Later segments: skip the first
|
|
||||||
// point — it duplicates the previous segment's tail.
|
|
||||||
size_t startK = (i == 0) ? 0 : 1;
|
size_t startK = (i == 0) ? 0 : 1;
|
||||||
for (size_t k = startK; k < segPath.size(); ++k)
|
for (size_t k = startK; k < segPath.size(); ++k)
|
||||||
refined.emplace_back(segPath[k].GetPositionX(),
|
refined.emplace_back(segPath[k].GetPositionX(),
|
||||||
|
|||||||
@ -163,13 +163,12 @@ bool NewRpgBaseAction::MoveFarTo(WorldPosition dest)
|
|||||||
// waypoint spline at dest.
|
// waypoint spline at dest.
|
||||||
bool tryNodes = (dis >= nodeFirstDis && sPlayerbotAIConfig.enableTravelNodes);
|
bool tryNodes = (dis >= nodeFirstDis && sPlayerbotAIConfig.enableTravelNodes);
|
||||||
|
|
||||||
// If a node plan is already active, ride it — but only if its
|
// Ride an active plan to completion as long as its destination
|
||||||
// destination still matches the requested dest. Otherwise the
|
// still matches. Remaining distance can drop below nodeFirstDis
|
||||||
// old plan (e.g. built toward a quest objective POI) would keep
|
// mid-route (e.g. crossing a zone border near the target); killing
|
||||||
// driving the bot after the caller switched targets (e.g. to a
|
// the plan here would replace remaining waypoints with raw mmap
|
||||||
// turn-in NPC). cmangos's ResolveMovePath dodges this by being
|
// and often produce a u-turn. Clear only on dest change.
|
||||||
// stateless; we have a long-lived plan flag, so check explicitly.
|
if (botAI->rpgInfo.HasActiveTravelPlan())
|
||||||
if (tryNodes && botAI->rpgInfo.HasActiveTravelPlan())
|
|
||||||
{
|
{
|
||||||
if (botAI->rpgInfo.travelPlan.destination.distance(dest) > 10.0f)
|
if (botAI->rpgInfo.travelPlan.destination.distance(dest) > 10.0f)
|
||||||
botAI->rpgInfo.ClearTravel();
|
botAI->rpgInfo.ClearTravel();
|
||||||
@ -192,11 +191,6 @@ bool NewRpgBaseAction::MoveFarTo(WorldPosition dest)
|
|||||||
}
|
}
|
||||||
// Graph returned no plan — fall through to mmap probe.
|
// Graph returned no plan — fall through to mmap probe.
|
||||||
}
|
}
|
||||||
else if (botAI->rpgInfo.HasActiveTravelPlan())
|
|
||||||
{
|
|
||||||
// Move dropped below node-first threshold — drop any leftover plan.
|
|
||||||
botAI->rpgInfo.ClearTravel();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 40-step chained mmap probe — fallback when the node graph
|
// 40-step chained mmap probe — fallback when the node graph
|
||||||
// returned no plan (or for short moves below nodeFirstDis).
|
// returned no plan (or for short moves below nodeFirstDis).
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user