diff options
| author | Ovah <dreadkiller@gmx.de> | 2020-01-22 13:32:38 +0100 |
|---|---|---|
| committer | ccrs <ccrs@users.noreply.github.com> | 2020-01-22 13:32:38 +0100 |
| commit | 02daf1bf3afc570c26e8e9f431866fcb3720174a (patch) | |
| tree | 1659f7e73725c865fd2b3926c9032e187cbbcedd /src | |
| parent | bc1d37f20d7c27d6fe34356bcbb388550e7aee63 (diff) | |
Core/Movement: properly fix aura interrupts during movement (#24068)
We want our movement to be fully updated before even thinking about interrupting anything. The old logic was updating positions, interrupting stuff and afterwards updating movement generators. This way we were ending up with false interrupts.
properly fixes #22908
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 26 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 8 |
2 files changed, 27 insertions, 7 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 694b675256e..40f0ec3725b 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -455,6 +455,12 @@ void Unit::Update(uint32 p_time) UpdateSplineMovement(p_time); i_motionMaster->Update(p_time); + // Wait with the aura interrupts until we have updated our movement generators and position + if (GetTypeId() == TYPEID_PLAYER) + InterruptMovementBasedAuras(); + else if (!movespline->Finalized()) + InterruptMovementBasedAuras(); + if (!GetAI() && (GetTypeId() != TYPEID_PLAYER || (IsCharmed() && GetCharmerGUID().IsCreature()))) UpdateCharmAI(); RefreshAI(); @@ -519,6 +525,16 @@ void Unit::UpdateSplinePosition() UpdatePosition(loc.x, loc.y, loc.z, loc.orientation); } +void Unit::InterruptMovementBasedAuras() +{ + // TODO: Check if orientation transport offset changed instead of only global orientation + if (_positionUpdateInfo.Turned) + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TURNING); + + if (_positionUpdateInfo.Relocated && !GetVehicle()) + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOVE); +} + void Unit::DisableSpline() { m_movementInfo.RemoveMovementFlag(MovementFlags(MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD)); @@ -12730,15 +12746,8 @@ bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool tel std::fabs(GetPositionY() - y) > 0.001f || std::fabs(GetPositionZ() - z) > 0.001f); - // TODO: Check if orientation transport offset changed instead of only global orientation - if (turn) - RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TURNING); - if (relocated) { - if (!GetVehicle()) - RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOVE); - // move and update visible state if need if (GetTypeId() == TYPEID_PLAYER) GetMap()->PlayerRelocation(ToPlayer(), x, y, z, orientation); @@ -12750,6 +12759,9 @@ bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool tel UpdatePositionData(); + _positionUpdateInfo.Relocated = relocated; + _positionUpdateInfo.Turned = turn; + return (relocated || turn); } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index e1bad058282..bf37de2b822 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -714,6 +714,12 @@ enum ReactiveType MAX_REACTIVE }; +struct PositionUpdateInfo +{ + bool Relocated = false; + bool Turned = false; +}; + // delay time next attack to prevent client attack animation problems #define ATTACK_DISPLAY_DELAY 200 #define MAX_PLAYER_STEALTH_DETECT_RANGE 30.0f // max distance for detection targets by player @@ -1763,6 +1769,7 @@ class TC_GAME_API Unit : public WorldObject void UpdateSplineMovement(uint32 t_diff); void UpdateSplinePosition(); + void InterruptMovementBasedAuras(); // player or player's pet float GetCombatRatingReduction(CombatRating cr) const; @@ -1810,6 +1817,7 @@ class TC_GAME_API Unit : public WorldObject bool _isWalkingBeforeCharm; ///< Are we walking before we were charmed? SpellHistory* m_spellHistory; + PositionUpdateInfo _positionUpdateInfo; }; namespace Trinity |
