refactor(Core/Movement): WaitForReach formula parity + PointsArray overload

This commit is contained in:
bash 2026-05-31 18:05:35 +02:00
parent d7b29b5e73
commit 2bb0bc04b8
2 changed files with 33 additions and 2 deletions

View File

@ -888,25 +888,52 @@ float MovementAction::MoveDelay(float distance, bool backwards)
return delay; return delay;
} }
// TODO should this be removed? (or modified to use "last movement" value?)
void MovementAction::WaitForReach(float distance) void MovementAction::WaitForReach(float distance)
{ {
float delay = 1000.0f * MoveDelay(distance); // Reference formula: 1000 * MoveDelay(distance) + reactDelay. The
// reactDelay gives the bot a small slack at the end of a move so the
// next action sees the bot at rest rather than mid-spline.
float delay = 1000.0f * MoveDelay(distance) + sPlayerbotAIConfig.reactDelay;
if (delay > sPlayerbotAIConfig.maxWaitForMove) if (delay > sPlayerbotAIConfig.maxWaitForMove)
delay = sPlayerbotAIConfig.maxWaitForMove; delay = sPlayerbotAIConfig.maxWaitForMove;
// Combat clamp deliberately disabled (reference comments it out):
// clamping to globalCoolDown in combat caused bots to re-evaluate
// mid-pull and abandon a chase before reaching attack range. The
// commented block is preserved verbatim should we need to revisit.
/*
Unit* target = *botAI->GetAiObjectContext()->GetValue<Unit*>("current target"); Unit* target = *botAI->GetAiObjectContext()->GetValue<Unit*>("current target");
Unit* player = *botAI->GetAiObjectContext()->GetValue<Unit*>("enemy player target"); Unit* player = *botAI->GetAiObjectContext()->GetValue<Unit*>("enemy player target");
if ((player || target) && delay > sPlayerbotAIConfig.globalCoolDown) if ((player || target) && delay > sPlayerbotAIConfig.globalCoolDown)
delay = sPlayerbotAIConfig.globalCoolDown; delay = sPlayerbotAIConfig.globalCoolDown;
*/
if (delay < 0) if (delay < 0)
delay = 0; delay = 0;
// Reference uses SetDuration on the Action; AC's equivalent is
// SetNextCheckDelay on the AI loop. Same outcome: re-evaluation is
// postponed by `delay` ms.
botAI->SetNextCheckDelay((uint32)delay); botAI->SetNextCheckDelay((uint32)delay);
} }
void MovementAction::WaitForReach(Movement::PointsArray const& path)
{
float distance = 0.0f;
if (!path.empty())
{
G3D::Vector3 const* previousPoint = &path[0];
for (auto it = path.begin() + 1; it != path.end(); ++it)
{
G3D::Vector3 const& pathPoint = (*it);
distance += (*previousPoint - pathPoint).length();
previousPoint = &pathPoint;
}
}
WaitForReach(distance);
}
// similiar to botAI->SetNextCheckDelay() but only stops movement // similiar to botAI->SetNextCheckDelay() but only stops movement
void MovementAction::SetNextMovementDelay(float delayMillis) void MovementAction::SetNextMovementDelay(float delayMillis)
{ {

View File

@ -96,6 +96,10 @@ protected:
bool ReachCombatTo(Unit* target, float distance = 0.0f); bool ReachCombatTo(Unit* target, float distance = 0.0f);
float MoveDelay(float distance, bool backwards = false); float MoveDelay(float distance, bool backwards = false);
void WaitForReach(float distance); void WaitForReach(float distance);
// PointsArray overload: sums segment distances and calls the float
// version. Matches the reference's WaitForReach(PointsArray) used at
// the end of DispatchMovement.
void WaitForReach(Movement::PointsArray const& path);
void SetNextMovementDelay(float delayMillis); void SetNextMovementDelay(float delayMillis);
bool IsMovingAllowed(WorldObject* target); bool IsMovingAllowed(WorldObject* target);
bool IsDuplicateMove(float x, float y, float z); bool IsDuplicateMove(float x, float y, float z);