*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_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_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_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.'),
@@ -5100,17 +5101,17 @@ DROP TABLE IF EXISTS `spell_group`;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `spell_group` (
`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`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Spell System';
/*!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;
/*!40000 ALTER TABLE `spell_elixir` DISABLE KEYS */;
/*!40000 ALTER TABLE `spell_group` DISABLE KEYS */;
INSERT INTO `spell_group` (`id`, `spell_id`) VALUES
-- SPELL_GROUP_ELIXIR_BATTLE
(1, 2367),
@@ -5284,14 +5285,128 @@ INSERT INTO `spell_group` (`id`, `spell_id`) VALUES
(4, 41611),
(4, 46837),
(4, 46839),
-- SPELL_GROUP_WELL_FED
(5, 18191),
(5, 18192),
(5, 18193),
(5, 18194),
(5, 18222),
(5, 22730),
(5, 25661);
-- 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);
/*!40000 ALTER TABLE `spell_group` ENABLE KEYS */;
UNLOCK TABLES;
@@ -6761,26 +6876,41 @@ LOCK TABLES `spell_scripts` WRITE;
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 character_set_client = utf8 */;
CREATE TABLE `spell_stack_masks` (
`id` int(32) unsigned NOT NULL default '0',
`mask` int(64) unsigned NOT NULL default '0',
PRIMARY KEY (`id`)
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;
/*!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;
/*!40000 ALTER TABLE `spell_stack_masks` DISABLE KEYS */;
/*!40000 ALTER TABLE `spell_stack_masks` ENABLE KEYS */;
LOCK TABLES `spell_group_stack_rules` WRITE;
/*!40000 ALTER TABLE `spell_group_stack_rules` DISABLE 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;
--
@@ -6797,7 +6927,7 @@ CREATE TABLE `spell_ranks` (
) 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;
+1 -1
View File
@@ -508,7 +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 },
{ "spell_group_stack_rules", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellGroupStackRulesCommand, "", NULL },
{ "trinity_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadTrinityStringCommand, "", NULL },
{ "auctions", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAuctionsCommand, "", 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 HandleReloadSpellPetAurasCommand(const char* args);
bool HandleReloadSpellDisabledCommand(const char* args);
bool HandleReloadSpellStackMasksCommand(const char* args);
bool HandleReloadSpellGroupStackRulesCommand(const char* args);
bool HandleReloadAuctionsCommand(const char* args);
bool HandleReloadWpScriptsCommand(const char* args);
+5 -5
View File
@@ -659,7 +659,7 @@ bool ChatHandler::HandleReloadAllSpellCommand(const char*)
HandleReloadSpellScriptTargetCommand("a");
HandleReloadSpellTargetPositionCommand("a");
HandleReloadSpellThreatsCommand("a");
HandleReloadSpellStackMasksCommand("a");
HandleReloadSpellGroupStackRulesCommand("a");
HandleReloadSpellPetAurasCommand("a");
HandleReloadSpellDisabledCommand("a");
return true;
@@ -1094,11 +1094,11 @@ bool ChatHandler::HandleReloadSpellThreatsCommand(const char*)
return true;
}
bool ChatHandler::HandleReloadSpellStackMasksCommand(const char*)
bool ChatHandler::HandleReloadSpellGroupStackRulesCommand(const char*)
{
sLog.outString( "Re-Loading Spell stacking masks..." );
spellmgr.LoadSpellStackMasks();
SendGlobalGMSysMessage("DB table `spell_stack_masks` (spell stacking masks) reloaded.");
sLog.outString( "Re-Loading Spell Group Stack Rules..." );
spellmgr.LoadSpellGroupStackRules();
SendGlobalGMSysMessage("DB table `spell_group_stack_rules` (spell stacking definitions) reloaded.");
return true;
}
+14 -29
View File
@@ -3216,44 +3216,29 @@ void Spell::EffectEnergize(uint32 i)
}
// get all available elixirs by mask and spell level
std::list<uint32> avalibleElixirs;
std::set<uint32> avalibleElixirs;
if (!guardianFound)
{
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);
}
}
spellmgr.GetSetOfSpellsInSpellGroup(SPELL_GROUP_ELIXIR_GUARDIAN, avalibleElixirs);
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);
for ( SpellGroupSpellMap::const_iterator itr = battleGroup.first; itr != battleGroup.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);
SpellEntry const *spellInfo = sSpellStore.LookupEntry(*itr);
if (spellInfo->spellLevel < m_spellInfo->spellLevel || spellInfo->spellLevel > unitTarget->getLevel())
avalibleElixirs.erase(itr++);
else if(spellmgr.IsSpellMemberOfSpellGroup(*itr, SPELL_GROUP_ELIXIR_SHATTRATH))
avalibleElixirs.erase(itr++);
else if(spellmgr.IsSpellMemberOfSpellGroup(*itr, SPELL_GROUP_ELIXIR_UNSTABLE))
avalibleElixirs.erase(itr++);
else
++itr;
}
}
avalibleElixirs.unique();
if (!avalibleElixirs.empty())
{
// cast random elixir on target
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);
m_caster->CastSpell(unitTarget,*itr,true,m_CastItem);
}
+72 -84
View File
@@ -510,14 +510,6 @@ SpellSpecific GetSpellSpecific(SpellEntry const * spellInfo)
else if(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
else
{
@@ -555,8 +547,6 @@ SpellSpecific GetSpellSpecific(SpellEntry const * spellInfo)
}
case SPELLFAMILY_WARRIOR:
{
if (spellInfo->SpellFamilyFlags[1] & 0x000080)
return SPELL_SPECIFIC_POSITIVE_SHOUT;
if (spellInfo->Id == 12292) // Death Wish
return SPELL_SPECIFIC_WARRIOR_ENRAGE;
@@ -579,12 +569,6 @@ SpellSpecific GetSpellSpecific(SpellEntry const * spellInfo)
}
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
if (spellInfo->SpellFamilyFlags[0] & 0x20)
return SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT;
@@ -608,9 +592,6 @@ SpellSpecific GetSpellSpecific(SpellEntry const * spellInfo)
if (IsSealSpell(spellInfo))
return SPELL_SPECIFIC_SEAL;
if (spellInfo->SpellFamilyFlags[0] & 0x11010002)
return SPELL_SPECIFIC_BLESSING;
if (spellInfo->SpellFamilyFlags[0] & 0x00002190)
return SPELL_SPECIFIC_HAND;
@@ -632,9 +613,6 @@ SpellSpecific GetSpellSpecific(SpellEntry const * spellInfo)
break;
}
case SPELLFAMILY_POTION:
return spellmgr.GetSpellElixirSpecific(spellInfo->Id);
case SPELLFAMILY_DEATHKNIGHT:
if (spellInfo->Id == SPELL_BLOOD_PRESENCE_48266 || spellInfo->Id == SPELL_FROST_PRESENCE_48263 || spellInfo->Id == SPELL_UNHOLY_PRESENCE_48265)
//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;
}
@@ -680,10 +655,8 @@ bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific s
case SPELL_SPECIFIC_STING:
case SPELL_SPECIFIC_CURSE:
case SPELL_SPECIFIC_ASPECT:
case SPELL_SPECIFIC_POSITIVE_SHOUT:
case SPELL_SPECIFIC_JUDGEMENT:
case SPELL_SPECIFIC_WARLOCK_CORRUPTION:
case SPELL_SPECIFIC_BLESSING:
return spellSpec1==spellSpec2;
default:
return false;
@@ -701,13 +674,11 @@ bool IsSingleFromSpellSpecificPerTarget(SpellSpecific spellSpec1, SpellSpecific
case SPELL_SPECIFIC_ELEMENTAL_SHIELD:
case SPELL_SPECIFIC_MAGE_POLYMORPH:
case SPELL_SPECIFIC_PRESENCE:
case SPELL_SPECIFIC_WELL_FED:
case SPELL_SPECIFIC_CHARM:
case SPELL_SPECIFIC_SCROLL:
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
@@ -719,16 +690,6 @@ bool IsSingleFromSpellSpecificPerTarget(SpellSpecific spellSpec1, SpellSpecific
return spellSpec2==SPELL_SPECIFIC_FOOD
|| spellSpec2==SPELL_SPECIFIC_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:
return false;
}
@@ -1488,6 +1449,8 @@ void SpellMgr::LoadSpellGroups()
barGoLink bar( result->GetRowCount() );
std::set<uint32> groups;
do
{
Field *fields = result->Fetch();
@@ -1495,45 +1458,73 @@ void SpellMgr::LoadSpellGroups()
bar.step();
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)
{
sLog.outErrorDb("Spell %u listed in `spell_group` does not exist", spell_id);
continue;
sLog.outErrorDb("Spell %u listed in `spell_group` does not exist", itr->second);
mSpellGroupSpell.erase(itr++);
}
if (GetSpellRank(spell_id) > 1)
else if (GetSpellRank(itr->second) > 1)
{
sLog.outErrorDb("Spell %u listed in `spell_group` is not first rank of spell", spell_id);
continue;
sLog.outErrorDb("Spell %u listed in `spell_group` is not first rank of spell", itr->second);
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);
continue;
}
mSpellSpellGroup.insert(SpellSpellGroupMap::value_type(spell_id, (SpellGroup)group_id));
mSpellGroupSpell.insert(SpellGroupSpellMap::value_type((SpellGroup)group_id, spell_id));
std::set<uint32> spells;
GetSetOfSpellsInSpellGroup(SpellGroup(*groupItr), spells);
for (std::set<uint32>::iterator spellItr = spells.begin() ; spellItr != spells.end() ; ++spellItr)
{
++count;
} while( result->NextRow() );
mSpellSpellGroup.insert(SpellSpellGroupMap::value_type(*spellItr, SpellGroup(*groupItr)));
}
}
sLog.outString();
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;
// 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 )
{
@@ -1542,7 +1533,7 @@ void SpellMgr::LoadSpellStackMasks()
bar.step();
sLog.outString();
sLog.outString( ">> Loaded %u spell stacking masks definitions", count );
sLog.outString( ">> Loaded %u spell group stack rules", count );
return;
}
@@ -1554,24 +1545,29 @@ void SpellMgr::LoadSpellStackMasks()
bar.step();
uint32 id = fields[0].GetUInt32();
uint8 mask = fields[1].GetUInt32();
SpellEntry const* spellInfo = sSpellStore.LookupEntry(id);
if (!spellInfo)
uint32 group_id = fields[0].GetUInt32();
uint8 stack_rule = fields[1].GetUInt32();
if (stack_rule >= SPELL_GROUP_STACK_RULE_MAX)
{
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;
}
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;
} while( result->NextRow() );
sLog.outString();
sLog.outString( ">> Loaded %u spell stacking masks definitions", count );
sLog.outString( ">> Loaded %u spell group stack rules", count );
}
void SpellMgr::LoadSpellThreats()
@@ -3075,12 +3071,14 @@ 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)
SpellGroupStackRule stackRule = CheckSpellGroupStackRules(spellInfo_1->Id, spellInfo_2->Id);
if (stackRule)
{
if (stackRule == SPELL_GROUP_STACK_RULE_EXCLUSIVE)
return false;
if (sameCaster && stackRule == SPELL_GROUP_STACK_RULE_EXCLUSIVE_FROM_SAME_CASTER)
return false;
}
if(spellInfo_1->SpellFamilyName != spellInfo_2->SpellFamilyName)
return true;
@@ -3092,18 +3090,8 @@ bool SpellMgr::CanAurasStack(SpellEntry const *spellInfo_1, SpellEntry const *sp
return true;
// 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])
{
// 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);
//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]
|| spellInfo_1->EffectApplyAuraName[i] != spellInfo_2->EffectApplyAuraName[i]
|| 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_SEAL = 1,
SPELL_SPECIFIC_BLESSING = 2,
SPELL_SPECIFIC_AURA = 3,
SPELL_SPECIFIC_STING = 4,
SPELL_SPECIFIC_CURSE = 5,
@@ -155,13 +154,8 @@ enum SpellSpecific
SPELL_SPECIFIC_MAGE_ARMOR = 9,
SPELL_SPECIFIC_ELEMENTAL_SHIELD = 10,
SPELL_SPECIFIC_MAGE_POLYMORPH = 11,
SPELL_SPECIFIC_POSITIVE_SHOUT = 12,
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_WELL_FED = 18,
SPELL_SPECIFIC_FOOD = 19,
SPELL_SPECIFIC_DRINK = 20,
SPELL_SPECIFIC_FOOD_AND_DRINK = 21,
@@ -173,8 +167,6 @@ enum SpellSpecific
SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT = 27,
SPELL_SPECIFIC_HAND = 28,
SPELL_SPECIFIC_PHASE = 29,
SPELL_SPECIFIC_BLESSING_OF_MIGHT = 30,
SPELL_SPECIFIC_BATTLE_SHOUT = 31
};
#define SPELL_LINKED_MAX_SPELLS 200000
@@ -639,19 +631,30 @@ enum SpellGroup
SPELL_GROUP_ELIXIR_GUARDIAN = 2,
SPELL_GROUP_ELIXIR_UNSTABLE = 3,
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::pair<SpellSpellGroupMap::const_iterator,SpellSpellGroupMap::const_iterator> SpellSpellGroupMapBounds;
// 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;
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, uint32> SpellStackMaskMap;
// Spell script target related declarations (accessed using SpellMgr functions)
enum SpellScriptTargetType
@@ -889,46 +892,73 @@ class SpellMgr
{
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;
SpellSpellGroupMapBounds spellGroup = GetSpellSpellGroupMapBounds(spellid);
for ( SpellSpellGroupMap::const_iterator itr = spellGroup.first; itr != spellGroup.second ; ++itr)
std::set<SpellGroup> usedGroups;
GetSetOfSpellsInSpellGroup(group_id, foundSpells, usedGroups);
}
void GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set<uint32>& foundSpells, std::set<SpellGroup>& usedGroups) const
{
if (itr->second == SPELL_GROUP_ELIXIR_BATTLE
|| itr->second == SPELL_GROUP_ELIXIR_GUARDIAN)
if (usedGroups.find(group_id) != usedGroups.end())
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;
}
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
SpellStackMaskMap const& GetSpellStackMasksMap() const { return mSpellStackMasks; }
uint32 GetSpellStackMask(uint32 spellid) const
SpellGroupStackRule rule = SPELL_GROUP_STACK_RULE_DEFAULT;
for (std::set<SpellGroup>::iterator itr = groups.begin() ; itr!= groups.end() ; ++itr)
{
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;
SpellGroupStackMap::const_iterator found = mSpellGroupStack.find(*itr);
if (found != mSpellGroupStack.end())
rule = found->second;
if (rule)
break;
}
return 0x0;
return rule;
}
uint16 GetSpellThreat(uint32 spellid) const
@@ -1072,19 +1102,12 @@ class SpellMgr
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);
// 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)
if (itr1->second.first == itr2->second.first)
if (itr1->second.rank <= itr2->second.rank)
return true;
return false;
}
@@ -1264,7 +1287,7 @@ class SpellMgr
void LoadPetLevelupSpellMap();
void LoadPetDefaultSpells();
void LoadSpellAreas();
void LoadSpellStackMasks();
void LoadSpellGroupStackRules();
private:
bool _isPositiveSpell(uint32 spellId, bool deep) const;
@@ -1286,7 +1309,7 @@ class SpellMgr
SpellPetAuraMap mSpellPetAuraMap;
SpellCustomAttribute mSpellCustomAttr;
SpellLinkedMap mSpellLinkedMap;
SpellStackMaskMap mSpellStackMasks;
SpellGroupStackMap mSpellGroupStack;
SpellEnchantProcEventMap mSpellEnchantProcEventMap;
EnchantCustomAttribute mEnchantCustomAttr;
PetLevelupSpellMap mPetLevelupSpellMap;
+3 -3
View File
@@ -1311,7 +1311,7 @@ void World::SetInitialWorldSettings()
sLog.outString("Loading Spell Required Data...");
spellmgr.LoadSpellRequired();
sLog.outString("Loading Spell Elixir types...");
sLog.outString("Loading Spell Group types...");
spellmgr.LoadSpellGroups();
sLog.outString("Loading Spell Learn Skills...");
@@ -1329,8 +1329,8 @@ void World::SetInitialWorldSettings()
sLog.outString("Loading Aggro Spells Definitions...");
spellmgr.LoadSpellThreats();
sLog.outString("Loading Spell Stacking masks...");
spellmgr.LoadSpellStackMasks();
sLog.outString("Loading Spell Group Stack Rules...");
spellmgr.LoadSpellGroupStackRules();
sLog.outString("Loading NPC Texts...");
objmgr.LoadGossipText();