diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/Pet.cpp | 11 | ||||
-rw-r--r-- | src/game/Player.cpp | 11 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 156 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 32 |
4 files changed, 146 insertions, 64 deletions
diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 4071cfb50bb..6a7d809da03 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -1858,12 +1858,19 @@ void Pet::CastPetAura(PetAura const* aura) CastSpell(this, auraId, true); } +struct DoPetLearnSpell +{ + DoPetLearnSpell(Pet& _pet) : pet(_pet) {} + void operator() (uint32 spell_id) { pet.learnSpell(spell_id); } + Pet& pet; +}; + void Pet::learnSpellHighRank(uint32 spellid) { learnSpell(spellid); - if(uint32 next = spellmgr.GetNextSpellInChain(spellid)) - learnSpellHighRank(next); + DoPetLearnSpell worker(*this); + spellmgr.doForHighRanks(spellid,worker); } void Pet::SynchronizeLevelWithOwner() diff --git a/src/game/Player.cpp b/src/game/Player.cpp index d610031da00..6c7fb40c3fa 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -20563,12 +20563,19 @@ bool Player::IsAllowUseFlyMountsHere() const return v_map == 530 || v_map == 571 && HasSpell(54197) && zoneId != 4197; } +struct DoPlayerLearnSpell +{ + DoPlayerLearnSpell(Player& _player) : player(_player) {} + void operator() (uint32 spell_id) { player.learnSpell(spell_id,false); } + Player& player; +}; + void Player::learnSpellHighRank(uint32 spellid) { learnSpell(spellid,false); - if(uint32 next = spellmgr.GetNextSpellInChain(spellid)) - learnSpellHighRank(next); + DoPlayerLearnSpell worker(*this); + spellmgr.doForHighRanks(spellid,worker); } void Player::_LoadSkills() diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index f1f43d57821..7e1da72be4e 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1204,6 +1204,13 @@ bool SpellMgr::IsAffectedByMod(SpellEntry const *spellInfo, SpellModifier *mod) return false; } +struct DoSpellProcEvent +{ + DoSpellProcEvent(SpellProcEventEntry const& _spe) : spe(_spe) {} + void operator() (uint32 spell_id) { spellmgr.mSpellProcEventMap[spell_id] = spe; } + SpellProcEventEntry const& spe; +}; + void SpellMgr::LoadSpellProcEvents() { mSpellProcEventMap.clear(); // need for reload case @@ -1238,6 +1245,15 @@ void SpellMgr::LoadSpellProcEvents() continue; } + uint32 first_id = GetFirstSpellInChain(entry); + + if ( first_id != entry ) + { + sLog.outErrorDb("Spell %u listed in `spell_proc_event` is not first rank (%u) in chain", entry, first_id); + // prevent loading since it won't have an effect anyway + continue; + } + SpellProcEventEntry spe; spe.schoolMask = fields[1].GetUInt32(); @@ -1253,6 +1269,10 @@ void SpellMgr::LoadSpellProcEvents() mSpellProcEventMap[entry] = spe; + // also add to high ranks + DoSpellProcEvent worker(spe); + doForHighRanks(entry,worker); + if (spell->procFlags==0) { if (spe.procFlags == 0) @@ -1274,6 +1294,74 @@ void SpellMgr::LoadSpellProcEvents() sLog.outString( ">> Loaded %u extra spell proc event conditions", count ); } +struct DoSpellProcItemEnchant +{ + DoSpellProcItemEnchant(SpellEnchantProcEntry const &_spe) : spe(_spe) {} + void operator() (uint32 spell_id) { spellmgr.mSpellEnchantProcEventMap[spell_id] = spe; } + SpellEnchantProcEntry const &spe; +}; + +void SpellMgr::LoadSpellEnchantProcData() +{ + mSpellEnchantProcEventMap.clear(); // need for reload case + + uint32 count = 0; + + // 0 1 2 3 + QueryResult *result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx FROM spell_enchant_proc_data"); + if( !result ) + { + + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u spell enchant proc event conditions", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + do + { + Field *fields = result->Fetch(); + + bar.step(); + + uint32 entry = fields[0].GetUInt32(); + + SpellItemEnchantmentEntry const *ench = sSpellItemEnchantmentStore.LookupEntry(entry); + if (!ench) + { + sLog.outErrorDb("Enchancment %u listed in `spell_enchant_proc_data` does not exist", entry); + continue; + } + + SpellEnchantProcEntry spe; + + spe.customChance = fields[1].GetUInt32(); + spe.PPMChance = fields[2].GetFloat(); + spe.procEx = fields[3].GetUInt32(); + + // also add to high ranks + DoSpellProcItemEnchant worker(spe); + doForThisAndHighRanks(entry,worker); + + ++count; + } while( result->NextRow() ); + + delete result; + + sLog.outString( ">> Loaded %u enchant proc data definitions", count); +} + +struct DoSpellBonusess +{ + DoSpellBonusess(SpellBonusEntry const& _spellBonus) : spellBonus(_spellBonus) {} + void operator() (uint32 spell_id) { spellmgr.mSpellBonusMap[spell_id] = spellBonus; } + SpellBonusEntry const& spellBonus; +}; + void SpellMgr::LoadSpellBonusess() { mSpellBonusMap.clear(); // need for reload case @@ -1296,13 +1384,22 @@ void SpellMgr::LoadSpellBonusess() bar.step(); uint32 entry = fields[0].GetUInt32(); - const SpellEntry *spell = sSpellStore.LookupEntry(entry); + SpellEntry const* spell = sSpellStore.LookupEntry(entry); if (!spell) { sLog.outErrorDb("Spell %u listed in `spell_bonus_data` does not exist", entry); continue; } + uint32 first_id = GetFirstSpellInChain(entry); + + if ( first_id != entry ) + { + sLog.outErrorDb("Spell %u listed in `spell_bonus_data` is not first rank (%u) in chain", entry, first_id); + // prevent loading since it won't have an effect anyway + continue; + } + SpellBonusEntry sbe; sbe.direct_damage = fields[1].GetFloat(); @@ -1312,6 +1409,11 @@ void SpellMgr::LoadSpellBonusess() mSpellBonusMap[entry] = sbe; ++count; + + // also add to high ranks + DoSpellBonusess worker(sbe); + doForHighRanks(entry,worker); + } while( result->NextRow() ); delete result; @@ -3321,58 +3423,6 @@ bool IsDispelableBySpell(SpellEntry const * dispelSpell, uint32 spellId, bool de return def; } -void SpellMgr::LoadSpellEnchantProcData() -{ - mSpellEnchantProcEventMap.clear(); // need for reload case - - uint32 count = 0; - - // 0 1 2 3 - QueryResult *result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx FROM spell_enchant_proc_data"); - if( !result ) - { - - barGoLink bar( 1 ); - - bar.step(); - - sLog.outString(); - sLog.outString( ">> Loaded %u spell enchant proc event conditions", count ); - return; - } - - barGoLink bar( result->GetRowCount() ); - do - { - Field *fields = result->Fetch(); - - bar.step(); - - uint32 enchantId = fields[0].GetUInt32(); - - SpellItemEnchantmentEntry const *ench = sSpellItemEnchantmentStore.LookupEntry(enchantId); - if (!ench) - { - sLog.outErrorDb("Enchancment %u listed in `spell_enchant_proc_data` does not exist", enchantId); - continue; - } - - SpellEnchantProcEntry spe; - - spe.customChance = fields[1].GetUInt32(); - spe.PPMChance = fields[2].GetFloat(); - spe.procEx = fields[3].GetUInt32(); - - mSpellEnchantProcEventMap[enchantId] = spe; - - ++count; - } while( result->NextRow() ); - - delete result; - - sLog.outString( ">> Loaded %u enchant proc data definitions", count); -} - void SpellMgr::LoadSpellRequired() { mSpellsReqSpell.clear(); // need for reload case diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index f1d551298f0..be34f4af2eb 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -729,6 +729,10 @@ inline bool IsProfessionOrRidingSkill(uint32 skill) class SpellMgr { + friend struct DoSpellBonusess; + friend struct DoSpellProcEvent; + friend struct DoSpellProcItemEnchant; + // Constructors public: SpellMgr(); @@ -798,13 +802,7 @@ class SpellMgr SpellBonusMap::const_iterator itr = mSpellBonusMap.find(spellId); if( itr != mSpellBonusMap.end( ) ) return &itr->second; - // Not found, try lookup for 1 spell rank if exist - if (uint32 rank_1 = GetFirstSpellInChain(spellId)) - { - SpellBonusMap::const_iterator itr2 = mSpellBonusMap.find(rank_1); - if( itr2 != mSpellBonusMap.end( ) ) - return &itr2->second; - } + return NULL; } @@ -862,6 +860,26 @@ class SpellMgr SpellsRequiringSpellMap const& GetSpellsRequiringSpell() const { return mSpellsReqSpell; } + template<typename Worker> + void doForThisAndHighRanks(uint32 spellid, Worker& worker) + { + worker(spellid); + if(uint32 nextSpellId = GetNextSpellInChain(spellid)) + doForThisAndHighRanks(nextSpellId, worker); + } + + template<typename Worker> + void doForHighRanks(uint32 spellid, Worker& worker) + { + if(uint32 nextSpellId = GetNextSpellInChain(spellid)) + { + worker(nextSpellId); + doForHighRanks(nextSpellId, worker); + } + } + + // Note: not use rank for compare to spell ranks: spell chains isn't linear order + // Use IsHighRankOfSpell instead uint8 GetSpellRank(uint32 spell_id) const { if(SpellChainNode const* node = GetSpellChainNode(spell_id)) |