diff options
author | Giacomo Pozzoni <giacomopoz@gmail.com> | 2021-06-06 17:51:00 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-06 17:51:00 +0200 |
commit | 9fe9dc087b4dc52af7897942a83c1f880d3a4ef8 (patch) | |
tree | 3e2f7d2355dc2f3d0d8df5b5fcc690ef36cd6955 | |
parent | 9f852c27b9a03d599f85a806cdae0c2d48427e53 (diff) |
Core/Movement: Add new flag MOVEMENTGENERATOR_FLAG_PERSIST_ON_DEATH (#26549)
* Core/Movement: Add new flag MOVEMENTGENERATOR_FLAG_PERSIST_ON_DEATH
Add new flag MOVEMENTGENERATOR_FLAG_PERSIST_ON_DEATH to keep movement generators even after death.
Fixes #23095
Could replace ff26027453179448bb972d88a51e565d71e95f3f
* Core/Movement: reorder new method MotionMaster::StopOnDeath
* Core/Movement: reorder new method MotionMaster::StopOnDeath
* Keep MoveJump movement generator after death
Co-authored-by: ccrs <ccrs@users.noreply.github.com>
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 15 | ||||
-rw-r--r-- | src/server/game/Movement/MotionMaster.cpp | 24 | ||||
-rw-r--r-- | src/server/game/Movement/MotionMaster.h | 1 | ||||
-rwxr-xr-x | src/server/game/Movement/MovementGenerator.h | 1 |
4 files changed, 28 insertions, 13 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index e066fedea7b..1d1b1ebe126 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -8722,19 +8722,8 @@ void Unit::setDeathState(DeathState s) // 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/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index cea4533136f..f3c00e15450 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -543,6 +543,28 @@ bool MotionMaster::GetDestination(float &x, float &y, float &z) return true; } +bool MotionMaster::StopOnDeath() +{ + if (MovementGenerator* movementGenerator = GetCurrentMovementGenerator()) + if (movementGenerator->HasFlag(MOVEMENTGENERATOR_FLAG_PERSIST_ON_DEATH)) + 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; +} + void MotionMaster::MoveIdle() { Add(GetIdleMovementGenerator(), MOTION_SLOT_DEFAULT); @@ -757,6 +779,7 @@ void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, floa GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(init), EFFECT_MOTION_TYPE, 0); movement->Priority = MOTION_PRIORITY_HIGHEST; + movement->AddFlag(MOVEMENTGENERATOR_FLAG_PERSIST_ON_DEATH); Add(movement); } @@ -801,6 +824,7 @@ void MotionMaster::MoveJump(float x, float y, float z, float o, float speedXY, f GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(init), EFFECT_MOTION_TYPE, id); movement->Priority = MOTION_PRIORITY_HIGHEST; movement->BaseUnitState = UNIT_STATE_JUMPING; + movement->AddFlag(MOVEMENTGENERATOR_FLAG_PERSIST_ON_DEATH); Add(movement); } diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index a2f9b572d2a..07bbf97d952 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -149,6 +149,7 @@ class TC_GAME_API MotionMaster void Clear(MovementGeneratorPriority priority); void PropagateSpeedChange(); bool GetDestination(float &x, float &y, float &z); + bool StopOnDeath(); void MoveIdle(); void MoveTargetedHome(); diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h index 24585c4e77f..9c51fecf9dd 100755 --- a/src/server/game/Movement/MovementGenerator.h +++ b/src/server/game/Movement/MovementGenerator.h @@ -39,6 +39,7 @@ enum MovementGeneratorFlags : uint16 MOVEMENTGENERATOR_FLAG_DEACTIVATED = 0x040, MOVEMENTGENERATOR_FLAG_INFORM_ENABLED = 0x080, MOVEMENTGENERATOR_FLAG_FINALIZED = 0x100, + MOVEMENTGENERATOR_FLAG_PERSIST_ON_DEATH = 0x200, MOVEMENTGENERATOR_FLAG_TRANSITORY = MOVEMENTGENERATOR_FLAG_SPEED_UPDATE_PENDING | MOVEMENTGENERATOR_FLAG_INTERRUPTED }; |