aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/Chat.cpp1
-rw-r--r--src/game/Chat.h1
-rw-r--r--src/game/Level3.cpp9
-rw-r--r--src/game/SpellMgr.cpp78
-rw-r--r--src/game/SpellMgr.h22
-rw-r--r--src/game/World.cpp3
6 files changed, 93 insertions, 21 deletions
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();