[Core/Threat] SpellThreat-Calculation revamped

short:
  - Threat is now distributed blizzlike (almost)

long:
  - Percent- and AP-Modifieres got add
  - Threat is now propperly distributed through multiple enemies
  - Most spells will cause initial threat in an amount equal to their SpellLevel
  - Energize-Effects will now be treated like healing (threat-wise)
  - Tanks got their missing +43% passive threat tacked on
  - Paladins are still missing 'Salvation' and will not only cause half threat with healing (essentially 25% of the amount healed)
This commit is contained in:
sarjuuk
2011-08-21 12:00:36 +02:00
committed by QAston
parent dc01541111
commit b40bf69319
9 changed files with 245 additions and 59 deletions

View File

@@ -0,0 +1,134 @@
-- ----------
-- Tank Class Passive Threat
-- ----------
DELETE FROM spell_linked_spell WHERE spell_effect IN (57340, 57339);
INSERT INTO spell_linked_spell VALUES
(7376, 57339, 2, 'Defensive Stance Passive - Tank Class Passive Threat'),
(21178, 57339, 2, 'Bear Form (Passive2) - Tank Class Passive Threat'),
(25780, 57340, 2, 'Righteous Fury - Tank Class Passive Threat'),
(48263, 57340, 2, 'Frost Presence - Tank Class Passive Threat');
-- ----------
-- restructure spell_threat
-- ----------
TRUNCATE TABLE `spell_threat`;
ALTER TABLE `spell_threat` CHANGE `Threat` `flatMod` int(6);
ALTER TABLE `spell_threat` ADD COLUMN `pctMod` FLOAT NOT NULL DEFAULT 1.0 COMMENT 'threat multiplier for damage/healing' AFTER `flatMod`;
ALTER TABLE `spell_threat` ADD COLUMN `apPctMod` FLOAT NOT NULL DEFAULT 0.0 COMMENT 'additional threat bonus from attack power' AFTER `pctMod`;
INSERT INTO `spell_threat` VALUES
-- Other
-- Src: SELECT id, SpellNameEN, RankEN FROM `Spell` WHERE `DescriptionEN` LIKE '%threat%' AND `SpellFamilyName` <> '0' AND NOT (Attributes & 0x40) GROUP BY SpellNameEN ORDER BY RankEN DESC;
(5676, 0, 2.00, 0.0), -- Searing Pain (Rank 1) (Warlock)
(28176, 0, 0.00, 0.0), -- Fel Armor - Heal (Rank 1) (Warlock) [Assumption]
(8056, 0, 2.00, 0.0), -- Frost Shock (Rank 1) (Shaman) [Assumption]
(26688, 0, 0.00, 0.0), -- Anesthetic Poison - Proc (Rank 1) (Rogue)
(15237, 0, 0.00, 0.0), -- Holy Nova - Heal (Rank 1) (Priest)
(23455, 0, 0.00, 0.0), -- Holy Nova - Damage (Rank 1) (Priest)
(32546, 0, 0.50, 0.0), -- Binding Heal (Rank 1) (Priest) [Assumption]
(33619, 0, 0.00, 0.0), -- Reflective Shield - Proc (Priest)
(2139, 180, 1.00, 0.0), -- Counterspell (Mage) [Assumption]
-- Death Knight
-- Src: http://www.tankspot.com/showthread.php?40485-Death-Knight-threat-values&p=113584#post113584
(63611, 0, 0.00, 0.0), -- Blood Presence - Heal
(45524, 240, 1.00, 0.0), -- Chains of Ice
(43265, 0, 1.90, 0.0), -- Death and Decay
(49576, 110, 1.00, 0.0), -- Death Grip
(48743, 0, 0.00, 0.0), -- Death Pact
(65142, 0, 0.00, 0.0), -- Ebon Plague
(47568, 0, 0.00, 0.0), -- Empower Rune Weapon
(51209, 112, 1.00, 0.0), -- Hungering Cold
(49039, 110, 1.00, 0.0), -- Lichborn
(56815, 0, 1.75, 0.0), -- Rune Strike
(50422, 0, 0.00, 0.0), -- Scent of Blood - Proc
(55090, 51, 1.00, 0.0), -- Scourge Strike (Rank 1)
(55265, 63, 1.00, 0.0), -- Scourge Strike (Rank 2)
(55270, 98, 1.00, 0.0), -- Scourge Strike (Rank 3)
(55271, 120, 1.00, 0.0), -- Scourge Strike (Rank 4)
(49916, 138, 1.00, 0.0), -- Strangulate
(50181, 0, 0.00, 0.0), -- Vendetta - Proc
-- Druid
-- Src: http://www.tankspot.com/showthread.php?47813-WOTLK-Bear-Threat-Values&p=200948#post200948
(17057, 0, 0.00, 0.0), -- Furor - Proc
(5211, 53, 1.00, 0.0), -- Bash (Rank 3)
(6798, 105, 1.00, 0.0), -- Bash (Rank 2)
(8983, 158, 1.00, 0.0), -- Bash (Rank 1)
(45334, 40, 1.00, 0.0), -- Feral Charge (Bear) - Root
(19675, 80, 1.00, 0.0), -- Feral Charge (Bear) - Interrupt
(34299, 0, 0.00, 0.0), -- Improved Leader of the Pack - Heal
(6807, 13, 1.00, 0.0), -- Maul (Rank 1)
(6808, 20, 1.00, 0.0), -- Maul (Rank 2)
(6809, 27, 1.00, 0.0), -- Maul (Rank 3)
(8972, 47, 1.00, 0.0), -- Maul (Rank 4)
(9745, 75, 1.00, 0.0), -- Maul (Rank 5)
(9880, 106, 1.00, 0.0), -- Maul (Rank 6)
(9881, 140, 1.00, 0.0), -- Maul (Rank 7)
(26996, 212, 1.00, 0.0), -- Maul (Rank 8)
(48479, 345, 1.00, 0.0), -- Maul (Rank 9)
(48480, 422, 1.00, 0.0), -- Maul (Rank 10)
(60089, 638, 1.00, 0.0), -- Faerie Fire (Feral) - Proc
(33745, 182, 0.50, 0.0), -- Lacerate (Rank 1)
(48567, 409, 0.50, 0.0), -- Lacerate (Rank 2)
(48568, 515, 0.50, 0.0), -- Lacerate (Rank 3)
(779, 0, 1.50, 0.0), -- Swipe (Bear) (Rank 1)
(5209, 98, 1.00, 0.0), -- Challenging Roar
(29166, 0, 10.0, 0.0), -- Innervate [base is 5 per 1 mana]
-- Paladin
-- Src: http://www.tankspot.com/showthread.php?39761-Paladin-Threat-Values-(Updated-for-3.2.2)&p=103813#post103813
(7294, 0, 2.00, 0.0), -- Retribution Aura
(20185, 0, 0.00, 0.0), -- Judgement of Light
(19742, 0, 0.00, 0.0), -- Blessing of Wisdom (Rank 1)
(25894, 0, 0.00, 0.0), -- Greater Blessing of Wisdom (Rank 1)
(20470, 0, 0.00, 0.0), -- Righteous Fury
(498, 0, 0.00, 0.0), -- Divine Protection
-- Warrior
-- Src: http://www.tankspot.com/showthread.php?39775-WoW-3.0-Threat-Values-(Warrior)&p=103972#post103972
(845, 8, 1.00, 0.0), -- Cleave (Rank 1)
(7369, 15, 1.00, 0.0), -- Cleave (Rank 2)
(11608, 25, 1.00, 0.0), -- Cleave (Rank 3)
(11609, 35, 1.00, 0.0), -- Cleave (Rank 4)
(20569, 48, 1.00, 0.0), -- Cleave (Rank 5)
(25231, 68, 1.00, 0.0), -- Cleave (Rank 6)
(47519, 95, 1.00, 0.0), -- Cleave (Rank 7)
(47520, 112, 1.00, 0.0), -- Cleave (Rank 8)
(78, 5, 1.00, 0.0), -- Heroic Strike (Rank 1)
(284, 10, 1.00, 0.0), -- Heroic Strike (Rank 2)
(285, 16, 1.00, 0.0), -- Heroic Strike (Rank 3)
(1608, 22, 1.00, 0.0), -- Heroic Strike (Rank 4)
(11564, 31, 1.00, 0.0), -- Heroic Strike (Rank 5)
(11565, 48, 1.00, 0.0), -- Heroic Strike (Rank 6)
(11566, 70, 1.00, 0.0), -- Heroic Strike (Rank 7)
(11567, 92, 1.00, 0.0), -- Heroic Strike (Rank 8)
(25286, 104, 1.00, 0.0), -- Heroic Strike (Rank 9)
(29707, 121, 1.00, 0.0), -- Heroic Strike (Rank 10)
(30324, 164, 1.00, 0.0), -- Heroic Strike (Rank 11)
(47449, 224, 1.00, 0.0), -- Heroic Strike (Rank 12)
(47450, 259, 1.00, 0.0), -- Heroic Strike (Rank 13)
(57755, 0, 1.50, 0.0), -- Heroic Throw
(6572, 7, 1.00, 0.0), -- Revenge (Rank 1)
(6574, 11, 1.00, 0.0), -- Revenge (Rank 2)
(7379, 15, 1.00, 0.0), -- Revenge (Rank 3)
(11600, 27, 1.00, 0.0), -- Revenge (Rank 4)
(11601, 41, 1.00, 0.0), -- Revenge (Rank 5)
(25288, 53, 1.00, 0.0), -- Revenge (Rank 6)
(25269, 58, 1.00, 0.0), -- Revenge (Rank 7)
(30357, 71, 1.00, 0.0), -- Revenge (Rank 8)
(57823, 121, 1.00, 0.0), -- Revenge (Rank 9)
(23922, 228, 1.00, 0.0), -- Shield Slam (Rank 1)
(23923, 268, 1.00, 0.0), -- Shield Slam (Rank 2)
(23924, 307, 1.00, 0.0), -- Shield Slam (Rank 3)
(23925, 347, 1.00, 0.0), -- Shield Slam (Rank 4)
(25258, 387, 1.00, 0.0), -- Shield Slam (Rank 5)
(30356, 426, 1.00, 0.0), -- Shield Slam (Rank 6)
(47487, 650, 1.00, 0.0), -- Shield Slam (Rank 7)
(47488, 770, 1.00, 0.0), -- Shield Slam (Rank 8)
(1464, 18, 1.00, 0.0), -- Slam (Rank 1)
(8820, 24, 1.00, 0.0), -- Slam (Rank 2)
(11604, 38, 1.00, 0.0), -- Slam (Rank 3)
(11605, 49, 1.00, 0.0), -- Slam (Rank 4)
(25241, 59, 1.00, 0.0), -- Slam (Rank 5)
(25242, 78, 1.00, 0.0), -- Slam (Rank 6)
(47474, 123, 1.00, 0.0), -- Slam (Rank 7)
(47475, 140, 1.00, 0.0), -- Slam (Rank 8)
(7386, 345, 1.00, 0.05), -- Sunder Armor
(20243, 0, 1.00, 0.05), -- Devastate (Rank 1)
(6343, 0, 1.85, 0.0); -- Thunder Clap (Rank 1)

