diff --git a/Source/Framework/Constants/Movement/MovementConst.cs b/Source/Framework/Constants/Movement/MovementConst.cs index 78e7419c7..35458932f 100644 --- a/Source/Framework/Constants/Movement/MovementConst.cs +++ b/Source/Framework/Constants/Movement/MovementConst.cs @@ -97,6 +97,7 @@ namespace Framework.Constants Deactivated = 0x040, InformEnabled = 0x080, Finalized = 0x100, + PersistOnDeath = 0x200, Transitory = SpeedUpdatePending | Interrupted } diff --git a/Source/Game/Entities/Unit/Unit.cs b/Source/Game/Entities/Unit/Unit.cs index 812368dd1..f33a7ae2c 100644 --- a/Source/Game/Entities/Unit/Unit.cs +++ b/Source/Game/Entities/Unit/Unit.cs @@ -1397,18 +1397,8 @@ namespace Game.Entities // Don't clear the movement if the Unit was on a vehicle as we are exiting now if (!isOnVehicle) { - if (IsInWorld) - { - // Only clear MotionMaster for entities that exists in world - // Avoids crashes in the following conditions : - // * Using 'call pet' on dead pets - // * Using 'call stabled pet' - // * Logging in with dead pets - GetMotionMaster().Clear(); - GetMotionMaster().MoveIdle(); - } - StopMoving(); - DisableSpline(); + if (GetMotionMaster().StopOnDeath()) + DisableSpline(); } // without this when removing IncreaseMaxHealth aura player may stuck with 1 hp diff --git a/Source/Game/Movement/MotionMaster.cs b/Source/Game/Movement/MotionMaster.cs index 2bc25454d..6ce149a94 100644 --- a/Source/Game/Movement/MotionMaster.cs +++ b/Source/Game/Movement/MotionMaster.cs @@ -513,6 +513,29 @@ namespace Game.Movement return true; } + public bool StopOnDeath() + { + MovementGenerator movementGenerator = GetCurrentMovementGenerator(); + if (movementGenerator != null) + if (movementGenerator.HasFlag(MovementGeneratorFlags.PersistOnDeath)) + return false; + + if (_owner.IsInWorld) + { + // Only clear MotionMaster for entities that exists in world + // Avoids crashes in the following conditions : + // * Using 'call pet' on dead pets + // * Using 'call stabled pet' + // * Logging in with dead pets + Clear(); + MoveIdle(); + } + + _owner.StopMoving(); + + return true; + } + public void MoveIdle() { Add(GetIdleMovementGenerator(), MovementSlot.Default); @@ -710,6 +733,7 @@ namespace Game.Movement GenericMovementGenerator movement = new(init, MovementGeneratorType.Effect, 0); movement.Priority = MovementGeneratorPriority.Highest; + movement.AddFlag(MovementGeneratorFlags.PersistOnDeath); Add(movement); } @@ -793,6 +817,7 @@ namespace Game.Movement GenericMovementGenerator movement = new GenericMovementGenerator(init, MovementGeneratorType.Effect, id, arrivalSpellId, arrivalSpellTargetGuid); movement.Priority = MovementGeneratorPriority.Highest; movement.BaseUnitState = UnitState.Jumping; + movement.AddFlag(MovementGeneratorFlags.PersistOnDeath); Add(movement); }