diff options
Diffstat (limited to 'src/server/game/Spells/SpellMgr.cpp')
| -rwxr-xr-x | src/server/game/Spells/SpellMgr.cpp | 221 |
1 files changed, 181 insertions, 40 deletions
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index d6a447bd75f..4f07ed90c5d 100755 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1338,46 +1338,6 @@ void SpellMgr::LoadSpellProcEvents() sLog->outString(); } -void SpellMgr::LoadSpellBonusess() -{ - uint32 oldMSTime = getMSTime(); - - mSpellBonusMap.clear(); // need for reload case - uint32 count = 0; - // 0 1 2 3 4 - QueryResult result = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus, ap_dot_bonus FROM spell_bonus_data"); - if (!result) - { - sLog->outString(">> Loaded %u spell bonus data", count); - sLog->outString(); - return; - } - - do - { - Field *fields = result->Fetch(); - uint32 entry = fields[0].GetUInt32(); - - const SpellEntry *spell = sSpellStore.LookupEntry(entry); - if (!spell) - { - sLog->outErrorDb("Spell %u listed in `spell_bonus_data` does not exist", entry); - continue; - } - - SpellBonusEntry& sbe = mSpellBonusMap[entry]; - sbe.direct_damage = fields[1].GetFloat(); - sbe.dot_damage = fields[2].GetFloat(); - sbe.ap_bonus = fields[3].GetFloat(); - sbe.ap_dot_bonus = fields[4].GetFloat(); - - ++count; - } while (result->NextRow()); - - sLog->outString(">> Loaded %u extra spell bonus data in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); - sLog->outString(); -} - bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellEntry const* procSpell, uint32 procFlags, uint32 procExtra, bool active) { // No extra req need @@ -1507,6 +1467,187 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr return false; } +void SpellMgr::LoadSpellProcs() +{ + uint32 oldMSTime = getMSTime(); + + mSpellProcMap.clear(); // need for reload case + + uint32 count = 0; + + // 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"); + if (!result) + { + sLog->outString(">> Loaded %u spell proc conditions and data", count); + sLog->outString(); + return; + } + + do + { + Field* fields = result->Fetch(); + + int32 spellId = fields[0].GetInt32(); + + bool allRanks = false; + if (spellId <=0) + { + allRanks = true; + spellId = -spellId; + } + + SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellId); + if (!spellEntry) + { + sLog->outErrorDb("Spell %u listed in `spell_proc` does not exist", spellId); + continue; + } + + if (allRanks) + { + if (sSpellMgr->GetFirstSpellInChain(spellId) != uint32(spellId)) + { + sLog->outErrorDb("Spell %u listed in `spell_proc` is not first rank of spell.", fields[0].GetInt32()); + continue; + } + } + + SpellProcEntry baseProcEntry; + + baseProcEntry.schoolMask = fields[1].GetUInt32(); + baseProcEntry.spellFamilyName = fields[2].GetUInt32(); + 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(); + baseProcEntry.cooldown = fields[13].GetFloat(); + baseProcEntry.charges = fields[14].GetUInt32(); + + while(true) + { + if (mSpellProcMap.find(spellId) != mSpellProcMap.end()) + { + sLog->outErrorDb("Spell %u listed in `spell_proc` has duplicate entry in the table", spellId); + break; + } + SpellProcEntry procEntry = SpellProcEntry(baseProcEntry); + + // take defaults from dbcs + if (!procEntry.typeMask) + procEntry.typeMask = spellEntry->procFlags; + if (!procEntry.charges) + procEntry.charges = spellEntry->procCharges; + if (!procEntry.chance && !procEntry.ratePerMinute) + procEntry.chance = float(spellEntry->procChance); + + // validate data + if (procEntry.schoolMask & ~SPELL_SCHOOL_MASK_ALL) + sLog->outErrorDb("`spell_proc` table entry for spellId %u has wrong `schoolMask` set: %u", spellId, procEntry.schoolMask); + if (procEntry.spellFamilyName && (procEntry.spellFamilyName < 3 || procEntry.spellFamilyName > 17 || procEntry.spellFamilyName == 14 || procEntry.spellFamilyName == 16)) + sLog->outErrorDb("`spell_proc` table entry for spellId %u has wrong `spellFamilyName` set: %u", spellId, procEntry.spellFamilyName); + if (procEntry.chance < 0) + { + sLog->outErrorDb("`spell_proc` table entry for spellId %u has negative value in `chance` field", spellId); + procEntry.chance = 0; + } + if (procEntry.ratePerMinute < 0) + { + sLog->outErrorDb("`spell_proc` table entry for spellId %u has negative value in `ratePerMinute` field", spellId); + procEntry.ratePerMinute = 0; + } + if (procEntry.cooldown < 0) + { + sLog->outErrorDb("`spell_proc` table entry for spellId %u has negative value in `cooldown` field", spellId); + procEntry.cooldown = 0; + } + if (procEntry.chance == 0 && procEntry.ratePerMinute == 0) + sLog->outErrorDb("`spell_proc` table entry for spellId %u doesn't have `chance` and `ratePerMinute` values defined, proc will not be triggered", spellId); + if (procEntry.charges > 99) + { + sLog->outErrorDb("`spell_proc` table entry for spellId %u has too big value in `charges` field", spellId); + procEntry.charges = 99; + } + if (!procEntry.typeMask) + sLog->outErrorDb("`spell_proc` table entry for spellId %u doesn't have `typeMask` value defined, proc will not be triggered", spellId); + if (procEntry.spellTypeMask & ~PROC_SPELL_PHASE_MASK_ALL) + sLog->outErrorDb("`spell_proc` table entry for spellId %u has wrong `spellTypeMask` set: %u", spellId, procEntry.spellTypeMask); + if (procEntry.spellTypeMask && !(procEntry.typeMask & SPELL_PROC_FLAG_MASK)) + sLog->outErrorDb("`spell_proc` table entry for spellId %u 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) + sLog->outErrorDb("`spell_proc` table entry for spellId %u 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) + sLog->outErrorDb("`spell_proc` table entry for spellId %u has wrong `spellPhaseMask` set: %u", spellId, procEntry.spellPhaseMask); + if (procEntry.spellPhaseMask && !(procEntry.typeMask & REQ_SPELL_PHASE_PROC_FLAG_MASK)) + sLog->outErrorDb("`spell_proc` table entry for spellId %u has `spellPhaseMask` value defined, but it won't be used for defined `typeMask` value", spellId); + if (procEntry.hitMask & ~PROC_HIT_MASK_ALL) + sLog->outErrorDb("`spell_proc` table entry for spellId %u has wrong `hitMask` set: %u", 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))))) + sLog->outErrorDb("`spell_proc` table entry for spellId %u has `hitMask` value defined, but it won't be used for defined `typeMask` and `spellPhaseMask` values", spellId); + + mSpellProcMap[spellId] = procEntry; + + if (allRanks) + { + spellId = sSpellMgr->GetNextSpellInChain(spellId); + spellEntry = sSpellStore.LookupEntry(spellId); + } + else + break; + } + ++count; + } while (result->NextRow()); + + sLog->outString(">> Loaded %u spell proc conditions and data in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); + sLog->outString(); +} + +void SpellMgr::LoadSpellBonusess() +{ + uint32 oldMSTime = getMSTime(); + + mSpellBonusMap.clear(); // need for reload case + uint32 count = 0; + // 0 1 2 3 4 + QueryResult result = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus, ap_dot_bonus FROM spell_bonus_data"); + if (!result) + { + sLog->outString(">> Loaded %u spell bonus data", count); + sLog->outString(); + return; + } + + do + { + Field *fields = result->Fetch(); + uint32 entry = fields[0].GetUInt32(); + + const SpellEntry *spell = sSpellStore.LookupEntry(entry); + if (!spell) + { + sLog->outErrorDb("Spell %u listed in `spell_bonus_data` does not exist", entry); + continue; + } + + SpellBonusEntry& sbe = mSpellBonusMap[entry]; + sbe.direct_damage = fields[1].GetFloat(); + sbe.dot_damage = fields[2].GetFloat(); + sbe.ap_bonus = fields[3].GetFloat(); + sbe.ap_dot_bonus = fields[4].GetFloat(); + + ++count; + } while (result->NextRow()); + + sLog->outString(">> Loaded %u extra spell bonus data in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); + sLog->outString(); +} + void SpellMgr::LoadSpellGroups() { uint32 oldMSTime = getMSTime(); |
