aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorccrs <ccrs@users.noreply.github.com>2019-10-21 13:55:23 +0200
committerShauren <shauren.trinity@gmail.com>2021-12-18 23:03:00 +0100
commitdfb2221552048512b4fda0c7e0c97ecf808106f9 (patch)
tree900f9525bd740471d3c18c80787d85c84ee105e9 /src
parent7f074efa0498f9c0a8b8eaed733f462763ae099d (diff)
Core/Movement: delay movement update in MotionMaster until its owner signals AddToWorld
ref #23199 closes #23876 (cherry picked from commit d033032d33cff5dae76000f8432d78746cda9e06)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp1
-rw-r--r--src/server/game/Movement/MotionMaster.cpp44
-rw-r--r--src/server/game/Movement/MotionMaster.h7
3 files changed, 38 insertions, 14 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 3821c974849..d7d4fe80531 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -9098,6 +9098,7 @@ void Unit::RestoreDisabledAI()
void Unit::AddToWorld()
{
WorldObject::AddToWorld();
+ i_motionMaster->AddToWorld();
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::EnterWorld);
}
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 9c6ae257ec1..cdfe8144868 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -95,7 +95,7 @@ MotionMaster::~MotionMaster()
void MotionMaster::Initialize()
{
- if (HasFlag(MOTIONMASTER_FLAG_UPDATE))
+ if (HasFlag(MOTIONMASTER_FLAG_DELAYED))
{
DelayedActionDefine action = [this]()
{
@@ -113,6 +113,16 @@ void MotionMaster::InitializeDefault()
Add(FactorySelector::SelectMovementGenerator(_owner), MOTION_SLOT_DEFAULT);
}
+void MotionMaster::AddToWorld()
+{
+ if (!HasFlag(MOTIONMASTER_FLAG_INITIALIZATION_PENDING))
+ return;
+
+ ResolveDelayedActions();
+
+ RemoveFlag(MOTIONMASTER_FLAG_INITIALIZATION_PENDING);
+}
+
bool MotionMaster::Empty() const
{
return !_defaultGenerator && _generators.empty();
@@ -277,6 +287,9 @@ void MotionMaster::Update(uint32 diff)
if (!_owner)
return;
+ if (HasFlag(MOTIONMASTER_FLAG_INITIALIZATION_PENDING))
+ return;
+
ASSERT(!Empty(), "MotionMaster:Update: update called without Initializing! (%s)", _owner->GetGUID().ToString().c_str());
AddFlag(MOTIONMASTER_FLAG_UPDATE);
@@ -304,11 +317,7 @@ void MotionMaster::Update(uint32 diff)
RemoveFlag(MOTIONMASTER_FLAG_UPDATE);
- while (!_delayedActions.empty())
- {
- _delayedActions.front().Resolve();
- _delayedActions.pop_front();
- }
+ ResolveDelayedActions();
}
void MotionMaster::Add(MovementGenerator* movement, MovementSlot slot/* = MOTION_SLOT_ACTIVE*/)
@@ -322,7 +331,7 @@ void MotionMaster::Add(MovementGenerator* movement, MovementSlot slot/* = MOTION
return;
}
- if (HasFlag(MOTIONMASTER_FLAG_UPDATE))
+ if (HasFlag(MOTIONMASTER_FLAG_DELAYED))
{
DelayedActionDefine action = [this, movement, slot]()
{
@@ -339,7 +348,7 @@ void MotionMaster::Remove(MovementGenerator* movement, MovementSlot slot/* = MOT
if (!movement || IsInvalidMovementSlot(slot))
return;
- if (HasFlag(MOTIONMASTER_FLAG_UPDATE))
+ if (HasFlag(MOTIONMASTER_FLAG_DELAYED))
{
DelayedActionDefine action = [this, movement, slot]()
{
@@ -377,7 +386,7 @@ void MotionMaster::Remove(MovementGeneratorType type, MovementSlot slot/* = MOTI
if (IsInvalidMovementGeneratorType(type) || IsInvalidMovementSlot(slot))
return;
- if (HasFlag(MOTIONMASTER_FLAG_UPDATE))
+ if (HasFlag(MOTIONMASTER_FLAG_DELAYED))
{
DelayedActionDefine action = [this, type, slot]()
{
@@ -415,7 +424,7 @@ void MotionMaster::Remove(MovementGeneratorType type, MovementSlot slot/* = MOTI
void MotionMaster::Clear()
{
- if (HasFlag(MOTIONMASTER_FLAG_UPDATE))
+ if (HasFlag(MOTIONMASTER_FLAG_DELAYED))
{
DelayedActionDefine action = [this]()
{
@@ -434,7 +443,7 @@ void MotionMaster::Clear(MovementSlot slot)
if (IsInvalidMovementSlot(slot))
return;
- if (HasFlag(MOTIONMASTER_FLAG_UPDATE))
+ if (HasFlag(MOTIONMASTER_FLAG_DELAYED))
{
DelayedActionDefine action = [this, slot]()
{
@@ -462,7 +471,7 @@ void MotionMaster::Clear(MovementSlot slot)
void MotionMaster::Clear(MovementGeneratorMode mode)
{
- if (HasFlag(MOTIONMASTER_FLAG_UPDATE))
+ if (HasFlag(MOTIONMASTER_FLAG_DELAYED))
{
DelayedActionDefine action = [this, mode]()
{
@@ -484,7 +493,7 @@ void MotionMaster::Clear(MovementGeneratorMode mode)
void MotionMaster::Clear(MovementGeneratorPriority priority)
{
- if (HasFlag(MOTIONMASTER_FLAG_UPDATE))
+ if (HasFlag(MOTIONMASTER_FLAG_DELAYED))
{
DelayedActionDefine action = [this, priority]()
{
@@ -1074,6 +1083,15 @@ void MotionMaster::LaunchMoveSpline(Movement::MoveSplineInit&& init, uint32 id/*
/******************** Private methods ********************/
+void MotionMaster::ResolveDelayedActions()
+{
+ while (!_delayedActions.empty())
+ {
+ _delayedActions.front().Resolve();
+ _delayedActions.pop_front();
+ }
+}
+
void MotionMaster::Remove(MotionMasterContainer::iterator iterator, bool active, bool movementInform)
{
MovementGenerator* pointer = *iterator;
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index 65f4dcbc540..61069cf4cf4 100644
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -47,7 +47,10 @@ enum MotionMasterFlags : uint8
{
MOTIONMASTER_FLAG_NONE = 0x0,
MOTIONMASTER_FLAG_UPDATE = 0x1, // Update in progress
- MOTIONMASTER_FLAG_STATIC_INITIALIZATION_PENDING = 0x2
+ MOTIONMASTER_FLAG_STATIC_INITIALIZATION_PENDING = 0x2, // Static movement (MOTION_SLOT_DEFAULT) hasn't been initialized
+ MOTIONMASTER_FLAG_INITIALIZATION_PENDING = 0x4, // MotionMaster is stalled until signaled
+
+ MOTIONMASTER_FLAG_DELAYED = MOTIONMASTER_FLAG_STATIC_INITIALIZATION_PENDING | MOTIONMASTER_FLAG_INITIALIZATION_PENDING
};
enum MotionMasterDelayedActionType : uint8
@@ -112,6 +115,7 @@ class TC_GAME_API MotionMaster
void Initialize();
void InitializeDefault();
+ void AddToWorld();
bool Empty() const;
uint32 Size() const;
@@ -199,6 +203,7 @@ class TC_GAME_API MotionMaster
bool HasFlag(uint8 const flag) const { return (_flags & flag) != 0; }
void RemoveFlag(uint8 const flag) { _flags &= ~flag; }
+ void ResolveDelayedActions();
void Remove(MotionMasterContainer::iterator iterator, bool active, bool movementInform);
void Pop(bool active, bool movementInform);
void DirectInitialize();