diff options
author | ariel- <ariel-@users.noreply.github.com> | 2018-02-20 17:27:02 -0300 |
---|---|---|
committer | funjoker <funjoker109@gmail.com> | 2021-08-08 21:21:34 +0200 |
commit | 70c26d53cb94f0e78a57ecc2279c960370891aa4 (patch) | |
tree | 483fc32d5c348c381d71af6e108511432a297aa1 /src | |
parent | 47e41be5157f2e3bb536dfc4f2cbbdc66e64b4bd (diff) |
Core/Entities: unit states cleanup
- Added new UNIT_STATE_FOCUSING for creature focus system, this will stop creatures adding/clearing the UNIT_STATE_CANNOT_TURN mask (eg UNIT_STATE_STUNNED if stunned while focusing a spell)
- Added UNIT_STATE_CHARMED that gets set/removed on any charm type (UNIT_STATE_POSSESSED is only for possess as it's name suggests)
- The new states are checked against mask to know whenever client needs to regain character control
Closes and fixes #21460
(cherry picked from commit ba27711145d1b015578aedb48ea8532b4f0bec75)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 52 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 16 |
4 files changed, 45 insertions, 31 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 6f1e78e86d5..9dfff1fad98 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -3234,7 +3234,7 @@ void Creature::FocusTarget(Spell const* focusSpell, WorldObject const* target) } if (noTurnDuringCast) - AddUnitState(UNIT_STATE_CANNOT_TURN); + AddUnitState(UNIT_STATE_FOCUSING); } bool Creature::IsFocusing(Spell const* focusSpell, bool withDelay) @@ -3288,7 +3288,7 @@ void Creature::ReleaseFocus(Spell const* focusSpell, bool withDelay) MustReacquireTarget(); if (m_focusSpell->GetSpellInfo()->HasAttribute(SPELL_ATTR5_DONT_TURN_DURING_CAST)) - ClearUnitState(UNIT_STATE_CANNOT_TURN); + ClearUnitState(UNIT_STATE_FOCUSING); m_focusSpell = nullptr; m_focusDelay = (!IsPet() && withDelay) ? GameTime::GetGameTimeMS() : 0; // don't allow re-target right away to prevent visual bugs diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index b2bd8469268..d2a2ef0d40d 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -25558,6 +25558,10 @@ void Player::ResurrectUsingRequestDataImpl() void Player::SetClientControl(Unit* target, bool allowMove) { + // still affected by some aura that shouldn't allow control, only allow on last such aura to be removed + if (allowMove && target->HasUnitState(UNIT_STATE_CANT_CLIENT_CONTROL)) + return; + WorldPackets::Movement::ControlUpdate data; data.Guid = target->GetGUID(); data.On = allowMove; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 828f40b0889..76ead47fe5e 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11658,19 +11658,24 @@ void Unit::SetControlled(bool apply, UnitState state) return; } - // Unit States might have been already cleared but auras still present. I need to check with HasAuraType - if (HasAuraType(SPELL_AURA_MOD_STUN)) - SetStunned(true); + ApplyControlStatesIfNeeded(); + } +} - if (HasAuraType(SPELL_AURA_MOD_ROOT) || HasAuraType(SPELL_AURA_MOD_ROOT_2)) - SetRooted(true); +void Unit::ApplyControlStatesIfNeeded() +{ + // Unit States might have been already cleared but auras still present. I need to check with HasAuraType + if (HasUnitState(UNIT_STATE_STUNNED) || HasAuraType(SPELL_AURA_MOD_STUN)) + SetStunned(true); - if (HasAuraType(SPELL_AURA_MOD_CONFUSE)) - SetConfused(true); + if (HasUnitState(UNIT_STATE_ROOT) || HasAuraType(SPELL_AURA_MOD_ROOT) || HasAuraType(SPELL_AURA_MOD_ROOT_2)) + SetRooted(true); - if (HasAuraType(SPELL_AURA_MOD_FEAR)) - SetFeared(true); - } + if (HasUnitState(UNIT_STATE_CONFUSED) || HasAuraType(SPELL_AURA_MOD_CONFUSE)) + SetConfused(true); + + if (HasUnitState(UNIT_STATE_FLEEING) || HasAuraType(SPELL_AURA_MOD_FEAR)) + SetFeared(true); } void Unit::SetStunned(bool apply) @@ -11772,12 +11777,11 @@ void Unit::SetFeared(bool apply) } } - if (Player* player = ToPlayer()) + // block / allow control to real player in control (eg charmer) + if (GetTypeId() == TYPEID_PLAYER) { - if (apply) - player->SetClientControl(this, false); - else if (!HasUnitState(UNIT_STATE_LOST_CONTROL)) - player->SetClientControl(this, true); + if (m_playerMovingMe) + m_playerMovingMe->SetClientControl(this, !apply); } } @@ -11799,12 +11803,11 @@ void Unit::SetConfused(bool apply) } } - if (Player* player = ToPlayer()) + // block / allow control to real player in control (eg charmer) + if (GetTypeId() == TYPEID_PLAYER) { - if (apply) - player->SetClientControl(this, false); - else if (!HasUnitState(UNIT_STATE_LOST_CONTROL)) - player->SetClientControl(this, true); + if (m_playerMovingMe) + m_playerMovingMe->SetClientControl(this, !apply); } } @@ -11968,6 +11971,8 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au break; } } + + AddUnitState(UNIT_STATE_CHARMED); return true; } @@ -12073,8 +12078,7 @@ void Unit::RemoveCharmedBy(Unit* charmer) IsAIEnabled = false; } - if (!HasUnitState(UNIT_STATE_LOST_CONTROL)) - player->SetClientControl(this, true); + player->SetClientControl(this, true); } EngageWithTarget(charmer); @@ -12084,6 +12088,10 @@ void Unit::RemoveCharmedBy(Unit* charmer) playerCharmer->SendRemoveControlBar(); else if (GetTypeId() == TYPEID_PLAYER || (GetTypeId() == TYPEID_UNIT && !IsGuardian())) DeleteCharmInfo(); + + // reset confused movement for example + ApplyControlStatesIfNeeded(); + ClearUnitState(UNIT_STATE_CHARMED); } void Unit::RestoreFaction() diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 9db37c5e7a1..eee89e86692 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -244,11 +244,11 @@ enum UnitState : uint32 { UNIT_STATE_DIED = 0x00000001, // player has fake death aura UNIT_STATE_MELEE_ATTACKING = 0x00000002, // player is melee attacking someone - //UNIT_STATE_MELEE_ATTACK_BY = 0x00000004, // player is melee attack by someone + UNIT_STATE_CHARMED = 0x00000004, // having any kind of charm aura on self UNIT_STATE_STUNNED = 0x00000008, UNIT_STATE_ROAMING = 0x00000010, UNIT_STATE_CHASE = 0x00000020, - //UNIT_STATE_SEARCHING = 0x00000040, + UNIT_STATE_FOCUSING = 0x00000040, UNIT_STATE_FLEEING = 0x00000080, UNIT_STATE_IN_FLIGHT = 0x00000100, // player is in flight mode UNIT_STATE_FOLLOW = 0x00000200, @@ -258,7 +258,7 @@ enum UnitState : uint32 UNIT_STATE_ISOLATED = 0x00002000, // area auras do not affect other players UNIT_STATE_ATTACK_PLAYER = 0x00004000, UNIT_STATE_CASTING = 0x00008000, - UNIT_STATE_POSSESSED = 0x00010000, + UNIT_STATE_POSSESSED = 0x00010000, // being possessed by another unit UNIT_STATE_CHARGING = 0x00020000, UNIT_STATE_JUMPING = 0x00040000, UNIT_STATE_MOVE = 0x00100000, @@ -271,8 +271,8 @@ enum UnitState : uint32 UNIT_STATE_FOLLOW_MOVE = 0x08000000, UNIT_STATE_IGNORE_PATHFINDING = 0x10000000, // do not use pathfinding in any MovementGenerator - UNIT_STATE_ALL_STATE_SUPPORTED = UNIT_STATE_DIED | UNIT_STATE_MELEE_ATTACKING | UNIT_STATE_STUNNED | UNIT_STATE_ROAMING | UNIT_STATE_CHASE - | UNIT_STATE_FLEEING | UNIT_STATE_IN_FLIGHT | UNIT_STATE_FOLLOW | UNIT_STATE_ROOT | UNIT_STATE_CONFUSED + UNIT_STATE_ALL_STATE_SUPPORTED = UNIT_STATE_DIED | UNIT_STATE_MELEE_ATTACKING | UNIT_STATE_CHARMED | UNIT_STATE_STUNNED | UNIT_STATE_ROAMING | UNIT_STATE_CHASE + | UNIT_STATE_FOCUSING | UNIT_STATE_FLEEING | UNIT_STATE_IN_FLIGHT | UNIT_STATE_FOLLOW | UNIT_STATE_ROOT | UNIT_STATE_CONFUSED | UNIT_STATE_DISTRACTED | UNIT_STATE_ISOLATED | UNIT_STATE_ATTACK_PLAYER | UNIT_STATE_CASTING | UNIT_STATE_POSSESSED | UNIT_STATE_CHARGING | UNIT_STATE_JUMPING | UNIT_STATE_MOVE | UNIT_STATE_ROTATING | UNIT_STATE_EVADE | UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE @@ -281,10 +281,11 @@ enum UnitState : uint32 UNIT_STATE_UNATTACKABLE = UNIT_STATE_IN_FLIGHT, UNIT_STATE_MOVING = UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE | UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE, UNIT_STATE_CONTROLLED = UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING, + UNIT_STATE_CANT_CLIENT_CONTROL = UNIT_STATE_CONFUSED | UNIT_STATE_CHARMED | UNIT_STATE_POSSESSED | UNIT_STATE_FLEEING | UNIT_STATE_POSSESSED, UNIT_STATE_LOST_CONTROL = UNIT_STATE_CONTROLLED | UNIT_STATE_POSSESSED | UNIT_STATE_JUMPING | UNIT_STATE_CHARGING, + UNIT_STATE_CANNOT_AUTOATTACK = UNIT_STATE_CONTROLLED | UNIT_STATE_CHARGING | UNIT_STATE_CASTING, UNIT_STATE_SIGHTLESS = UNIT_STATE_LOST_CONTROL | UNIT_STATE_EVADE, - UNIT_STATE_CANNOT_AUTOATTACK = UNIT_STATE_LOST_CONTROL | UNIT_STATE_CASTING, - UNIT_STATE_CANNOT_TURN = UNIT_STATE_LOST_CONTROL | UNIT_STATE_ROTATING, + UNIT_STATE_CANNOT_TURN = UNIT_STATE_LOST_CONTROL | UNIT_STATE_ROTATING | UNIT_STATE_FOCUSING, UNIT_STATE_NOT_MOVE = UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DIED | UNIT_STATE_DISTRACTED, UNIT_STATE_ALL_ERASABLE = UNIT_STATE_ALL_STATE_SUPPORTED & ~(UNIT_STATE_IGNORE_PATHFINDING), @@ -1770,6 +1771,7 @@ class TC_GAME_API Unit : public WorldObject float GetPositionZMinusOffset() const; void SetControlled(bool apply, UnitState state); + void ApplyControlStatesIfNeeded(); ///----------Pet responses methods----------------- void SendPetActionFeedback(PetActionFeedback msg, uint32 spellId); |