Fix: prevent MoveSplineInitArgs::Validate velocity asserts (velocity > 0.01f) for bots, pets, and charmed units (#1534)

* MoveSplineInitArgs::Validate: expression 'velocity > 0.01f' failed for GUID Full

* Update BotMovementUtils.h
This commit is contained in:
Alex Dcnh
2025-08-12 01:53:48 +02:00
committed by GitHub
parent c6b0424c29
commit 4e3ac609bd
6 changed files with 111 additions and 3 deletions

35
src/BotMovementUtils.h Normal file
View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
* and/or modify it under version 2 of the License, or (at your option), any later version.
*/
#pragma once
#include "Unit.h"
#include "Player.h"
#include "MotionMaster.h"
inline bool CanStartMoveSpline(Player* bot) {
if (!bot) return false;
if (!bot->IsAlive()) return false;
if (bot->IsBeingTeleported() || bot->IsInFlight()) return false;
if (bot->HasUnitState(UNIT_STATE_LOST_CONTROL) || bot->HasRootAura() ||
bot->HasStunAura() || bot->IsCharmed() || bot->isFrozen() || bot->IsPolymorphed())
return false;
if (bot->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_CONTROLLED) != NULL_MOTION_TYPE)
return false;
if (bot->GetSpeed(MOVE_RUN) <= 0.01f) return false;
return true;
}
inline bool CanStartMoveSpline(Unit* u) {
if (!u) return false;
if (!u->IsAlive()) return false;
if (u->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_CONFUSED | UNIT_STATE_FLEEING))
return false;
if (u->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_CONTROLLED) != NULL_MOTION_TYPE)
return false;
if (u->GetSpeed(MOVE_RUN) <= 0.01f) return false;
return true;
}

View File

@@ -57,6 +57,7 @@
#include "Unit.h"
#include "UpdateTime.h"
#include "Vehicle.h"
#include "BotMovementUtils.h"
const int SPELL_TITAN_GRIP = 49152;
@@ -6325,11 +6326,27 @@ void PlayerbotAI::PetFollow()
if (!pet)
return;
pet->AttackStop();
pet->InterruptNonMeleeSpells(false);
/* pet->InterruptNonMeleeSpells(false);
pet->ClearInPetCombat();
pet->GetMotionMaster()->MoveFollow(bot, PET_FOLLOW_DIST, pet->GetFollowAngle());
if (pet->ToPet())
pet->ToPet()->ClearCastWhenWillAvailable();*/
// [Fix: MoveSplineInitArgs::Validate: expression 'velocity > 0.01f' failed for GUID Full:]
pet->InterruptNonMeleeSpells(false);
pet->ClearInPetCombat();
if (CanStartMoveSpline(pet))
{
pet->GetMotionMaster()->MoveFollow(bot, PET_FOLLOW_DIST, pet->GetFollowAngle());
}
else
{
pet->StopMovingOnCurrentPos(); // on nenvoie pas dordre invalide
}
if (pet->ToPet())
pet->ToPet()->ClearCastWhenWillAvailable();
//End Fix
CharmInfo* charmInfo = pet->GetCharmInfo();
if (!charmInfo)
return;

View File

@@ -591,6 +591,17 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
bot->CleanupAfterTaxiFlight();
}
// [Fix MoveSplineInitArgs::Validate: expression 'velocity > 0.01f' failed for GUID Full: 0x00000000000019ba Type: Player Low: 6586] Ensure valid speeds before any next movement command
bot->StopMoving();
bot->UpdateSpeed(MOVE_WALK, true);
bot->UpdateSpeed(MOVE_RUN, true);
bot->UpdateSpeed(MOVE_SWIM, true);
bot->UpdateSpeed(MOVE_FLIGHT, true); // OK even if not flying
if (bot->GetSpeed(MOVE_RUN) <= 0.01f) // Belt-and-suspenders: if the run speed has stayed ~0, reset to the default rate
bot->SetSpeedRate(MOVE_RUN, 1.0f);
// End Fix
// check activity
botAI->AllowActivity(ALL_ACTIVITY, true);

View File

