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
This commit is contained in:
Grimdhex
2024-09-11 16:50:24 +02:00
committed by GitHub
parent 30e77ae880
commit 56d2cc7b4c
2 changed files with 284 additions and 243 deletions

View File

@@ -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())

View File

@@ -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();
[[nodiscard]] Unit* getAttackerForHelper() const; // If someone wants to help, who to give them
if (!IsEngaged())
return nullptr;
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
// 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);
//------------------------------------------------------//
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(); }
// target dependent range checks
float GetSpellMaxRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const;
float GetSpellMinRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const;
[[nodiscard]] bool CanFreeMove() const
{
float f_BaseAttackTime = GetFloatValue(static_cast<uint16>(UNIT_FIELD_BASEATTACKTIME) + att) / m_modAttackSpeedPct[att];
return (uint32)f_BaseAttackTime;
return !HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_FLEEING | UNIT_STATE_IN_FLIGHT |
UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED) && !GetOwnerGUID();
}
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 SetUInt32Value(uint16 index, uint32 value);
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); }
[[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;