View File

@@ -40,10 +40,9 @@ void HostileRefManager::threatAssist(Unit* victim, float baseThreat, SpellInfo c
threat /= getSize();
while (ref)
{
if (victim == getOwner())
ref->addThreat(threat); // It is faster to modify the threat durectly if possible
else
ref->getSource()->addThreat(victim, threat);
if (ThreatCalcHelper::isValidProcess(victim, ref->getSource()->getOwner(), threatSpell))
ref->getSource()->doAddThreat(victim, threat);
ref = ref->next();
}
}

View File

@@ -36,8 +36,14 @@ float ThreatCalcHelper::calcThreat(Unit* hatedUnit, Unit* /*hatingUnit*/, float
{
if (threatSpell)
{
if (threatSpell->AttributesEx & SPELL_ATTR1_NO_THREAT)
return 0.0f;
if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(threatSpell->Id))
if (threatEntry->pctMod != 1.0f)
threat *= threatEntry->pctMod;
// Energize is not affected by Mods
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
if (threatSpell->Effects[i].Effect == SPELL_EFFECT_ENERGIZE || threatSpell->Effects[i].ApplyAuraName == SPELL_AURA_PERIODIC_ENERGIZE)
return threat;
if (Player* modOwner = hatedUnit->GetSpellModOwner())
modOwner->ApplySpellMod(threatSpell->Id, SPELLMOD_THREAT, threat);
@@ -46,7 +52,7 @@ float ThreatCalcHelper::calcThreat(Unit* hatedUnit, Unit* /*hatingUnit*/, float
return hatedUnit->ApplyTotalThreatModifier(threat, schoolMask);
}
bool ThreatCalcHelper::isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellInfo const* /*threatSpell*/)
bool ThreatCalcHelper::isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellInfo const* threatSpell)
{
//function deals with adding threat and adding players and pets into ThreatList
//mobs, NPCs, guards have ThreatList and HateOfflineList
@@ -68,6 +74,10 @@ bool ThreatCalcHelper::isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellIn
if (!hatedUnit->isAlive() || !hatingUnit->isAlive())
return false;
// spell not causing threat
if (threatSpell && threatSpell->AttributesEx & SPELL_ATTR1_NO_THREAT)
return false;
ASSERT(hatingUnit->GetTypeId() == TYPEID_UNIT);
return true;

View File

@@ -791,12 +791,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
victim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DIRECT_DAMAGE, spellProto ? spellProto->Id : 0);
if (victim->GetTypeId() != TYPEID_PLAYER)
{
if (spellProto && IsDamageToThreatSpell(spellProto))
victim->AddThreat(this, damage * 2.0f, damageSchoolMask, spellProto);
else
victim->AddThreat(this, (float)damage, damageSchoolMask, spellProto);
}
else // victim is a player
{
// random durability for items (HIT TAKEN)
@@ -10334,6 +10329,9 @@ void Unit::EnergizeBySpell(Unit* victim, uint32 spellID, uint32 damage, Powers p
SendEnergizeSpellLog(victim, spellID, damage, powerType);
// needs to be called after sending spell log
victim->ModifyPower(powerType, damage);
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID);
victim->getHostileRefManager().threatAssist(this, float(damage) * 0.5f, spellInfo);
}
uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack)
@@ -11622,30 +11620,6 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) cons
return false;
}
bool Unit::IsDamageToThreatSpell(SpellInfo const* spellInfo) const
{
if (!spellInfo)
return false;
switch(spellInfo->SpellFamilyName)
{
case SPELLFAMILY_WARLOCK:
if (spellInfo->SpellFamilyFlags[0] == 0x100) // Searing Pain
return true;
break;
case SPELLFAMILY_SHAMAN:
if (spellInfo->SpellFamilyFlags[0] == SPELLFAMILYFLAG_SHAMAN_FROST_SHOCK)
return true;
break;
case SPELLFAMILY_DEATHKNIGHT:
if (spellInfo->SpellFamilyFlags[1] == 0x20000000) // Rune Strike
return true;
break;
}
return false;
}
void Unit::MeleeDamageBonus(Unit* victim, uint32 *pdamage, WeaponAttackType attType, SpellInfo const* spellProto)
{
if (!victim)

View File

@@ -1572,8 +1572,6 @@ class Unit : public WorldObject
void SendPlaySpellVisual(uint32 id);
void SendPlaySpellImpact(uint64 guid, uint32 id);
bool IsDamageToThreatSpell(SpellInfo const* spellInfo) const;
void DeMorph();
void SendAttackStateUpdate(CalcDamageInfo *damageInfo);

View File

@@ -4536,20 +4536,53 @@ void Spell::TakeReagents()
void Spell::HandleThreatSpells()
{
if (!m_targets.GetUnitTarget())
if (m_UniqueTargetInfo.empty())
return;
if (!m_targets.GetUnitTarget()->CanHaveThreatList())
if ((m_spellInfo->AttributesEx & SPELL_ATTR1_NO_THREAT) ||
(m_spellInfo->AttributesEx3 & SPELL_ATTR3_NO_INITIAL_AGGRO))
return;
uint16 threat = sSpellMgr->GetSpellThreat(m_spellInfo->Id);
float threat = 0.0f;
if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
{
if (threatEntry->apPctMod != 0.0f)
threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
if (!threat)
threat += threatEntry->flatMod;
}
else if ((m_spellInfo->AttributesCu & SPELL_ATTR0_CU_NO_INITIAL_THREAT) == 0)
threat += m_spellInfo->SpellLevel;
// past this point only multiplicative effects occur
if (threat == 0.0f)
return;
m_targets.GetUnitTarget()->AddThreat(m_caster, float(threat));
// since 2.0.1 threat from positive effects also is distributed among all targets, so the overall caused threat is at most the defined bonus
threat /= m_UniqueTargetInfo.size();
sLog->outStaticDebug("Spell %u, rank %u, added an additional %i threat", m_spellInfo->Id, m_spellInfo->GetRank(), threat);
for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
if (ihit->missCondition != SPELL_MISS_NONE)
continue;
Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
if (!target)
continue;
// positive spells distribute threat among all units that are in combat with target, like healing
if (m_spellInfo->_IsPositiveSpell())
target->getHostileRefManager().threatAssist(m_caster, threat, m_spellInfo);
// for negative spells threat gets distributed among affected targets
else
{
if (!target->CanHaveThreatList())
continue;
target->AddThreat(m_caster, threat, m_spellInfo->GetSchoolMask(), m_spellInfo);
}
}
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell %u, added an additional %f threat for %s %u target(s)", m_spellInfo->Id, threat, m_spellInfo->_IsPositiveSpell() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
}
void Spell::HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i)

