*Drop spell_stack_masks table

*Add spell_group_stack_rules table (for more info see wiki)
*The table is maintained by core team
*Move some spell specific out of core to the new table

--HG--
branch : trunk
This commit is contained in:
QAston
2010-02-02 22:35:01 +01:00
parent 70425115f0
commit 10695f9131
13 changed files with 483 additions and 206 deletions
+4
View File
@@ -0,0 +1,4 @@
DELETE FROM `command` WHERE `name` = 'reload spell_group_stack_rules';
DELETE FROM `command` WHERE `name` = 'reload spell_elixir';
DELETE FROM `command` WHERE `name` = 'reload spell_stack_masks';
INSERT INTO `command` VALUES ('reload spell_group_stack_rules','3','Syntax: .reload spell_group\nReload spell_group_stack_rules table.');
+126
View File
@@ -0,0 +1,126 @@
ALTER TABLE spell_group
MODIFY spell_id INT(11) NOT NULL DEFAULT 0;
DELETE FROM spell_group WHERE id IN(5, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011);
INSERT INTO spell_group (id, spell_id) VALUES
-- Well Fed
(1001, 19705),
(1001, 19706),
(1001, 19708),
(1001, 19709),
(1001, 19710),
(1001, 19711),
(1001, 24799),
(1001, 24870),
(1001, 25694),
(1001, 25941),
(1001, 33254),
(1001, 33256),
(1001, 33257),
(1001, 33259),
(1001, 33261),
(1001, 33263),
(1001, 33265),
(1001, 33268),
(1001, 33272),
(1001, 35272),
(1001, 40323),
(1001, 42293),
(1001, 43764),
(1001, 43771),
(1001, 44097),
(1001, 44098),
(1001, 44099),
(1001, 44100),
(1001, 44101),
(1001, 44102),
(1001, 44104),
(1001, 44105),
(1001, 44106),
(1001, 45245),
(1001, 45619),
(1001, 46682),
(1001, 46687),
(1001, 46899),
(1001, 53284),
(1001, 57079),
(1001, 57097),
(1001, 57100),
(1001, 57102),
(1001, 57107),
(1001, 57111),
(1001, 57139),
(1001, 57286),
(1001, 57288),
(1001, 57291),
(1001, 57294),
(1001, 57325),
(1001, 57327),
(1001, 57329),
(1001, 57332),
(1001, 57334),
(1001, 57356),
(1001, 57358),
(1001, 57360),
(1001, 57363),
(1001, 57365),
(1001, 57367),
(1001, 57371),
(1001, 57373),
(1001, 57399),
(1001, 58468),
(1001, 58479),
(1001, 59230),
(1001, 59690),
(1001, 59699),
(1001, 62349),
(1001, 64057),
(1001, 65247),
(1001, 65365),
(1001, 65410),
(1001, 65412),
(1001, 65414),
(1001, 65415),
(1001, 65416),
(1001, 66623),
(1001, 66624),
(1001, 69559),
(1001, 18125),
(1001, 18141),
(1001, 23697),
-- Blessing of Might
(1002, 19740),
(1002, 25782),
(1002, 56520),
-- Battle Shout
(1003, 6673),
-- Blessing of Might, Battle Shout
(1004, -1002),
(1004, -1003),
-- Blessing of Wisdom
(1005, 19742),
(1005, 25894),
(1005, 56521),
-- Blessing of Kings
(1006, 20217),
(1006, 25898),
(1006, 43223),
(1006, 56525),
(1006, 58054),
-- Blessing of Sanctuary
(1007, 20911),
(1007, 25899),
-- Blessing of Protection
(1008, 41450),
(1008, 23415),
-- Blessing of Light
(1009, 32770),
-- Blessings
(1010, -1002),
(1010, -1005),
(1010, -1006),
(1010, -1007),
(1010, -1008),
(1010, -1009),
-- Commanding shout, Battle Shout
(1011, 469),
(1011, -1003);
@@ -0,0 +1,20 @@
DROP TABLE IF EXISTS `spell_group_stack_rules`;
CREATE TABLE `spell_group_stack_rules` (
`group_id` INT(11) UNSIGNED NOT NULL DEFAULT 0,
`stack_rule` TINYINT(3) NOT NULL DEFAULT 0,
PRIMARY KEY (`group_id`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO spell_group_stack_rules (group_id, stack_rule) VALUES
(1, 1),
(2, 1),
(1001, 1),
(1002, 1),
(1003, 1),
(1004, 1),
(1005, 1),
(1006, 1),
(1007, 1),
(1008, 1),
(1009, 1),
(1010, 2),
(1011, 1);
@@ -0,0 +1 @@
DROP TABLE IF EXISTS `spell_stack_masks`;
+152 -22
View File
@@ -607,6 +607,7 @@ INSERT INTO `command` VALUES
('reload spell_bonus_data','3','Syntax: .reload spell_bonus_data\nReload spell_bonus_data table.'), ('reload spell_bonus_data','3','Syntax: .reload spell_bonus_data\nReload spell_bonus_data table.'),
('reload spell_disabled','3','Syntax: .reload spell_disabled\nReload spell_disabled table.'), ('reload spell_disabled','3','Syntax: .reload spell_disabled\nReload spell_disabled table.'),
('reload spell_group','3','Syntax: .reload spell_group\nReload spell_group table.'), ('reload spell_group','3','Syntax: .reload spell_group\nReload spell_group table.'),
('reload spell_group_stack_rules','3','Syntax: .reload spell_group\nReload spell_group_stack_rules table.'),
('reload spell_learn_spell','3','Syntax: .reload spell_learn_spell\nReload spell_learn_spell table.'), ('reload spell_learn_spell','3','Syntax: .reload spell_learn_spell\nReload spell_learn_spell table.'),
('reload spell_linked_spell','3','Usage: .reload spell_linked_spell\r\nReloads the spell_linked_spell DB table.'), ('reload spell_linked_spell','3','Usage: .reload spell_linked_spell\r\nReloads the spell_linked_spell DB table.'),
('reload spell_loot_template','3','Syntax: .reload spell_loot_template\nReload spell_loot_template table.'), ('reload spell_loot_template','3','Syntax: .reload spell_loot_template\nReload spell_loot_template table.'),
@@ -5100,17 +5101,17 @@ DROP TABLE IF EXISTS `spell_group`;
/*!40101 SET character_set_client = utf8 */; /*!40101 SET character_set_client = utf8 */;
CREATE TABLE `spell_group` ( CREATE TABLE `spell_group` (
`id` int(11) unsigned NOT NULL DEFAULT 0, `id` int(11) unsigned NOT NULL DEFAULT 0,
`spell_id` int(11) unsigned NOT NULL DEFAULT 0, `spell_id` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`, `spell_id`) PRIMARY KEY (`id`, `spell_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Spell System'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Spell System';
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
-- --
-- Dumping data for table `spell_elixir` -- Dumping data for table `spell_group`
-- --
LOCK TABLES `spell_group` WRITE; LOCK TABLES `spell_group` WRITE;
/*!40000 ALTER TABLE `spell_elixir` DISABLE KEYS */; /*!40000 ALTER TABLE `spell_group` DISABLE KEYS */;
INSERT INTO `spell_group` (`id`, `spell_id`) VALUES INSERT INTO `spell_group` (`id`, `spell_id`) VALUES
-- SPELL_GROUP_ELIXIR_BATTLE -- SPELL_GROUP_ELIXIR_BATTLE
(1, 2367), (1, 2367),
@@ -5284,14 +5285,128 @@ INSERT INTO `spell_group` (`id`, `spell_id`) VALUES
(4, 41611), (4, 41611),
(4, 46837), (4, 46837),
(4, 46839), (4, 46839),
-- SPELL_GROUP_WELL_FED -- Well Fed
(5, 18191), (1001, 19705),
(5, 18192), (1001, 19706),
(5, 18193), (1001, 19708),
(5, 18194), (1001, 19709),
(5, 18222), (1001, 19710),
(5, 22730), (1001, 19711),
(5, 25661); (1001, 24799),
(1001, 24870),
(1001, 25694),
(1001, 25941),
(1001, 33254),
(1001, 33256),
(1001, 33257),
(1001, 33259),
(1001, 33261),
(1001, 33263),
(1001, 33265),
(1001, 33268),
(1001, 33272),
(1001, 35272),
(1001, 40323),
(1001, 42293),
(1001, 43764),
(1001, 43771),
(1001, 44097),
(1001, 44098),
(1001, 44099),
(1001, 44100),
(1001, 44101),
(1001, 44102),
(1001, 44104),
(1001, 44105),
(1001, 44106),
(1001, 45245),
(1001, 45619),
(1001, 46682),
(1001, 46687),
(1001, 46899),
(1001, 53284),
(1001, 57079),
(1001, 57097),
(1001, 57100),
(1001, 57102),
(1001, 57107),
(1001, 57111),
(1001, 57139),
(1001, 57286),
(1001, 57288),
(1001, 57291),
(1001, 57294),
(1001, 57325),
(1001, 57327),
(1001, 57329),
(1001, 57332),
(1001, 57334),
(1001, 57356),
(1001, 57358),
(1001, 57360),
(1001, 57363),
(1001, 57365),
(1001, 57367),
(1001, 57371),
(1001, 57373),
(1001, 57399),
(1001, 58468),
(1001, 58479),
(1001, 59230),
(1001, 59690),
(1001, 59699),
(1001, 62349),
(1001, 64057),
(1001, 65247),
(1001, 65365),
(1001, 65410),
(1001, 65412),
(1001, 65414),
(1001, 65415),
(1001, 65416),
(1001, 66623),
(1001, 66624),
(1001, 69559),
(1001, 18125),
(1001, 18141),
(1001, 23697),
-- Blessing of Might
(1002, 19740),
(1002, 25782),
(1002, 56520),
-- Battle Shout
(1003, 6673),
-- Blessing of Might, Battle Shout
(1004, -1002),
(1004, -1003),
-- Blessing of Wisdom
(1005, 19742),
(1005, 25894),
(1005, 56521),
-- Blessing of Kings
(1006, 20217),
(1006, 25898),
(1006, 43223),
(1006, 56525),
(1006, 58054),
-- Blessing of Sanctuary
(1007, 20911),
(1007, 25899),
-- Blessing of Protection
(1008, 41450),
(1008, 23415),
-- Blessing of Light
(1009, 32770),
-- Blessings
(1010, -1002),
(1010, -1005),
(1010, -1006),
(1010, -1007),
(1010, -1008),
(1010, -1009),
-- Commanding shout, Battle Shout
(1011, 469),
(1011, -1003);
/*!40000 ALTER TABLE `spell_group` ENABLE KEYS */; /*!40000 ALTER TABLE `spell_group` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;
@@ -6761,26 +6876,41 @@ LOCK TABLES `spell_scripts` WRITE;
UNLOCK TABLES; UNLOCK TABLES;
-- --
-- Table structure for table `spell_stack_masks` -- Table structure for table `spell_group_stack_rules`
-- --
DROP TABLE IF EXISTS `spell_stack_masks`; DROP TABLE IF EXISTS `spell_group_stack_rules`;
/*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */; /*!40101 SET character_set_client = utf8 */;
CREATE TABLE `spell_stack_masks` ( DROP TABLE IF EXISTS `spell_group_stack_rules`;
`id` int(32) unsigned NOT NULL default '0', CREATE TABLE `spell_group_stack_rules` (
`mask` int(64) unsigned NOT NULL default '0', `group_id` INT(11) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) `stack_rule` TINYINT(3) NOT NULL DEFAULT 0,
PRIMARY KEY (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
-- --
-- Dumping data for table `spell_stack_masks` -- Dumping data for table `spell_group_stack_rules`
-- --
LOCK TABLES `spell_stack_masks` WRITE; LOCK TABLES `spell_group_stack_rules` WRITE;
/*!40000 ALTER TABLE `spell_stack_masks` DISABLE KEYS */; /*!40000 ALTER TABLE `spell_group_stack_rules` DISABLE KEYS */;
/*!40000 ALTER TABLE `spell_stack_masks` ENABLE KEYS */; INSERT INTO spell_group_stack_rules (`group_id`, `stack_rule`) VALUES
(1, 1),
(2, 1),
(1001, 1),
(1002, 1),
(1003, 1),
(1004, 1),
(1005, 1),
(1006, 1),
(1007, 1),
(1008, 1),
(1009, 1),
(1010, 2),
(1011, 1);
/*!40000 ALTER TABLE `spell_group_stack_rules` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;
-- --
@@ -6797,7 +6927,7 @@ CREATE TABLE `spell_ranks` (
) ENGINE=MYISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Spell Rank Data'; ) ENGINE=MYISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Spell Rank Data';
-- --
-- Dumping data for table `spell_stack_masks` -- Dumping data for table `spell_ranks`
-- --
LOCK TABLES `spell_ranks` WRITE; LOCK TABLES `spell_ranks` WRITE;
+1 -1
View File
@@ -508,7 +508,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "spell_target_position", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL }, { "spell_target_position", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL },
{ "spell_threats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellThreatsCommand, "", NULL }, { "spell_threats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellThreatsCommand, "", NULL },
{ "spell_disabled", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellDisabledCommand, "", NULL }, { "spell_disabled", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellDisabledCommand, "", NULL },
{ "spell_stack_masks", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellStackMasksCommand, "", NULL }, { "spell_group_stack_rules", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellGroupStackRulesCommand, "", NULL },
{ "trinity_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadTrinityStringCommand, "", NULL }, { "trinity_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadTrinityStringCommand, "", NULL },
{ "auctions", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAuctionsCommand, "", NULL }, { "auctions", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAuctionsCommand, "", NULL },
{ "waypoint_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadWpScriptsCommand, "", NULL }, { "waypoint_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadWpScriptsCommand, "", NULL },
+1 -1
View File
@@ -421,7 +421,7 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleReloadSpellThreatsCommand(const char* args); bool HandleReloadSpellThreatsCommand(const char* args);
bool HandleReloadSpellPetAurasCommand(const char* args); bool HandleReloadSpellPetAurasCommand(const char* args);
bool HandleReloadSpellDisabledCommand(const char* args); bool HandleReloadSpellDisabledCommand(const char* args);
bool HandleReloadSpellStackMasksCommand(const char* args); bool HandleReloadSpellGroupStackRulesCommand(const char* args);
bool HandleReloadAuctionsCommand(const char* args); bool HandleReloadAuctionsCommand(const char* args);
bool HandleReloadWpScriptsCommand(const char* args); bool HandleReloadWpScriptsCommand(const char* args);
+5 -5
View File
@@ -659,7 +659,7 @@ bool ChatHandler::HandleReloadAllSpellCommand(const char*)
HandleReloadSpellScriptTargetCommand("a"); HandleReloadSpellScriptTargetCommand("a");
HandleReloadSpellTargetPositionCommand("a"); HandleReloadSpellTargetPositionCommand("a");
HandleReloadSpellThreatsCommand("a"); HandleReloadSpellThreatsCommand("a");
HandleReloadSpellStackMasksCommand("a"); HandleReloadSpellGroupStackRulesCommand("a");
HandleReloadSpellPetAurasCommand("a"); HandleReloadSpellPetAurasCommand("a");
HandleReloadSpellDisabledCommand("a"); HandleReloadSpellDisabledCommand("a");
return true; return true;
@@ -1094,11 +1094,11 @@ bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
return true; return true;
} }
bool ChatHandler::HandleReloadSpellStackMasksCommand(const char*) bool ChatHandler::HandleReloadSpellGroupStackRulesCommand(const char*)
{ {
sLog.outString( "Re-Loading Spell stacking masks..." ); sLog.outString( "Re-Loading Spell Group Stack Rules..." );
spellmgr.LoadSpellStackMasks(); spellmgr.LoadSpellGroupStackRules();
SendGlobalGMSysMessage("DB table `spell_stack_masks` (spell stacking masks) reloaded."); SendGlobalGMSysMessage("DB table `spell_group_stack_rules` (spell stacking definitions) reloaded.");
return true; return true;
} }
+14 -29
View File
@@ -3216,44 +3216,29 @@ void Spell::EffectEnergize(uint32 i)
} }
// get all available elixirs by mask and spell level // get all available elixirs by mask and spell level
std::list<uint32> avalibleElixirs; std::set<uint32> avalibleElixirs;
if (!guardianFound) if (!guardianFound)
{ spellmgr.GetSetOfSpellsInSpellGroup(SPELL_GROUP_ELIXIR_GUARDIAN, avalibleElixirs);
SpellGroupSpellMapBounds guardianGroup = spellmgr.GetSpellGroupSpellMapBounds(SPELL_GROUP_ELIXIR_GUARDIAN);
for ( SpellGroupSpellMap::const_iterator itr = guardianGroup.first; itr != guardianGroup.second ; ++itr)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->second);
if (spellInfo && (spellInfo->spellLevel < m_spellInfo->spellLevel || spellInfo->spellLevel > unitTarget->getLevel()))
continue;
if(spellmgr.IsSpellMemberOfSpellGroup(itr->second, SPELL_GROUP_ELIXIR_SHATTRATH))
continue;
if(spellmgr.IsSpellMemberOfSpellGroup(itr->second, SPELL_GROUP_ELIXIR_UNSTABLE))
continue;
avalibleElixirs.push_back(itr->second);
}
}
if (!battleFound) if (!battleFound)
spellmgr.GetSetOfSpellsInSpellGroup(SPELL_GROUP_ELIXIR_BATTLE, avalibleElixirs);
for (std::set<uint32>::iterator itr = avalibleElixirs.begin(); itr != avalibleElixirs.end() ;)
{ {
SpellGroupSpellMapBounds battleGroup = spellmgr.GetSpellGroupSpellMapBounds(SPELL_GROUP_ELIXIR_BATTLE); SpellEntry const *spellInfo = sSpellStore.LookupEntry(*itr);
for ( SpellGroupSpellMap::const_iterator itr = battleGroup.first; itr != battleGroup.second ; ++itr) if (spellInfo->spellLevel < m_spellInfo->spellLevel || spellInfo->spellLevel > unitTarget->getLevel())
{ avalibleElixirs.erase(itr++);
SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->second); else if(spellmgr.IsSpellMemberOfSpellGroup(*itr, SPELL_GROUP_ELIXIR_SHATTRATH))
if (spellInfo && (spellInfo->spellLevel < m_spellInfo->spellLevel || spellInfo->spellLevel > unitTarget->getLevel())) avalibleElixirs.erase(itr++);
continue; else if(spellmgr.IsSpellMemberOfSpellGroup(*itr, SPELL_GROUP_ELIXIR_UNSTABLE))
if(spellmgr.IsSpellMemberOfSpellGroup(itr->second, SPELL_GROUP_ELIXIR_SHATTRATH)) avalibleElixirs.erase(itr++);
continue; else
if(spellmgr.IsSpellMemberOfSpellGroup(itr->second, SPELL_GROUP_ELIXIR_UNSTABLE)) ++itr;
continue;
avalibleElixirs.push_back(itr->second);
} }
}
avalibleElixirs.unique();
if (!avalibleElixirs.empty()) if (!avalibleElixirs.empty())
{ {
// cast random elixir on target // cast random elixir on target
uint32 rand_spell = urand(0,avalibleElixirs.size()-1); uint32 rand_spell = urand(0,avalibleElixirs.size()-1);
std::list<uint32>::iterator itr = avalibleElixirs.begin(); std::set<uint32>::iterator itr = avalibleElixirs.begin();
std::advance(itr, rand_spell); std::advance(itr, rand_spell);
m_caster->CastSpell(unitTarget,*itr,true,m_CastItem); m_caster->CastSpell(unitTarget,*itr,true,m_CastItem);
} }
+72 -84
View File
@@ -510,14 +510,6 @@ SpellSpecific GetSpellSpecific(SpellEntry const * spellInfo)
else if(drink) else if(drink)
return SPELL_SPECIFIC_DRINK; return SPELL_SPECIFIC_DRINK;
} }
// Well Fed buffs (must be exclusive with Food / Drink replenishment effects, or else Well Fed will cause them to be removed)
// SpellIcon 2560 is Spell 46687, does not have this flag
else if ((spellInfo->AttributesEx2 & SPELL_ATTR_EX2_FOOD_BUFF) || spellInfo->SpellIconID == 2560)
return SPELL_SPECIFIC_WELL_FED;
// this may be a hack
//else if((spellInfo->AttributesEx2 & SPELL_ATTR_EX2_FOOD_BUFF)
// && !spellInfo->Category)
// return SPELL_WELL_FED;
// scrolls effects // scrolls effects
else else
{ {
@@ -555,8 +547,6 @@ SpellSpecific GetSpellSpecific(SpellEntry const * spellInfo)
} }
case SPELLFAMILY_WARRIOR: case SPELLFAMILY_WARRIOR:
{ {
if (spellInfo->SpellFamilyFlags[1] & 0x000080)
return SPELL_SPECIFIC_POSITIVE_SHOUT;
if (spellInfo->Id == 12292) // Death Wish if (spellInfo->Id == 12292) // Death Wish
return SPELL_SPECIFIC_WARRIOR_ENRAGE; return SPELL_SPECIFIC_WARRIOR_ENRAGE;
@@ -579,12 +569,6 @@ SpellSpecific GetSpellSpecific(SpellEntry const * spellInfo)
} }
case SPELLFAMILY_PRIEST: case SPELLFAMILY_PRIEST:
{ {
// "Well Fed" buff from Blessed Sunfruit, Blessed Sunfruit Juice, Alterac Spring Water
if ((spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_SITTING) &&
(spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK) &&
(spellInfo->SpellIconID == 52 || spellInfo->SpellIconID == 79))
return SPELL_SPECIFIC_WELL_FED;
// Divine Spirit and Prayer of Spirit // Divine Spirit and Prayer of Spirit
if (spellInfo->SpellFamilyFlags[0] & 0x20) if (spellInfo->SpellFamilyFlags[0] & 0x20)
return SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT; return SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT;
@@ -608,9 +592,6 @@ SpellSpecific GetSpellSpecific(SpellEntry const * spellInfo)
if (IsSealSpell(spellInfo)) if (IsSealSpell(spellInfo))
return SPELL_SPECIFIC_SEAL; return SPELL_SPECIFIC_SEAL;
if (spellInfo->SpellFamilyFlags[0] & 0x11010002)
return SPELL_SPECIFIC_BLESSING;
if (spellInfo->SpellFamilyFlags[0] & 0x00002190) if (spellInfo->SpellFamilyFlags[0] & 0x00002190)
return SPELL_SPECIFIC_HAND; return SPELL_SPECIFIC_HAND;
@@ -632,9 +613,6 @@ SpellSpecific GetSpellSpecific(SpellEntry const * spellInfo)
break; break;
} }
case SPELLFAMILY_POTION:
return spellmgr.GetSpellElixirSpecific(spellInfo->Id);
case SPELLFAMILY_DEATHKNIGHT: case SPELLFAMILY_DEATHKNIGHT:
if (spellInfo->Id == SPELL_BLOOD_PRESENCE_48266 || spellInfo->Id == SPELL_FROST_PRESENCE_48263 || spellInfo->Id == SPELL_UNHOLY_PRESENCE_48265) if (spellInfo->Id == SPELL_BLOOD_PRESENCE_48266 || spellInfo->Id == SPELL_FROST_PRESENCE_48263 || spellInfo->Id == SPELL_UNHOLY_PRESENCE_48265)
//if (spellInfo->Category == 47) //if (spellInfo->Category == 47)
@@ -662,9 +640,6 @@ SpellSpecific GetSpellSpecific(SpellEntry const * spellInfo)
} }
} }
} }
// elixirs can have different families, but potion most ofc.
if(SpellSpecific sp = spellmgr.GetSpellElixirSpecific(spellInfo->Id))
return sp;
return SPELL_SPECIFIC_NORMAL; return SPELL_SPECIFIC_NORMAL;
} }
@@ -680,10 +655,8 @@ bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific s
case SPELL_SPECIFIC_STING: case SPELL_SPECIFIC_STING:
case SPELL_SPECIFIC_CURSE: case SPELL_SPECIFIC_CURSE:
case SPELL_SPECIFIC_ASPECT: case SPELL_SPECIFIC_ASPECT:
case SPELL_SPECIFIC_POSITIVE_SHOUT:
case SPELL_SPECIFIC_JUDGEMENT: case SPELL_SPECIFIC_JUDGEMENT:
case SPELL_SPECIFIC_WARLOCK_CORRUPTION: case SPELL_SPECIFIC_WARLOCK_CORRUPTION:
case SPELL_SPECIFIC_BLESSING:
return spellSpec1==spellSpec2; return spellSpec1==spellSpec2;
default: default:
return false; return false;
@@ -701,13 +674,11 @@ bool IsSingleFromSpellSpecificPerTarget(SpellSpecific spellSpec1, SpellSpecific
case SPELL_SPECIFIC_ELEMENTAL_SHIELD: case SPELL_SPECIFIC_ELEMENTAL_SHIELD:
case SPELL_SPECIFIC_MAGE_POLYMORPH: case SPELL_SPECIFIC_MAGE_POLYMORPH:
case SPELL_SPECIFIC_PRESENCE: case SPELL_SPECIFIC_PRESENCE:
case SPELL_SPECIFIC_WELL_FED:
case SPELL_SPECIFIC_CHARM: case SPELL_SPECIFIC_CHARM:
case SPELL_SPECIFIC_SCROLL: case SPELL_SPECIFIC_SCROLL:
case SPELL_SPECIFIC_WARRIOR_ENRAGE: case SPELL_SPECIFIC_WARRIOR_ENRAGE:
case SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE: case SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE:
case SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT: case SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT:
case SPELL_SPECIFIC_POSITIVE_SHOUT:
return spellSpec1==spellSpec2; return spellSpec1==spellSpec2;
case SPELL_SPECIFIC_FOOD: case SPELL_SPECIFIC_FOOD:
return spellSpec2==SPELL_SPECIFIC_FOOD return spellSpec2==SPELL_SPECIFIC_FOOD
@@ -719,16 +690,6 @@ bool IsSingleFromSpellSpecificPerTarget(SpellSpecific spellSpec1, SpellSpecific
return spellSpec2==SPELL_SPECIFIC_FOOD return spellSpec2==SPELL_SPECIFIC_FOOD
|| spellSpec2==SPELL_SPECIFIC_DRINK || spellSpec2==SPELL_SPECIFIC_DRINK
|| spellSpec2==SPELL_SPECIFIC_FOOD_AND_DRINK; || spellSpec2==SPELL_SPECIFIC_FOOD_AND_DRINK;
case SPELL_SPECIFIC_BATTLE_ELIXIR:
return spellSpec2==SPELL_SPECIFIC_BATTLE_ELIXIR
|| spellSpec2==SPELL_SPECIFIC_FLASK_ELIXIR;
case SPELL_SPECIFIC_GUARDIAN_ELIXIR:
return spellSpec2==SPELL_SPECIFIC_GUARDIAN_ELIXIR
|| spellSpec2==SPELL_SPECIFIC_FLASK_ELIXIR;
case SPELL_SPECIFIC_FLASK_ELIXIR:
return spellSpec2==SPELL_SPECIFIC_BATTLE_ELIXIR
|| spellSpec2==SPELL_SPECIFIC_GUARDIAN_ELIXIR
|| spellSpec2==SPELL_SPECIFIC_FLASK_ELIXIR;
default: default:
return false; return false;
} }
@@ -1488,6 +1449,8 @@ void SpellMgr::LoadSpellGroups()
barGoLink bar( result->GetRowCount() ); barGoLink bar( result->GetRowCount() );
std::set<uint32> groups;
do do
{ {
Field *fields = result->Fetch(); Field *fields = result->Fetch();
@@ -1495,45 +1458,73 @@ void SpellMgr::LoadSpellGroups()
bar.step(); bar.step();
uint32 group_id = fields[0].GetUInt32(); uint32 group_id = fields[0].GetUInt32();
uint32 spell_id = fields[1].GetUInt32(); if (group_id <= SPELL_GROUP_DB_RANGE_MIN && group_id >= SPELL_GROUP_CORE_RANGE_MAX)
{
sLog.outErrorDb("SpellGroup id %u listed in `spell_groups` is in core range, but is not defined in core!", group_id);
continue;
}
int32 spell_id = fields[1].GetInt32();
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell_id); groups.insert(std::set<uint32>::value_type(group_id));
mSpellGroupSpell.insert(SpellGroupSpellMap::value_type((SpellGroup)group_id, spell_id));
} while( result->NextRow() );
for (SpellGroupSpellMap::iterator itr = mSpellGroupSpell.begin(); itr!= mSpellGroupSpell.end() ; )
{
if (itr->second < 0)
{
if (groups.find(abs(itr->second)) == groups.end())
{
sLog.outErrorDb("SpellGroup id %u listed in `spell_groups` does not exist", abs(itr->second));
mSpellGroupSpell.erase(itr++);
}
else
++itr;
}
else
{
SpellEntry const* spellInfo = sSpellStore.LookupEntry(itr->second);
if (!spellInfo) if (!spellInfo)
{ {
sLog.outErrorDb("Spell %u listed in `spell_group` does not exist", spell_id); sLog.outErrorDb("Spell %u listed in `spell_group` does not exist", itr->second);
continue; mSpellGroupSpell.erase(itr++);
} }
else if (GetSpellRank(itr->second) > 1)
if (GetSpellRank(spell_id) > 1)
{ {
sLog.outErrorDb("Spell %u listed in `spell_group` is not first rank of spell", spell_id); sLog.outErrorDb("Spell %u listed in `spell_group` is not first rank of spell", itr->second);
continue; mSpellGroupSpell.erase(itr++);
}
else
++itr;
}
} }
if (IsSpellMemberOfSpellGroup(spell_id, (SpellGroup)group_id)) for (std::set<uint32>::iterator groupItr = groups.begin() ; groupItr != groups.end() ; ++groupItr)
{ {
sLog.outErrorDb("Spell %u listed in `spell_group` is added twice to one group %u", spell_id, group_id); std::set<uint32> spells;
continue; GetSetOfSpellsInSpellGroup(SpellGroup(*groupItr), spells);
}
mSpellSpellGroup.insert(SpellSpellGroupMap::value_type(spell_id, (SpellGroup)group_id));
mSpellGroupSpell.insert(SpellGroupSpellMap::value_type((SpellGroup)group_id, spell_id));
for (std::set<uint32>::iterator spellItr = spells.begin() ; spellItr != spells.end() ; ++spellItr)
{
++count; ++count;
} while( result->NextRow() ); mSpellSpellGroup.insert(SpellSpellGroupMap::value_type(*spellItr, SpellGroup(*groupItr)));
}
}
sLog.outString(); sLog.outString();
sLog.outString( ">> Loaded %u spell group definitions", count ); sLog.outString( ">> Loaded %u spell group definitions", count );
} }
void SpellMgr::LoadSpellStackMasks() void SpellMgr::LoadSpellGroupStackRules()
{ {
mSpellStackMasks.clear(); // need for reload case mSpellGroupStack.clear(); // need for reload case
uint32 count = 0; uint32 count = 0;
// 0 1 // 0 1
QueryResult_AutoPtr result = WorldDatabase.Query("SELECT id, mask FROM spell_stack_masks"); QueryResult_AutoPtr result = WorldDatabase.Query("SELECT group_id, stack_rule FROM spell_group_stack_rules");
if( !result ) if( !result )
{ {
@@ -1542,7 +1533,7 @@ void SpellMgr::LoadSpellStackMasks()
bar.step(); bar.step();
sLog.outString(); sLog.outString();
sLog.outString( ">> Loaded %u spell stacking masks definitions", count ); sLog.outString( ">> Loaded %u spell group stack rules", count );
return; return;
} }
@@ -1554,24 +1545,29 @@ void SpellMgr::LoadSpellStackMasks()
bar.step(); bar.step();
uint32 id = fields[0].GetUInt32(); uint32 group_id = fields[0].GetUInt32();
uint8 mask = fields[1].GetUInt32(); uint8 stack_rule = fields[1].GetUInt32();
if (stack_rule >= SPELL_GROUP_STACK_RULE_MAX)
SpellEntry const* spellInfo = sSpellStore.LookupEntry(id);
if (!spellInfo)
{ {
sLog.outErrorDb("Spell %u listed in `spell_stack_masks` does not exist", id); sLog.outErrorDb("SpellGroupStackRule %u listed in `spell_group_stack_rules` does not exist", stack_rule);
continue; continue;
} }
mSpellStackMasks[id] = mask; SpellGroupSpellMapBounds spellGroup = GetSpellGroupSpellMapBounds((SpellGroup)group_id);
if (spellGroup.first == spellGroup.second)
{
sLog.outErrorDb("SpellGroup id %u listed in `spell_group_stack_rules` does not exist", group_id);
continue;
}
mSpellGroupStack[(SpellGroup)group_id] = (SpellGroupStackRule)stack_rule;
++count; ++count;
} while( result->NextRow() ); } while( result->NextRow() );
sLog.outString(); sLog.outString();
sLog.outString( ">> Loaded %u spell stacking masks definitions", count ); sLog.outString( ">> Loaded %u spell group stack rules", count );
} }
void SpellMgr::LoadSpellThreats() void SpellMgr::LoadSpellThreats()
@@ -3075,12 +3071,14 @@ bool SpellMgr::CanAurasStack(SpellEntry const *spellInfo_1, SpellEntry const *sp
|| sameCaster && IsSingleFromSpellSpecificPerCaster(spellSpec_1, spellSpec_2)) || sameCaster && IsSingleFromSpellSpecificPerCaster(spellSpec_1, spellSpec_2))
return false; return false;
// Stacking Checks by family masks SpellGroupStackRule stackRule = CheckSpellGroupStackRules(spellInfo_1->Id, spellInfo_2->Id);
uint32 spellSpecMask_1 = GetSpellStackMask(spellInfo_1->Id); if (stackRule)
uint32 spellSpecMask_2 = GetSpellStackMask(spellInfo_2->Id); {
if (spellSpecMask_1 && spellSpecMask_2) if (stackRule == SPELL_GROUP_STACK_RULE_EXCLUSIVE)
if ((spellSpecMask_1 & spellSpecMask_2) != 0)
return false; return false;
if (sameCaster && stackRule == SPELL_GROUP_STACK_RULE_EXCLUSIVE_FROM_SAME_CASTER)
return false;
}
if(spellInfo_1->SpellFamilyName != spellInfo_2->SpellFamilyName) if(spellInfo_1->SpellFamilyName != spellInfo_2->SpellFamilyName)
return true; return true;
@@ -3092,18 +3090,8 @@ bool SpellMgr::CanAurasStack(SpellEntry const *spellInfo_1, SpellEntry const *sp
return true; return true;
// check same periodic auras // check same periodic auras
for (uint32 i = 0; i < 3; ++i) for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{ {
// area auras should not stack (shaman totem)
if(spellInfo_1->Effect[i] != SPELL_EFFECT_APPLY_AURA
&& spellInfo_1->Effect[i] != SPELL_EFFECT_PERSISTENT_AREA_AURA)
continue;
// not channeled AOE effects should not stack (blizzard should, but Consecration should not)
if((IsAreaEffectTarget[spellInfo_1->EffectImplicitTargetA[i]] || IsAreaEffectTarget[spellInfo_1->EffectImplicitTargetB[i]])
&& !IsChanneledSpell(spellInfo_1))
continue;
switch(spellInfo_1->EffectApplyAuraName[i]) switch(spellInfo_1->EffectApplyAuraName[i])
{ {
// DOT or HOT from different casters will stack // DOT or HOT from different casters will stack
@@ -3157,7 +3145,7 @@ bool SpellMgr::CanAurasStack(SpellEntry const *spellInfo_1, SpellEntry const *sp
spellInfo_2 = sSpellStore.LookupEntry(spellId_2); spellInfo_2 = sSpellStore.LookupEntry(spellId_2);
//if spells do not have the same effect or aura or miscvalue, they will stack //if spells do not have the same effect or aura or miscvalue, they will stack
for (uint32 i = 0; i < 3; ++i) for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if(spellInfo_1->Effect[i] != spellInfo_2->Effect[i] if(spellInfo_1->Effect[i] != spellInfo_2->Effect[i]
|| spellInfo_1->EffectApplyAuraName[i] != spellInfo_2->EffectApplyAuraName[i] || spellInfo_1->EffectApplyAuraName[i] != spellInfo_2->EffectApplyAuraName[i]
|| spellInfo_1->EffectMiscValue[i] != spellInfo_2->EffectMiscValue[i]) // paladin resist aura || spellInfo_1->EffectMiscValue[i] != spellInfo_2->EffectMiscValue[i]) // paladin resist aura
+76 -53
View File
@@ -145,7 +145,6 @@ enum SpellSpecific
{ {
SPELL_SPECIFIC_NORMAL = 0, SPELL_SPECIFIC_NORMAL = 0,
SPELL_SPECIFIC_SEAL = 1, SPELL_SPECIFIC_SEAL = 1,
SPELL_SPECIFIC_BLESSING = 2,
SPELL_SPECIFIC_AURA = 3, SPELL_SPECIFIC_AURA = 3,
SPELL_SPECIFIC_STING = 4, SPELL_SPECIFIC_STING = 4,
SPELL_SPECIFIC_CURSE = 5, SPELL_SPECIFIC_CURSE = 5,
@@ -155,13 +154,8 @@ enum SpellSpecific
SPELL_SPECIFIC_MAGE_ARMOR = 9, SPELL_SPECIFIC_MAGE_ARMOR = 9,
SPELL_SPECIFIC_ELEMENTAL_SHIELD = 10, SPELL_SPECIFIC_ELEMENTAL_SHIELD = 10,
SPELL_SPECIFIC_MAGE_POLYMORPH = 11, SPELL_SPECIFIC_MAGE_POLYMORPH = 11,
SPELL_SPECIFIC_POSITIVE_SHOUT = 12,
SPELL_SPECIFIC_JUDGEMENT = 13, SPELL_SPECIFIC_JUDGEMENT = 13,
SPELL_SPECIFIC_BATTLE_ELIXIR = 14,
SPELL_SPECIFIC_GUARDIAN_ELIXIR = 15,
SPELL_SPECIFIC_FLASK_ELIXIR = 16,
SPELL_SPECIFIC_WARLOCK_CORRUPTION= 17, SPELL_SPECIFIC_WARLOCK_CORRUPTION= 17,
SPELL_SPECIFIC_WELL_FED = 18,
SPELL_SPECIFIC_FOOD = 19, SPELL_SPECIFIC_FOOD = 19,
SPELL_SPECIFIC_DRINK = 20, SPELL_SPECIFIC_DRINK = 20,
SPELL_SPECIFIC_FOOD_AND_DRINK = 21, SPELL_SPECIFIC_FOOD_AND_DRINK = 21,
@@ -173,8 +167,6 @@ enum SpellSpecific
SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT = 27, SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT = 27,
SPELL_SPECIFIC_HAND = 28, SPELL_SPECIFIC_HAND = 28,
SPELL_SPECIFIC_PHASE = 29, SPELL_SPECIFIC_PHASE = 29,
SPELL_SPECIFIC_BLESSING_OF_MIGHT = 30,
SPELL_SPECIFIC_BATTLE_SHOUT = 31
}; };
#define SPELL_LINKED_MAX_SPELLS 200000 #define SPELL_LINKED_MAX_SPELLS 200000
@@ -639,19 +631,30 @@ enum SpellGroup
SPELL_GROUP_ELIXIR_GUARDIAN = 2, SPELL_GROUP_ELIXIR_GUARDIAN = 2,
SPELL_GROUP_ELIXIR_UNSTABLE = 3, SPELL_GROUP_ELIXIR_UNSTABLE = 3,
SPELL_GROUP_ELIXIR_SHATTRATH = 4, SPELL_GROUP_ELIXIR_SHATTRATH = 4,
SPELL_GROUP_WELL_FED = 5, SPELL_GROUP_CORE_RANGE_MAX = 5,
}; };
// spell_id, group_id #define SPELL_GROUP_DB_RANGE_MIN 1000
// spell_id, group_id // native if true, inherited if false
typedef std::multimap<uint32, SpellGroup > SpellSpellGroupMap; typedef std::multimap<uint32, SpellGroup > SpellSpellGroupMap;
typedef std::pair<SpellSpellGroupMap::const_iterator,SpellSpellGroupMap::const_iterator> SpellSpellGroupMapBounds; typedef std::pair<SpellSpellGroupMap::const_iterator,SpellSpellGroupMap::const_iterator> SpellSpellGroupMapBounds;
// group_id, spell_id // group_id, spell_id
typedef std::multimap<SpellGroup, uint32> SpellGroupSpellMap; typedef std::multimap<SpellGroup, int32> SpellGroupSpellMap;
typedef std::pair<SpellGroupSpellMap::const_iterator,SpellGroupSpellMap::const_iterator> SpellGroupSpellMapBounds; typedef std::pair<SpellGroupSpellMap::const_iterator,SpellGroupSpellMap::const_iterator> SpellGroupSpellMapBounds;
enum SpellGroupStackRule
{
SPELL_GROUP_STACK_RULE_DEFAULT = 0,
SPELL_GROUP_STACK_RULE_EXCLUSIVE = 1,
SPELL_GROUP_STACK_RULE_EXCLUSIVE_FROM_SAME_CASTER = 2,
};
#define SPELL_GROUP_STACK_RULE_MAX 3
typedef std::map<SpellGroup, SpellGroupStackRule> SpellGroupStackMap;
typedef std::map<uint32, uint16> SpellThreatMap; typedef std::map<uint32, uint16> SpellThreatMap;
typedef std::map<uint32, uint32> SpellStackMaskMap;
// Spell script target related declarations (accessed using SpellMgr functions) // Spell script target related declarations (accessed using SpellMgr functions)
enum SpellScriptTargetType enum SpellScriptTargetType
@@ -889,46 +892,73 @@ class SpellMgr
{ {
return SpellGroupSpellMapBounds(mSpellGroupSpell.lower_bound(group_id),mSpellGroupSpell.upper_bound(group_id)); return SpellGroupSpellMapBounds(mSpellGroupSpell.lower_bound(group_id),mSpellGroupSpell.upper_bound(group_id));
} }
SpellSpecific GetSpellElixirSpecific(uint32 spellid) const void GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set<uint32>& foundSpells) const
{ {
SpellSpecific spec = SPELL_SPECIFIC_NORMAL; std::set<SpellGroup> usedGroups;
SpellSpellGroupMapBounds spellGroup = GetSpellSpellGroupMapBounds(spellid); GetSetOfSpellsInSpellGroup(group_id, foundSpells, usedGroups);
for ( SpellSpellGroupMap::const_iterator itr = spellGroup.first; itr != spellGroup.second ; ++itr) }
void GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set<uint32>& foundSpells, std::set<SpellGroup>& usedGroups) const
{ {
if (itr->second == SPELL_GROUP_ELIXIR_BATTLE if (usedGroups.find(group_id) != usedGroups.end())
|| itr->second == SPELL_GROUP_ELIXIR_GUARDIAN) return;
usedGroups.insert(group_id);
SpellGroupSpellMapBounds groupSpell = GetSpellGroupSpellMapBounds(group_id);
for ( SpellGroupSpellMap::const_iterator itr = groupSpell.first; itr != groupSpell.second ; ++itr)
{ {
if (spec) if (itr->second < 0)
{ {
spec = SPELL_SPECIFIC_FLASK_ELIXIR; SpellGroup currGroup = (SpellGroup)abs(itr->second);
GetSetOfSpellsInSpellGroup(currGroup, foundSpells, usedGroups);
}
else
{
foundSpells.insert(itr->second);
}
}
}
SpellGroupStackRule CheckSpellGroupStackRules(uint32 spellid_1, uint32 spellid_2) const
{
spellid_1 = GetFirstSpellInChain(spellid_1);
spellid_2 = GetFirstSpellInChain(spellid_2);
// find SpellGroups which are common for both spells
SpellSpellGroupMapBounds spellGroup1 = GetSpellSpellGroupMapBounds(spellid_1);
std::set<SpellGroup> groups;
for ( SpellSpellGroupMap::const_iterator itr = spellGroup1.first; itr != spellGroup1.second ; ++itr)
{
if (IsSpellMemberOfSpellGroup(spellid_2, itr->second))
{
bool add = true;
SpellGroupSpellMapBounds groupSpell = GetSpellGroupSpellMapBounds(itr->second);
for ( SpellGroupSpellMap::const_iterator itr2 = groupSpell.first; itr2 != groupSpell.second ; ++itr2)
{
if (itr2->second < 0)
{
SpellGroup currGroup = (SpellGroup)abs(itr2->second);
if (IsSpellMemberOfSpellGroup(spellid_1, currGroup) && IsSpellMemberOfSpellGroup(spellid_2, currGroup))
{
add = false;
break; break;
} }
else if (itr->second == SPELL_GROUP_ELIXIR_BATTLE)
spec = SPELL_SPECIFIC_BATTLE_ELIXIR;
else if (itr->second == SPELL_GROUP_ELIXIR_GUARDIAN)
spec = SPELL_SPECIFIC_GUARDIAN_ELIXIR;
} }
} }
return spec; if (add)
groups.insert(itr->second);
}
} }
// Used for stacking in spellmgr, and possibly in cancast checks SpellGroupStackRule rule = SPELL_GROUP_STACK_RULE_DEFAULT;
SpellStackMaskMap const& GetSpellStackMasksMap() const { return mSpellStackMasks; }
uint32 GetSpellStackMask(uint32 spellid) const for (std::set<SpellGroup>::iterator itr = groups.begin() ; itr!= groups.end() ; ++itr)
{ {
SpellStackMaskMap::const_iterator itr = mSpellStackMasks.find(spellid); SpellGroupStackMap::const_iterator found = mSpellGroupStack.find(*itr);
if(itr!=mSpellStackMasks.end()) if (found != mSpellGroupStack.end())
return itr->second; rule = found->second;
if (rule)
// Not found, try lookup for 1 spell rank if exist break;
if (uint32 rank_1 = GetFirstSpellInChain(spellid))
{
SpellStackMaskMap::const_iterator itr2 = mSpellStackMasks.find(rank_1);
if(itr2 != mSpellStackMasks.end())
return itr2->second;
} }
return rule;
return 0x0;
} }
uint16 GetSpellThreat(uint32 spellid) const uint16 GetSpellThreat(uint32 spellid) const
@@ -1072,19 +1102,12 @@ class SpellMgr
uint8 IsHighRankOfSpell(uint32 spell1,uint32 spell2) const uint8 IsHighRankOfSpell(uint32 spell1,uint32 spell2) const
{ {
SpellChainMap::const_iterator itr = mSpellChains.find(spell1); SpellChainMap::const_iterator itr1 = mSpellChains.find(spell1);
SpellChainMap::const_iterator itr2 = mSpellChains.find(spell2);
uint32 rank2 = GetSpellRank(spell2); if (itr1->second.first == itr2->second.first)
if (itr1->second.rank <= itr2->second.rank)
// not ordered correctly by rank value
if(itr == mSpellChains.end() || !rank2 || itr->second.rank <= rank2)
return false;
// check present in same rank chain
for (; itr != mSpellChains.end(); itr = mSpellChains.find(itr->second.prev))
if(itr->second.prev==spell2)
return true; return true;
return false; return false;
} }
@@ -1264,7 +1287,7 @@ class SpellMgr
void LoadPetLevelupSpellMap(); void LoadPetLevelupSpellMap();
void LoadPetDefaultSpells(); void LoadPetDefaultSpells();
void LoadSpellAreas(); void LoadSpellAreas();
void LoadSpellStackMasks(); void LoadSpellGroupStackRules();
private: private:
bool _isPositiveSpell(uint32 spellId, bool deep) const; bool _isPositiveSpell(uint32 spellId, bool deep) const;
@@ -1286,7 +1309,7 @@ class SpellMgr
SpellPetAuraMap mSpellPetAuraMap; SpellPetAuraMap mSpellPetAuraMap;
SpellCustomAttribute mSpellCustomAttr; SpellCustomAttribute mSpellCustomAttr;
SpellLinkedMap mSpellLinkedMap; SpellLinkedMap mSpellLinkedMap;
SpellStackMaskMap mSpellStackMasks; SpellGroupStackMap mSpellGroupStack;
SpellEnchantProcEventMap mSpellEnchantProcEventMap; SpellEnchantProcEventMap mSpellEnchantProcEventMap;
EnchantCustomAttribute mEnchantCustomAttr; EnchantCustomAttribute mEnchantCustomAttr;
PetLevelupSpellMap mPetLevelupSpellMap; PetLevelupSpellMap mPetLevelupSpellMap;
+3 -3
View File
@@ -1311,7 +1311,7 @@ void World::SetInitialWorldSettings()
sLog.outString("Loading Spell Required Data..."); sLog.outString("Loading Spell Required Data...");
spellmgr.LoadSpellRequired(); spellmgr.LoadSpellRequired();
sLog.outString("Loading Spell Elixir types..."); sLog.outString("Loading Spell Group types...");
spellmgr.LoadSpellGroups(); spellmgr.LoadSpellGroups();
sLog.outString("Loading Spell Learn Skills..."); sLog.outString("Loading Spell Learn Skills...");
@@ -1329,8 +1329,8 @@ void World::SetInitialWorldSettings()
sLog.outString("Loading Aggro Spells Definitions..."); sLog.outString("Loading Aggro Spells Definitions...");
spellmgr.LoadSpellThreats(); spellmgr.LoadSpellThreats();
sLog.outString("Loading Spell Stacking masks..."); sLog.outString("Loading Spell Group Stack Rules...");
spellmgr.LoadSpellStackMasks(); spellmgr.LoadSpellGroupStackRules();
sLog.outString("Loading NPC Texts..."); sLog.outString("Loading NPC Texts...");
objmgr.LoadGossipText(); objmgr.LoadGossipText();