From f6b8840e3458daa51b4606438f71164ddff7dd05 Mon Sep 17 00:00:00 2001 From: Angelo Venturini Date: Thu, 13 Oct 2022 14:04:55 -0300 Subject: [PATCH] refactor: rename spell_proc fields (#13334) Co-authored-by: Shauren --- .../rev_1665085095263613800.sql | 18 +++ src/server/game/Spells/Auras/SpellAuras.cpp | 14 +- src/server/game/Spells/Auras/SpellAuras.h | 2 +- src/server/game/Spells/SpellMgr.cpp | 128 +++++++++--------- src/server/game/Spells/SpellMgr.h | 26 ++-- 5 files changed, 100 insertions(+), 88 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1665085095263613800.sql diff --git a/data/sql/updates/pending_db_world/rev_1665085095263613800.sql b/data/sql/updates/pending_db_world/rev_1665085095263613800.sql new file mode 100644 index 000000000..71737bdfc --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1665085095263613800.sql @@ -0,0 +1,18 @@ +-- +ALTER TABLE `spell_proc` + CHANGE `spellId` `SpellId` INT(11) NOT NULL DEFAULT 0 FIRST, + CHANGE `schoolMask` `SchoolMask` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `SpellId`, + CHANGE `spellFamilyName` `SpellFamilyName` SMALLINT(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `SchoolMask`, + CHANGE `spellFamilyMask0` `SpellFamilyMask0` INT(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `SpellFamilyName`, + CHANGE `spellFamilyMask1` `SpellFamilyMask1` INT(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `SpellFamilyMask0`, + CHANGE `spellFamilyMask2` `SpellFamilyMask2` INT(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `SpellFamilyMask1`, + CHANGE `typeMask` `ProcFlags` INT(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `SpellFamilyMask2`, + CHANGE `spellTypeMask` `SpellTypeMask` INT(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `ProcFlags`, + CHANGE `spellPhaseMask` `SpellPhaseMask` INT(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `SpellTypeMask`, + CHANGE `hitMask` `HitMask` INT(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `SpellPhaseMask`, + CHANGE `attributesMask` `AttributesMask` INT(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `HitMask`, + CHANGE `ratePerMinute` `ProcsPerMinute` FLOAT NOT NULL DEFAULT 0 AFTER `AttributesMask`, + CHANGE `chance` `Chance` FLOAT NOT NULL DEFAULT 0 AFTER `ProcsPerMinute`, + CHANGE `cooldown` `Cooldown` INT(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `Chance`, + CHANGE `charges` `Charges` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `Cooldown`; + \ No newline at end of file diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 8d2add5c3..e13872796 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -976,7 +976,7 @@ uint8 Aura::CalcMaxCharges(Unit* caster) const { uint32 maxProcCharges = m_spellInfo->ProcCharges; if (SpellProcEntry const* procEntry = sSpellMgr->GetSpellProcEntry(GetId())) - maxProcCharges = procEntry->charges; + maxProcCharges = procEntry->Charges; if (caster) if (Player* modOwner = caster->GetSpellModOwner()) @@ -2202,9 +2202,9 @@ bool Aura::IsProcOnCooldown() const return false; } -void Aura::AddProcCooldown(uint32 /*msec*/) +void Aura::AddProcCooldown(Milliseconds /*msec*/) { - //m_procCooldown = GameTime::GetGameTime().count() + msec; + //m_procCooldown = std:chrono::steady_clock::now() + msec; } void Aura::PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo) @@ -2225,7 +2225,7 @@ void Aura::PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInf ASSERT(procEntry); // cooldowns should be added to the whole aura (see 51698 area aura) - AddProcCooldown(procEntry->cooldown); + AddProcCooldown(procEntry->Cooldown); } bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo) const @@ -2314,16 +2314,16 @@ bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventI float Aura::CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) const { - float chance = procEntry.chance; + float chance = procEntry.Chance; // calculate chances depending on unit with caster's data // so talents modifying chances and judgements will have properly calculated proc chance if (Unit* caster = GetCaster()) { // calculate ppm chance if present and we're using weapon - if (eventInfo.GetDamageInfo() && procEntry.ratePerMinute != 0) + if (eventInfo.GetDamageInfo() && procEntry.ProcsPerMinute != 0) { uint32 WeaponSpeed = caster->GetAttackTime(eventInfo.GetDamageInfo()->GetAttackType()); - chance = caster->GetPPMProcChance(WeaponSpeed, procEntry.ratePerMinute, GetSpellInfo()); + chance = caster->GetPPMProcChance(WeaponSpeed, procEntry.ProcsPerMinute, GetSpellInfo()); } // apply chance modifer aura, applies also to ppm chance (see improved judgement of light spell) if (Player* modOwner = caster->GetSpellModOwner()) diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index d98f391dc..172be1314 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -196,7 +196,7 @@ public: // and some dependant problems fixed before it can replace old proc system (for example cooldown handling) // currently proc system functionality is implemented in Unit::ProcDamageAndSpell bool IsProcOnCooldown() const; - void AddProcCooldown(uint32 msec); + void AddProcCooldown(Milliseconds msec); bool IsUsingCharges() const { return m_isUsingCharges; } void SetUsingCharges(bool val) { m_isUsingCharges = val; } void PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 8d9524bf5..eb474c22c 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -898,11 +898,11 @@ SpellProcEntry const* SpellMgr::GetSpellProcEntry(uint32 spellId) const bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) const { // proc type doesn't match - if (!(eventInfo.GetTypeMask() & procEntry.typeMask)) + if (!(eventInfo.GetTypeMask() & procEntry.ProcFlags)) return false; // check XP or honor target requirement - if (procEntry.attributesMask & PROC_ATTR_REQ_EXP_OR_HONOR) + if (procEntry.AttributesMask & PROC_ATTR_REQ_EXP_OR_HONOR) if (Player* actor = eventInfo.GetActor()->ToPlayer()) if (eventInfo.GetActionTarget() && !actor->isHonorOrXPTarget(eventInfo.GetActionTarget())) return false; @@ -912,37 +912,37 @@ bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcE return true; // check school mask (if set) for other trigger types - if (procEntry.schoolMask && !(eventInfo.GetSchoolMask() & procEntry.schoolMask)) + if (procEntry.SchoolMask && !(eventInfo.GetSchoolMask() & procEntry.SchoolMask)) return false; // check spell family name/flags (if set) for spells if (eventInfo.GetTypeMask() & (PERIODIC_PROC_FLAG_MASK | SPELL_PROC_FLAG_MASK | PROC_FLAG_DONE_TRAP_ACTIVATION)) { - if (procEntry.spellFamilyName && (procEntry.spellFamilyName != eventInfo.GetSpellInfo()->SpellFamilyName)) + if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName != eventInfo.GetSpellInfo()->SpellFamilyName)) return false; - if (procEntry.spellFamilyMask && !(procEntry.spellFamilyMask & eventInfo.GetSpellInfo()->SpellFamilyFlags)) + if (procEntry.SpellFamilyMask && !(procEntry.SpellFamilyMask & eventInfo.GetSpellInfo()->SpellFamilyFlags)) return false; } // check spell type mask (if set) if (eventInfo.GetTypeMask() & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK)) { - if (procEntry.spellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.spellTypeMask)) + if (procEntry.SpellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.SpellTypeMask)) return false; } // check spell phase mask if (eventInfo.GetTypeMask() & REQ_SPELL_PHASE_PROC_FLAG_MASK) { - if (!(eventInfo.GetSpellPhaseMask() & procEntry.spellPhaseMask)) + if (!(eventInfo.GetSpellPhaseMask() & procEntry.SpellPhaseMask)) return false; } // check hit mask (on taken hit or on done hit, but not on spell cast phase) if ((eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) || ((eventInfo.GetTypeMask() & DONE_HIT_PROC_FLAG_MASK) && !(eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST))) { - uint32 hitMask = procEntry.hitMask; + uint32 hitMask = procEntry.HitMask; // get default values if hit mask not set if (!hitMask) { @@ -1833,8 +1833,8 @@ void SpellMgr::LoadSpellProcs() mSpellProcMap.clear(); // need for reload case - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 - QueryResult result = WorldDatabase.Query("SELECT spellId, schoolMask, spellFamilyName, spellFamilyMask0, spellFamilyMask1, spellFamilyMask2, typeMask, spellTypeMask, spellPhaseMask, hitMask, attributesMask, ratePerMinute, chance, cooldown, charges FROM spell_proc"); + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + QueryResult result = WorldDatabase.Query("SELECT SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc"); if (!result) { LOG_WARN("server.loading", ">> Loaded 0 Spell Proc Conditions And Data. DB table `spell_proc` Is Empty."); @@ -1874,21 +1874,20 @@ void SpellMgr::LoadSpellProcs() SpellProcEntry baseProcEntry; - baseProcEntry.schoolMask = fields[1].Get(); - baseProcEntry.spellFamilyName = fields[2].Get(); - baseProcEntry.spellFamilyMask[0] = fields[3].Get(); - baseProcEntry.spellFamilyMask[1] = fields[4].Get(); - baseProcEntry.spellFamilyMask[2] = fields[5].Get(); - baseProcEntry.typeMask = fields[6].Get(); - baseProcEntry.spellTypeMask = fields[7].Get(); - baseProcEntry.spellPhaseMask = fields[8].Get(); - baseProcEntry.hitMask = fields[9].Get(); - baseProcEntry.attributesMask = fields[10].Get(); - baseProcEntry.ratePerMinute = fields[11].Get(); - baseProcEntry.chance = fields[12].Get(); - float cooldown = fields[13].Get(); - baseProcEntry.cooldown = uint32(cooldown); - baseProcEntry.charges = fields[14].Get(); + baseProcEntry.SchoolMask = fields[1].Get(); + baseProcEntry.SpellFamilyName = fields[2].Get(); + baseProcEntry.SpellFamilyMask[0] = fields[3].Get(); + baseProcEntry.SpellFamilyMask[1] = fields[4].Get(); + baseProcEntry.SpellFamilyMask[2] = fields[5].Get(); + baseProcEntry.ProcFlags = fields[6].Get(); + baseProcEntry.SpellTypeMask = fields[7].Get(); + baseProcEntry.SpellPhaseMask = fields[8].Get(); + baseProcEntry.HitMask = fields[9].Get(); + baseProcEntry.AttributesMask = fields[10].Get(); + baseProcEntry.ProcsPerMinute = fields[11].Get(); + baseProcEntry.Chance = fields[12].Get(); + baseProcEntry.Cooldown = Milliseconds(fields[13].Get()); + baseProcEntry.Charges = fields[14].Get(); while (spellInfo) { @@ -1900,56 +1899,51 @@ void SpellMgr::LoadSpellProcs() SpellProcEntry procEntry = SpellProcEntry(baseProcEntry); // take defaults from dbcs - if (!procEntry.typeMask) - procEntry.typeMask = spellInfo->ProcFlags; - if (!procEntry.charges) - procEntry.charges = spellInfo->ProcCharges; - if (!procEntry.chance && !procEntry.ratePerMinute) - procEntry.chance = float(spellInfo->ProcChance); + if (!procEntry.ProcFlags) + procEntry.ProcFlags = spellInfo->ProcFlags; + if (!procEntry.Charges) + procEntry.Charges = spellInfo->ProcCharges; + if (!procEntry.Chance && !procEntry.ProcsPerMinute) + procEntry.Chance = float(spellInfo->ProcChance); // validate data - if (procEntry.schoolMask & ~SPELL_SCHOOL_MASK_ALL) - LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has wrong `schoolMask` set: {}", spellId, procEntry.schoolMask); - if (procEntry.spellFamilyName && (procEntry.spellFamilyName < 3 || procEntry.spellFamilyName > 17 || procEntry.spellFamilyName == 14 || procEntry.spellFamilyName == 16)) - LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has wrong `spellFamilyName` set: {}", spellId, procEntry.spellFamilyName); - if (procEntry.chance < 0) + if (procEntry.SchoolMask & ~SPELL_SCHOOL_MASK_ALL) + LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SchoolMask` set: {}", spellId, procEntry.SchoolMask); + if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName < 3 || procEntry.SpellFamilyName > 17 || procEntry.SpellFamilyName == 14 || procEntry.SpellFamilyName == 16)) + LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellFamilyName` set: {}", spellId, procEntry.SpellFamilyName); + if (procEntry.Chance < 0) { - LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has negative value in `chance` field", spellId); - procEntry.chance = 0; + LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `Chance` field", spellId); + procEntry.Chance = 0; } - if (procEntry.ratePerMinute < 0) + if (procEntry.ProcsPerMinute < 0) { - LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has negative value in `ratePerMinute` field", spellId); - procEntry.ratePerMinute = 0; + LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `ProcsPerMinute` field", spellId); + procEntry.ProcsPerMinute = 0; } - if (cooldown < 0) + if (procEntry.Chance == 0 && procEntry.ProcsPerMinute == 0) + LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `Chance` and `ProcsPerMinute` values defined, proc will not be triggered", spellId); + if (procEntry.Charges > 99) { - LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has negative value in `cooldown` field", spellId); - procEntry.cooldown = 0; + LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has too big value in `Charges` field", spellId); + procEntry.Charges = 99; } - if (procEntry.chance == 0 && procEntry.ratePerMinute == 0) - LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} doesn't have `chance` and `ratePerMinute` values defined, proc will not be triggered", spellId); - if (procEntry.charges > 99) - { - LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has too big value in `charges` field", spellId); - procEntry.charges = 99; - } - if (!procEntry.typeMask) - LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} doesn't have `typeMask` value defined, proc will not be triggered", spellId); - if (procEntry.spellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL) - LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has wrong `spellTypeMask` set: {}", spellId, procEntry.spellTypeMask); - if (procEntry.spellTypeMask && !(procEntry.typeMask & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK))) - LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has `spellTypeMask` value defined, but it won't be used for defined `typeMask` value", spellId); - if (!procEntry.spellPhaseMask && procEntry.typeMask & REQ_SPELL_PHASE_PROC_FLAG_MASK) - LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} doesn't have `spellPhaseMask` value defined, but it's required for defined `typeMask` value, proc will not be triggered", spellId); - if (procEntry.spellPhaseMask & ~PROC_SPELL_PHASE_MASK_ALL) - LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has wrong `spellPhaseMask` set: {}", spellId, procEntry.spellPhaseMask); - if (procEntry.spellPhaseMask && !(procEntry.typeMask & REQ_SPELL_PHASE_PROC_FLAG_MASK)) - LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has `spellPhaseMask` value defined, but it won't be used for defined `typeMask` value", spellId); - if (procEntry.hitMask & ~PROC_HIT_MASK_ALL) - LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has wrong `hitMask` set: {}", spellId, procEntry.hitMask); - if (procEntry.hitMask && !(procEntry.typeMask & TAKEN_HIT_PROC_FLAG_MASK || (procEntry.typeMask & DONE_HIT_PROC_FLAG_MASK && (!procEntry.spellPhaseMask || procEntry.spellPhaseMask & (PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH))))) - LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has `hitMask` value defined, but it won't be used for defined `typeMask` and `spellPhaseMask` values", spellId); + if (!procEntry.ProcFlags) + LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `ProcFlags` value defined, proc will not be triggered", spellId); + if (procEntry.SpellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL) + LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellTypeMask` set: {}", spellId, procEntry.SpellTypeMask); + if (procEntry.SpellTypeMask && !(procEntry.ProcFlags & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK))) + LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has `SpellTypeMask` value defined, but it won't be used for defined `ProcFlags` value", spellId); + if (!procEntry.SpellPhaseMask && procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK) + LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `SpellPhaseMask` value defined, but it's required for defined `ProcFlags` value, proc will not be triggered", spellId); + if (procEntry.SpellPhaseMask & ~PROC_SPELL_PHASE_MASK_ALL) + LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellPhaseMask` set: {}", spellId, procEntry.SpellPhaseMask); + if (procEntry.SpellPhaseMask && !(procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK)) + LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has `SpellPhaseMask` value defined, but it won't be used for defined `ProcFlags` value", spellId); + if (procEntry.HitMask & ~PROC_HIT_MASK_ALL) + LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `HitMask` set: {}", spellId, procEntry.HitMask); + if (procEntry.HitMask && !(procEntry.ProcFlags & TAKEN_HIT_PROC_FLAG_MASK || (procEntry.ProcFlags & DONE_HIT_PROC_FLAG_MASK && (!procEntry.SpellPhaseMask || procEntry.SpellPhaseMask & (PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH))))) + LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has `HitMask` value defined, but it won't be used for defined `ProcFlags` and `SpellPhaseMask` values", spellId); mSpellProcMap[spellInfo->Id] = procEntry; diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index d02342f11..aa548a4d5 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -263,7 +263,7 @@ enum ProcFlagsHit PROC_HIT_REFLECT = 0x0000800, PROC_HIT_INTERRUPT = 0x0001000, // (not used atm) PROC_HIT_FULL_BLOCK = 0x0002000, - PROC_HIT_MASK_ALL = 0x2FFF, + PROC_HIT_MASK_ALL = 0x0002FFF, }; enum ProcAttributes @@ -288,18 +288,18 @@ typedef std::unordered_map SpellProcEventMap; 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 - flag96 spellFamilyMask; // if nonzero - bitmask for matching proc condition based on candidate spell's SpellFamilyFlags - uint32 typeMask; // 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 - float ratePerMinute; // 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 perMinuteRate set - uint32 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 + flag96 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 + 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 }; typedef std::unordered_map SpellProcMap;