summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGrimdhex <176165533+Grimdhex@users.noreply.github.com>2024-09-11 16:50:24 +0200
committerGitHub <noreply@github.com>2024-09-11 11:50:24 -0300
commit56d2cc7b4c975448680dfb79ecae91dadcbad22c (patch)
treef74b9581d09bc072ea0a3d2560ccbdc4b6c667c3 /src
parent30e77ae8807a5be29d763482d9a01065f040e388 (diff)
refactor(Cote/Unit): cleanup - part2 (#19821)
* fix(Core/AI): remove an unused variable * Move variables at the end of each sections * reorder several methods * remove few inline defintions * few codestyle fixes
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp25
-rw-r--r--src/server/game/Entities/Unit/Unit.h500
2 files changed, 283 insertions, 242 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 659a42dbf7..b9699d13d4 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -738,6 +738,20 @@ bool Unit::GetRandomContactPoint(Unit const* obj, float& x, float& y, float& z,
return true;
}
+Unit* Unit::getAttackerForHelper() const
+{
+ if (GetVictim() != nullptr)
+ return GetVictim();
+
+ if (!IsEngaged())
+ return nullptr;
+
+ if (!m_attackers.empty())
+ return *(m_attackers.begin());
+
+ return nullptr;
+}
+
void Unit::UpdateInterruptMask()
{
m_interruptMask = 0;
@@ -17222,6 +17236,17 @@ void Unit::SetContestedPvP(Player* attackedPlayer, bool lookForNearContestedGuar
}
}
+void Unit::SetCantProc(bool apply)
+{
+ if (apply)
+ ++m_procDeep;
+ else
+ {
+ ASSERT(m_procDeep);
+ --m_procDeep;
+ }
+}
+
void Unit::AddPetAura(PetAura const* petSpell)
{
if (!IsPlayer())
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 4e7fc51d11..74dae46679 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -653,6 +653,8 @@ public:
~Unit() override;
+ void Update(uint32 time) override;
+
UnitAI* GetAI() { return i_AI; }
void SetAI(UnitAI* newAI) { i_AI = newAI; }
@@ -662,20 +664,101 @@ public:
void CleanupBeforeRemoveFromMap(bool finalCleanup);
void CleanupsBeforeDelete(bool finalCleanup = true) override; // used in ~Creature/~Player (or before mass creature delete to remove cross-references to already deleted units)
+ /*********************************************************/
+ /*** UNIT HELPERS ***/
+ /*********************************************************/
+ void SetUInt32Value(uint16 index, uint32 value); /// @todo: move this in Object class or move GetUInt32value here but keep consistency
+
+ void AddUnitState(uint32 f) { m_state |= f; }
+ [[nodiscard]] bool HasUnitState(const uint32 f) const { return (m_state & f); }
+ void ClearUnitState(uint32 f) { m_state &= ~f; }
+ [[nodiscard]] uint32 GetUnitState() const { return m_state; }
+
+ [[nodiscard]] uint32 HasUnitTypeMask(uint32 mask) const { return mask & m_unitTypeMask; }
+ void AddUnitTypeMask(uint32 mask) { m_unitTypeMask |= mask; }
+ [[nodiscard]] uint32 GetUnitTypeMask() const { return m_unitTypeMask; }
+
+ UnitFlags GetUnitFlags() const { return UnitFlags(GetUInt32Value(UNIT_FIELD_FLAGS)); }
+ bool HasUnitFlag(UnitFlags flags) const { return HasFlag(UNIT_FIELD_FLAGS, flags); } /// @brief UnitFlags available in UnitDefines.h
+ void SetUnitFlag(UnitFlags flags) { SetFlag(UNIT_FIELD_FLAGS, flags); } /// @brief UnitFlags available in UnitDefines.h
+ void RemoveUnitFlag(UnitFlags flags) { RemoveFlag(UNIT_FIELD_FLAGS, flags); } /// @brief Remove the Unit flag specify only
+ void ReplaceAllUnitFlags(UnitFlags flags) { SetUInt32Value(UNIT_FIELD_FLAGS, flags); } /// @brief Remove all UnitFlags and set new ones. UnitFlags available in UnitDefines.h
+
+ UnitFlags2 GetUnitFlags2() const { return UnitFlags2(GetUInt32Value(UNIT_FIELD_FLAGS_2)); }
+ bool HasUnitFlag2(UnitFlags2 flags) const { return HasFlag(UNIT_FIELD_FLAGS_2, flags); }
+ void SetUnitFlag2(UnitFlags2 flags) { SetFlag(UNIT_FIELD_FLAGS_2, flags); }
+ void RemoveUnitFlag2(UnitFlags2 flags) { RemoveFlag(UNIT_FIELD_FLAGS_2, flags); }
+ void ReplaceAllUnitFlags2(UnitFlags2 flags) { SetUInt32Value(UNIT_FIELD_FLAGS_2, flags); }
+
+ NPCFlags GetNpcFlags() const { return NPCFlags(GetUInt32Value(UNIT_NPC_FLAGS)); }
+ bool HasNpcFlag(NPCFlags flags) const { return HasFlag(UNIT_NPC_FLAGS, flags) != 0; }
+ void SetNpcFlag(NPCFlags flags) { SetFlag(UNIT_NPC_FLAGS, flags); }
+ void RemoveNpcFlag(NPCFlags flags) { RemoveFlag(UNIT_NPC_FLAGS, flags); }
+ void ReplaceAllNpcFlags(NPCFlags flags) { SetUInt32Value(UNIT_NPC_FLAGS, flags); }
+
uint32 GetDynamicFlags() const override { return GetUInt32Value(UNIT_DYNAMIC_FLAGS); }
void ReplaceAllDynamicFlags(uint32 flag) override { SetUInt32Value(UNIT_DYNAMIC_FLAGS, flag); }
- DiminishingLevels GetDiminishing(DiminishingGroup group);
- void IncrDiminishing(DiminishingGroup group);
- float ApplyDiminishingToDuration(DiminishingGroup group, int32& duration, Unit* caster, DiminishingLevels Level, int32 limitduration);
- void ApplyDiminishingAura(DiminishingGroup group, bool apply);
- void ClearDiminishings() { m_Diminishing.clear(); }
+ /*********************************************************/
+ /*** UNIT TYPES, CLASSES, RACES... ***/
+ /*********************************************************/
- // target dependent range checks
- float GetSpellMaxRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const;
- float GetSpellMinRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const;
+ // Unit type methods
+ [[nodiscard]] bool IsSummon() const { return m_unitTypeMask & UNIT_MASK_SUMMON; }
+ [[nodiscard]] bool IsGuardian() const { return m_unitTypeMask & UNIT_MASK_GUARDIAN; }
+ [[nodiscard]] bool IsControllableGuardian() const { return m_unitTypeMask & UNIT_MASK_CONTROLABLE_GUARDIAN; }
+ [[nodiscard]] bool IsPet() const { return m_unitTypeMask & UNIT_MASK_PET; }
+ [[nodiscard]] bool IsHunterPet() const { return m_unitTypeMask & UNIT_MASK_HUNTER_PET; }
+ [[nodiscard]] bool IsTotem() const { return m_unitTypeMask & UNIT_MASK_TOTEM; }
+ [[nodiscard]] bool IsVehicle() const { return m_unitTypeMask & UNIT_MASK_VEHICLE; }
- void Update(uint32 time) override;
+ // NPC type methods
+ [[nodiscard]] bool IsVendor() const { return HasNpcFlag(UNIT_NPC_FLAG_VENDOR); }
+ [[nodiscard]] bool IsTrainer() const { return HasNpcFlag(UNIT_NPC_FLAG_TRAINER); }
+ [[nodiscard]] bool IsQuestGiver() const { return HasNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); }
+ [[nodiscard]] bool IsGossip() const { return HasNpcFlag(UNIT_NPC_FLAG_GOSSIP); }
+ [[nodiscard]] bool IsTaxi() const { return HasNpcFlag(UNIT_NPC_FLAG_FLIGHTMASTER); }
+ [[nodiscard]] bool IsGuildMaster() const { return HasNpcFlag(UNIT_NPC_FLAG_PETITIONER); }
+ [[nodiscard]] bool IsBattleMaster() const { return HasNpcFlag(UNIT_NPC_FLAG_BATTLEMASTER); }
+ [[nodiscard]] bool IsBanker() const { return HasNpcFlag(UNIT_NPC_FLAG_BANKER); }
+ [[nodiscard]] bool IsInnkeeper() const { return HasNpcFlag(UNIT_NPC_FLAG_INNKEEPER); }
+ [[nodiscard]] bool IsSpiritHealer() const { return HasNpcFlag(UNIT_NPC_FLAG_SPIRITHEALER); }
+ [[nodiscard]] bool IsSpiritGuide() const { return HasNpcFlag(UNIT_NPC_FLAG_SPIRITGUIDE); }
+ [[nodiscard]] bool IsTabardDesigner() const { return HasNpcFlag(UNIT_NPC_FLAG_TABARDDESIGNER); }
+ [[nodiscard]] bool IsAuctioner() const { return HasNpcFlag(UNIT_NPC_FLAG_AUCTIONEER); }
+ [[nodiscard]] bool IsArmorer() const { return HasNpcFlag(UNIT_NPC_FLAG_REPAIR); }
+ [[nodiscard]] bool IsServiceProvider() const
+ {
+ return HasNpcFlag(UNIT_NPC_FLAG_VENDOR | UNIT_NPC_FLAG_TRAINER | UNIT_NPC_FLAG_FLIGHTMASTER |
+ UNIT_NPC_FLAG_PETITIONER | UNIT_NPC_FLAG_BATTLEMASTER | UNIT_NPC_FLAG_BANKER |
+ UNIT_NPC_FLAG_INNKEEPER | UNIT_NPC_FLAG_SPIRITHEALER |
+ UNIT_NPC_FLAG_SPIRITGUIDE | UNIT_NPC_FLAG_TABARDDESIGNER | UNIT_NPC_FLAG_AUCTIONEER);
+ }
+ [[nodiscard]] bool IsSpiritService() const { return HasNpcFlag(UNIT_NPC_FLAG_SPIRITHEALER | UNIT_NPC_FLAG_SPIRITGUIDE); }
+
+ // Race methods
+ [[nodiscard]] uint8 getRace(bool original = false) const;
+ void setRace(uint8 race);
+ [[nodiscard]] uint32 getRaceMask() const { return 1 << (getRace(true) - 1); }
+ [[nodiscard]] DisplayRace GetDisplayRaceFromModelId(uint32 modelId) const;
+ [[nodiscard]] DisplayRace GetDisplayRace() const { return GetDisplayRaceFromModelId(GetDisplayId()); };
+
+ // Class methods
+ [[nodiscard]] uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, 1); }
+ [[nodiscard]] virtual bool IsClass(Classes unitClass, [[maybe_unused]] ClassContext context = CLASS_CONTEXT_NONE) const { return (getClass() == unitClass); }
+ [[nodiscard]] uint32 getClassMask() const { return 1 << (getClass() - 1); }
+
+ // Gender methods
+ [[nodiscard]] uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, 2); }
+
+ // Factions methods
+ [[nodiscard]] uint32 GetFaction() const { return GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE); }
+ void SetFaction(uint32 faction);
+ [[nodiscard]] FactionTemplateEntry const* GetFactionTemplateEntry() const;
+
+ /*********************************************************/
+ /*** METHODS RELATED TO COMBATS ***/
+ /*********************************************************/
void setAttackTimer(WeaponAttackType type, int32 time) { m_attackTimer[type] = time; } /// @todo - Look to convert to std::chrono
void resetAttackTimer(WeaponAttackType type = BASE_ATTACK);
@@ -692,30 +775,9 @@ public:
float GetMeleeRange(Unit const* target) const;
virtual SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = BASE_ATTACK, uint8 damageIndex = 0) const = 0;
bool GetRandomContactPoint(Unit const* target, float& x, float& y, float& z, bool force = false) const;
- uint32 m_extraAttacks;
- bool m_canDualWield;
-
- void _addAttacker(Unit* pAttacker) // must be called only from Unit::Attack(Unit*)
- {
- m_attackers.insert(pAttacker);
- }
- void _removeAttacker(Unit* pAttacker) // must be called only from Unit::AttackStop()
- {
- m_attackers.erase(pAttacker);
- }
- [[nodiscard]] Unit* getAttackerForHelper() const // If someone wants to help, who to give them
- {
- if (GetVictim() != nullptr)
- return GetVictim();
- if (!IsEngaged())
- return nullptr;
+ [[nodiscard]] Unit* getAttackerForHelper() const; // If someone wants to help, who to give them
- if (!m_attackers.empty())
- return *(m_attackers.begin());
-
- return nullptr;
- }
bool Attack(Unit* victim, bool meleeAttack);
void CastStop(uint32 except_spellid = 0, bool withInstant = true);
@@ -735,39 +797,64 @@ public:
void SendMeleeAttackStop(Unit* victim = nullptr);
void SendMeleeAttackStart(Unit* victim, Player* sendTo = nullptr);
- void AddUnitState(uint32 f) { m_state |= f; }
- [[nodiscard]] bool HasUnitState(const uint32 f) const { return (m_state & f); }
- void ClearUnitState(uint32 f) { m_state &= ~f; }
- [[nodiscard]] uint32 GetUnitState() const { return m_state; }
- [[nodiscard]] bool CanFreeMove() const
+ [[nodiscard]] uint32 GetAttackTime(WeaponAttackType att) const
{
- return !HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_FLEEING | UNIT_STATE_IN_FLIGHT |
- UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED) && !GetOwnerGUID();
+ float f_BaseAttackTime = GetFloatValue(static_cast<uint16>(UNIT_FIELD_BASEATTACKTIME) + att) / m_modAttackSpeedPct[att];
+ return (uint32)f_BaseAttackTime;
}
- [[nodiscard]] uint32 HasUnitTypeMask(uint32 mask) const { return mask & m_unitTypeMask; }
- void AddUnitTypeMask(uint32 mask) { m_unitTypeMask |= mask; }
- [[nodiscard]] uint32 GetUnitTypeMask() const { return m_unitTypeMask; }
- [[nodiscard]] bool IsSummon() const { return m_unitTypeMask & UNIT_MASK_SUMMON; }
- [[nodiscard]] bool IsGuardian() const { return m_unitTypeMask & UNIT_MASK_GUARDIAN; }
- [[nodiscard]] bool IsControllableGuardian() const { return m_unitTypeMask & UNIT_MASK_CONTROLABLE_GUARDIAN; }
- [[nodiscard]] bool IsPet() const { return m_unitTypeMask & UNIT_MASK_PET; }
- [[nodiscard]] bool IsHunterPet() const { return m_unitTypeMask & UNIT_MASK_HUNTER_PET; }
- [[nodiscard]] bool IsTotem() const { return m_unitTypeMask & UNIT_MASK_TOTEM; }
- [[nodiscard]] bool IsVehicle() const { return m_unitTypeMask & UNIT_MASK_VEHICLE; }
+ void SetAttackTime(WeaponAttackType att, uint32 val) { SetFloatValue(static_cast<uint16>(UNIT_FIELD_BASEATTACKTIME) + att, val * m_modAttackSpeedPct[att]); }
+ void ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply);
+ void ApplyCastTimePercentMod(float val, bool apply);
+
+ void SetImmuneToAll(bool apply, bool keepCombat = false) { SetImmuneToPC(apply, keepCombat); SetImmuneToNPC(apply, keepCombat); }
+ bool IsImmuneToAll() const { return IsImmuneToPC() && IsImmuneToNPC(); }
+ void SetImmuneToPC(bool apply, bool keepCombat = false);
+ bool IsImmuneToPC() const { return HasUnitFlag(UNIT_FLAG_IMMUNE_TO_PC); }
+ void SetImmuneToNPC(bool apply, bool keepCombat = false);
+ bool IsImmuneToNPC() const { return HasUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC); }
+
+ bool IsEngaged() const { return IsInCombat(); }
+ bool IsEngagedBy(Unit const* who) const { return IsInCombatWith(who); }
+
+ [[nodiscard]] bool IsInCombat() const { return HasUnitFlag(UNIT_FLAG_IN_COMBAT); }
+ bool IsInCombatWith(Unit const* who) const;
+
+ [[nodiscard]] bool IsPetInCombat() const { return HasUnitFlag(UNIT_FLAG_PET_IN_COMBAT); }
+ void CombatStart(Unit* target, bool initialAggro = true);
+ void CombatStartOnCast(Unit* target, bool initialAggro = true, uint32 duration = 0);
+ void SetInCombatState(bool PvP, Unit* enemy = nullptr, uint32 duration = 0);
+ void SetInCombatWith(Unit* enemy, uint32 duration = 0);
+ void ClearInCombat();
+ void ClearInPetCombat();
+ [[nodiscard]] uint32 GetCombatTimer() const { return m_CombatTimer; }
+ void SetCombatTimer(uint32 timer) { m_CombatTimer = timer; }
+
+ // Threat related methods
+ [[nodiscard]] bool CanHaveThreatList() const;
+ void AddThreat(Unit* victim, float fThreat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* threatSpell = nullptr);
+ float ApplyTotalThreatModifier(float fThreat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL);
+ void TauntApply(Unit* victim);
+ void TauntFadeOut(Unit* taunter);
+ ThreatMgr& GetThreatMgr() { return m_ThreatMgr; }
+ ThreatMgr const& GetThreatMgr() const { return m_ThreatMgr; }
+ void addHatedBy(HostileReference* pHostileReference) { m_HostileRefMgr.insertFirst(pHostileReference); };
+ void removeHatedBy(HostileReference* /*pHostileReference*/) { /* nothing to do yet */ }
+ HostileRefMgr& getHostileRefMgr() { return m_HostileRefMgr; }
+
+ // Redirect Threat
+ void SetRedirectThreat(ObjectGuid guid, uint32 pct) { _redirectThreatInfo.Set(guid, pct); }
+ void ResetRedirectThreat() { SetRedirectThreat(ObjectGuid::Empty, 0); }
+ void ModifyRedirectThreat(int32 amount) { _redirectThreatInfo.ModifyThreatPct(amount); }
+ uint32 GetRedirectThreatPercent() { return _redirectThreatInfo.GetThreatPct(); }
+ [[nodiscard]] Unit* GetRedirectThreatTarget() const;
+ /*********************************************************/
+ /*** METHODS RELATED TO STATS ***/
+ /*********************************************************/
[[nodiscard]] uint8 GetLevel() const { return uint8(GetUInt32Value(UNIT_FIELD_LEVEL)); }
uint8 getLevelForTarget(WorldObject const* /*target*/) const override { return GetLevel(); }
void SetLevel(uint8 lvl, bool showLevelChange = true);
- [[nodiscard]] uint8 getRace(bool original = false) const;
- void setRace(uint8 race);
- [[nodiscard]] uint32 getRaceMask() const { return 1 << (getRace(true) - 1); }
- [[nodiscard]] uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, 1); }
- [[nodiscard]] virtual bool IsClass(Classes unitClass, [[maybe_unused]] ClassContext context = CLASS_CONTEXT_NONE) const { return (getClass() == unitClass); }
- [[nodiscard]] uint32 getClassMask() const { return 1 << (getClass() - 1); }
- [[nodiscard]] uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, 2); }
- [[nodiscard]] DisplayRace GetDisplayRaceFromModelId(uint32 modelId) const;
- [[nodiscard]] DisplayRace GetDisplayRace() const { return GetDisplayRaceFromModelId(GetDisplayId()); };
[[nodiscard]] float GetStat(Stats stat) const { return float(GetUInt32Value(static_cast<uint16>(UNIT_FIELD_STAT0) + stat)); }
void SetStat(Stats stat, int32 val) { SetStatInt32Value(static_cast<uint16>(UNIT_FIELD_STAT0) + stat, val); }
@@ -805,42 +892,58 @@ public:
[[nodiscard]] uint32 GetMaxPower(Powers power) const { return GetUInt32Value(static_cast<uint16>(UNIT_FIELD_MAXPOWER1) + power); }
void SetPower(Powers power, uint32 val, bool withPowerUpdate = true, bool fromRegenerate = false);
void SetMaxPower(Powers power, uint32 val);
+
// returns the change in power
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate = true);
int32 ModifyPowerPct(Powers power, float pct, bool apply = true);
- [[nodiscard]] uint32 GetAttackTime(WeaponAttackType att) const
- {
- float f_BaseAttackTime = GetFloatValue(static_cast<uint16>(UNIT_FIELD_BASEATTACKTIME) + att) / m_modAttackSpeedPct[att];
- return (uint32)f_BaseAttackTime;
- }
-
- void SetAttackTime(WeaponAttackType att, uint32 val) { SetFloatValue(static_cast<uint16>(UNIT_FIELD_BASEATTACKTIME) + att, val * m_modAttackSpeedPct[att]); }
- void ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply);
- void ApplyCastTimePercentMod(float val, bool apply);
+ // stat system
+ bool HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, float amount, bool apply);
+ void SetModifierValue(UnitMods unitMod, UnitModifierType modifierType, float value) { m_auraModifiersGroup[unitMod][modifierType] = value; }
+ [[nodiscard]] float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const;
+ [[nodiscard]] float GetTotalStatValue(Stats stat, float additionalValue = 0.0f) const;
+ [[nodiscard]] float GetTotalAuraModValue(UnitMods unitMod) const;
+ [[nodiscard]] SpellSchools GetSpellSchoolByAuraGroup(UnitMods unitMod) const;
+ [[nodiscard]] Stats GetStatByAuraGroup(UnitMods unitMod) const;
+ [[nodiscard]] Powers GetPowerTypeByAuraGroup(UnitMods unitMod) const;
+ [[nodiscard]] bool CanModifyStats() const { return m_canModifyStats; }
+ void SetCanModifyStats(bool modifyStats) { m_canModifyStats = modifyStats; }
+ virtual bool UpdateStats(Stats stat) = 0;
+ virtual bool UpdateAllStats() = 0;
+ virtual void UpdateResistances(uint32 school) = 0;
+ virtual void UpdateAllResistances();
+ virtual void UpdateArmor() = 0;
+ virtual void UpdateMaxHealth() = 0;
+ virtual void UpdateMaxPower(Powers power) = 0;
+ virtual void UpdateAttackPowerAndDamage(bool ranged = false) = 0;
+ virtual void UpdateDamagePhysical(WeaponAttackType attType);
+ float GetTotalAttackPowerValue(WeaponAttackType attType, Unit* pVictim = nullptr) const;
+ [[nodiscard]] float GetWeaponDamageRange(WeaponAttackType attType, WeaponDamageRange type, uint8 damageIndex = 0) const;
+ void SetBaseWeaponDamage(WeaponAttackType attType, WeaponDamageRange damageRange, float value, uint8 damageIndex = 0) { m_weaponDamage[attType][damageRange][damageIndex] = value; }
+ virtual void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage, uint8 damageIndex = 0) = 0;
+ uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask = 0);
+ float GetAPMultiplier(WeaponAttackType attType, bool normalized);
+ //------------------------------------------------------//
- void SetUInt32Value(uint16 index, uint32 value);
+ DiminishingLevels GetDiminishing(DiminishingGroup group);
+ void IncrDiminishing(DiminishingGroup group);
+ float ApplyDiminishingToDuration(DiminishingGroup group, int32& duration, Unit* caster, DiminishingLevels Level, int32 limitduration);
+ void ApplyDiminishingAura(DiminishingGroup group, bool apply);
+ void ClearDiminishings() { m_Diminishing.clear(); }
- UnitFlags GetUnitFlags() const { return UnitFlags(GetUInt32Value(UNIT_FIELD_FLAGS)); }
- bool HasUnitFlag(UnitFlags flags) const { return HasFlag(UNIT_FIELD_FLAGS, flags); } /// @brief UnitFlags available in UnitDefines.h
- void SetUnitFlag(UnitFlags flags) { SetFlag(UNIT_FIELD_FLAGS, flags); } /// @brief UnitFlags available in UnitDefines.h
- void RemoveUnitFlag(UnitFlags flags) { RemoveFlag(UNIT_FIELD_FLAGS, flags); } /// @brief Remove the Unit flag specify only
- void ReplaceAllUnitFlags(UnitFlags flags) { SetUInt32Value(UNIT_FIELD_FLAGS, flags); } /// @brief Remove all UnitFlags and set new ones. UnitFlags available in UnitDefines.h
+ // target dependent range checks
+ float GetSpellMaxRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const;
+ float GetSpellMinRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const;
- UnitFlags2 GetUnitFlags2() const { return UnitFlags2(GetUInt32Value(UNIT_FIELD_FLAGS_2)); }
- bool HasUnitFlag2(UnitFlags2 flags) const { return HasFlag(UNIT_FIELD_FLAGS_2, flags); }
- void SetUnitFlag2(UnitFlags2 flags) { SetFlag(UNIT_FIELD_FLAGS_2, flags); }
- void RemoveUnitFlag2(UnitFlags2 flags) { RemoveFlag(UNIT_FIELD_FLAGS_2, flags); }
- void ReplaceAllUnitFlags2(UnitFlags2 flags) { SetUInt32Value(UNIT_FIELD_FLAGS_2, flags); }
+ [[nodiscard]] bool CanFreeMove() const
+ {
+ return !HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_FLEEING | UNIT_STATE_IN_FLIGHT |
+ UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED) && !GetOwnerGUID();
+ }
[[nodiscard]] SheathState GetSheath() const { return SheathState(GetByteValue(UNIT_FIELD_BYTES_2, 0)); }
virtual void SetSheath(SheathState sheathed) { SetByteValue(UNIT_FIELD_BYTES_2, 0, sheathed); }
- // faction template id
- [[nodiscard]] uint32 GetFaction() const { return GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE); }
- void SetFaction(uint32 faction);
- [[nodiscard]] FactionTemplateEntry const* GetFactionTemplateEntry() const;
-
ReputationRank GetReactionTo(Unit const* target, bool checkOriginalFaction = false) const;
ReputationRank GetFactionReactionTo(FactionTemplateEntry const* factionTemplateEntry, Unit const* target) const;
@@ -978,6 +1081,7 @@ public:
return value;
}
+
uint32 GetUnitMeleeSkill(Unit const* target = nullptr) const { return (target ? getLevelForTarget(target) : GetLevel()) * 5; }
uint32 GetDefenseSkillValue(Unit const* target = nullptr) const;
uint32 GetWeaponSkillValue(WeaponAttackType attType, Unit const* target = nullptr) const;
@@ -987,61 +1091,10 @@ public:
MeleeHitOutcome RollMeleeOutcomeAgainst (Unit const* victim, WeaponAttackType attType) const;
MeleeHitOutcome RollMeleeOutcomeAgainst (Unit const* victim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance) const;
- NPCFlags GetNpcFlags() const { return NPCFlags(GetUInt32Value(UNIT_NPC_FLAGS)); }
- bool HasNpcFlag(NPCFlags flags) const { return HasFlag(UNIT_NPC_FLAGS, flags) != 0; }
- void SetNpcFlag(NPCFlags flags) { SetFlag(UNIT_NPC_FLAGS, flags); }
- void RemoveNpcFlag(NPCFlags flags) { RemoveFlag(UNIT_NPC_FLAGS, flags); }
- void ReplaceAllNpcFlags(NPCFlags flags) { SetUInt32Value(UNIT_NPC_FLAGS, flags); }
-
- [[nodiscard]] bool IsVendor() const { return HasNpcFlag(UNIT_NPC_FLAG_VENDOR); }
- [[nodiscard]] bool IsTrainer() const { return HasNpcFlag(UNIT_NPC_FLAG_TRAINER); }
- [[nodiscard]] bool IsQuestGiver() const { return HasNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); }
- [[nodiscard]] bool IsGossip() const { return HasNpcFlag(UNIT_NPC_FLAG_GOSSIP); }
- [[nodiscard]] bool IsTaxi() const { return HasNpcFlag(UNIT_NPC_FLAG_FLIGHTMASTER); }
- [[nodiscard]] bool IsGuildMaster() const { return HasNpcFlag(UNIT_NPC_FLAG_PETITIONER); }
- [[nodiscard]] bool IsBattleMaster() const { return HasNpcFlag(UNIT_NPC_FLAG_BATTLEMASTER); }
- [[nodiscard]] bool IsBanker() const { return HasNpcFlag(UNIT_NPC_FLAG_BANKER); }
- [[nodiscard]] bool IsInnkeeper() const { return HasNpcFlag(UNIT_NPC_FLAG_INNKEEPER); }
- [[nodiscard]] bool IsSpiritHealer() const { return HasNpcFlag(UNIT_NPC_FLAG_SPIRITHEALER); }
- [[nodiscard]] bool IsSpiritGuide() const { return HasNpcFlag(UNIT_NPC_FLAG_SPIRITGUIDE); }
- [[nodiscard]] bool IsTabardDesigner() const { return HasNpcFlag(UNIT_NPC_FLAG_TABARDDESIGNER); }
- [[nodiscard]] bool IsAuctioner() const { return HasNpcFlag(UNIT_NPC_FLAG_AUCTIONEER); }
- [[nodiscard]] bool IsArmorer() const { return HasNpcFlag(UNIT_NPC_FLAG_REPAIR); }
- [[nodiscard]] bool IsServiceProvider() const
- {
- return HasNpcFlag(UNIT_NPC_FLAG_VENDOR | UNIT_NPC_FLAG_TRAINER | UNIT_NPC_FLAG_FLIGHTMASTER |
- UNIT_NPC_FLAG_PETITIONER | UNIT_NPC_FLAG_BATTLEMASTER | UNIT_NPC_FLAG_BANKER |
- UNIT_NPC_FLAG_INNKEEPER | UNIT_NPC_FLAG_SPIRITHEALER |
- UNIT_NPC_FLAG_SPIRITGUIDE | UNIT_NPC_FLAG_TABARDDESIGNER | UNIT_NPC_FLAG_AUCTIONEER);
- }
- [[nodiscard]] bool IsSpiritService() const { return HasNpcFlag(UNIT_NPC_FLAG_SPIRITHEALER | UNIT_NPC_FLAG_SPIRITGUIDE); }
[[nodiscard]] bool IsCritter() const { return GetCreatureType() == CREATURE_TYPE_CRITTER; }
[[nodiscard]] bool IsInFlight() const { return HasUnitState(UNIT_STATE_IN_FLIGHT); }
- void SetImmuneToAll(bool apply, bool keepCombat = false) { SetImmuneToPC(apply, keepCombat); SetImmuneToNPC(apply, keepCombat); }
- bool IsImmuneToAll() const { return IsImmuneToPC() && IsImmuneToNPC(); }
- void SetImmuneToPC(bool apply, bool keepCombat = false);
- bool IsImmuneToPC() const { return HasUnitFlag(UNIT_FLAG_IMMUNE_TO_PC); }
- void SetImmuneToNPC(bool apply, bool keepCombat = false);
- bool IsImmuneToNPC() const { return HasUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC); }
-
- bool IsEngaged() const { return IsInCombat(); }
- bool IsEngagedBy(Unit const* who) const { return IsInCombatWith(who); }
-
- [[nodiscard]] bool IsInCombat() const { return HasUnitFlag(UNIT_FLAG_IN_COMBAT); }
- bool IsInCombatWith(Unit const* who) const;
-
- [[nodiscard]] bool IsPetInCombat() const { return HasUnitFlag(UNIT_FLAG_PET_IN_COMBAT); }
- void CombatStart(Unit* target, bool initialAggro = true);
- void CombatStartOnCast(Unit* target, bool initialAggro = true, uint32 duration = 0);
- void SetInCombatState(bool PvP, Unit* enemy = nullptr, uint32 duration = 0);
- void SetInCombatWith(Unit* enemy, uint32 duration = 0);
- void ClearInCombat();
- void ClearInPetCombat();
- [[nodiscard]] uint32 GetCombatTimer() const { return m_CombatTimer; }
- void SetCombatTimer(uint32 timer) { m_CombatTimer = timer; }
-
[[nodiscard]] bool HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, uint32 familyFlags) const;
[[nodiscard]] bool virtual HasSpell(uint32 /*spellID*/) const { return false; }
[[nodiscard]] bool HasBreakableByDamageAuraType(AuraType type, uint32 excludeAura = 0) const;
@@ -1207,7 +1260,6 @@ public:
void RemoveCharmedBy(Unit* charmer);
void RestoreFaction();
- ControlSet m_Controlled;
[[nodiscard]] Unit* GetFirstControlled() const;
void RemoveAllControlled(bool onDeath = false);
@@ -1228,7 +1280,7 @@ public:
void DeleteCharmInfo();
void UpdateCharmAI();
//Player* GetMoverSource() const;
- SafeUnitPointer m_movedByPlayer;
+
SharedVisionList const& GetSharedVisionList() { return m_sharedVision; }
void AddPlayerToVision(Player* player);
void RemovePlayerFromVision(Player* player);
@@ -1408,9 +1460,6 @@ public:
[[nodiscard]] virtual bool IsMovementPreventedByCasting() const;
- ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT];
- ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT];
-
[[nodiscard]] ShapeshiftForm GetShapeshiftForm() const { return ShapeshiftForm(GetByteValue(UNIT_FIELD_BYTES_2, 3)); }
void SetShapeshiftForm(ShapeshiftForm form)
{
@@ -1425,44 +1474,6 @@ public:
[[nodiscard]] bool IsInDisallowedMountForm() const;
- float m_modMeleeHitChance;
- float m_modRangedHitChance;
- float m_modSpellHitChance;
- int32 m_baseSpellCritChance;
-
- float m_threatModifier[MAX_SPELL_SCHOOL];
- float m_modAttackSpeedPct[3];
-
- // Event handler
- EventProcessor m_Events;
-
- // stat system
- bool HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, float amount, bool apply);
- void SetModifierValue(UnitMods unitMod, UnitModifierType modifierType, float value) { m_auraModifiersGroup[unitMod][modifierType] = value; }
- [[nodiscard]] float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const;
- [[nodiscard]] float GetTotalStatValue(Stats stat, float additionalValue = 0.0f) const;
- [[nodiscard]] float GetTotalAuraModValue(UnitMods unitMod) const;
- [[nodiscard]] SpellSchools GetSpellSchoolByAuraGroup(UnitMods unitMod) const;
- [[nodiscard]] Stats GetStatByAuraGroup(UnitMods unitMod) const;
- [[nodiscard]] Powers GetPowerTypeByAuraGroup(UnitMods unitMod) const;
- [[nodiscard]] bool CanModifyStats() const { return m_canModifyStats; }
- void SetCanModifyStats(bool modifyStats) { m_canModifyStats = modifyStats; }
- virtual bool UpdateStats(Stats stat) = 0;
- virtual bool UpdateAllStats() = 0;
- virtual void UpdateResistances(uint32 school) = 0;
- virtual void UpdateAllResistances();
- virtual void UpdateArmor() = 0;
- virtual void UpdateMaxHealth() = 0;
- virtual void UpdateMaxPower(Powers power) = 0;
- virtual void UpdateAttackPowerAndDamage(bool ranged = false) = 0;
- virtual void UpdateDamagePhysical(WeaponAttackType attType);
- float GetTotalAttackPowerValue(WeaponAttackType attType, Unit* pVictim = nullptr) const;
- [[nodiscard]] float GetWeaponDamageRange(WeaponAttackType attType, WeaponDamageRange type, uint8 damageIndex = 0) const;
- void SetBaseWeaponDamage(WeaponAttackType attType, WeaponDamageRange damageRange, float value, uint8 damageIndex = 0) { m_weaponDamage[attType][damageRange][damageIndex] = value; }
- virtual void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage, uint8 damageIndex = 0) = 0;
- uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask = 0);
- float GetAPMultiplier(WeaponAttackType attType, bool normalized);
-
bool isInFrontInMap(Unit const* target, float distance, float arc = M_PI) const;
bool isInBackInMap(Unit const* target, float distance, float arc = M_PI) const;
@@ -1476,21 +1487,6 @@ public:
void SetPhaseMask(uint32 newPhaseMask, bool update) override;// overwrite WorldObject::SetPhaseMask
void UpdateObjectVisibility(bool forced = true, bool fromUpdate = false) override;
- SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY];
- uint32 m_lastSanctuaryTime;
-
- // Threat related methods
- [[nodiscard]] bool CanHaveThreatList() const;
- void AddThreat(Unit* victim, float fThreat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* threatSpell = nullptr);
- float ApplyTotalThreatModifier(float fThreat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL);
- void TauntApply(Unit* victim);
- void TauntFadeOut(Unit* taunter);
- ThreatMgr& GetThreatMgr() { return m_ThreatMgr; }
- ThreatMgr const& GetThreatMgr() const { return m_ThreatMgr; }
- void addHatedBy(HostileReference* pHostileReference) { m_HostileRefMgr.insertFirst(pHostileReference); };
- void removeHatedBy(HostileReference* /*pHostileReference*/) { /* nothing to do yet */ }
- HostileRefMgr& getHostileRefMgr() { return m_HostileRefMgr; }
-
VisibleAuraMap const* GetVisibleAuras() { return &m_visibleAuras; }
AuraApplication* GetVisibleAura(uint8 slot)
{
@@ -1629,7 +1625,7 @@ public:
void DisableSpline();
///-----------Combo point system-------------------
- // This unit having CP on other units
+ // This unit having CP on other units
[[nodiscard]] uint8 GetComboPoints(Unit const* who = nullptr) const { return (who && m_comboTarget != who) ? 0 : m_comboPoints; }
[[nodiscard]] uint8 GetComboPoints(ObjectGuid const& guid) const { return (m_comboTarget && m_comboTarget->GetGUID() == guid) ? m_comboPoints : 0; }
[[nodiscard]] Unit* GetComboTarget() const { return m_comboTarget; }
@@ -1660,21 +1656,9 @@ public:
void UpdateAuraForGroup(uint8 slot);
// proc trigger system
- bool CanProc() {return !m_procDeep;}
- void SetCantProc(bool apply)
- {
- if (apply)
- ++m_procDeep;
- else
- {
- ASSERT(m_procDeep);
- --m_procDeep;
- }
- }
+ bool CanProc() { return !m_procDeep; }
+ void SetCantProc(bool apply);
- // pet auras
- typedef std::set<PetAura const*> PetAuraSet;
- PetAuraSet m_petAuras;
void AddPetAura(PetAura const* petSpell);
void RemovePetAura(PetAura const* petSpell);
void CastPetAura(PetAura const* aura);
@@ -1683,14 +1667,6 @@ public:
[[nodiscard]] uint32 GetModelForForm(ShapeshiftForm form, uint32 spellId) const;
uint32 GetModelForTotem(PlayerTotemType totemType);
- // Redirect Threat
- void SetRedirectThreat(ObjectGuid guid, uint32 pct) { _redirectThreatInfo.Set(guid, pct); }
- void ResetRedirectThreat() { SetRedirectThreat(ObjectGuid::Empty, 0); }
- void ModifyRedirectThreat(int32 amount) { _redirectThreatInfo.ModifyThreatPct(amount); }
- uint32 GetRedirectThreatPercent() { return _redirectThreatInfo.GetThreatPct(); }
- [[nodiscard]] Unit* GetRedirectThreatTarget() const;
-
- bool IsAIEnabled, NeedChangeAI;
bool CreateVehicleKit(uint32 id, uint32 creatureEntry);
void RemoveVehicleKit();
[[nodiscard]] Vehicle* GetVehicleKit()const { return m_vehicleKit; }
@@ -1702,9 +1678,6 @@ public:
/// Returns the transport this unit is on directly (if on vehicle and transport, return vehicle)
[[nodiscard]] TransportBase* GetDirectTransport() const;
- bool m_ControlledByPlayer;
- bool m_CreatedByPlayer;
-
bool HandleSpellClick(Unit* clicker, int8 seatId = -1);
void EnterVehicle(Unit* base, int8 seatId = -1);
void EnterVehicleUnattackable(Unit* base, int8 seatId = -1);
@@ -1743,17 +1716,10 @@ public:
TempSummon* ToTempSummon() { if (IsSummon()) return reinterpret_cast<TempSummon*>(this); else return nullptr; }
[[nodiscard]] const TempSummon* ToTempSummon() const { if (IsSummon()) return reinterpret_cast<const TempSummon*>(this); else return nullptr; }
- // Safe mover
- std::set<SafeUnitPointer*> SafeUnitPointerSet;
void AddPointedBy(SafeUnitPointer* sup) { SafeUnitPointerSet.insert(sup); }
void RemovePointedBy(SafeUnitPointer* sup) { SafeUnitPointerSet.erase(sup); }
static void HandleSafeUnitPointersOnDelete(Unit* thisUnit);
- // Relocation Nofier optimization
- Position m_last_notify_position;
- uint32 m_last_notify_mstime;
- uint16 m_delayed_unit_relocation_timer;
- uint16 m_delayed_unit_ai_notify_timer;
- bool bRequestForcedVisibilityUpdate;
+
void ExecuteDelayedUnitRelocationEvent();
void ExecuteDelayedUnitAINotifyEvent();
@@ -1779,9 +1745,6 @@ public:
void SetInstantCast(bool set) { _instantCast = set; }
[[nodiscard]] bool CanInstantCast() const { return _instantCast; }
- // Movement info
- Movement::MoveSpline* movespline;
-
virtual void Talk(std::string_view text, ChatMsg msgType, Language language, float textRange, WorldObject const* target);
virtual void Say(std::string_view text, Language language, WorldObject const* target = nullptr);
virtual void Yell(std::string_view text, Language language, WorldObject const* target = nullptr);
@@ -1806,18 +1769,76 @@ public:
[[nodiscard]] uint32 GetOldFactionId() const { return _oldFactionId; }
+ //----------- Public variables ----------//
+ uint32 m_extraAttacks;
+ bool m_canDualWield;
+
+ ControlSet m_Controlled;
+
+ SafeUnitPointer m_movedByPlayer;
+
+ ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT];
+ ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT];
+
+ float m_modMeleeHitChance;
+ float m_modRangedHitChance;
+ float m_modSpellHitChance;
+ int32 m_baseSpellCritChance;
+
+ float m_threatModifier[MAX_SPELL_SCHOOL];
+ float m_modAttackSpeedPct[3];
+
+ // Event handler
+ EventProcessor m_Events;
+
+ SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY];
+ uint32 m_lastSanctuaryTime;
+
+ // pet auras
+ typedef std::set<PetAura const*> PetAuraSet;
+ PetAuraSet m_petAuras;
+
+ bool IsAIEnabled;
+ bool NeedChangeAI;
+
+ bool m_ControlledByPlayer;
+ bool m_CreatedByPlayer;
+
+ // Safe mover
+ std::set<SafeUnitPointer*> SafeUnitPointerSet;
+
+ // Relocation Nofier optimization
+ Position m_last_notify_position;
+ uint32 m_last_notify_mstime;
+ uint16 m_delayed_unit_relocation_timer;
+ uint16 m_delayed_unit_ai_notify_timer;
+ bool bRequestForcedVisibilityUpdate;
+
+ // Movement info
+ Movement::MoveSpline* movespline;
+
protected:
explicit Unit (bool isWorldObject);
void BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) override;
- UnitAI* i_AI, *i_disabledAI;
-
void _UpdateSpells(uint32 time);
void _DeleteRemovedAuras();
void _UpdateAutoRepeatSpell();
+ bool IsAlwaysVisibleFor(WorldObject const* seer) const override;
+ bool IsAlwaysDetectableFor(WorldObject const* seer) const override;
+
+ void SetFeared(bool apply, Unit* fearedBy = nullptr, bool isFear = false);
+ void SetConfused(bool apply);
+ void SetStunned(bool apply);
+ void SetRooted(bool apply, bool isStun = false);
+
+ //----------- Protected variables ----------//
+ UnitAI* i_AI;
+ UnitAI* i_disabledAI;
+
uint8 m_realRace;
uint8 m_race;
@@ -1851,7 +1872,7 @@ protected:
AuraEffectList m_modAuras[TOTAL_AURAS];
AuraList m_scAuras; // casted singlecast auras
- AuraApplicationList m_interruptableAuras; // auras which have interrupt mask applied on unit
+ AuraApplicationList m_interruptableAuras; // auras which have interrupt mask applied on unit
AuraStateAurasMap m_auraStateAuras; // Used for improve performance of aura state checks on aura apply/remove
uint32 m_interruptMask;
@@ -1882,10 +1903,10 @@ protected:
// xinef: apply resilience
bool m_applyResilience;
- bool IsAlwaysVisibleFor(WorldObject const* seer) const override;
- bool IsAlwaysDetectableFor(WorldObject const* seer) const override;
bool _instantCast;
+ uint32 m_rootTimes;
+
private:
bool IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent, ProcEventInfo const& eventInfo);
bool HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, ProcEventInfo const& eventInfo);
@@ -1905,15 +1926,12 @@ private:
void PatchValuesUpdate(ByteBuffer& valuesUpdateBuf, BuildValuesCachePosPointers& posPointers, Player* target);
void InvalidateValuesUpdateCache() { _valuesUpdateCache.clear(); }
-protected:
- void SetFeared(bool apply, Unit* fearedBy = nullptr, bool isFear = false);
- void SetConfused(bool apply);
- void SetStunned(bool apply);
- void SetRooted(bool apply, bool isStun = false);
+ [[nodiscard]] float processDummyAuras(float TakenTotalMod) const;
- uint32 m_rootTimes;
+ void _addAttacker(Unit* pAttacker) { m_attackers.insert(pAttacker); } ///@note: Call only in Unit::Attack()
+ void _removeAttacker(Unit* pAttacker) { m_attackers.erase(pAttacker); } ///@note: Call only in Unit::AttackStop()
-private:
+ //----------- Private variables ----------//
uint32 m_state; // Even derived shouldn't modify
uint32 m_CombatTimer;
uint32 m_lastManaUse; // msecs
@@ -1937,8 +1955,6 @@ private:
uint32 _oldFactionId; ///< faction before charm
bool _isWalkingBeforeCharm; ///< Are we walking before we were charmed?
- [[nodiscard]] float processDummyAuras(float TakenTotalMod) const;
-
uint32 _lastExtraAttackSpell;
std::unordered_map<ObjectGuid /*guid*/, uint32 /*count*/> extraAttacksTargets;
ObjectGuid _lastDamagedTargetGuid;