diff options
-rw-r--r-- | sql/updates/7168_world_spell_stack_masks.sql | 7 | ||||
-rw-r--r-- | src/game/Chat.cpp | 1 | ||||
-rw-r--r-- | src/game/Chat.h | 1 | ||||
-rw-r--r-- | src/game/Level3.cpp | 9 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 78 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 22 | ||||
-rw-r--r-- | src/game/World.cpp | 3 |
7 files changed, 100 insertions, 21 deletions
diff --git a/sql/updates/7168_world_spell_stack_masks.sql b/sql/updates/7168_world_spell_stack_masks.sql new file mode 100644 index 00000000000..c3e4f0c1275 --- /dev/null +++ b/sql/updates/7168_world_spell_stack_masks.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS `spell_stack_masks`;
+
+CREATE TABLE `spell_stack_masks` (
+ `id` int(32) unsigned NOT NULL default '0',
+ `mask` int(64) unsigned NOT NULL default '0',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index f21e3b2511d..3cc868a2b3e 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -508,6 +508,7 @@ ChatCommand * ChatHandler::getCommandTable() { "spell_target_position", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL }, { "spell_threats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellThreatsCommand, "", NULL }, { "spell_disabled", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellDisabledCommand, "", NULL }, + { "spell_stack_masks", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellStackMasksCommand, "", NULL }, { "trinity_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadTrinityStringCommand, "", NULL }, { "auctions", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAuctionsCommand, "", NULL }, { "waypoint_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadWpScriptsCommand, "", NULL }, diff --git a/src/game/Chat.h b/src/game/Chat.h index f4dba8b6596..817a9306eba 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -421,6 +421,7 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleReloadSpellThreatsCommand(const char* args); bool HandleReloadSpellPetAurasCommand(const char* args); bool HandleReloadSpellDisabledCommand(const char* args); + bool HandleReloadSpellStackMasksCommand(const char* args); bool HandleReloadAuctionsCommand(const char* args); bool HandleReloadWpScriptsCommand(const char* args); diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 9af7c517321..2755cb9c9b5 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -659,6 +659,7 @@ bool ChatHandler::HandleReloadAllSpellCommand(const char*) HandleReloadSpellScriptTargetCommand("a"); HandleReloadSpellTargetPositionCommand("a"); HandleReloadSpellThreatsCommand("a"); + HandleReloadSpellStackMasksCommand("a"); HandleReloadSpellPetAurasCommand("a"); HandleReloadSpellDisabledCommand("a"); return true; @@ -1093,6 +1094,14 @@ bool ChatHandler::HandleReloadSpellThreatsCommand(const char*) return true; } +bool ChatHandler::HandleReloadSpellStackMasksCommand(const char*) +{ + sLog.outString( "Re-Loading Spell stacking masks..." ); + spellmgr.LoadSpellStackMasks(); + SendGlobalGMSysMessage("DB table `spell_stack_masks` (spell stacking masks) reloaded."); + return true; +} + bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*) { sLog.outString( "Re-Loading Spell pet auras..."); diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index ea98dab2c99..c1b187fdad5 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -546,8 +546,6 @@ SpellSpecific GetSpellSpecific(SpellEntry const * spellInfo) } case SPELLFAMILY_WARRIOR: { - if (spellInfo->SpellFamilyFlags[0] & 0x10000) - return SPELL_SPECIFIC_BATTLE_SHOUT; if (spellInfo->SpellFamilyFlags[1] & 0x000080) return SPELL_SPECIFIC_POSITIVE_SHOUT; if (spellInfo->Id == 12292) // Death Wish @@ -601,9 +599,6 @@ SpellSpecific GetSpellSpecific(SpellEntry const * spellInfo) if (IsSealSpell(spellInfo)) return SPELL_SPECIFIC_SEAL; - if (spellInfo->SpellFamilyFlags[0] & 0x00000002) - return SPELL_SPECIFIC_BLESSING_OF_MIGHT; - if (spellInfo->SpellFamilyFlags[0] & 0x11010002) return SPELL_SPECIFIC_BLESSING; @@ -676,17 +671,11 @@ bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific s case SPELL_SPECIFIC_STING: case SPELL_SPECIFIC_CURSE: case SPELL_SPECIFIC_ASPECT: - case SPELL_SPECIFIC_BATTLE_SHOUT: case SPELL_SPECIFIC_POSITIVE_SHOUT: case SPELL_SPECIFIC_JUDGEMENT: case SPELL_SPECIFIC_WARLOCK_CORRUPTION: - return spellSpec1==spellSpec2; - case SPELL_SPECIFIC_BLESSING_OF_MIGHT: - return spellSpec2==SPELL_SPECIFIC_BLESSING - || spellSpec2 == SPELL_SPECIFIC_BLESSING_OF_MIGHT; case SPELL_SPECIFIC_BLESSING: - return spellSpec2==SPELL_SPECIFIC_BLESSING_OF_MIGHT - || spellSpec2==SPELL_SPECIFIC_BLESSING; + return spellSpec1==spellSpec2; default: return false; } @@ -709,6 +698,7 @@ bool IsSingleFromSpellSpecificPerTarget(SpellSpecific spellSpec1, SpellSpecific case SPELL_SPECIFIC_WARRIOR_ENRAGE: case SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE: case SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT: + case SPELL_SPECIFIC_POSITIVE_SHOUT: return spellSpec1==spellSpec2; case SPELL_SPECIFIC_FOOD: return spellSpec2==SPELL_SPECIFIC_FOOD @@ -730,15 +720,6 @@ bool IsSingleFromSpellSpecificPerTarget(SpellSpecific spellSpec1, SpellSpecific return spellSpec2==SPELL_SPECIFIC_BATTLE_ELIXIR || spellSpec2==SPELL_SPECIFIC_GUARDIAN_ELIXIR || spellSpec2==SPELL_SPECIFIC_FLASK_ELIXIR; - case SPELL_SPECIFIC_BLESSING_OF_MIGHT: - return spellSpec2==SPELL_SPECIFIC_BATTLE_SHOUT; - case SPELL_SPECIFIC_BATTLE_SHOUT: - return spellSpec2==SPELL_SPECIFIC_BLESSING_OF_MIGHT - || spellSpec2==SPELL_SPECIFIC_POSITIVE_SHOUT - || spellSpec2==SPELL_SPECIFIC_BATTLE_SHOUT; - case SPELL_SPECIFIC_POSITIVE_SHOUT: - return spellSpec2==SPELL_SPECIFIC_BATTLE_SHOUT - || spellSpec2==SPELL_SPECIFIC_POSITIVE_SHOUT; default: return false; } @@ -1523,6 +1504,54 @@ void SpellMgr::LoadSpellElixirs() sLog.outString( ">> Loaded %u spell elixir definitions", count ); } +void SpellMgr::LoadSpellStackMasks() +{ + mSpellStackMasks.clear(); // need for reload case + + uint32 count = 0; + + // 0 1 + QueryResult_AutoPtr result = WorldDatabase.Query("SELECT id, mask FROM spell_stack_masks"); + if( !result ) + { + + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outString( ">> Loaded %u spell stacking masks definitions", count ); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + Field *fields = result->Fetch(); + + bar.step(); + + uint32 id = fields[0].GetUInt32(); + uint8 mask = fields[1].GetUInt32(); + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(id); + + if (!spellInfo) + { + sLog.outErrorDb("Spell %u listed in `spell_stack_masks` does not exist", id); + continue; + } + + mSpellStackMasks[id] = mask; + + ++count; + } while( result->NextRow() ); + + sLog.outString(); + sLog.outString( ">> Loaded %u spell stacking masks definitions", count ); +} + void SpellMgr::LoadSpellThreats() { mSpellThreatMap.clear(); // need for reload case @@ -2999,6 +3028,13 @@ bool SpellMgr::CanAurasStack(SpellEntry const *spellInfo_1, SpellEntry const *sp || sameCaster && IsSingleFromSpellSpecificPerCaster(spellSpec_1, spellSpec_2)) return false; + // Stacking Checks by family masks + uint32 spellSpecMask_1 = GetSpellStackMask(spellInfo_1->Id); + uint32 spellSpecMask_2 = GetSpellStackMask(spellInfo_2->Id); + if (spellSpecMask_1 && spellSpecMask_2) + if ((spellSpecMask_1 & spellSpecMask_2) != 0) + return false; + if(spellInfo_1->SpellFamilyName != spellInfo_2->SpellFamilyName) return true; diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index fb38e36bafd..0336b615f5e 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -642,6 +642,7 @@ typedef UNORDERED_MAP<uint32, SpellBonusEntry> SpellBonusMap; typedef std::map<uint32, uint8> SpellElixirMap; typedef std::map<uint32, uint16> SpellThreatMap; +typedef std::map<uint32, uint32> SpellStackMaskMap; // Spell script target related declarations (accessed using SpellMgr functions) enum SpellScriptTargetType @@ -882,6 +883,25 @@ class SpellMgr return SPELL_SPECIFIC_NORMAL; } + // Used for stacking in spellmgr, and possibly in cancast checks + SpellStackMaskMap const& GetSpellStackMasksMap() const { return mSpellStackMasks; } + uint32 GetSpellStackMask(uint32 spellid) const + { + SpellStackMaskMap::const_iterator itr = mSpellStackMasks.find(spellid); + if(itr!=mSpellStackMasks.end()) + return itr->second; + + // Not found, try lookup for 1 spell rank if exist + if (uint32 rank_1 = GetFirstSpellInChain(spellid)) + { + SpellStackMaskMap::const_iterator itr2 = mSpellStackMasks.find(rank_1); + if(itr2 != mSpellStackMasks.end()) + return itr2->second; + } + + return 0x0; + } + uint16 GetSpellThreat(uint32 spellid) const { SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellid); @@ -1206,6 +1226,7 @@ class SpellMgr void LoadPetLevelupSpellMap(); void LoadPetDefaultSpells(); void LoadSpellAreas(); + void LoadSpellStackMasks(); private: bool _isPositiveSpell(uint32 spellId, bool deep) const; @@ -1226,6 +1247,7 @@ class SpellMgr SpellPetAuraMap mSpellPetAuraMap; SpellCustomAttribute mSpellCustomAttr; SpellLinkedMap mSpellLinkedMap; + SpellStackMaskMap mSpellStackMasks; SpellEnchantProcEventMap mSpellEnchantProcEventMap; EnchantCustomAttribute mEnchantCustomAttr; PetLevelupSpellMap mPetLevelupSpellMap; diff --git a/src/game/World.cpp b/src/game/World.cpp index 9c68dca848f..a9a0c9426eb 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1329,6 +1329,9 @@ void World::SetInitialWorldSettings() sLog.outString("Loading Aggro Spells Definitions..."); spellmgr.LoadSpellThreats(); + sLog.outString("Loading Spell Stacking masks..."); + spellmgr.LoadSpellStackMasks(); + sLog.outString("Loading NPC Texts..."); objmgr.LoadGossipText(); |