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:
hondacrx
2022-01-05 17:26:33 -05:00
parent 95c3782ccb
commit efb7142aef
3 changed files with 36 additions and 14 deletions
@@ -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
+1
View File
@@ -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);
} }
+31 -13
View File
@@ -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);