aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2018-02-20 17:27:02 -0300
committerfunjoker <funjoker109@gmail.com>2021-08-08 21:21:34 +0200
commit70c26d53cb94f0e78a57ecc2279c960370891aa4 (patch)
tree483fc32d5c348c381d71af6e108511432a297aa1 /src
parent47e41be5157f2e3bb536dfc4f2cbbdc66e64b4bd (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.cpp4
-rw-r--r--src/server/game/Entities/Player/Player.cpp4
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp52
-rw-r--r--src/server/game/Entities/Unit/Unit.h16
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);