From 2e1f848f09e14a81e469909f4507a37d218adfcb Mon Sep 17 00:00:00 2001 From: Jelle Meeus Date: Tue, 29 Jul 2025 05:58:30 -0700 Subject: [PATCH] fix(Core/Unit): Add melee leeway for auto attacks (#22566) --- src/server/game/Entities/Object/ObjectDefines.h | 2 ++ src/server/game/Entities/Unit/Unit.cpp | 3 +++ src/server/game/Entities/Unit/Unit.h | 6 ++++++ src/server/game/Spells/Spell.cpp | 2 +- 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/server/game/Entities/Object/ObjectDefines.h b/src/server/game/Entities/Object/ObjectDefines.h index 2913e587b..bfae02203 100644 --- a/src/server/game/Entities/Object/ObjectDefines.h +++ b/src/server/game/Entities/Object/ObjectDefines.h @@ -48,6 +48,8 @@ #define NOMINAL_MELEE_RANGE 5.0f #define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players #define DEFAULT_COLLISION_HEIGHT 2.03128f // Most common value in dbc +#define LEEWAY_MIN_MOVE_SPEED 4.97f // NYI +#define LEEWAY_BONUS_RANGE 2.66f // used for creating values for respawn for example inline uint32 PAIR64_HIPART(uint64 x); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 96a10b1c7..e1cd1735c 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -674,6 +674,9 @@ bool Unit::IsWithinMeleeRange(Unit const* obj, float dist) const float maxdist = dist + GetMeleeRange(obj); + if ((IsPlayer() || obj->IsPlayer()) && HasLeewayMovement() && obj->HasLeewayMovement()) + maxdist += LEEWAY_BONUS_RANGE; + return distsq < maxdist * maxdist; } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index f83e2a623..4dc7cb585 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1639,6 +1639,12 @@ public: UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED) && !GetOwnerGUID(); } + [[nodiscard]] bool HasLeewayMovement() const + { + return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT | MOVEMENTFLAG_FALLING) + && !IsWalking(); + } + void KnockbackFrom(float x, float y, float speedXY, float speedZ); void JumpTo(float speedXY, float speedZ, bool forward = true); void JumpTo(WorldObject* obj, float speedZ); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index ca543c804..439713ee7 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -7109,7 +7109,7 @@ SpellCastResult Spell::CheckRange(bool strict) if (range_type == SPELL_RANGE_MELEE) { float real_max_range = max_range; - if (!m_caster->IsCreature() && m_caster->isMoving() && target->isMoving() && !m_caster->IsWalking() && !target->IsWalking()) + if (!m_caster->IsCreature() && m_caster->HasLeewayMovement() && target->HasLeewayMovement()) real_max_range -= MIN_MELEE_REACH; // Because of lag, we can not check too strictly here (is only used if both caster and target are moving) else real_max_range -= 2 * MIN_MELEE_REACH;