@@ -9,6 +9,7 @@
#include "LastMovementValue.h"
#include "Playerbots.h"
#include "Transport.h"
#include "BotMovementUtils.h"
bool ReachAreaTriggerAction::Execute(Event event)
{
@@ -40,7 +41,18 @@ bool ReachAreaTriggerAction::Execute(Event event)
return true;
}
bot->GetMotionMaster()->MovePoint(at->map, at->x, at->y, at->z);
// bot->GetMotionMaster()->MovePoint(at->map, at->x, at->y, at->z);
// [Fix: MoveSplineInitArgs::Validate: expression 'velocity > 0.01f' failed for GUID Full:]
if (CanStartMoveSpline(bot))
{
bot->GetMotionMaster()->MovePoint(at->map, at->x, at->y, at->z);
}
else
{
bot->StopMovingOnCurrentPos();
botAI->SetNextCheckDelay(sPlayerbotAIConfig->reactDelay);
return false;
}
float distance = bot->GetDistance(at->x, at->y, at->z);
float delay = 1000.0f * distance / bot->GetSpeed(MOVE_RUN) + sPlayerbotAIConfig->reactDelay;

View File

@@ -42,6 +42,7 @@
#include "Vehicle.h"
#include "WaypointMovementGenerator.h"
#include "Corpse.h"
#include "BotMovementUtils.h"
MovementAction::MovementAction(PlayerbotAI* botAI, std::string const name) : Action(botAI, name)
{
@@ -81,6 +82,10 @@ bool MovementAction::JumpTo(uint32 mapId, float x, float y, float z, MovementPri
float botZ = bot->GetPositionZ();
float speed = bot->GetSpeed(MOVE_RUN);
MotionMaster& mm = *bot->GetMotionMaster();
// [Fix: MoveSplineInitArgs::Validate: expression 'velocity > 0.01f' failed for GUID Full:]
if (!CanStartMoveSpline(bot))
return false;
// End Fix
mm.Clear();
mm.MoveJump(x, y, z, speed, speed, 1);
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), 1000, priority);
@@ -207,6 +212,10 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
if (distance > 0.01f)
{
MotionMaster& mm = *vehicleBase->GetMotionMaster(); // need to move vehicle, not bot
// [Fix: MoveSplineInitArgs::Validate: expression 'velocity > 0.01f' failed for GUID Full:]
if (!CanStartMoveSpline(bot))
return false;
// End Fix
mm.Clear();
if (!backwards)
{
@@ -242,6 +251,10 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// botAI->InterruptSpell();
// }
MotionMaster& mm = *bot->GetMotionMaster();
//[Fix: MoveSplineInitArgs::Validate: expression 'velocity > 0.01f' failed for GUID Full:]
if (!CanStartMoveSpline(bot))
return false;
// End Fix
mm.Clear();
if (!backwards)
{
@@ -284,6 +297,10 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// }
MotionMaster& mm = *bot->GetMotionMaster();
G3D::Vector3 endP = path.back();
// [Fix: MoveSplineInitArgs::Validate: expression 'velocity > 0.01f' failed for GUID Full:]
if (!CanStartMoveSpline(bot))
return false;
// End Fix
mm.Clear();
if (!backwards)
{

View File

@@ -9,6 +9,7 @@
#include "RaidNaxxStrategy.h"
#include "ScriptedCreature.h"
#include "SharedDefines.h"
#include "BotMovementUtils.h"
bool GrobbulusGoBehindAction::Execute(Event event)
{
@@ -258,11 +259,26 @@ bool RazuviousUseObedienceCrystalAction::Execute(Event event)
return false;
}
if (charm->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_ACTIVE) == NULL_MOTION_TYPE)
{
/*{
charm->GetMotionMaster()->Clear();
charm->GetMotionMaster()->MoveChase(target);
charm->GetAI()->AttackStart(target);
}*/
// [Fix: MoveSplineInitArgs::Validate: expression 'velocity > 0.01f' failed for GUID Full:]
{
if (CanStartMoveSpline(charm))
{
charm->GetMotionMaster()->Clear();
charm->GetMotionMaster()->MoveChase(target);
}
else
{
charm->StopMoving();
}
charm->GetAI()->AttackStart(target);
}
// End Fix
Aura* forceObedience = botAI->GetAura("force obedience", charm);
uint32 duration_time;
if (!forceObedience)