diff options
-rw-r--r-- | sql/updates/world/3.3.5/2016_05_11_01_world.sql | 16 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.cpp | 10 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 130 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.h | 26 |
4 files changed, 95 insertions, 87 deletions
diff --git a/sql/updates/world/3.3.5/2016_05_11_01_world.sql b/sql/updates/world/3.3.5/2016_05_11_01_world.sql new file mode 100644 index 00000000000..4bd9598bb9b --- /dev/null +++ b/sql/updates/world/3.3.5/2016_05_11_01_world.sql @@ -0,0 +1,16 @@ +ALTER TABLE `spell_proc` + CHANCE `spellId` `SpellId` int(11) NOT NULL DEFAULT 0 FIRST, + CHANCE `schoolMask` `SchoolMask` tinyint(3) unsigned NOT NULL DEFAULT 0 AFTER `SpellId`, + CHANCE `spellFamilyName` `SpellFamilyName` smallint(5) unsigned NOT NULL DEFAULT 0 AFTER `SchoolMask`, + CHANCE `spellFamilyMask0` `SpellFamilyMask0` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellFamilyName`, + CHANCE `spellFamilyMask1` `SpellFamilyMask1` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellFamilyMask0`, + CHANCE `spellFamilyMask2` `SpellFamilyMask2` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellFamilyMask1`, + CHANCE `typeMask` `ProcFlags` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellFamilyMask2`, + CHANCE `spellTypeMask` `SpellTypeMask` int(10) unsigned NOT NULL DEFAULT 0 AFTER `ProcFlags`, + CHANCE `spellPhaseMask` `SpellPhaseMask` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellTypeMask`, + CHANCE `hitMask` `HitMask` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellPhaseMask`, + CHANCE `attributesMask` `AttributesMask` int(10) unsigned NOT NULL DEFAULT 0 AFTER `HitMask`, + CHANCE `ratePerMinute` `ProcsPerMinute` float NOT NULL DEFAULT 0 AFTER `AttributesMask`, + CHANCE `chance` `Chance` float NOT NULL DEFAULT 0 AFTER `ProcsPerMinute`, + CHANCE `cooldown` `Cooldown` int(10) unsigned NOT NULL DEFAULT 0 AFTER `Chance`, + CHANCE `charges` `Charges` tinyint(3) unsigned NOT NULL DEFAULT 0 AFTER `Cooldown`; diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 1ca5df6b327..cab485e5063 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -789,7 +789,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()) @@ -1884,7 +1884,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 @@ -1963,16 +1963,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/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 50f750f2ca5..56042e05257 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -955,11 +955,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; @@ -969,7 +969,7 @@ 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 @@ -977,31 +977,31 @@ bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcE { SpellInfo const* eventSpellInfo = eventInfo.GetSpellInfo(); - if (procEntry.spellFamilyName && eventSpellInfo && (procEntry.spellFamilyName != eventSpellInfo->SpellFamilyName)) + if (procEntry.SpellFamilyName && eventSpellInfo && (procEntry.SpellFamilyName != eventSpellInfo->SpellFamilyName)) return false; - if (procEntry.spellFamilyMask && eventSpellInfo && !(procEntry.spellFamilyMask & eventSpellInfo->SpellFamilyFlags)) + if (procEntry.SpellFamilyMask && eventSpellInfo && !(procEntry.SpellFamilyMask & eventSpellInfo->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) { @@ -1929,8 +1929,11 @@ 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 + QueryResult result = WorldDatabase.Query("SELECT SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, " + // 6 7 8 9 10 11 12 13 14 + "ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc"); + if (!result) { TC_LOG_INFO("server.loading", ">> Loaded 0 spell proc conditions and data. DB table `spell_proc` is empty."); @@ -1972,21 +1975,20 @@ void SpellMgr::LoadSpellProcs() SpellProcEntry baseProcEntry; - baseProcEntry.schoolMask = fields[1].GetInt8(); - baseProcEntry.spellFamilyName = fields[2].GetUInt16(); - baseProcEntry.spellFamilyMask[0] = fields[3].GetUInt32(); - baseProcEntry.spellFamilyMask[1] = fields[4].GetUInt32(); - baseProcEntry.spellFamilyMask[2] = fields[5].GetUInt32(); - baseProcEntry.typeMask = fields[6].GetUInt32(); - baseProcEntry.spellTypeMask = fields[7].GetUInt32(); - baseProcEntry.spellPhaseMask = fields[8].GetUInt32(); - baseProcEntry.hitMask = fields[9].GetUInt32(); - baseProcEntry.attributesMask = fields[10].GetUInt32(); - baseProcEntry.ratePerMinute = fields[11].GetFloat(); - baseProcEntry.chance = fields[12].GetFloat(); - float cooldown = fields[13].GetFloat(); - baseProcEntry.cooldown = uint32(cooldown); - baseProcEntry.charges = fields[14].GetUInt32(); + baseProcEntry.SchoolMask = fields[1].GetInt8(); + baseProcEntry.SpellFamilyName = fields[2].GetUInt16(); + baseProcEntry.SpellFamilyMask[0] = fields[3].GetUInt32(); + baseProcEntry.SpellFamilyMask[1] = fields[4].GetUInt32(); + baseProcEntry.SpellFamilyMask[2] = fields[5].GetUInt32(); + baseProcEntry.ProcFlags = fields[6].GetUInt32(); + baseProcEntry.SpellTypeMask = fields[7].GetUInt32(); + baseProcEntry.SpellPhaseMask = fields[8].GetUInt32(); + baseProcEntry.HitMask = fields[9].GetUInt32(); + baseProcEntry.AttributesMask = fields[10].GetUInt32(); + baseProcEntry.ProcsPerMinute = fields[11].GetFloat(); + baseProcEntry.Chance = fields[12].GetFloat(); + baseProcEntry.Cooldown = Milliseconds(fields[13].GetUInt32()); + baseProcEntry.Charges = fields[14].GetUInt8(); while (spellInfo) { @@ -1999,56 +2001,46 @@ 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) - TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `schoolMask` set: %u", spellInfo->Id, procEntry.schoolMask); - if (procEntry.spellFamilyName && (procEntry.spellFamilyName < 3 || procEntry.spellFamilyName > 17 || procEntry.spellFamilyName == 14 || procEntry.spellFamilyName == 16)) - TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `spellFamilyName` set: %u", spellInfo->Id, procEntry.spellFamilyName); - if (procEntry.chance < 0) - { - TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in the `chance` field", spellInfo->Id); - procEntry.chance = 0; - } - if (procEntry.ratePerMinute < 0) - { - TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in the `ratePerMinute` field", spellInfo->Id); - procEntry.ratePerMinute = 0; - } - if (cooldown < 0) + if (procEntry.SchoolMask & ~SPELL_SCHOOL_MASK_ALL) + TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `SchoolMask` set: %u", spellInfo->Id, procEntry.SchoolMask); + if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName < 3 || procEntry.SpellFamilyName > 17 || procEntry.SpellFamilyName == 14 || procEntry.SpellFamilyName == 16)) + TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `SpellFamilyName` set: %u", spellInfo->Id, procEntry.SpellFamilyName); + if (procEntry.Chance < 0) { - TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in the `cooldown` field", spellInfo->Id); - procEntry.cooldown = 0; + TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in the `Chance` field", spellInfo->Id); + procEntry.Chance = 0; } - if (procEntry.chance == 0 && procEntry.ratePerMinute == 0) - TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u doesn't have any `chance` and `ratePerMinute` values defined, proc will not be triggered", spellInfo->Id); - if (procEntry.charges > 99) + if (procEntry.ProcsPerMinute < 0) { - TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has a too big `charges` field value.", spellInfo->Id); - procEntry.charges = 99; + TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in the `ProcsPerMinute` field", spellInfo->Id); + procEntry.ProcsPerMinute = 0; } - if (!procEntry.typeMask) - TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u doesn't have any `typeMask` value defined, proc will not be triggered.", spellInfo->Id); - if (procEntry.spellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL) - TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `spellTypeMask` set: %u", spellInfo->Id, procEntry.spellTypeMask); - if (procEntry.spellTypeMask && !(procEntry.typeMask & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK))) - TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has `spellTypeMask` value defined, but it will not be used for the defined `typeMask` value.", spellInfo->Id); - if (!procEntry.spellPhaseMask && procEntry.typeMask & REQ_SPELL_PHASE_PROC_FLAG_MASK) - TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u doesn't have any `spellPhaseMask` value defined, but it is required for the defined `typeMask` value. Proc will not be triggered.", spellInfo->Id); - if (procEntry.spellPhaseMask & ~PROC_SPELL_PHASE_MASK_ALL) - TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has wrong `spellPhaseMask` set: %u", spellInfo->Id, procEntry.spellPhaseMask); - if (procEntry.spellPhaseMask && !(procEntry.typeMask & REQ_SPELL_PHASE_PROC_FLAG_MASK)) - TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has a `spellPhaseMask` value defined, but it will not be used for the defined `typeMask` value.", spellInfo->Id); - if (procEntry.hitMask & ~PROC_HIT_MASK_ALL) - TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has wrong `hitMask` set: %u", spellInfo->Id, 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))))) - TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has `hitMask` value defined, but it will not be used for defined `typeMask` and `spellPhaseMask` values.", spellInfo->Id); + if (procEntry.Chance == 0 && procEntry.ProcsPerMinute == 0) + TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u doesn't have any `Chance` and `ProcsPerMinute` values defined, proc will not be triggered", spellInfo->Id); + if (!procEntry.ProcFlags) + TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u doesn't have any `ProcFlags` value defined, proc will not be triggered.", spellInfo->Id); + if (procEntry.SpellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL) + TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `SpellTypeMask` set: %u", spellInfo->Id, procEntry.SpellTypeMask); + if (procEntry.SpellTypeMask && !(procEntry.ProcFlags & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK))) + TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has `SpellTypeMask` value defined, but it will not be used for the defined `ProcFlags` value.", spellInfo->Id); + if (!procEntry.SpellPhaseMask && procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK) + TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u doesn't have any `SpellPhaseMask` value defined, but it is required for the defined `ProcFlags` value. Proc will not be triggered.", spellInfo->Id); + if (procEntry.SpellPhaseMask & ~PROC_SPELL_PHASE_MASK_ALL) + TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has wrong `SpellPhaseMask` set: %u", spellInfo->Id, procEntry.SpellPhaseMask); + if (procEntry.SpellPhaseMask && !(procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK)) + TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has a `SpellPhaseMask` value defined, but it will not be used for the defined `ProcFlags` value.", spellInfo->Id); + if (procEntry.HitMask & ~PROC_HIT_MASK_ALL) + TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has wrong `HitMask` set: %u", spellInfo->Id, 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))))) + TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has `HitMask` value defined, but it will not be used for defined `ProcFlags` and `SpellPhaseMask` values.", spellInfo->Id); mSpellProcMap[spellInfo->Id] = procEntry; diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index fea7513b092..75da933636c 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -266,7 +266,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 @@ -290,18 +290,18 @@ typedef std::unordered_map<uint32, SpellProcEventEntry> 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<uint32, SpellProcEntry> SpellProcMap; |