mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-06-20 15:39:25 +02:00
refactor(Core/Movement): DispatchPathPoints → DispatchMovement (TravelPath sig + transport sandwich)
This commit is contained in:
parent
2bb0bc04b8
commit
59f82465e1
@ -338,7 +338,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
|
||||
|
||||
// Path-aware funnel: ResolveMovePath → makeShortCut →
|
||||
// UpcommingSpecialMovement/HandleSpecialMovement → ClipPath →
|
||||
// DispatchPathPoints. Matches the reference's MoveTo2 flow.
|
||||
// DispatchMovement. Matches the reference's MoveTo2 flow.
|
||||
return MoveTo2(WorldPosition(mapId, x, y, z),
|
||||
idle, react, false, ignoreEnemyTargets, priority, lessDelay);
|
||||
}
|
||||
@ -2993,12 +2993,7 @@ bool MovementAction::MoveTo2(WorldPosition endPos,
|
||||
botAI->TellMasterNoFacing(tlog);
|
||||
}
|
||||
|
||||
std::vector<WorldPosition> const& pts = path.getPointPath();
|
||||
Movement::PointsArray points;
|
||||
points.reserve(pts.size());
|
||||
for (auto const& wp : pts)
|
||||
points.emplace_back(wp.GetPositionX(), wp.GetPositionY(), wp.GetPositionZ());
|
||||
if (points.empty())
|
||||
if (path.empty())
|
||||
return false;
|
||||
|
||||
if (!bot->IsMounted() && !bot->IsInCombat() &&
|
||||
@ -3006,7 +3001,7 @@ bool MovementAction::MoveTo2(WorldPosition endPos,
|
||||
botAI->DoSpecificAction("check mount state", Event(), true);
|
||||
|
||||
bool const dispatched =
|
||||
DispatchPathPoints(endPos, points, "walk", priority, lessDelay);
|
||||
DispatchMovement(path, endPos, "walk", priority, lessDelay);
|
||||
|
||||
if (dispatched && !idle)
|
||||
ClearIdleState();
|
||||
@ -3014,12 +3009,20 @@ bool MovementAction::MoveTo2(WorldPosition endPos,
|
||||
return dispatched;
|
||||
}
|
||||
|
||||
bool MovementAction::DispatchPathPoints(WorldPosition const& dest,
|
||||
Movement::PointsArray& points,
|
||||
char const* label,
|
||||
MovementPriority priority,
|
||||
bool lessDelay)
|
||||
bool MovementAction::DispatchMovement(TravelPath const& path,
|
||||
WorldPosition const& dest,
|
||||
char const* label,
|
||||
MovementPriority priority,
|
||||
bool lessDelay)
|
||||
{
|
||||
// Build the PointsArray from the TravelPath. Done here (not at the
|
||||
// caller) so DispatchMovement can be invoked with a TravelPath
|
||||
// directly, matching the reference's signature.
|
||||
std::vector<WorldPosition> const& pts = path.getPointPath();
|
||||
Movement::PointsArray points;
|
||||
points.reserve(pts.size());
|
||||
for (auto const& wp : pts)
|
||||
points.emplace_back(wp.GetPositionX(), wp.GetPositionY(), wp.GetPositionZ());
|
||||
if (points.empty())
|
||||
return false;
|
||||
|
||||
@ -3080,11 +3083,22 @@ bool MovementAction::DispatchPathPoints(WorldPosition const& dest,
|
||||
if (bot->IsNonMeleeSpellCast(true))
|
||||
bot->InterruptNonMeleeSpells(true);
|
||||
|
||||
// Per-point terrain clamp.
|
||||
// Per-point terrain clamp with transport-passenger conversion
|
||||
// sandwich: when on a transport, path coords are in transport-local
|
||||
// space; UpdateAllowedPositionZ samples world terrain, so we convert
|
||||
// local→world, snap, world→local. Without the sandwich, snapping a
|
||||
// transport-relative point against world terrain produces garbage.
|
||||
Transport* transport = bot->GetTransport();
|
||||
for (auto& pt : points)
|
||||
{
|
||||
if (transport)
|
||||
transport->CalculatePassengerPosition(pt.x, pt.y, pt.z);
|
||||
bot->UpdateAllowedPositionZ(pt.x, pt.y, pt.z);
|
||||
if (transport)
|
||||
transport->CalculatePassengerOffset(pt.x, pt.y, pt.z);
|
||||
}
|
||||
|
||||
// mm.Clear → MovePoint(last) → MoveSplinePath → WaitForReach.
|
||||
// mm.Clear → MovePoint(last) → MoveSplinePath.
|
||||
MotionMaster* mm = bot->GetMotionMaster();
|
||||
mm->Clear();
|
||||
|
||||
@ -3102,7 +3116,8 @@ bool MovementAction::DispatchPathPoints(WorldPosition const& dest,
|
||||
|
||||
// WaitForReach equivalent: cache the dispatched target + duration on
|
||||
// lastMove. Leave ~10y headroom on long paths so we re-evaluate
|
||||
// before arrival.
|
||||
// before arrival. (Reference also calls WaitForReach here, which
|
||||
// blocks the AI loop; we omit that — see header comment.)
|
||||
float waitDist = totalDist > sPlayerbotAIConfig.reactDistance
|
||||
? std::max(totalDist - 10.0f, 0.0f) : totalDist;
|
||||
UnitMoveType const speedType = (moveMode == FORCED_MOVEMENT_WALK) ? MOVE_WALK : MOVE_RUN;
|
||||
|
||||
@ -65,7 +65,7 @@ protected:
|
||||
// with makeShortCut, handles special head segments
|
||||
// (portal/area-trigger/transport/flight) via HandleSpecialMovement,
|
||||
// clips at hostile creatures via ClipPath (unless ignoreEnemyTargets),
|
||||
// and dispatches the resulting walk via DispatchPathPoints.
|
||||
// and dispatches the resulting walk via DispatchMovement.
|
||||
// MoveTo(mapId,...) delegates here unless an intentional bypass
|
||||
// (exact_waypoint / disableMoveSplinePath / flying / swimming /
|
||||
// backwards) routes the move straight to DoMovePoint.
|
||||
@ -75,16 +75,27 @@ protected:
|
||||
MovementPriority priority = MovementPriority::MOVEMENT_NORMAL,
|
||||
bool lessDelay = false);
|
||||
|
||||
// Centralized walk dispatch. Applies inactive-bot teleport carve-out,
|
||||
// masterWalking mode, pre-dispatch state cleanup (clear emote, stand,
|
||||
// interrupt cast), per-point UpdateAllowedPositionZ, mm.Clear →
|
||||
// MovePoint(last) → MoveSplinePath, and a WaitForReach equivalent
|
||||
// that caches the destination + duration on lastMove.
|
||||
bool DispatchPathPoints(WorldPosition const& dest,
|
||||
Movement::PointsArray& points,
|
||||
char const* label,
|
||||
MovementPriority priority = MovementPriority::MOVEMENT_NORMAL,
|
||||
bool lessDelay = false);
|
||||
// Centralized walk dispatch. Mirrors the reference's DispatchMovement
|
||||
// shape: takes a TravelPath, builds the PointsArray internally,
|
||||
// applies inactive-bot teleport carve-out, masterWalking mode,
|
||||
// pre-dispatch state cleanup (clear emote, stand, interrupt cast),
|
||||
// transport-passenger coordinate sandwich
|
||||
// (CalculatePassengerPosition → UpdateAllowedPositionZ → Offset)
|
||||
// around the per-point Z snap, mm.Clear → MovePoint(last) →
|
||||
// MoveSplinePath. Caches the destination + duration on lastMove.
|
||||
//
|
||||
// Divergence from reference: reference ends with WaitForReach(size)
|
||||
// which blocks the AI loop until the move completes. AC's combat
|
||||
// callers (ReachCombatTo) currently funnel through MoveTo → MoveTo2
|
||||
// → DispatchMovement; blocking the AI loop here would suspend combat
|
||||
// re-evaluation for the full move duration. Until combat dispatch is
|
||||
// restructured to bypass MoveTo2, the WaitForReach is deliberately
|
||||
// omitted.
|
||||
bool DispatchMovement(TravelPath const& path,
|
||||
WorldPosition const& dest,
|
||||
char const* label,
|
||||
MovementPriority priority = MovementPriority::MOVEMENT_NORMAL,
|
||||
bool lessDelay = false);
|
||||
bool MoveTo(WorldObject* target, float distance = 0.0f,
|
||||
MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
|
||||
bool MoveNear(WorldObject* target, float distance = sPlayerbotAIConfig.contactDistance,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user