mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-13 19:53:02 -04:00
Core/Movement: delay movement update in MotionMaster until its owner signals AddToWorld
ref #23199 closes #23876
This commit is contained in:
@@ -9455,8 +9455,11 @@ void Unit::RestoreDisabledAI()
|
||||
|
||||
void Unit::AddToWorld()
|
||||
{
|
||||
if (!IsInWorld())
|
||||
WorldObject::AddToWorld();
|
||||
if (IsInWorld())
|
||||
return;
|
||||
|
||||
WorldObject::AddToWorld();
|
||||
i_motionMaster->AddToWorld();
|
||||
}
|
||||
|
||||
void Unit::RemoveFromWorld()
|
||||
|
||||
@@ -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]()
|
||||
{
|
||||
@@ -1019,6 +1028,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;
|
||||
|
||||
@@ -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;
|
||||
@@ -198,6 +202,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();
|
||||
|
||||
Reference in New Issue
Block a user