View File

@@ -186,7 +186,7 @@ enum SpellCustomAttributes
SPELL_ATTR0_CU_CONE_BACK = 0x00000002,
SPELL_ATTR0_CU_CONE_LINE = 0x00000004,
SPELL_ATTR0_CU_SHARE_DAMAGE = 0x00000008,
SPELL_ATTR0_CU_NONE1 = 0x00000010, // UNUSED
SPELL_ATTR0_CU_NO_INITIAL_THREAT = 0x00000010,
SPELL_ATTR0_CU_NONE2 = 0x00000020, // UNUSED
SPELL_ATTR0_CU_AURA_CC = 0x00000040,
SPELL_ATTR0_CU_DIRECT_DAMAGE = 0x00000100,

View File

@@ -965,13 +965,19 @@ SpellBonusEntry const* SpellMgr::GetSpellBonusData(uint32 spellId) const
return NULL;
}
uint16 SpellMgr::GetSpellThreat(uint32 spellid) const
SpellThreatEntry const* SpellMgr::GetSpellThreatEntry(uint32 spellID) const
{
SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellid);
if (itr == mSpellThreatMap.end())
return 0;
return itr->second;
SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellID);
if (itr != mSpellThreatMap.end())
return &itr->second;
else
{
uint32 firstSpell = GetFirstSpellInChain(spellID);
SpellThreatMap::const_iterator itr = mSpellThreatMap.find(firstSpell);
if (itr != mSpellThreatMap.end())
return &itr->second;
}
return NULL;
}
SkillLineAbilityMapBounds SpellMgr::GetSkillLineAbilityMapBounds(uint32 spell_id) const
@@ -1940,8 +1946,8 @@ void SpellMgr::LoadSpellThreats()
uint32 count = 0;
// 0 1
QueryResult result = WorldDatabase.Query("SELECT entry, Threat FROM spell_threat");
// 0 1 2 3
QueryResult result = WorldDatabase.Query("SELECT entry, flatMod, pctMod, apPctMod FROM spell_threat");
if (!result)
{
sLog->outString(">> Loaded 0 aggro generating spells");
@@ -1954,7 +1960,6 @@ void SpellMgr::LoadSpellThreats()
Field *fields = result->Fetch();
uint32 entry = fields[0].GetUInt32();
uint16 Threat = fields[1].GetUInt16();
if (!GetSpellInfo(entry))
{
@@ -1962,12 +1967,16 @@ void SpellMgr::LoadSpellThreats()
continue;
}
mSpellThreatMap[entry] = Threat;
SpellThreatEntry ste;
ste.flatMod = fields[1].GetInt16();
ste.pctMod = fields[2].GetFloat();
ste.apPctMod = fields[3].GetFloat();
++count;
mSpellThreatMap[entry] = ste;
count++;
} while (result->NextRow());
sLog->outString(">> Loaded %u aggro generating spells in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
sLog->outString(">> Loaded %u SpellThreatEntries in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
sLog->outString();
}
@@ -2634,6 +2643,18 @@ void SpellMgr::LoadSpellCustomAttr()
case SPELL_AURA_MOD_STUN:
spellInfo->AttributesCu |= SPELL_ATTR0_CU_AURA_CC;
break;
case SPELL_AURA_PERIODIC_HEAL:
case SPELL_AURA_PERIODIC_DAMAGE:
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
case SPELL_AURA_PERIODIC_LEECH:
case SPELL_AURA_PERIODIC_MANA_LEECH:
case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
case SPELL_AURA_PERIODIC_ENERGIZE:
case SPELL_AURA_OBS_MOD_HEALTH:
case SPELL_AURA_OBS_MOD_POWER:
case SPELL_AURA_POWER_BURN_MANA:
spellInfo->AttributesCu |= SPELL_ATTR0_CU_NO_INITIAL_THREAT;
break;
}
switch (spellInfo->Effects[j].Effect)
@@ -2646,6 +2667,16 @@ void SpellMgr::LoadSpellCustomAttr()
case SPELL_EFFECT_HEAL:
spellInfo->AttributesCu |= SPELL_ATTR0_CU_DIRECT_DAMAGE;
break;
case SPELL_EFFECT_POWER_DRAIN:
case SPELL_EFFECT_POWER_BURN:
case SPELL_EFFECT_HEAL_MAX_HEALTH:
case SPELL_EFFECT_HEALTH_LEECH:
case SPELL_EFFECT_HEAL_PCT:
case SPELL_EFFECT_ENERGIZE_PCT:
case SPELL_EFFECT_ENERGIZE:
case SPELL_EFFECT_HEAL_MECHANICAL:
spellInfo->AttributesCu |= SPELL_ATTR0_CU_NO_INITIAL_THREAT;
break;
case SPELL_EFFECT_CHARGE:
case SPELL_EFFECT_CHARGE_DEST:
case SPELL_EFFECT_JUMP:

View File

@@ -349,7 +349,14 @@ enum SpellGroupStackRule
typedef std::map<SpellGroup, SpellGroupStackRule> SpellGroupStackMap;
typedef std::map<uint32, uint16> SpellThreatMap;
struct SpellThreatEntry
{
int32 flatMod; // flat threat-value for this Spell - default: 0
float pctMod; // threat-multiplier for this Spell - default: 1.0f
float apPctMod; // Pct of AP that is added as Threat - default: 0.0f
};
typedef std::map<uint32, SpellThreatEntry> SpellThreatMap;
// Spell script target related declarations (accessed using SpellMgr functions)
enum SpellScriptTargetType
@@ -603,7 +610,7 @@ class SpellMgr
SpellBonusEntry const* GetSpellBonusData(uint32 spellId) const;
// Spell threat table
uint16 GetSpellThreat(uint32 spellid) const;
SpellThreatEntry const* GetSpellThreatEntry(uint32 spellID) const;
SkillLineAbilityMapBounds GetSkillLineAbilityMapBounds(uint32 spell_id) const;