diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 938086961..98e5b890a 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -995,6 +995,30 @@ std::string Object::GetDebugInfo() const
return sstr.str();
}
+UnitMoveType MovementInfo::GetSpeedType(uint32 moveFlags)
+{
+ if (moveFlags & MOVEMENTFLAG_FLYING)
+ {
+ if (moveFlags & MOVEMENTFLAG_BACKWARD)
+ return MOVE_FLIGHT_BACK;
+
+ return MOVE_FLIGHT;
+ }
+ else if (moveFlags & MOVEMENTFLAG_SWIMMING)
+ {
+ if (moveFlags & MOVEMENTFLAG_BACKWARD)
+ return MOVE_SWIM_BACK;
+
+ return MOVE_SWIM;
+ }
+ else if (moveFlags & MOVEMENTFLAG_WALKING)
+ return MOVE_WALK;
+ else if (moveFlags & MOVEMENTFLAG_BACKWARD)
+ return MOVE_RUN_BACK;
+
+ return MOVE_RUN;
+}
+
void MovementInfo::OutDebug()
{
LOG_INFO("movement", "MOVEMENT INFO");
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index b6bea411f..d2da4b523 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -31,6 +31,7 @@
#include "ObjectGuid.h"
#include "Optional.h"
#include "Position.h"
+#include "UnitDefines.h"
#include "UpdateData.h"
#include "UpdateMask.h"
#include "ObjectVisibilityContainer.h"
@@ -344,6 +345,9 @@ struct MovementInfo
void RemoveMovementFlag(uint32 flag) { flags &= ~flag; }
[[nodiscard]] bool HasMovementFlag(uint32 flag) const { return flags & flag; }
+ [[nodiscard]] UnitMoveType GetSpeedType() const { return GetSpeedType(flags); }
+ [[nodiscard]] static UnitMoveType GetSpeedType(uint32 moveFlags);
+
[[nodiscard]] uint16 GetExtraMovementFlags() const { return flags2; }
void AddExtraMovementFlag(uint16 flag) { flags2 |= flag; }
[[nodiscard]] bool HasExtraMovementFlag(uint16 flag) const { return flags2 & flag; }
diff --git a/src/server/game/Entities/Unit/UnitDefines.h b/src/server/game/Entities/Unit/UnitDefines.h
index dc80e1fba..3b81afcad 100644
--- a/src/server/game/Entities/Unit/UnitDefines.h
+++ b/src/server/game/Entities/Unit/UnitDefines.h
@@ -15,6 +15,9 @@
* with this program. If not, see .
*/
+#ifndef ACORE_UNITDEFINES_H
+#define ACORE_UNITDEFINES_H
+
#include "Define.h"
#include "EnumFlag.h"
@@ -487,3 +490,5 @@ enum SplineType
SPLINETYPE_FACING_TARGET = 3,
SPLINETYPE_FACING_ANGLE = 4
};
+
+#endif // ACORE_UNITDEFINES_H
diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
index 4ff366c13..f67808892 100644
--- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
@@ -430,20 +430,27 @@ void ChaseMovementGenerator::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 GetVelocity(Unit* owner, Unit* target, G3D::Vector3 const& dest, bool playerPet)
{
Optional 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))
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp
index e1dbd9be5..4ae646e37 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.cpp
+++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp
@@ -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()