Compare commits

...

5 Commits

2 changed files with 44 additions and 9 deletions

View File

@ -3405,15 +3405,34 @@ bool MovementAction::ExecuteTravelPlan(TravelPlan& state)
case PathNodeType::NODE_PATH: case PathNodeType::NODE_PATH:
case PathNodeType::NODE_NODE: case PathNodeType::NODE_NODE:
{ {
// Batch consecutive walk points into one spline. Capped small 20 points per tick. // Batch consecutive walk points into one spline. Capped at
// 20 points OR ~70y of accumulated distance — whichever
// comes first. The distance cap gives the planner regular
// re-evaluation points without committing the whole
// remaining route up front; stepIdx advances exactly in
// step with what's actually dispatched, so the next tick
// picks up from the truncation point.
static constexpr uint32 MAX_SPLINE_POINTS = 20; static constexpr uint32 MAX_SPLINE_POINTS = 20;
static constexpr float MAX_BATCH_LENGTH = 70.0f;
state.walkPoints.clear(); state.walkPoints.clear();
float accumulated = 0.f;
while (state.stepIdx < state.steps.size() && state.walkPoints.size() < MAX_SPLINE_POINTS) while (state.stepIdx < state.steps.size() && state.walkPoints.size() < MAX_SPLINE_POINTS)
{ {
const PathNodePoint& wp = state.steps[state.stepIdx]; const PathNodePoint& wp = state.steps[state.stepIdx];
if (wp.type != PathNodeType::NODE_PATH && wp.type != PathNodeType::NODE_NODE) if (wp.type != PathNodeType::NODE_PATH && wp.type != PathNodeType::NODE_NODE)
break; break;
state.walkPoints.push_back(G3D::Vector3(wp.point.GetPositionX(), wp.point.GetPositionY(), wp.point.GetPositionZ())); G3D::Vector3 next(wp.point.GetPositionX(), wp.point.GetPositionY(), wp.point.GetPositionZ());
if (!state.walkPoints.empty())
{
accumulated += (next - state.walkPoints.back()).length();
if (accumulated >= MAX_BATCH_LENGTH)
{
state.walkPoints.push_back(next);
state.stepIdx++;
break;
}
}
state.walkPoints.push_back(next);
state.stepIdx++; state.stepIdx++;
} }

View File

@ -236,13 +236,29 @@ bool NewRpgBaseAction::MoveFarTo(WorldPosition dest)
if (points.size() >= 2) if (points.size() >= 2)
{ {
// Cap the chain at 20 waypoints. Beyond that, the // Cap dispatched path length at ~70y. MoveFarTo's
// chained probe's accuracy degrades (more chained // early-exit (top of function) lets the active spline
// PathGenerator calls = more stitching artifacts) and // run until bot is within 10y of its endpoint, then
// the spline interpolation between distant waypoints // replans from the new position. Capping per-dispatch
// is more likely to drift through air. // distance gives the planner regular re-evaluation
if (points.size() > 20) // points without the per-tick replan cost of fully
points.resize(20); // unbounded chunks.
{
constexpr float maxDispatchLength = 70.0f;
float accumulated = 0.f;
size_t cutoff = points.size();
for (size_t i = 1; i < points.size(); ++i)
{
accumulated += (points[i] - points[i - 1]).length();
if (accumulated >= maxDispatchLength)
{
cutoff = i + 1;
break;
}
}
if (cutoff < points.size())
points.resize(cutoff);
}
LOG_INFO("playerbots", "[MoveFar] {} mmap-path | dis={:.0f} | endDist={:.0f} | wp={} | mmapFails={} nodeFails={} | flags={}{}{}", LOG_INFO("playerbots", "[MoveFar] {} mmap-path | dis={:.0f} | endDist={:.0f} | wp={} | mmapFails={} nodeFails={} | flags={}{}{}",
bot->GetName(), dis, endDistToDest, (uint32)points.size(), bot->GetName(), dis, endDistToDest, (uint32)points.size(),