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()