aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Spells/SpellMgr.cpp
diff options
context:
space:
mode:
authorQAston <qaston@gmail.com>2011-06-26 13:54:44 +0200
committerQAston <qaston@gmail.com>2011-06-26 13:54:44 +0200
commitac88fa026f7996444a865dd15ea8955e22b90d99 (patch)
tree664b42516aee60013363b7404b457efad8a9a25d /src/server/game/Spells/SpellMgr.cpp
parent6dcee0c0ea23617849a6b04ae22d2b74fb04f097 (diff)
Database/Spells: Add spell_proc table which is a replacement for spell_proc_event table. This is the initial patch from series of patches changing the way we currently handle procs in the core, and doesn't interfere with existing code in any way.
Diffstat (limited to 'src/server/game/Spells/SpellMgr.cpp')
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.cpp221
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();