diff --git a/src/Ai/Base/Actions/MovementActions.cpp b/src/Ai/Base/Actions/MovementActions.cpp index 3d4063306..2b9e0f3ce 100644 --- a/src/Ai/Base/Actions/MovementActions.cpp +++ b/src/Ai/Base/Actions/MovementActions.cpp @@ -3334,33 +3334,18 @@ bool MovementAction::ExecuteTravelPlan(TravelPlan& state) case PathNodeType::NODE_NODE: { // 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. + // 20 points per dispatch as a cheap upper bound on per-tick + // work; stepIdx advances exactly in step with what's + // dispatched, so the next tick picks up from the cutoff. static constexpr uint32 MAX_SPLINE_POINTS = 20; - static constexpr float MAX_BATCH_LENGTH = 70.0f; state.walkPoints.clear(); - float accumulated = 0.f; while (state.stepIdx < state.steps.size() && state.walkPoints.size() < MAX_SPLINE_POINTS) { const PathNodePoint& wp = state.steps[state.stepIdx]; if (wp.type != PathNodeType::NODE_PATH && wp.type != PathNodeType::NODE_NODE) break; - 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.walkPoints.push_back(G3D::Vector3(wp.point.GetPositionX(), + wp.point.GetPositionY(), wp.point.GetPositionZ())); state.stepIdx++; } diff --git a/src/Ai/World/Rpg/Action/NewRpgBaseAction.cpp b/src/Ai/World/Rpg/Action/NewRpgBaseAction.cpp index 80c2daf5d..b33dddbd7 100644 --- a/src/Ai/World/Rpg/Action/NewRpgBaseAction.cpp +++ b/src/Ai/World/Rpg/Action/NewRpgBaseAction.cpp @@ -77,17 +77,12 @@ bool NewRpgBaseAction::MoveFarTo(WorldPosition dest) } } - // 10% lastPath reuse — route commitment across combat - // interruptions. If the cached path's endpoint is still close - // (within 10%) to the new dest AND bot is mid-flight toward it - // (>10y away AND currently moving), reuse silently. The - // bot->isMoving() guard prevents reuse from short-circuiting - // when bot is stopped between dispatches — in that case we - // MUST fall through to dispatch the next leg, not return true - // and stand still. + // 10% lastPath reuse — if the cached path's endpoint is still + // close (within 10%) to the new dest AND we're not nearly there, + // keep the existing route. Matches cmangos ResolveMovePath. { LastMovement& lastMove = AI_VALUE(LastMovement&, "last movement"); - if (bot->isMoving() && !lastMove.lastPath.empty()) + if (!lastMove.lastPath.empty()) { WorldPosition lastBack = lastMove.lastPath.getBack(); if (lastBack.GetMapId() == dest.GetMapId()) @@ -176,30 +171,6 @@ bool NewRpgBaseAction::MoveFarTo(WorldPosition dest) if (points.size() >= 2) { - // Cap dispatched path length at ~70y. MoveFarTo's - // early-exit (top of function) lets the active spline - // run until bot is within 10y of its endpoint, then - // replans from the new position. Capping per-dispatch - // distance gives the planner regular re-evaluation - // points without the per-tick replan cost of fully - // 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={}", bot->GetName(), dis, endDistToDest, (uint32)points.size()); EmitDebugMove("MoveFar", "mmap",