diff options
-rw-r--r-- | sql/updates/world/master/2022_02_09_00_world.sql | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 14 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 16 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 16 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.h | 4 | ||||
-rw-r--r-- | src/server/game/Spells/SpellDefines.h | 25 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.h | 2 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 99 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.h | 136 |
11 files changed, 181 insertions, 141 deletions
diff --git a/sql/updates/world/master/2022_02_09_00_world.sql b/sql/updates/world/master/2022_02_09_00_world.sql new file mode 100644 index 00000000000..1d4490faa18 --- /dev/null +++ b/sql/updates/world/master/2022_02_09_00_world.sql @@ -0,0 +1,2 @@ +ALTER TABLE `serverside_spell` ADD `ProcFlags2` int unsigned NOT NULL DEFAULT 0 AFTER `ProcFlags`; +ALTER TABLE `spell_proc` ADD `ProcFlags2` int unsigned NOT NULL DEFAULT 0 AFTER `ProcFlags`; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index cfb20a015b8..f49e08be4fb 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -261,7 +261,7 @@ uint32 HealInfo::GetHitMask() const } ProcEventInfo::ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, - uint32 typeMask, uint32 spellTypeMask, + ProcFlagsInit const& typeMask, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo) : @@ -5181,7 +5181,7 @@ void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage const* log) SendCombatLogMessage(&packet); } -/*static*/ void Unit::ProcSkillsAndAuras(Unit* actor, Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo) +/*static*/ void Unit::ProcSkillsAndAuras(Unit* actor, Unit* actionTarget, ProcFlagsInit const& typeMaskActor, ProcFlagsInit const& typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo) { WeaponAttackType attType = damageInfo ? damageInfo->GetAttackType() : BASE_ATTACK; if (typeMaskActor && actor) @@ -9749,7 +9749,7 @@ void Unit::GetProcAurasTriggeredOnEvent(AuraApplicationProcContainer& aurasTrigg } } -void Unit::TriggerAurasProcOnEvent(AuraApplicationList* myProcAuras, AuraApplicationList* targetProcAuras, Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo) +void Unit::TriggerAurasProcOnEvent(AuraApplicationList* myProcAuras, AuraApplicationList* targetProcAuras, Unit* actionTarget, ProcFlagsInit const& typeMaskActor, ProcFlagsInit const& typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo) { // prepare data for self trigger ProcEventInfo myProcEventInfo(this, actionTarget, actionTarget, typeMaskActor, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index b0438292d04..7aa45afde80 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -480,7 +480,7 @@ class TC_GAME_API HealInfo class TC_GAME_API ProcEventInfo { public: - ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, uint32 typeMask, + ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, ProcFlagsInit const& typeMask, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo); @@ -488,7 +488,7 @@ class TC_GAME_API ProcEventInfo Unit* GetActionTarget() const { return _actionTarget; } Unit* GetProcTarget() const { return _procTarget; } - uint32 GetTypeMask() const { return _typeMask; } + FlagsArray<int32, 2> GetTypeMask() const { return _typeMask; } uint32 GetSpellTypeMask() const { return _spellTypeMask; } uint32 GetSpellPhaseMask() const { return _spellPhaseMask; } uint32 GetHitMask() const { return _hitMask; } @@ -505,7 +505,7 @@ class TC_GAME_API ProcEventInfo Unit* const _actor; Unit* const _actionTarget; Unit* const _procTarget; - uint32 _typeMask; + FlagsArray<int32, 2> _typeMask; uint32 _spellTypeMask; uint32 _spellPhaseMask; uint32 _hitMask; @@ -531,8 +531,8 @@ struct CalcDamageInfo // Helpers WeaponAttackType AttackType; // - uint32 ProcAttacker; - uint32 ProcVictim; + ProcFlagsInit ProcAttacker; + ProcFlagsInit ProcVictim; uint32 CleanDamage; // Used only for rage calculation MeleeHitOutcome HitOutCome; /// @todo remove this field (need use TargetState) }; @@ -1027,13 +1027,13 @@ class TC_GAME_API Unit : public WorldObject void KillSelf(bool durabilityLoss = true, bool skipSettingDeathState = false) { Unit::Kill(this, this, durabilityLoss, skipSettingDeathState); } static void DealHeal(HealInfo& healInfo); - static void ProcSkillsAndAuras(Unit* actor, Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, + static void ProcSkillsAndAuras(Unit* actor, Unit* actionTarget, ProcFlagsInit const& typeMaskActor, ProcFlagsInit const& typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo); void GetProcAurasTriggeredOnEvent(AuraApplicationProcContainer& aurasTriggeringProc, AuraApplicationList* procAuras, ProcEventInfo& eventInfo); void TriggerAurasProcOnEvent(AuraApplicationList* myProcAuras, AuraApplicationList* targetProcAuras, - Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, + Unit* actionTarget, ProcFlagsInit const& typeMaskActor, ProcFlagsInit const& typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo); void TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, AuraApplicationProcContainer& procAuras); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 0b4291f4682..ee86422c252 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -5324,8 +5324,8 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const Unit::DealDamageMods(caster, target, damage, &absorb); // Set trigger flag - uint32 procAttacker = PROC_FLAG_DONE_PERIODIC; - uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC; + ProcFlagsInit procAttacker = PROC_FLAG_DONE_PERIODIC; + ProcFlagsInit procVictim = PROC_FLAG_TAKEN_PERIODIC; uint32 hitMask = damageInfo.GetHitMask(); if (damage) { @@ -5420,8 +5420,8 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c log.HitInfo |= SPELL_HIT_TYPE_CRIT; // Set trigger flag - uint32 procAttacker = PROC_FLAG_DONE_PERIODIC; - uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC; + ProcFlagsInit procAttacker = PROC_FLAG_DONE_PERIODIC; + ProcFlagsInit procVictim = PROC_FLAG_TAKEN_PERIODIC; uint32 hitMask = damageInfo.GetHitMask(); if (damage) { @@ -5534,8 +5534,8 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const if (GetAuraType() == SPELL_AURA_OBS_MOD_HEALTH) return; - uint32 procAttacker = PROC_FLAG_DONE_PERIODIC; - uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC; + ProcFlagsInit procAttacker = PROC_FLAG_DONE_PERIODIC; + ProcFlagsInit procVictim = PROC_FLAG_TAKEN_PERIODIC; uint32 hitMask = crit ? PROC_HIT_CRITICAL : PROC_HIT_NORMAL; // ignore item heals if (GetBase()->GetCastItemGUID().IsEmpty()) @@ -5696,8 +5696,8 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con Unit::DealDamageMods(damageInfo.attacker, damageInfo.target, damageInfo.damage, &damageInfo.absorb); // Set trigger flag - uint32 procAttacker = PROC_FLAG_DONE_PERIODIC; - uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC; + ProcFlagsInit procAttacker = PROC_FLAG_DONE_PERIODIC; + ProcFlagsInit procVictim = PROC_FLAG_TAKEN_PERIODIC; uint32 hitMask = createProcHitMask(&damageInfo, SPELL_MISS_NONE); uint32 spellTypeMask = PROC_SPELL_TYPE_NO_DMG_HEAL; if (damageInfo.damage) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 8afc6d1af6d..5ac413809f6 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -585,8 +585,6 @@ m_spellValue(new SpellValue(m_spellInfo, caster)), _spellEvent(nullptr) effectInfo = nullptr; m_damage = 0; m_healing = 0; - m_procAttacker = 0; - m_procVictim = 0; m_hitMask = 0; focusObject = nullptr; m_castId = ObjectGuid::Create<HighGuid::Cast>(SPELL_CAST_SOURCE_NORMAL, m_caster->GetMapId(), m_spellInfo->Id, m_caster->GetMap()->GenerateLowGuid<HighGuid::Cast>()); @@ -2148,7 +2146,7 @@ void Spell::prepareDataForTriggerSystem() // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_hitMask) //========================================================================================== - m_procVictim = m_procAttacker = 0; + m_procVictim = m_procAttacker = PROC_FLAG_NONE; // Get data for type of attack and fill base info for trigger switch (m_spellInfo->DmgClass) { @@ -2225,8 +2223,8 @@ class ProcReflectDelayed : public BasicEvent if (!caster) return true; - uint32 const typeMaskActor = PROC_FLAG_NONE; - uint32 const typeMaskActionTarget = PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG; + ProcFlags const typeMaskActor = PROC_FLAG_NONE; + ProcFlags const typeMaskActionTarget = PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG; uint32 const spellTypeMask = PROC_SPELL_TYPE_DAMAGE | PROC_SPELL_TYPE_NO_DMG_HEAL; uint32 const spellPhaseMask = PROC_SPELL_PHASE_NONE; uint32 const hitMask = PROC_HIT_REFLECT; @@ -2597,8 +2595,8 @@ void Spell::TargetInfo::DoDamageAndTriggers(Spell* spell) if (caster) { // Fill base trigger info - uint32 procAttacker = spell->m_procAttacker; - uint32 procVictim = spell->m_procVictim; + ProcFlagsInit procAttacker = spell->m_procAttacker; + ProcFlagsInit procVictim = spell->m_procVictim; uint32 procSpellType = PROC_SPELL_TYPE_NONE; uint32 hitMask = PROC_HIT_NONE; @@ -3690,7 +3688,7 @@ void Spell::_cast(bool skipCheck) return; // Handle procs on cast - uint32 procAttacker = m_procAttacker; + ProcFlagsInit procAttacker = m_procAttacker; if (!procAttacker) { if (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC) @@ -3949,7 +3947,7 @@ void Spell::_handle_finish_phase() if (!m_originalCaster) return; - uint32 procAttacker = m_procAttacker; + ProcFlagsInit procAttacker = m_procAttacker; if (!procAttacker) { if (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC) diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index a2702ccad4b..d9d39f1096a 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -712,8 +712,8 @@ class TC_GAME_API Spell // ****************************************** // Spell trigger system // ****************************************** - uint32 m_procAttacker; // Attacker trigger flags - uint32 m_procVictim; // Victim trigger flags + ProcFlagsInit m_procAttacker; // Attacker trigger flags + ProcFlagsInit m_procVictim; // Victim trigger flags uint32 m_hitMask; void prepareDataForTriggerSystem(); diff --git a/src/server/game/Spells/SpellDefines.h b/src/server/game/Spells/SpellDefines.h index e9e683d36bc..f651339e1f8 100644 --- a/src/server/game/Spells/SpellDefines.h +++ b/src/server/game/Spells/SpellDefines.h @@ -19,6 +19,7 @@ #define TRINITY_SPELLDEFINES_H #include "Define.h" +#include "FlagsArray.h" #include "EnumFlag.h" #include "ObjectGuid.h" #include "Optional.h" @@ -34,6 +35,8 @@ class Spell; class Unit; class WorldObject; enum Difficulty : uint8; +enum ProcFlags : uint32; +enum ProcFlags2 : int32; namespace UF { @@ -484,4 +487,26 @@ struct SpellCastVisual operator WorldPackets::Spells::SpellCastVisual() const; }; +class ProcFlagsInit : public FlagsArray<int32, 2> +{ +public: + constexpr ProcFlagsInit(ProcFlags procFlags = {}, ProcFlags2 procFlags2 = {}) + { + _storage[0] = int32(procFlags); + _storage[1] = int32(procFlags2); + } + + constexpr ProcFlagsInit& operator|=(ProcFlags procFlags) + { + _storage[0] |= int32(procFlags); + return *this; + } + + constexpr ProcFlagsInit& operator|=(ProcFlags2 procFlags2) + { + _storage[1] |= int32(procFlags2); + return *this; + } +}; + #endif diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 82b67f9f851..e2d3bacd848 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1135,7 +1135,7 @@ SpellInfo::SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, S // SpellAuraOptionsEntry if (SpellAuraOptionsEntry const* _options = data.AuraOptions) { - ProcFlags = _options->ProcTypeMask[0]; + ProcFlags = _options->ProcTypeMask; ProcChance = _options->ProcChance; ProcCharges = _options->ProcCharges; ProcCooldown = _options->ProcCategoryRecovery; diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 9a73a1aec45..94b2d8dd0e7 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -382,7 +382,7 @@ class TC_GAME_API SpellInfo EnumFlag<SpellAuraInterruptFlags2> AuraInterruptFlags2 = SpellAuraInterruptFlags2::None; EnumFlag<SpellAuraInterruptFlags> ChannelInterruptFlags = SpellAuraInterruptFlags::None; EnumFlag<SpellAuraInterruptFlags2> ChannelInterruptFlags2 = SpellAuraInterruptFlags2::None; - uint32 ProcFlags = 0; + FlagsArray<int32, 2> ProcFlags; uint32 ProcChance = 0; uint32 ProcCharges = 0; uint32 ProcCooldown = 0; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index daa875d0fc2..64533be0a58 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1480,8 +1480,8 @@ void SpellMgr::LoadSpellProcs() // 0 1 2 3 4 5 6 QueryResult result = WorldDatabase.Query("SELECT SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, SpellFamilyMask3, " - // 7 8 9 10 11 12 13 14 15 16 - "ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, DisableEffectsMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc"); + // 7 8 9 10 11 12 13 14 15 16 17 + "ProcFlags, ProcFlags2, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, DisableEffectsMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc"); uint32 count = 0; if (result) @@ -1526,16 +1526,17 @@ void SpellMgr::LoadSpellProcs() baseProcEntry.SpellFamilyMask[1] = fields[4].GetUInt32(); baseProcEntry.SpellFamilyMask[2] = fields[5].GetUInt32(); baseProcEntry.SpellFamilyMask[3] = fields[6].GetUInt32(); - baseProcEntry.ProcFlags = fields[7].GetUInt32(); - baseProcEntry.SpellTypeMask = fields[8].GetUInt32(); - baseProcEntry.SpellPhaseMask = fields[9].GetUInt32(); - baseProcEntry.HitMask = fields[10].GetUInt32(); - baseProcEntry.AttributesMask = fields[11].GetUInt32(); - baseProcEntry.DisableEffectsMask = fields[12].GetUInt32(); - baseProcEntry.ProcsPerMinute = fields[13].GetFloat(); - baseProcEntry.Chance = fields[14].GetFloat(); - baseProcEntry.Cooldown = Milliseconds(fields[15].GetUInt32()); - baseProcEntry.Charges = fields[16].GetUInt8(); + baseProcEntry.ProcFlags[0] = fields[7].GetUInt32(); + baseProcEntry.ProcFlags[1] = fields[8].GetUInt32(); + baseProcEntry.SpellTypeMask = fields[9].GetUInt32(); + baseProcEntry.SpellPhaseMask = fields[10].GetUInt32(); + baseProcEntry.HitMask = fields[11].GetUInt32(); + baseProcEntry.AttributesMask = fields[12].GetUInt32(); + baseProcEntry.DisableEffectsMask = fields[13].GetUInt32(); + baseProcEntry.ProcsPerMinute = fields[14].GetFloat(); + baseProcEntry.Chance = fields[15].GetFloat(); + baseProcEntry.Cooldown = Milliseconds(fields[16].GetUInt32()); + baseProcEntry.Charges = fields[17].GetUInt8(); while (spellInfo) { @@ -1781,7 +1782,8 @@ void SpellMgr::LoadSpellProcs() { if (spellEffectInfo.IsAura()) { - TC_LOG_ERROR("sql.sql", "Spell Id %u has DBC ProcFlags %u, but it's of non-proc aura type, it probably needs an entry in `spell_proc` table to be handled correctly.", spellInfo.Id, spellInfo.ProcFlags); + TC_LOG_ERROR("sql.sql", "Spell Id %u has DBC ProcFlags 0x%X 0x%X, but it's of non-proc aura type, it probably needs an entry in `spell_proc` table to be handled correctly.", + spellInfo.Id, spellInfo.ProcFlags[0], spellInfo.ProcFlags[1]); break; } } @@ -2772,13 +2774,13 @@ void SpellMgr::LoadSpellInfoServerside() "ExcludeCasterAuraState, ExcludeTargetAuraState, CasterAuraSpell, TargetAuraSpell, ExcludeCasterAuraSpell, ExcludeTargetAuraSpell, CastingTimeIndex, " // 35 36 37 38 39 40 41 "RecoveryTime, CategoryRecoveryTime, StartRecoveryCategory, StartRecoveryTime, InterruptFlags, AuraInterruptFlags1, AuraInterruptFlags2, " - // 42 43 44 45 46 47 48 49 50 51 - "ChannelInterruptFlags1, ChannelInterruptFlags2, ProcFlags, ProcChance, ProcCharges, ProcCooldown, ProcBasePPM, MaxLevel, BaseLevel, SpellLevel, " - // 52 53 54 55 56 57 58 59 60 + // 42 43 44 45 46 47 48 49 50 51 52 + "ChannelInterruptFlags1, ChannelInterruptFlags2, ProcFlags, ProcFlags2, ProcChance, ProcCharges, ProcCooldown, ProcBasePPM, MaxLevel, BaseLevel, SpellLevel, " + // 35 54 55 56 57 58 59 60 61 "DurationIndex, RangeIndex, Speed, LaunchDelay, StackAmount, EquippedItemClass, EquippedItemSubClassMask, EquippedItemInventoryTypeMask, ContentTuningId, " - // 61 62 63 64 65 66 67 68 69 70 + // 62 63 64 65 66 67 68 69 70 71 "SpellName, ConeAngle, ConeWidth, MaxTargetLevel, MaxAffectedTargets, SpellFamilyName, SpellFamilyFlags1, SpellFamilyFlags2, SpellFamilyFlags3, SpellFamilyFlags4, " - // 71 72 73 74 75 + // 72 73 74 75 76 "DmgClass, PreventionType, AreaGroupId, SchoolMask, ChargeCategoryId FROM serverside_spell"); if (spellsResult) { @@ -2796,7 +2798,7 @@ void SpellMgr::LoadSpellInfoServerside() continue; } - mServersideSpellNames.emplace_back(spellId, fields[61].GetString()); + mServersideSpellNames.emplace_back(spellId, fields[62].GetString()); SpellInfo& spellInfo = const_cast<SpellInfo&>(*mSpellInfoMap.emplace(&mServersideSpellNames.back().Name, difficulty, spellEffects[{ spellId, difficulty }]).first); spellInfo.CategoryId = fields[2].GetUInt32(); @@ -2841,34 +2843,35 @@ void SpellMgr::LoadSpellInfoServerside() spellInfo.AuraInterruptFlags2 = SpellAuraInterruptFlags2(fields[41].GetUInt32()); spellInfo.ChannelInterruptFlags = SpellAuraInterruptFlags(fields[42].GetUInt32()); spellInfo.ChannelInterruptFlags2 = SpellAuraInterruptFlags2(fields[43].GetUInt32()); - spellInfo.ProcFlags = fields[44].GetUInt32(); - spellInfo.ProcChance = fields[45].GetUInt32(); - spellInfo.ProcCharges = fields[46].GetUInt32(); - spellInfo.ProcCooldown = fields[47].GetUInt32(); - spellInfo.ProcBasePPM = fields[48].GetFloat(); - spellInfo.MaxLevel = fields[49].GetUInt32(); - spellInfo.BaseLevel = fields[50].GetUInt32(); - spellInfo.SpellLevel = fields[51].GetUInt32(); - spellInfo.DurationEntry = sSpellDurationStore.LookupEntry(fields[52].GetUInt32()); - spellInfo.RangeEntry = sSpellRangeStore.LookupEntry(fields[53].GetUInt32()); - spellInfo.Speed = fields[54].GetFloat(); - spellInfo.LaunchDelay = fields[55].GetFloat(); - spellInfo.StackAmount = fields[56].GetUInt32(); - spellInfo.EquippedItemClass = fields[57].GetInt32(); - spellInfo.EquippedItemSubClassMask = fields[58].GetInt32(); - spellInfo.EquippedItemInventoryTypeMask = fields[59].GetInt32(); - spellInfo.ContentTuningId = fields[60].GetUInt32(); - spellInfo.ConeAngle = fields[62].GetFloat(); - spellInfo.Width = fields[63].GetFloat(); - spellInfo.MaxTargetLevel = fields[64].GetUInt32(); - spellInfo.MaxAffectedTargets = fields[65].GetUInt32(); - spellInfo.SpellFamilyName = fields[66].GetUInt32(); - spellInfo.SpellFamilyFlags = flag128(fields[67].GetUInt32(), fields[68].GetUInt32(), fields[69].GetUInt32(), fields[70].GetUInt32()); - spellInfo.DmgClass = fields[71].GetUInt32(); - spellInfo.PreventionType = fields[72].GetUInt32(); - spellInfo.RequiredAreasID = fields[73].GetInt32(); - spellInfo.SchoolMask = fields[74].GetUInt32(); - spellInfo.ChargeCategoryId = fields[75].GetUInt32(); + spellInfo.ProcFlags[0] = fields[44].GetUInt32(); + spellInfo.ProcFlags[1] = fields[45].GetUInt32(); + spellInfo.ProcChance = fields[46].GetUInt32(); + spellInfo.ProcCharges = fields[47].GetUInt32(); + spellInfo.ProcCooldown = fields[48].GetUInt32(); + spellInfo.ProcBasePPM = fields[49].GetFloat(); + spellInfo.MaxLevel = fields[50].GetUInt32(); + spellInfo.BaseLevel = fields[51].GetUInt32(); + spellInfo.SpellLevel = fields[52].GetUInt32(); + spellInfo.DurationEntry = sSpellDurationStore.LookupEntry(fields[53].GetUInt32()); + spellInfo.RangeEntry = sSpellRangeStore.LookupEntry(fields[54].GetUInt32()); + spellInfo.Speed = fields[55].GetFloat(); + spellInfo.LaunchDelay = fields[56].GetFloat(); + spellInfo.StackAmount = fields[57].GetUInt32(); + spellInfo.EquippedItemClass = fields[58].GetInt32(); + spellInfo.EquippedItemSubClassMask = fields[59].GetInt32(); + spellInfo.EquippedItemInventoryTypeMask = fields[60].GetInt32(); + spellInfo.ContentTuningId = fields[61].GetUInt32(); + spellInfo.ConeAngle = fields[63].GetFloat(); + spellInfo.Width = fields[64].GetFloat(); + spellInfo.MaxTargetLevel = fields[65].GetUInt32(); + spellInfo.MaxAffectedTargets = fields[66].GetUInt32(); + spellInfo.SpellFamilyName = fields[67].GetUInt32(); + spellInfo.SpellFamilyFlags = flag128(fields[68].GetUInt32(), fields[69].GetUInt32(), fields[70].GetUInt32(), fields[71].GetUInt32()); + spellInfo.DmgClass = fields[72].GetUInt32(); + spellInfo.PreventionType = fields[73].GetUInt32(); + spellInfo.RequiredAreasID = fields[74].GetInt32(); + spellInfo.SchoolMask = fields[75].GetUInt32(); + spellInfo.ChargeCategoryId = fields[76].GetUInt32(); } while (spellsResult->NextRow()); } @@ -4696,7 +4699,7 @@ void SpellMgr::LoadSpellInfoCorrections() // disable proc for magnet auras, they're handled differently if (spellInfo->HasAura(SPELL_AURA_SPELL_MAGNET)) - spellInfo->ProcFlags = 0; + spellInfo->ProcFlags = std::array<int32, 2>{}; // due to the way spell system works, unit would change orientation in Spell::_cast if (spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE)) diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index e98d0070985..e096ac22d87 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -131,69 +131,69 @@ enum SpellLinkedType // Spell proc event related declarations (accessed using SpellMgr functions) -enum ProcFlags +enum ProcFlags : uint32 { - PROC_FLAG_NONE = 0x00000000, + PROC_FLAG_NONE = 0x00000000, - PROC_FLAG_KILLED = 0x00000001, // 00 Killed by agressor - not sure about this flag - PROC_FLAG_KILL = 0x00000002, // 01 Kill target (in most cases need XP/Honor reward) + PROC_FLAG_KILLED = 0x00000001, // 00 Killed by agressor - not sure about this flag + PROC_FLAG_KILL = 0x00000002, // 01 Kill target (in most cases need XP/Honor reward) - PROC_FLAG_DONE_MELEE_AUTO_ATTACK = 0x00000004, // 02 Done melee auto attack - PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK = 0x00000008, // 03 Taken melee auto attack + PROC_FLAG_DONE_MELEE_AUTO_ATTACK = 0x00000004, // 02 Done melee auto attack + PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK = 0x00000008, // 03 Taken melee auto attack - PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS = 0x00000010, // 04 Done attack by Spell that has dmg class melee - PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS = 0x00000020, // 05 Taken attack by Spell that has dmg class melee + PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS = 0x00000010, // 04 Done attack by Spell that has dmg class melee + PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS = 0x00000020, // 05 Taken attack by Spell that has dmg class melee - PROC_FLAG_DONE_RANGED_AUTO_ATTACK = 0x00000040, // 06 Done ranged auto attack - PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK = 0x00000080, // 07 Taken ranged auto attack + PROC_FLAG_DONE_RANGED_AUTO_ATTACK = 0x00000040, // 06 Done ranged auto attack + PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK = 0x00000080, // 07 Taken ranged auto attack - PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS = 0x00000100, // 08 Done attack by Spell that has dmg class ranged - PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS = 0x00000200, // 09 Taken attack by Spell that has dmg class ranged + PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS = 0x00000100, // 08 Done attack by Spell that has dmg class ranged + PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS = 0x00000200, // 09 Taken attack by Spell that has dmg class ranged - PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS = 0x00000400, // 10 Done positive spell that has dmg class none - PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS = 0x00000800, // 11 Taken positive spell that has dmg class none + PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS = 0x00000400, // 10 Done positive spell that has dmg class none + PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS = 0x00000800, // 11 Taken positive spell that has dmg class none - PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG = 0x00001000, // 12 Done negative spell that has dmg class none - PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG = 0x00002000, // 13 Taken negative spell that has dmg class none + PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG = 0x00001000, // 12 Done negative spell that has dmg class none + PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG = 0x00002000, // 13 Taken negative spell that has dmg class none - PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS = 0x00004000, // 14 Done positive spell that has dmg class magic - PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS = 0x00008000, // 15 Taken positive spell that has dmg class magic + PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS = 0x00004000, // 14 Done positive spell that has dmg class magic + PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS = 0x00008000, // 15 Taken positive spell that has dmg class magic - PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG = 0x00010000, // 16 Done negative spell that has dmg class magic - PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG = 0x00020000, // 17 Taken negative spell that has dmg class magic + PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG = 0x00010000, // 16 Done negative spell that has dmg class magic + PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG = 0x00020000, // 17 Taken negative spell that has dmg class magic - PROC_FLAG_DONE_PERIODIC = 0x00040000, // 18 Successful do periodic (damage / healing) - PROC_FLAG_TAKEN_PERIODIC = 0x00080000, // 19 Taken spell periodic (damage / healing) + PROC_FLAG_DONE_PERIODIC = 0x00040000, // 18 Successful do periodic (damage / healing) + PROC_FLAG_TAKEN_PERIODIC = 0x00080000, // 19 Taken spell periodic (damage / healing) - PROC_FLAG_TAKEN_DAMAGE = 0x00100000, // 20 Taken any damage - PROC_FLAG_DONE_TRAP_ACTIVATION = 0x00200000, // 21 On trap activation (possibly needs name change to ON_GAMEOBJECT_CAST or USE) + PROC_FLAG_TAKEN_DAMAGE = 0x00100000, // 20 Taken any damage + PROC_FLAG_DONE_TRAP_ACTIVATION = 0x00200000, // 21 On trap activation (possibly needs name change to ON_GAMEOBJECT_CAST or USE) - PROC_FLAG_DONE_MAINHAND_ATTACK = 0x00400000, // 22 Done main-hand melee attacks (spell and autoattack) - PROC_FLAG_DONE_OFFHAND_ATTACK = 0x00800000, // 23 Done off-hand melee attacks (spell and autoattack) + PROC_FLAG_DONE_MAINHAND_ATTACK = 0x00400000, // 22 Done main-hand melee attacks (spell and autoattack) + PROC_FLAG_DONE_OFFHAND_ATTACK = 0x00800000, // 23 Done off-hand melee attacks (spell and autoattack) - PROC_FLAG_DEATH = 0x01000000, // 24 Died in any way - PROC_FLAG_JUMP = 0x02000000, // 25 Jumped + PROC_FLAG_DEATH = 0x01000000, // 24 Died in any way + PROC_FLAG_JUMP = 0x02000000, // 25 Jumped - PROC_FLAG_ENTER_COMBAT = 0x08000000, // 27 Entered combat - PROC_FLAG_ENCOUNTER_START = 0x10000000, // 28 Encounter started + PROC_FLAG_ENTER_COMBAT = 0x08000000, // 27 Entered combat + PROC_FLAG_ENCOUNTER_START = 0x10000000, // 28 Encounter started - PROC_FLAG_CAST_ENDED = 0x20000000, // 29 Cast Ended - PROC_FLAG_LOOTED = 0x40000000, // 30 Looted (took from loot, not opened loot window) + PROC_FLAG_CAST_ENDED = 0x20000000, // 29 Cast Ended + PROC_FLAG_LOOTED = 0x40000000, // 30 Looted (took from loot, not opened loot window) - PROC_FLAG_TAKE_HELPFUL_PERIODIC = 0x80000000, // 31 Take Helpful Periodic + PROC_FLAG_TAKE_HELPFUL_PERIODIC = 0x80000000, // 31 Take Helpful Periodic // flag masks - AUTO_ATTACK_PROC_FLAG_MASK = PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK + AUTO_ATTACK_PROC_FLAG_MASK = PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK | PROC_FLAG_DONE_RANGED_AUTO_ATTACK | PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK, - MELEE_PROC_FLAG_MASK = PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK + MELEE_PROC_FLAG_MASK = PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK | PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS | PROC_FLAG_DONE_MAINHAND_ATTACK | PROC_FLAG_DONE_OFFHAND_ATTACK, - RANGED_PROC_FLAG_MASK = PROC_FLAG_DONE_RANGED_AUTO_ATTACK | PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK + RANGED_PROC_FLAG_MASK = PROC_FLAG_DONE_RANGED_AUTO_ATTACK | PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS, - SPELL_PROC_FLAG_MASK = PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS + SPELL_PROC_FLAG_MASK = PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS | PROC_FLAG_DONE_RANGED_AUTO_ATTACK | PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS @@ -203,22 +203,34 @@ enum ProcFlags | PROC_FLAG_DONE_PERIODIC | PROC_FLAG_TAKEN_PERIODIC | PROC_FLAG_DONE_TRAP_ACTIVATION, - DONE_HIT_PROC_FLAG_MASK = PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_DONE_RANGED_AUTO_ATTACK - | PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS - | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG - | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG - | PROC_FLAG_DONE_PERIODIC | PROC_FLAG_DONE_TRAP_ACTIVATION - | PROC_FLAG_DONE_MAINHAND_ATTACK | PROC_FLAG_DONE_OFFHAND_ATTACK, + DONE_HIT_PROC_FLAG_MASK = PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_DONE_RANGED_AUTO_ATTACK + | PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS + | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG + | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG + | PROC_FLAG_DONE_PERIODIC | PROC_FLAG_DONE_TRAP_ACTIVATION + | PROC_FLAG_DONE_MAINHAND_ATTACK | PROC_FLAG_DONE_OFFHAND_ATTACK, + + TAKEN_HIT_PROC_FLAG_MASK = PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK | PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK + | PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS + | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG + | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG + | PROC_FLAG_TAKEN_PERIODIC | PROC_FLAG_TAKEN_DAMAGE, + + REQ_SPELL_PHASE_PROC_FLAG_MASK = SPELL_PROC_FLAG_MASK & DONE_HIT_PROC_FLAG_MASK +}; - TAKEN_HIT_PROC_FLAG_MASK = PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK | PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK - | PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS - | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG - | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG - | PROC_FLAG_TAKEN_PERIODIC | PROC_FLAG_TAKEN_DAMAGE, +DEFINE_ENUM_FLAG(ProcFlags); - REQ_SPELL_PHASE_PROC_FLAG_MASK = SPELL_PROC_FLAG_MASK & DONE_HIT_PROC_FLAG_MASK +enum ProcFlags2 : int32 +{ + PROC_FLAG_2_NONE = 0x00000000, + PROC_FLAG_2_TARGET_DIES = 0x00000001, + PROC_FLAG_2_KNOCKBACK = 0x00000002, + PROC_FLAG_2_CAST_SUCCESSFUL = 0x00000004 }; +DEFINE_ENUM_FLAG(ProcFlags2); + #define MELEE_BASED_TRIGGER_MASK (PROC_FLAG_DONE_MELEE_AUTO_ATTACK | \ PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK | \ PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS | \ @@ -288,19 +300,19 @@ enum ProcAttributes struct SpellProcEntry { - uint32 SchoolMask; // if nonzero - bitmask for matching proc condition based on spell's school - uint32 SpellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyName - flag128 SpellFamilyMask; // if nonzero - bitmask for matching proc condition based on candidate spell's SpellFamilyFlags - uint32 ProcFlags; // if nonzero - owerwrite procFlags field for given Spell.dbc entry, bitmask for matching proc condition, see enum ProcFlags - uint32 SpellTypeMask; // if nonzero - bitmask for matching proc condition based on candidate spell's damage/heal effects, see enum ProcFlagsSpellType - uint32 SpellPhaseMask; // if nonzero - bitmask for matching phase of a spellcast on which proc occurs, see enum ProcFlagsSpellPhase - uint32 HitMask; // if nonzero - bitmask for matching proc condition based on hit result, see enum ProcFlagsHit - uint32 AttributesMask; // bitmask, see ProcAttributes - uint32 DisableEffectsMask;// bitmask - float ProcsPerMinute; // if nonzero - chance to proc is equal to value * aura caster's weapon speed / 60 - float Chance; // if nonzero - owerwrite procChance field for given Spell.dbc entry, defines chance of proc to occur, not used if ProcsPerMinute set - Milliseconds Cooldown; // if nonzero - cooldown in secs for aura proc, applied to aura - uint32 Charges; // if nonzero - owerwrite procCharges field for given Spell.dbc entry, defines how many times proc can occur before aura remove, 0 - infinite + uint32 SchoolMask; // if nonzero - bitmask for matching proc condition based on spell's school + uint32 SpellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyName + flag128 SpellFamilyMask; // if nonzero - bitmask for matching proc condition based on candidate spell's SpellFamilyFlags + FlagsArray<int32, 2> ProcFlags; // if nonzero - owerwrite procFlags field for given Spell.dbc entry, bitmask for matching proc condition, see enum ProcFlags + uint32 SpellTypeMask; // if nonzero - bitmask for matching proc condition based on candidate spell's damage/heal effects, see enum ProcFlagsSpellType + uint32 SpellPhaseMask; // if nonzero - bitmask for matching phase of a spellcast on which proc occurs, see enum ProcFlagsSpellPhase + uint32 HitMask; // if nonzero - bitmask for matching proc condition based on hit result, see enum ProcFlagsHit + uint32 AttributesMask; // bitmask, see ProcAttributes + uint32 DisableEffectsMask; // bitmask + float ProcsPerMinute; // if nonzero - chance to proc is equal to value * aura caster's weapon speed / 60 + float Chance; // if nonzero - owerwrite procChance field for given Spell.dbc entry, defines chance of proc to occur, not used if ProcsPerMinute set + Milliseconds Cooldown; // if nonzero - cooldown in secs for aura proc, applied to aura + uint32 Charges; // if nonzero - owerwrite procCharges field for given Spell.dbc entry, defines how many times proc can occur before aura remove, 0 - infinite }; enum EnchantProcAttributes |