diff options
| author | Grimdhex <176165533+Grimdhex@users.noreply.github.com> | 2024-09-11 16:50:24 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-11 11:50:24 -0300 |
| commit | 56d2cc7b4c975448680dfb79ecae91dadcbad22c (patch) | |
| tree | f74b9581d09bc072ea0a3d2560ccbdc4b6c667c3 /src | |
| parent | 30e77ae8807a5be29d763482d9a01065f040e388 (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.cpp | 25 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 500 |
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; |
