aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOvah <dreadkiller@gmx.de>2020-01-22 13:32:38 +0100
committerccrs <ccrs@users.noreply.github.com>2020-01-22 13:32:38 +0100
commit02daf1bf3afc570c26e8e9f431866fcb3720174a (patch)
tree1659f7e73725c865fd2b3926c9032e187cbbcedd /src
parentbc1d37f20d7c27d6fe34356bcbb388550e7aee63 (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.cpp26
-rw-r--r--src/server/game/Entities/Unit/Unit.h8
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