diff --git a/Source/Game/Movement/MotionMaster.cs b/Source/Game/Movement/MotionMaster.cs index 1ec337f75..48216bbb0 100644 --- a/Source/Game/Movement/MotionMaster.cs +++ b/Source/Game/Movement/MotionMaster.cs @@ -102,21 +102,15 @@ namespace Game.Movement DirectClean(reset); } - void ClearExpireList() + void Clear(MovementSlot slot) { - for (int i = 0; i < _expireList.Count; ++i) - DirectDelete(_expireList[i]); + if (Empty() || slot >= MovementSlot.Max) + return; - _expireList.Clear(); - - if (Empty()) - Initialize(); - else if (NeedInitTop()) - InitTop(); - else if (Convert.ToBoolean(_cleanFlag & MMCleanFlag.Reset)) - Top().Reset(_owner); - - _cleanFlag &= ~MMCleanFlag.Reset; + if (_cleanFlag.HasAnyFlag(MMCleanFlag.Update)) + DelayedClean(slot); + else + DirectClean(slot); } public void MovementExpired(bool reset = true) @@ -149,6 +143,12 @@ namespace Game.Movement return _slot[(int)slot].GetMovementGeneratorType(); } + public IMovementGenerator GetMotionSlot(MovementSlot slot) + { + Cypher.Assert((int)slot >= 0); + return _slot[(int)slot]; + } + public IMovementGenerator GetMotionSlot(int slot) { Cypher.Assert(slot >= 0); @@ -681,6 +681,24 @@ namespace Game.Movement Top().Reset(_owner); } + void DirectClean(MovementSlot slot) + { + IMovementGenerator motion = GetMotionSlot(slot); + if (motion != null) + { + _slot[(int)slot] = null; + DirectDelete(motion); + } + + while (!Empty() && Top() == null) + --_top; + + if (Empty()) + Initialize(); + else if (NeedInitTop()) + InitTop(); + } + void DelayedClean() { while (Size() > 1) @@ -692,6 +710,19 @@ namespace Game.Movement } } + void DelayedClean(MovementSlot slot) + { + IMovementGenerator motion = GetMotionSlot(slot); + if (motion != null) + { + _slot[(int)slot] = null; + DelayedDelete(motion); + } + + while (!Empty() && Top() == null) + --_top; + } + void DirectExpire(bool reset) { if (Size() > 1) @@ -740,6 +771,23 @@ namespace Game.Movement _expireList.Add(curr); } + void ClearExpireList() + { + for (int i = 0; i < _expireList.Count; ++i) + DirectDelete(_expireList[i]); + + _expireList.Clear(); + + if (Empty()) + Initialize(); + else if (NeedInitTop()) + InitTop(); + else if (_cleanFlag.HasAnyFlag(MMCleanFlag.Reset)) + Top().Reset(_owner); + + _cleanFlag &= ~MMCleanFlag.Reset; + } + public bool Empty() { return (_top < 0); } int Size() { return _top + 1; }