fix(Core/Movement): followers match their target's motion speed (#25085)
Co-authored-by: killerwife <killerwife@gmail.com>
This commit is contained in:
parent
e8d98dfc34
commit
17ecef7a07
5 changed files with 52 additions and 36 deletions
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@
|
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue