Core/Movement: delay movement update in MotionMaster until its owner signals AddToWorld
Port From (https://github.com/TrinityCore/TrinityCore/commit/dfb2221552048512b4fda0c7e0c97ecf808106f9)
This commit is contained in:
@@ -66,7 +66,10 @@ namespace Framework.Constants
|
|||||||
{
|
{
|
||||||
None = 0x0,
|
None = 0x0,
|
||||||
Update = 0x1, // Update in progress
|
Update = 0x1, // Update in progress
|
||||||
StaticInitializationPending = 0x2
|
StaticInitializationPending = 0x2, // Static movement (MOTION_SLOT_DEFAULT) hasn't been initialized
|
||||||
|
InitializationPending = 0x4, // MotionMaster is stalled until signaled
|
||||||
|
|
||||||
|
Delayed = StaticInitializationPending | InitializationPending
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum MotionMasterDelayedActionType
|
public enum MotionMasterDelayedActionType
|
||||||
|
|||||||
@@ -430,6 +430,7 @@ namespace Game.Entities
|
|||||||
public override void AddToWorld()
|
public override void AddToWorld()
|
||||||
{
|
{
|
||||||
base.AddToWorld();
|
base.AddToWorld();
|
||||||
|
i_motionMaster.AddToWorld();
|
||||||
|
|
||||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.EnterWorld);
|
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.EnterWorld);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ namespace Game.Movement
|
|||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
if (HasFlag(MotionMasterFlags.Update))
|
if (HasFlag(MotionMasterFlags.Delayed))
|
||||||
{
|
{
|
||||||
_delayedActions.Enqueue(new DelayedAction(() => Initialize(), MotionMasterDelayedActionType.Initialize));
|
_delayedActions.Enqueue(new DelayedAction(() => Initialize(), MotionMasterDelayedActionType.Initialize));
|
||||||
return;
|
return;
|
||||||
@@ -120,6 +120,16 @@ namespace Game.Movement
|
|||||||
Add(AI.AISelector.SelectMovementGenerator(_owner), MovementSlot.Default);
|
Add(AI.AISelector.SelectMovementGenerator(_owner), MovementSlot.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddToWorld()
|
||||||
|
{
|
||||||
|
if (!HasFlag(MotionMasterFlags.InitializationPending))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ResolveDelayedActions();
|
||||||
|
|
||||||
|
RemoveFlag(MotionMasterFlags.InitializationPending);
|
||||||
|
}
|
||||||
|
|
||||||
public bool Empty()
|
public bool Empty()
|
||||||
{
|
{
|
||||||
return _defaultGenerator == null && _generators.Empty();
|
return _defaultGenerator == null && _generators.Empty();
|
||||||
@@ -287,6 +297,9 @@ namespace Game.Movement
|
|||||||
if (!_owner)
|
if (!_owner)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (HasFlag(MotionMasterFlags.InitializationPending))
|
||||||
|
return;
|
||||||
|
|
||||||
Cypher.Assert(!Empty(), $"MotionMaster:Update: update called without Initializing! ({_owner.GetGUID()})");
|
Cypher.Assert(!Empty(), $"MotionMaster:Update: update called without Initializing! ({_owner.GetGUID()})");
|
||||||
|
|
||||||
AddFlag(MotionMasterFlags.Update);
|
AddFlag(MotionMasterFlags.Update);
|
||||||
@@ -315,11 +328,7 @@ namespace Game.Movement
|
|||||||
|
|
||||||
RemoveFlag(MotionMasterFlags.Update);
|
RemoveFlag(MotionMasterFlags.Update);
|
||||||
|
|
||||||
while (_delayedActions.Count != 0)
|
ResolveDelayedActions();
|
||||||
{
|
|
||||||
_delayedActions.Peek().Resolve();
|
|
||||||
_delayedActions.Dequeue();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Add(MovementGenerator movement, MovementSlot slot = MovementSlot.Active)
|
void Add(MovementGenerator movement, MovementSlot slot = MovementSlot.Active)
|
||||||
@@ -330,7 +339,7 @@ namespace Game.Movement
|
|||||||
if (IsInvalidMovementSlot(slot))
|
if (IsInvalidMovementSlot(slot))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (HasFlag(MotionMasterFlags.Update))
|
if (HasFlag(MotionMasterFlags.Delayed))
|
||||||
_delayedActions.Enqueue(new DelayedAction(() => Add(movement, slot), MotionMasterDelayedActionType.Add));
|
_delayedActions.Enqueue(new DelayedAction(() => Add(movement, slot), MotionMasterDelayedActionType.Add));
|
||||||
else
|
else
|
||||||
DirectAdd(movement, slot);
|
DirectAdd(movement, slot);
|
||||||
@@ -341,7 +350,7 @@ namespace Game.Movement
|
|||||||
if (movement == null || IsInvalidMovementSlot(slot))
|
if (movement == null || IsInvalidMovementSlot(slot))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (HasFlag(MotionMasterFlags.Update))
|
if (HasFlag(MotionMasterFlags.Delayed))
|
||||||
{
|
{
|
||||||
_delayedActions.Enqueue(new DelayedAction(() => Remove(movement, slot), MotionMasterDelayedActionType.Remove));
|
_delayedActions.Enqueue(new DelayedAction(() => Remove(movement, slot), MotionMasterDelayedActionType.Remove));
|
||||||
return;
|
return;
|
||||||
@@ -373,7 +382,7 @@ namespace Game.Movement
|
|||||||
if (IsInvalidMovementGeneratorType(type) || IsInvalidMovementSlot(slot))
|
if (IsInvalidMovementGeneratorType(type) || IsInvalidMovementSlot(slot))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (HasFlag(MotionMasterFlags.Update))
|
if (HasFlag(MotionMasterFlags.Delayed))
|
||||||
{
|
{
|
||||||
_delayedActions.Enqueue(new DelayedAction(() => Remove(type, slot), MotionMasterDelayedActionType.RemoveType));
|
_delayedActions.Enqueue(new DelayedAction(() => Remove(type, slot), MotionMasterDelayedActionType.RemoveType));
|
||||||
return;
|
return;
|
||||||
@@ -403,7 +412,7 @@ namespace Game.Movement
|
|||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
if (HasFlag(MotionMasterFlags.Update))
|
if (HasFlag(MotionMasterFlags.Delayed))
|
||||||
{
|
{
|
||||||
_delayedActions.Enqueue(new DelayedAction(() => Clear(), MotionMasterDelayedActionType.Clear));
|
_delayedActions.Enqueue(new DelayedAction(() => Clear(), MotionMasterDelayedActionType.Clear));
|
||||||
return;
|
return;
|
||||||
@@ -418,7 +427,7 @@ namespace Game.Movement
|
|||||||
if (IsInvalidMovementSlot(slot))
|
if (IsInvalidMovementSlot(slot))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (HasFlag(MotionMasterFlags.Update))
|
if (HasFlag(MotionMasterFlags.Delayed))
|
||||||
{
|
{
|
||||||
_delayedActions.Enqueue(new DelayedAction(() => Clear(slot), MotionMasterDelayedActionType.ClearSlot));
|
_delayedActions.Enqueue(new DelayedAction(() => Clear(slot), MotionMasterDelayedActionType.ClearSlot));
|
||||||
return;
|
return;
|
||||||
@@ -442,7 +451,7 @@ namespace Game.Movement
|
|||||||
|
|
||||||
public void Clear(MovementGeneratorMode mode)
|
public void Clear(MovementGeneratorMode mode)
|
||||||
{
|
{
|
||||||
if (HasFlag(MotionMasterFlags.Update))
|
if (HasFlag(MotionMasterFlags.Delayed))
|
||||||
{
|
{
|
||||||
_delayedActions.Enqueue(new DelayedAction(() => Clear(mode), MotionMasterDelayedActionType.ClearMode));
|
_delayedActions.Enqueue(new DelayedAction(() => Clear(mode), MotionMasterDelayedActionType.ClearMode));
|
||||||
return;
|
return;
|
||||||
@@ -457,7 +466,7 @@ namespace Game.Movement
|
|||||||
public void Clear(MovementGeneratorPriority priority)
|
public void Clear(MovementGeneratorPriority priority)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (HasFlag(MotionMasterFlags.Update))
|
if (HasFlag(MotionMasterFlags.Delayed))
|
||||||
{
|
{
|
||||||
_delayedActions.Enqueue(new DelayedAction(() => Clear(priority), MotionMasterDelayedActionType.ClearPriority));
|
_delayedActions.Enqueue(new DelayedAction(() => Clear(priority), MotionMasterDelayedActionType.ClearPriority));
|
||||||
return;
|
return;
|
||||||
@@ -990,6 +999,15 @@ namespace Game.Movement
|
|||||||
Add(movement);
|
Add(movement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResolveDelayedActions()
|
||||||
|
{
|
||||||
|
while (_delayedActions.Count != 0)
|
||||||
|
{
|
||||||
|
_delayedActions.Peek().Resolve();
|
||||||
|
_delayedActions.Dequeue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Remove(MovementGenerator movement, bool active, bool movementInform)
|
void Remove(MovementGenerator movement, bool active, bool movementInform)
|
||||||
{
|
{
|
||||||
_generators.Remove(movement);
|
_generators.Remove(movement);
|
||||||
|
|||||||
Reference in New Issue
Block a user