fix(Core/Movement): followers match their target's motion speed (#25085)
Co-authored-by: killerwife <killerwife@gmail.com>
This commit is contained in:
@@ -430,20 +430,27 @@ void ChaseMovementGenerator<T>::MovementInform(T* owner)
|
||||
|
||||
//-----------------------------------------------//
|
||||
|
||||
static float GetTargetSpeedInMotion(Unit* target)
|
||||
{
|
||||
if (!target->movespline->Finalized())
|
||||
return target->movespline->Velocity();
|
||||
|
||||
return target->GetSpeed(target->m_movementInfo.GetSpeedType());
|
||||
}
|
||||
|
||||
static Optional<float> GetVelocity(Unit* owner, Unit* target, G3D::Vector3 const& dest, bool playerPet)
|
||||
{
|
||||
Optional<float> speed = {};
|
||||
if (!owner->IsInCombat() && !owner->IsVehicle() && !owner->HasUnitFlag(UNIT_FLAG_POSSESSED) &&
|
||||
(owner->IsPet() || owner->IsGuardian() || owner->GetGUID() == target->GetCritterGUID() || owner->GetCharmerOrOwnerGUID() == target->GetGUID()))
|
||||
{
|
||||
uint32 moveFlags = target->GetUnitMovementFlags();
|
||||
if (target->IsWalking())
|
||||
{
|
||||
moveFlags |= MOVEMENTFLAG_WALKING;
|
||||
}
|
||||
if (owner->IsInCombat() || owner->IsVehicle() || owner->HasUnitFlag(UNIT_FLAG_POSSESSED))
|
||||
return speed;
|
||||
|
||||
bool isPetLike = owner->IsPet() || owner->IsGuardian() || owner->GetGUID() == target->GetCritterGUID() || owner->GetCharmerOrOwnerGUID() == target->GetGUID();
|
||||
|
||||
// For pets/guardians/critters or creature-to-creature follow: sync with target's speed
|
||||
if (isPetLike || (owner->IsCreature() && target->IsCreature()))
|
||||
{
|
||||
speed = GetTargetSpeedInMotion(target);
|
||||
|
||||
UnitMoveType moveType = Movement::SelectSpeedType(moveFlags);
|
||||
speed = target->GetSpeed(moveType);
|
||||
if (playerPet)
|
||||
{
|
||||
float distance = owner->GetDistance2d(dest.x, dest.y) - target->GetObjectSize() - (*speed / 2.f);
|
||||
@@ -462,7 +469,7 @@ static Position const PredictPosition(Unit* target)
|
||||
{
|
||||
Position pos = target->GetPosition();
|
||||
// 0.5 - it's time (0.5 sec) between starting movement opcode (e.g. MSG_MOVE_START_FORWARD) and MSG_MOVE_HEARTBEAT sent by client
|
||||
float speed = target->GetSpeed(Movement::SelectSpeedType(target->GetUnitMovementFlags())) * 0.5f;
|
||||
float speed = target->GetSpeed(target->m_movementInfo.GetSpeedType()) * 0.5f;
|
||||
float orientation = target->GetOrientation();
|
||||
|
||||
if (target->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FORWARD))
|
||||
|
||||
@@ -29,31 +29,7 @@ namespace Movement
|
||||
{
|
||||
UnitMoveType SelectSpeedType(uint32 moveFlags)
|
||||
{
|
||||
if (moveFlags & MOVEMENTFLAG_FLYING)
|
||||
{
|
||||
if (moveFlags & MOVEMENTFLAG_BACKWARD /*&& speed_obj.flight >= speed_obj.flight_back*/)
|
||||
return MOVE_FLIGHT_BACK;
|
||||
else
|
||||
return MOVE_FLIGHT;
|
||||
}
|
||||
else if (moveFlags & MOVEMENTFLAG_SWIMMING)
|
||||
{
|
||||
if (moveFlags & MOVEMENTFLAG_BACKWARD /*&& speed_obj.swim >= speed_obj.swim_back*/)
|
||||
return MOVE_SWIM_BACK;
|
||||
else
|
||||
return MOVE_SWIM;
|
||||
}
|
||||
else if (moveFlags & MOVEMENTFLAG_WALKING)
|
||||
{
|
||||
//if (speed_obj.run > speed_obj.walk)
|
||||
return MOVE_WALK;
|
||||
}
|
||||
else if (moveFlags & MOVEMENTFLAG_BACKWARD /*&& speed_obj.run >= speed_obj.run_back*/)
|
||||
return MOVE_RUN_BACK;
|
||||
|
||||
// Flying creatures use MOVEMENTFLAG_CAN_FLY or MOVEMENTFLAG_DISABLE_GRAVITY
|
||||
// Run speed is their default flight speed.
|
||||
return MOVE_RUN;
|
||||
return MovementInfo::GetSpeedType(moveFlags);
|
||||
}
|
||||
|
||||
int32 MoveSplineInit::Launch()
|
||||
|
||||
Reference in New Issue
Block a user