aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2016-10-17 01:52:40 -0300
committerjoschiwald <joschiwald.trinity@gmail.com>2017-10-03 20:53:49 +0200
commit2d75d8071bb6d85987bdc5d88ed2271822fcbcfd (patch)
tree01389c522f87cdff0be720bf66f9d0ca804beb90
parent4d5eacd3af8406e41f6f335355b1f860f2323ee1 (diff)
Core/Globals: compute aura diminishing return info at startup and cache it
Core/Entities: Save diminish return on an array instead of a linked list (cherry picked from commit 9b0fa51022fba3d5ece96dd0ac8399be01ea5b0f)
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp99
-rw-r--r--src/server/game/Entities/Unit/Unit.h25
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h2
-rw-r--r--src/server/game/Spells/Spell.cpp27
-rw-r--r--src/server/game/Spells/Spell.h4
-rw-r--r--src/server/game/Spells/SpellInfo.cpp416
-rw-r--r--src/server/game/Spells/SpellInfo.h489
-rw-r--r--src/server/game/Spells/SpellMgr.cpp394
-rw-r--r--src/server/game/Spells/SpellMgr.h7
-rw-r--r--src/server/game/World/World.cpp3
10 files changed, 767 insertions, 699 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 0afe6e08c37..cd6bf8073da 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -8987,54 +8987,47 @@ void Unit::ModSpellDurationTime(SpellInfo const* spellInfo, int32 & duration, Sp
DiminishingLevels Unit::GetDiminishing(DiminishingGroup group)
{
- for (Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i)
- {
- if (i->DRGroup != group)
- continue;
-
- if (!i->hitCount)
- return DIMINISHING_LEVEL_1;
+ DiminishingReturn& diminish = m_Diminishing[group];
+ if (!diminish.hitCount)
+ return DIMINISHING_LEVEL_1;
- if (!i->hitTime)
- return DIMINISHING_LEVEL_1;
+ if (!diminish.hitTime)
+ return DIMINISHING_LEVEL_1;
- // If last spell was cast more than 18 seconds ago - reset the count.
- if (i->stack == 0 && getMSTimeDiff(i->hitTime, getMSTime()) > 18 * IN_MILLISECONDS)
- {
- i->hitCount = DIMINISHING_LEVEL_1;
- return DIMINISHING_LEVEL_1;
- }
- // or else increase the count.
- else
- return DiminishingLevels(i->hitCount);
+ // If last spell was cast more than 18 seconds ago - reset the count.
+ if (!diminish.stack && GetMSTimeDiffToNow(diminish.hitTime) > 18 * IN_MILLISECONDS)
+ {
+ diminish.hitCount = DIMINISHING_LEVEL_1;
+ return DIMINISHING_LEVEL_1;
}
- return DIMINISHING_LEVEL_1;
+
+ return DiminishingLevels(diminish.hitCount);
}
-void Unit::IncrDiminishing(DiminishingGroup group)
+void Unit::IncrDiminishing(SpellInfo const* auraSpellInfo, bool triggered)
{
+ DiminishingGroup const group = auraSpellInfo->GetDiminishingReturnsGroupForSpell(triggered);
+ DiminishingLevels const maxLevel = auraSpellInfo->GetDiminishingReturnsMaxLevel(triggered);
+
// Checking for existing in the table
- for (Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i)
- {
- if (i->DRGroup != group)
- continue;
- if (int32(i->hitCount) < GetDiminishingReturnsMaxLevel(group))
- i->hitCount += 1;
- return;
- }
- m_Diminishing.push_back(DiminishingReturn(group, getMSTime(), DIMINISHING_LEVEL_2));
+ DiminishingReturn& diminish = m_Diminishing[group];
+ if (static_cast<int32>(diminish.hitCount) < maxLevel)
+ ++diminish.hitCount;
}
-float Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit* caster, DiminishingLevels Level, int32 limitduration)
+float Unit::ApplyDiminishingToDuration(SpellInfo const* auraSpellInfo, bool triggered, int32& duration, Unit* caster, DiminishingLevels previousLevel)
{
+ DiminishingGroup const group = auraSpellInfo->GetDiminishingReturnsGroupForSpell(triggered);
if (duration == -1 || group == DIMINISHING_NONE)
return 1.0f;
+ int32 const limitDuration = auraSpellInfo->GetDiminishingReturnsLimitDuration(triggered);
+
// test pet/charm masters instead pets/charmeds
Unit const* targetOwner = GetCharmerOrOwner();
Unit const* casterOwner = caster->GetCharmerOrOwner();
- if (limitduration > 0 && duration > limitduration)
+ if (limitDuration > 0 && duration > limitDuration)
{
Unit const* target = targetOwner ? targetOwner : this;
Unit const* source = casterOwner ? casterOwner : caster;
@@ -9042,7 +9035,7 @@ float Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,
if ((target->GetTypeId() == TYPEID_PLAYER
|| (target->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH))
&& source->GetTypeId() == TYPEID_PLAYER)
- duration = limitduration;
+ duration = limitDuration;
}
float mod = 1.0f;
@@ -9053,7 +9046,7 @@ float Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,
{
if (GetTypeId() == TYPEID_UNIT && (ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_TAUNT_DIMINISH))
{
- DiminishingLevels diminish = Level;
+ DiminishingLevels diminish = previousLevel;
switch (diminish)
{
case DIMINISHING_LEVEL_1: break;
@@ -9068,11 +9061,11 @@ float Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,
}
case DIMINISHING_AOE_KNOCKBACK:
{
- if ((GetDiminishingReturnsGroupType(group) == DRTYPE_PLAYER && (((targetOwner ? targetOwner : this)->ToPlayer())
+ if ((auraSpellInfo->GetDiminishingReturnsGroupType(triggered) == DRTYPE_PLAYER && (((targetOwner ? targetOwner : this)->ToPlayer())
|| (ToCreature() && (ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH))))
- || GetDiminishingReturnsGroupType(group) == DRTYPE_ALL)
+ || auraSpellInfo->GetDiminishingReturnsGroupType(triggered) == DRTYPE_ALL)
{
- DiminishingLevels diminish = Level;
+ DiminishingLevels diminish = previousLevel;
switch (diminish)
{
case DIMINISHING_LEVEL_1: break;
@@ -9084,11 +9077,11 @@ float Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,
}
default:
{
- if ((GetDiminishingReturnsGroupType(group) == DRTYPE_PLAYER && (((targetOwner ? targetOwner : this)->ToPlayer())
+ if ((auraSpellInfo->GetDiminishingReturnsGroupType(triggered) == DRTYPE_PLAYER && (((targetOwner ? targetOwner : this)->ToPlayer())
|| (ToCreature() && (ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH))))
- || GetDiminishingReturnsGroupType(group) == DRTYPE_ALL)
+ || auraSpellInfo->GetDiminishingReturnsGroupType(triggered) == DRTYPE_ALL)
{
- DiminishingLevels diminish = Level;
+ DiminishingLevels diminish = previousLevel;
switch (diminish)
{
case DIMINISHING_LEVEL_1: break;
@@ -9109,24 +9102,26 @@ float Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,
void Unit::ApplyDiminishingAura(DiminishingGroup group, bool apply)
{
// Checking for existing in the table
- for (Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i)
+ DiminishingReturn& diminish = m_Diminishing[group];
+
+ if (apply)
+ ++diminish.stack;
+ else if (diminish.stack)
{
- if (i->DRGroup != group)
- continue;
+ --diminish.stack;
- if (apply)
- i->stack += 1;
- else if (i->stack)
- {
- i->stack -= 1;
- // Remember time after last aura from group removed
- if (i->stack == 0)
- i->hitTime = getMSTime();
- }
- break;
+ // Remember time after last aura from group removed
+ if (!diminish.stack)
+ diminish.hitTime = getMSTime();
}
}
+void Unit::ClearDiminishings()
+{
+ for (uint32 i = 0; i < DIMINISHING_MAX; ++i)
+ m_Diminishing[i].Clear();
+}
+
float Unit::GetSpellMaxRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const
{
if (!spellInfo->RangeEntry)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index b1fc3811791..572a6ec4c8c 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -31,6 +31,7 @@
#include "Util.h"
#include <boost/container/flat_set.hpp>
#include <algorithm>
+#include <array>
#include <map>
#define WORLD_TRIGGER 12999
@@ -539,11 +540,15 @@ enum UnitTypeMask
struct DiminishingReturn
{
- DiminishingReturn(DiminishingGroup group, uint32 t, uint32 count)
- : DRGroup(group), stack(0), hitTime(t), hitCount(count)
- { }
+ DiminishingReturn() : stack(0), hitTime(0), hitCount(DIMINISHING_LEVEL_1) { }
+
+ void Clear()
+ {
+ stack = 0;
+ hitTime = 0;
+ hitCount = DIMINISHING_LEVEL_1;
+ }
- DiminishingGroup DRGroup;
uint16 stack;
uint32 hitTime;
uint32 hitCount;
@@ -959,7 +964,7 @@ class TC_GAME_API Unit : public WorldObject
typedef std::list<AuraEffect*> AuraEffectList;
typedef std::list<Aura*> AuraList;
typedef std::list<AuraApplication *> AuraApplicationList;
- typedef std::list<DiminishingReturn> Diminishing;
+ typedef std::array<DiminishingReturn, DIMINISHING_MAX> Diminishing;
typedef std::deque<std::pair<uint32 /*procEffectMask*/, AuraApplication*>> AuraApplicationProcContainer;
@@ -979,11 +984,11 @@ class TC_GAME_API Unit : public WorldObject
void SendCombatLogMessage(WorldPackets::CombatLog::CombatLogServerPacket* combatLog) const;
- DiminishingLevels GetDiminishing(DiminishingGroup group);
- void IncrDiminishing(DiminishingGroup group);
- float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit* caster, DiminishingLevels Level, int32 limitduration);
- void ApplyDiminishingAura(DiminishingGroup group, bool apply);
- void ClearDiminishings() { m_Diminishing.clear(); }
+ DiminishingLevels GetDiminishing(DiminishingGroup group);
+ void IncrDiminishing(SpellInfo const* auraSpellInfo, bool triggered);
+ float ApplyDiminishingToDuration(SpellInfo const* auraSpellInfo, bool triggered, int32& duration, Unit* caster, DiminishingLevels previousLevel);
+ void ApplyDiminishingAura(DiminishingGroup group, bool apply);
+ void ClearDiminishings();
// target dependent range checks
float GetSpellMaxRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const;
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index e887176f5d2..4f239fa6e61 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -4597,6 +4597,8 @@ enum DiminishingGroup : uint16
DIMINISHING_AOE_KNOCKBACK = 6,
DIMINISHING_TAUNT = 7,
DIMINISHING_LIMITONLY = 8,
+
+ DIMINISHING_MAX
};
enum SummonCategory
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index fdb1ade8648..0e5bfa0d653 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -601,8 +601,6 @@ m_spellValue(new SpellValue(caster->GetMap()->GetDifficultyID(), m_spellInfo))
variance = 0.0f;
effectHandleMode = SPELL_EFFECT_HANDLE_LAUNCH;
effectInfo = nullptr;
- m_diminishLevel = DIMINISHING_LEVEL_1;
- m_diminishGroup = DIMINISHING_NONE;
m_damage = 0;
m_healing = 0;
m_procAttacker = 0;
@@ -2635,16 +2633,19 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
aura_effmask |= 1 << effect->EffectIndex;
// Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
- m_diminishGroup = GetDiminishingReturnsGroupForSpell(m_spellInfo);
- if (m_diminishGroup && aura_effmask)
+ bool const triggered = m_triggeredByAuraSpell != nullptr;
+ DiminishingGroup const diminishGroup = m_spellInfo->GetDiminishingReturnsGroupForSpell(triggered);
+
+ DiminishingLevels diminishLevel = DIMINISHING_LEVEL_1;
+ if (diminishGroup && aura_effmask)
{
- m_diminishLevel = unit->GetDiminishing(m_diminishGroup);
- DiminishingReturnsType type = GetDiminishingReturnsGroupType(m_diminishGroup);
+ diminishLevel = unit->GetDiminishing(diminishGroup);
+ DiminishingReturnsType type = m_spellInfo->GetDiminishingReturnsGroupType(triggered);
// Increase Diminishing on unit, current informations for actually casts will use values above
if ((type == DRTYPE_PLAYER &&
(unit->GetCharmerOrOwnerPlayerOrPlayerItself() || (unit->GetTypeId() == TYPEID_UNIT && unit->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH))) ||
type == DRTYPE_ALL)
- unit->IncrDiminishing(m_diminishGroup);
+ unit->IncrDiminishing(m_spellInfo, triggered);
}
if (aura_effmask)
@@ -2691,8 +2692,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
// Now Reduce spell duration using data received at spell hit
int32 duration = m_spellAura->GetMaxDuration();
- int32 limitduration = m_diminishGroup ? GetDiminishingReturnsLimitDuration(aurSpellInfo) : 0;
- float diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
+ float diminishMod = unit->ApplyDiminishingToDuration(aurSpellInfo, triggered, duration, m_originalCaster, diminishLevel);
// unit is immune to aura if it was diminished to 0 duration
if (diminishMod == 0.0f)
@@ -2707,7 +2707,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
}
else
{
- ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
+ ((UnitAura*)m_spellAura)->SetDiminishGroup(diminishGroup);
bool positive = m_spellAura->GetSpellInfo()->IsPositive();
if (AuraApplication* aurApp = m_spellAura->GetApplicationOfTarget(m_originalCaster->GetGUID()))
@@ -3537,9 +3537,6 @@ uint64 Spell::handle_delayed(uint64 t_offset)
void Spell::_handle_immediate_phase()
{
m_spellAura = NULL;
- // initialize Diminishing Returns Data
- m_diminishLevel = DIMINISHING_LEVEL_1;
- m_diminishGroup = DIMINISHING_NONE;
// handle some immediate features of the spell here
HandleThreatSpells();
@@ -4733,7 +4730,7 @@ void Spell::HandleThreatSpells()
continue;
// positive spells distribute threat among all units that are in combat with target, like healing
- if (m_spellInfo->_IsPositiveSpell())
+ if (m_spellInfo->IsPositive())
target->getHostileRefManager().threatAssist(m_caster, threatToAdd, m_spellInfo);
// for negative spells threat gets distributed among affected targets
else
@@ -4744,7 +4741,7 @@ void Spell::HandleThreatSpells()
target->AddThreat(m_caster, threatToAdd, m_spellInfo->GetSchoolMask(), m_spellInfo);
}
}
- TC_LOG_DEBUG("spells", "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()));
+ TC_LOG_DEBUG("spells", "Spell %u, added an additional %f threat for %s %u target(s)", m_spellInfo->Id, threat, m_spellInfo->IsPositive() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
}
void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode)
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index be318a0d541..297240b0f2f 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -743,10 +743,6 @@ class TC_GAME_API Spell
// used in effects handlers
Aura* m_spellAura;
- // this is set in Spell Hit, but used in Apply Aura handler
- DiminishingLevels m_diminishLevel;
- DiminishingGroup m_diminishGroup;
-
// -------------------------------------------
GameObject* focusObject;
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index bb2f497313a..27049feb3b5 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -2467,6 +2467,422 @@ void SpellInfo::_LoadSpellSpecific()
}();
}
+void SpellInfo::_LoadSpellDiminishInfo()
+{
+ auto diminishingGroupCompute = [this](bool triggered) -> DiminishingGroup
+ {
+ if (IsPositive())
+ return DIMINISHING_NONE;
+
+ if (HasAura(DIFFICULTY_NONE, SPELL_AURA_MOD_TAUNT))
+ return DIMINISHING_TAUNT;
+
+ switch (Id)
+ {
+ case 64803: // Entrapment
+ case 135373: // Entrapment
+ return DIMINISHING_ROOT;
+ case 24394: // Intimidation
+ return DIMINISHING_STUN;
+ case 118345: // Pulverize (Primal Earth Elemental)
+ return DIMINISHING_STUN;
+ case 118905: // Static Charge (Capacitor Totem)
+ return DIMINISHING_STUN;
+ case 108199: // Gorefiend's Grasp
+ return DIMINISHING_AOE_KNOCKBACK;
+ default:
+ break;
+ }
+
+ // Explicit Diminishing Groups
+ switch (SpellFamilyName)
+ {
+ case SPELLFAMILY_GENERIC:
+ break;
+ case SPELLFAMILY_MAGE:
+ {
+ // Frostjaw -- 102051
+ if (SpellFamilyFlags[2] & 0x40000)
+ return DIMINISHING_SILENCE;
+
+ // Frost Nova -- 122
+ if (SpellFamilyFlags[0] & 0x40)
+ return DIMINISHING_ROOT;
+ // Ice Ward -- 111340
+ if (SpellFamilyFlags[0] & 0x80000 && SpellFamilyFlags[2] & 0x2000)
+ return DIMINISHING_ROOT;
+ // Freeze (Water Elemental) -- 33395
+ if (SpellFamilyFlags[2] & 0x200)
+ return DIMINISHING_ROOT;
+
+ // Deep Freeze -- 44572
+ if (SpellFamilyFlags[1] & 0x100000)
+ return DIMINISHING_STUN;
+
+ // Dragon's Breath -- 31661
+ if (SpellFamilyFlags[0] & 0x800000)
+ return DIMINISHING_INCAPACITATE;
+ // Polymorph -- 118
+ if (SpellFamilyFlags[0] & 0x1000000)
+ return DIMINISHING_INCAPACITATE;
+ // Ring of Frost -- 82691
+ if (SpellFamilyFlags[2] & 0x40)
+ return DIMINISHING_INCAPACITATE;
+ // Ice Nova -- 157997
+ if (SpellFamilyFlags[2] & 0x800000)
+ return DIMINISHING_INCAPACITATE;
+ break;
+ }
+ case SPELLFAMILY_WARRIOR:
+ {
+ // Shockwave -- 132168
+ if (SpellFamilyFlags[1] & 0x8000)
+ return DIMINISHING_STUN;
+ // Storm Bolt -- 132169
+ if (SpellFamilyFlags[2] & 0x1000)
+ return DIMINISHING_STUN;
+
+ // Intimidating Shout -- 5246
+ if (SpellFamilyFlags[0] & 0x40000)
+ return DIMINISHING_DISORIENT;
+
+ // Hamstring -- 1715, 8 seconds in PvP (6.0)
+ if (SpellFamilyFlags[0] & 0x2)
+ return DIMINISHING_LIMITONLY;
+ break;
+ }
+ case SPELLFAMILY_WARLOCK:
+ {
+ // Mortal Coil -- 6789
+ if (SpellFamilyFlags[0] & 0x80000)
+ return DIMINISHING_INCAPACITATE;
+ // Banish -- 710
+ if (SpellFamilyFlags[1] & 0x8000000)
+ return DIMINISHING_INCAPACITATE;
+
+ // Fear -- 118699
+ if (SpellFamilyFlags[1] & 0x400)
+ return DIMINISHING_DISORIENT;
+ // Howl of Terror -- 5484
+ if (SpellFamilyFlags[1] & 0x8)
+ return DIMINISHING_DISORIENT;
+
+ // Shadowfury -- 30283
+ if (SpellFamilyFlags[1] & 0x1000)
+ return DIMINISHING_STUN;
+ // Summon Infernal -- 22703
+ if (SpellFamilyFlags[0] & 0x1000)
+ return DIMINISHING_STUN;
+ break;
+ }
+ case SPELLFAMILY_WARLOCK_PET:
+ {
+ // Fellash -- 115770
+ // Whiplash -- 6360
+ if (SpellFamilyFlags[0] & 0x8000000)
+ return DIMINISHING_AOE_KNOCKBACK;
+
+ // Mesmerize (Shivarra pet) -- 115268
+ // Seduction (Succubus pet) -- 6358
+ if (SpellFamilyFlags[0] & 0x2000000)
+ return DIMINISHING_DISORIENT;
+
+ // Axe Toss (Felguard pet) -- 89766
+ if (SpellFamilyFlags[1] & 0x4)
+ return DIMINISHING_STUN;
+ break;
+ }
+ case SPELLFAMILY_DRUID:
+ {
+ // Maim -- 22570
+ if (SpellFamilyFlags[1] & 0x80)
+ return DIMINISHING_STUN;
+ // Mighty Bash -- 5211
+ if (SpellFamilyFlags[0] & 0x2000)
+ return DIMINISHING_STUN;
+ // Rake -- 163505 -- no flags on the stun
+ if (Id == 163505)
+ return DIMINISHING_STUN;
+
+ // Incapacitating Roar -- 99, no flags on the stun, 14
+ if (SpellFamilyFlags[1] & 0x1)
+ return DIMINISHING_INCAPACITATE;
+
+ // Cyclone -- 33786
+ if (SpellFamilyFlags[1] & 0x20)
+ return DIMINISHING_DISORIENT;
+
+ // Typhoon -- 61391
+ if (SpellFamilyFlags[1] & 0x1000000)
+ return DIMINISHING_AOE_KNOCKBACK;
+ // Ursol's Vortex -- 118283, no family flags
+ if (Id == 118283)
+ return DIMINISHING_AOE_KNOCKBACK;
+
+ // Entangling Roots -- 339
+ if (SpellFamilyFlags[0] & 0x200)
+ return DIMINISHING_ROOT;
+ // Mass Entanglement -- 102359
+ if (SpellFamilyFlags[2] & 0x4)
+ return DIMINISHING_ROOT;
+
+ // Faerie Fire -- 770, 20 seconds in PvP (6.0)
+ if (SpellFamilyFlags[0] & 0x400)
+ return DIMINISHING_LIMITONLY;
+ break;
+ }
+ case SPELLFAMILY_ROGUE:
+ {
+ // Cheap Shot -- 1833
+ if (SpellFamilyFlags[0] & 0x400)
+ return DIMINISHING_STUN;
+ // Kidney Shot -- 408
+ if (SpellFamilyFlags[0] & 0x200000)
+ return DIMINISHING_STUN;
+
+ // Gouge -- 1776
+ if (SpellFamilyFlags[0] & 0x8)
+ return DIMINISHING_INCAPACITATE;
+ // Sap -- 6770
+ if (SpellFamilyFlags[0] & 0x80)
+ return DIMINISHING_INCAPACITATE;
+
+ // Blind -- 2094
+ if (SpellFamilyFlags[0] & 0x1000000)
+ return DIMINISHING_DISORIENT;
+
+ // Garrote -- 1330
+ if (SpellFamilyFlags[1] & 0x20000000)
+ return DIMINISHING_SILENCE;
+ break;
+ }
+ case SPELLFAMILY_HUNTER:
+ {
+ // Charge (Tenacity pet) -- 53148, no flags
+ if (Id == 53148)
+ return DIMINISHING_ROOT;
+ // Narrow Escape -- 136634, no flags
+ if (Id == 136634)
+ return DIMINISHING_ROOT;
+
+ // Binding Shot -- 117526, no flags
+ if (Id == 117526)
+ return DIMINISHING_STUN;
+
+ // Freezing Trap -- 3355
+ if (SpellFamilyFlags[0] & 0x8)
+ return DIMINISHING_INCAPACITATE;
+ // Wyvern Sting -- 19386
+ if (SpellFamilyFlags[1] & 0x1000)
+ return DIMINISHING_INCAPACITATE;
+ break;
+ }
+ case SPELLFAMILY_PALADIN:
+ {
+ // Repentance -- 20066
+ if (SpellFamilyFlags[0] & 0x4)
+ return DIMINISHING_INCAPACITATE;
+
+ // Turn Evil -- 10326
+ if (SpellFamilyFlags[1] & 0x800000)
+ return DIMINISHING_DISORIENT;
+
+ // Avenger's Shield -- 31935
+ if (SpellFamilyFlags[0] & 0x4000)
+ return DIMINISHING_SILENCE;
+
+ // Fist of Justice -- 105593
+ // Hammer of Justice -- 853
+ if (SpellFamilyFlags[0] & 0x800)
+ return DIMINISHING_STUN;
+ // Holy Wrath -- 119072
+ if (SpellFamilyFlags[1] & 0x200000)
+ return DIMINISHING_STUN;
+ break;
+ }
+ case SPELLFAMILY_SHAMAN:
+ {
+ // Hex -- 51514
+ if (SpellFamilyFlags[1] & 0x8000)
+ return DIMINISHING_INCAPACITATE;
+
+ // Thunderstorm -- 51490
+ if (SpellFamilyFlags[1] & 0x2000)
+ return DIMINISHING_AOE_KNOCKBACK;
+
+ // Earthgrab Totem -- 64695
+ if (SpellFamilyFlags[2] & 0x4000)
+ return DIMINISHING_ROOT;
+ break;
+ }
+ case SPELLFAMILY_DEATHKNIGHT:
+ {
+ // Strangulate -- 47476
+ if (SpellFamilyFlags[0] & 0x200)
+ return DIMINISHING_SILENCE;
+
+ // Asphyxiate -- 108194
+ if (SpellFamilyFlags[2] & 0x100000)
+ return DIMINISHING_STUN;
+ // Gnaw (Ghoul) -- 91800, no flags
+ if (Id == 91800)
+ return DIMINISHING_STUN;
+ // Monstrous Blow (Ghoul w/ Dark Transformation active) -- 91797
+ if (Id == 91797)
+ return DIMINISHING_STUN;
+ break;
+ }
+ case SPELLFAMILY_PRIEST:
+ {
+ // Dominate Mind -- 605
+ if (SpellFamilyFlags[0] & 0x20000 && GetSpellVisual() == 39068)
+ return DIMINISHING_INCAPACITATE;
+ // Holy Word: Chastise -- 88625
+ if (SpellFamilyFlags[2] & 0x20)
+ return DIMINISHING_INCAPACITATE;
+ // Psychic Horror -- 64044
+ if (SpellFamilyFlags[2] & 0x2000)
+ return DIMINISHING_INCAPACITATE;
+
+ // Psychic Scream -- 8122
+ if (SpellFamilyFlags[0] & 0x10000)
+ return DIMINISHING_DISORIENT;
+
+ // Silence -- 15487
+ if (SpellFamilyFlags[1] & 0x200000 && SchoolMask == SPELL_SCHOOL_MASK_SHADOW)
+ return DIMINISHING_SILENCE;
+ break;
+ }
+ case SPELLFAMILY_MONK:
+ {
+ // Disable -- 116706, no flags
+ if (Id == 116706)
+ return DIMINISHING_ROOT;
+
+ // Charging Ox Wave -- 119392
+ if (SpellFamilyFlags[1] & 0x10000)
+ return DIMINISHING_STUN;
+ // Fists of Fury -- 120086
+ if (SpellFamilyFlags[1] & 0x800000 && !(SpellFamilyFlags[2] & 0x8))
+ return DIMINISHING_STUN;
+ // Leg Sweep -- 119381
+ if (SpellFamilyFlags[1] & 0x200)
+ return DIMINISHING_STUN;
+
+ // Incendiary Breath (honor talent) -- 202274, no flags
+ if (Id == 202274)
+ return DIMINISHING_INCAPACITATE;
+ // Paralysis -- 115078
+ if (SpellFamilyFlags[2] & 0x800000)
+ return DIMINISHING_INCAPACITATE;
+ break;
+ }
+ default:
+ break;
+ }
+
+ return DIMINISHING_NONE;
+ };
+
+ auto diminishingTypeCompute = [](DiminishingGroup group) -> DiminishingReturnsType
+ {
+ switch (group)
+ {
+ case DIMINISHING_TAUNT:
+ case DIMINISHING_STUN:
+ return DRTYPE_ALL;
+ case DIMINISHING_LIMITONLY:
+ case DIMINISHING_NONE:
+ return DRTYPE_NONE;
+ default:
+ return DRTYPE_PLAYER;
+ }
+ };
+
+ auto diminishingMaxLevelCompute = [](DiminishingGroup group) -> DiminishingLevels
+ {
+ switch (group)
+ {
+ case DIMINISHING_TAUNT:
+ return DIMINISHING_LEVEL_TAUNT_IMMUNE;
+ case DIMINISHING_AOE_KNOCKBACK:
+ return DIMINISHING_LEVEL_2;
+ default:
+ return DIMINISHING_LEVEL_IMMUNE;
+ }
+ };
+
+ auto diminishingLimitDurationCompute = [this](DiminishingGroup group) -> int32
+ {
+ // Explicit diminishing duration
+ switch (SpellFamilyName)
+ {
+ case SPELLFAMILY_DRUID:
+ {
+ // Faerie Fire - 20 seconds in PvP (6.0)
+ if (SpellFamilyFlags[0] & 0x400)
+ return 20 * IN_MILLISECONDS;
+ break;
+ }
+ case SPELLFAMILY_HUNTER:
+ {
+ // Binding Shot - 3 seconds in PvP (6.0)
+ if (Id == 117526)
+ return 3 * IN_MILLISECONDS;
+ // Wyvern Sting - 6 seconds in PvP (6.0)
+ if (SpellFamilyFlags[1] & 0x1000)
+ return 6 * IN_MILLISECONDS;
+ break;
+ }
+ case SPELLFAMILY_MONK:
+ {
+ // Paralysis - 4 seconds in PvP regardless of if they are facing you (6.0)
+ if (SpellFamilyFlags[2] & 0x800000)
+ return 4 * IN_MILLISECONDS;
+ break;
+ }
+ default:
+ break;
+ }
+
+ return 8 * IN_MILLISECONDS;
+ };
+
+ SpellDiminishInfo triggeredInfo, normalInfo;
+ triggeredInfo.DiminishGroup = diminishingGroupCompute(true);
+ triggeredInfo.DiminishReturnType = diminishingTypeCompute(triggeredInfo.DiminishGroup);
+ triggeredInfo.DiminishMaxLevel = diminishingMaxLevelCompute(triggeredInfo.DiminishGroup);
+ triggeredInfo.DiminishDurationLimit = diminishingLimitDurationCompute(triggeredInfo.DiminishGroup);
+
+ normalInfo.DiminishGroup = diminishingGroupCompute(false);
+ normalInfo.DiminishReturnType = diminishingTypeCompute(normalInfo.DiminishGroup);
+ normalInfo.DiminishMaxLevel = diminishingMaxLevelCompute(normalInfo.DiminishGroup);
+ normalInfo.DiminishDurationLimit = diminishingLimitDurationCompute(normalInfo.DiminishGroup);
+
+ _diminishInfoTriggered = triggeredInfo;
+ _diminishInfoNonTriggered = normalInfo;
+}
+
+DiminishingGroup SpellInfo::GetDiminishingReturnsGroupForSpell(bool triggered) const
+{
+ return triggered ? _diminishInfoTriggered.DiminishGroup : _diminishInfoNonTriggered.DiminishGroup;
+}
+
+DiminishingReturnsType SpellInfo::GetDiminishingReturnsGroupType(bool triggered) const
+{
+ return triggered ? _diminishInfoTriggered.DiminishReturnType : _diminishInfoNonTriggered.DiminishReturnType;
+}
+
+DiminishingLevels SpellInfo::GetDiminishingReturnsMaxLevel(bool triggered) const
+{
+ return triggered ? _diminishInfoTriggered.DiminishMaxLevel : _diminishInfoNonTriggered.DiminishMaxLevel;
+}
+
+int32 SpellInfo::GetDiminishingReturnsLimitDuration(bool triggered) const
+{
+ return triggered ? _diminishInfoTriggered.DiminishDurationLimit : _diminishInfoNonTriggered.DiminishDurationLimit;
+}
+
float SpellInfo::GetMinRange(bool positive) const
{
if (!RangeEntry)
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index b04fa2403da..638a137fc32 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -28,6 +28,7 @@ class Unit;
class Player;
class Item;
class Spell;
+class SpellMgr;
class SpellInfo;
class WorldObject;
class AuraEffect;
@@ -320,6 +321,14 @@ typedef std::vector<AuraEffect*> AuraEffectVector;
struct SpellInfoLoadHelper;
+struct TC_GAME_API SpellDiminishInfo
+{
+ DiminishingGroup DiminishGroup = DIMINISHING_NONE;
+ DiminishingReturnsType DiminishReturnType = DRTYPE_NONE;
+ DiminishingLevels DiminishMaxLevel = DIMINISHING_LEVEL_IMMUNE;
+ int32 DiminishDurationLimit = 0;
+};
+
struct SpellPowerCost
{
Powers Power;
@@ -328,239 +337,253 @@ struct SpellPowerCost
class TC_GAME_API SpellInfo
{
-public:
- uint32 Id;
- uint32 CategoryId;
- uint32 Dispel;
- uint32 Mechanic;
- uint32 Attributes;
- uint32 AttributesEx;
- uint32 AttributesEx2;
- uint32 AttributesEx3;
- uint32 AttributesEx4;
- uint32 AttributesEx5;
- uint32 AttributesEx6;
- uint32 AttributesEx7;
- uint32 AttributesEx8;
- uint32 AttributesEx9;
- uint32 AttributesEx10;
- uint32 AttributesEx11;
- uint32 AttributesEx12;
- uint32 AttributesEx13;
- uint32 AttributesCu;
- uint64 Stances;
- uint64 StancesNot;
- uint32 Targets;
- uint32 TargetCreatureType;
- uint32 RequiresSpellFocus;
- uint32 FacingCasterFlags;
- uint32 CasterAuraState;
- uint32 TargetAuraState;
- uint32 ExcludeCasterAuraState;
- uint32 ExcludeTargetAuraState;
- uint32 CasterAuraSpell;
- uint32 TargetAuraSpell;
- uint32 ExcludeCasterAuraSpell;
- uint32 ExcludeTargetAuraSpell;
- SpellCastTimesEntry const* CastTimeEntry;
- uint32 RecoveryTime;
- uint32 CategoryRecoveryTime;
- uint32 StartRecoveryCategory;
- uint32 StartRecoveryTime;
- uint32 InterruptFlags;
- uint32 AuraInterruptFlags;
- uint32 ChannelInterruptFlags;
- uint32 ProcFlags;
- uint32 ProcChance;
- uint32 ProcCharges;
- uint32 ProcCooldown;
- float ProcBasePPM;
- std::vector<SpellProcsPerMinuteModEntry const*> ProcPPMMods;
- uint32 MaxLevel;
- uint32 BaseLevel;
- uint32 SpellLevel;
- SpellDurationEntry const* DurationEntry;
- std::vector<SpellPowerEntry const*> PowerCosts;
- uint32 RangeIndex;
- SpellRangeEntry const* RangeEntry;
- float Speed;
- uint32 StackAmount;
- uint32 Totem[MAX_SPELL_TOTEMS];
- int32 Reagent[MAX_SPELL_REAGENTS];
- uint32 ReagentCount[MAX_SPELL_REAGENTS];
- int32 EquippedItemClass;
- int32 EquippedItemSubClassMask;
- int32 EquippedItemInventoryTypeMask;
- uint32 TotemCategory[MAX_SPELL_TOTEMS];
- uint32 IconFileDataId;
- uint32 ActiveIconFileDataId;
- LocalizedString const* SpellName;
- float ConeAngle;
- float Width;
- uint32 MaxTargetLevel;
- uint32 MaxAffectedTargets;
- uint32 SpellFamilyName;
- flag128 SpellFamilyFlags;
- uint32 DmgClass;
- uint32 PreventionType;
- int32 RequiredAreasID;
- uint32 SchoolMask;
- uint32 ChargeCategoryId;
- // SpellScalingEntry
- struct ScalingInfo
- {
- int32 Class;
- uint32 MinScalingLevel;
- uint32 MaxScalingLevel;
- uint32 ScalesFromItemLevel;
- } Scaling;
-
- uint32 ExplicitTargetMask;
- SpellChainNode const* ChainEntry;
-
- SpellInfo(SpellInfoLoadHelper const& data, SpellEffectEntryMap const& effectsMap, SpellVisualMap&& visuals,
- std::unordered_map<uint32, SpellEffectScalingEntry const*> const& effectScaling);
- ~SpellInfo();
-
- uint32 GetCategory() const;
- bool HasEffect(uint32 difficulty, SpellEffectName effect) const;
- bool HasEffect(SpellEffectName effect) const;
- bool HasAura(uint32 difficulty, AuraType aura) const;
- bool HasAreaAuraEffect(uint32 difficulty) const;
- bool HasAreaAuraEffect() const;
-
- inline bool HasAttribute(SpellAttr0 attribute) const { return !!(Attributes & attribute); }
- inline bool HasAttribute(SpellAttr1 attribute) const { return !!(AttributesEx & attribute); }
- inline bool HasAttribute(SpellAttr2 attribute) const { return !!(AttributesEx2 & attribute); }
- inline bool HasAttribute(SpellAttr3 attribute) const { return !!(AttributesEx3 & attribute); }
- inline bool HasAttribute(SpellAttr4 attribute) const { return !!(AttributesEx4 & attribute); }
- inline bool HasAttribute(SpellAttr5 attribute) const { return !!(AttributesEx5 & attribute); }
- inline bool HasAttribute(SpellAttr6 attribute) const { return !!(AttributesEx6 & attribute); }
- inline bool HasAttribute(SpellAttr7 attribute) const { return !!(AttributesEx7 & attribute); }
- inline bool HasAttribute(SpellAttr8 attribute) const { return !!(AttributesEx8 & attribute); }
- inline bool HasAttribute(SpellAttr9 attribute) const { return !!(AttributesEx9 & attribute); }
- inline bool HasAttribute(SpellAttr10 attribute) const { return !!(AttributesEx10 & attribute); }
- inline bool HasAttribute(SpellAttr11 attribute) const { return !!(AttributesEx11 & attribute); }
- inline bool HasAttribute(SpellAttr12 attribute) const { return !!(AttributesEx12 & attribute); }
- inline bool HasAttribute(SpellAttr13 attribute) const { return !!(AttributesEx13 & attribute); }
- inline bool HasAttribute(SpellCustomAttributes customAttribute) const { return !!(AttributesCu & customAttribute); }
-
- bool IsExplicitDiscovery() const;
- bool IsLootCrafting() const;
- bool IsQuestTame() const;
- bool IsProfession(uint32 difficulty = DIFFICULTY_NONE) const;
- bool IsPrimaryProfession(uint32 difficulty = DIFFICULTY_NONE) const;
- bool IsPrimaryProfessionFirstRank(uint32 difficulty = DIFFICULTY_NONE) const;
- bool IsAbilityOfSkillType(uint32 skillType) const;
-
- bool IsAffectingArea(uint32 difficulty) const;
- bool IsTargetingArea(uint32 difficulty) const;
- bool NeedsExplicitUnitTarget() const;
- bool NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell, uint32 difficulty) const;
-
- bool IsPassive() const;
- bool IsAutocastable() const;
- bool IsStackableWithRanks() const;
- bool IsPassiveStackableWithRanks(uint32 difficulty) const;
- bool IsMultiSlotAura() const;
- bool IsStackableOnOneSlotWithDifferentCasters() const;
- bool IsCooldownStartedOnEvent() const;
- bool IsDeathPersistent() const;
- bool IsRequiringDeadTarget() const;
- bool IsAllowingDeadTarget() const;
- bool IsGroupBuff() const;
- bool CanBeUsedInCombat() const;
- bool IsPositive() const;
- bool IsPositiveEffect(uint8 effIndex) const;
- bool IsChanneled() const;
- bool NeedsComboPoints() const;
- bool IsBreakingStealth() const;
- bool IsRangedWeaponSpell() const;
- bool IsAutoRepeatRangedSpell() const;
- bool HasInitialAggro() const;
-
- bool IsAffectedBySpellMods() const;
- bool IsAffectedBySpellMod(SpellModifier const* mod) const;
-
- bool CanPierceImmuneAura(SpellInfo const* aura) const;
- bool CanDispelAura(SpellInfo const* aura) const;
-
- bool IsSingleTarget() const;
- bool IsAuraExclusiveBySpecificWith(SpellInfo const* spellInfo) const;
- bool IsAuraExclusiveBySpecificPerCasterWith(SpellInfo const* spellInfo) const;
-
- SpellCastResult CheckShapeshift(uint32 form) const;
- SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player = NULL) const;
- SpellCastResult CheckTarget(Unit const* caster, WorldObject const* target, bool implicit = true) const;
- SpellCastResult CheckExplicitTarget(Unit const* caster, WorldObject const* target, Item const* itemTarget = NULL) const;
- SpellCastResult CheckVehicle(Unit const* caster) const;
- bool CheckTargetCreatureType(Unit const* target) const;
-
- SpellSchoolMask GetSchoolMask() const;
- uint32 GetAllEffectsMechanicMask() const;
- uint32 GetEffectMechanicMask(uint32 effIndex) const;
- uint32 GetSpellMechanicMaskByEffectMask(uint32 effectMask) const;
- Mechanics GetEffectMechanic(uint32 effIndex, uint32 difficulty) const;
- //bool HasAnyEffectMechanic() const;
- uint32 GetDispelMask() const;
- static uint32 GetDispelMask(DispelType type);
- uint32 GetExplicitTargetMask() const;
-
- AuraStateType GetAuraState() const;
- SpellSpecificType GetSpellSpecific() const;
-
- float GetMinRange(bool positive = false) const;
- float GetMaxRange(bool positive = false, Unit* caster = NULL, Spell* spell = NULL) const;
-
- int32 CalcDuration(Unit* caster = nullptr) const;
- int32 GetDuration() const;
- int32 GetMaxDuration() const;
-
- uint32 GetMaxTicks(uint32 difficulty) const;
-
- uint32 CalcCastTime(uint8 level = 0, Spell* spell = NULL) const;
- uint32 GetRecoveryTime() const;
-
- std::vector<SpellPowerCost> CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) const;
-
- float CalcProcPPM(Unit* caster, int32 itemLevel) const;
-
- bool IsRanked() const;
- uint8 GetRank() const;
- SpellInfo const* GetFirstRankSpell() const;
- SpellInfo const* GetLastRankSpell() const;
- SpellInfo const* GetNextRankSpell() const;
- SpellInfo const* GetPrevRankSpell() const;
- SpellInfo const* GetAuraRankForLevel(uint8 level) const;
- bool IsRankOf(SpellInfo const* spellInfo) const;
- bool IsDifferentRankOf(SpellInfo const* spellInfo) const;
- bool IsHighRankOf(SpellInfo const* spellInfo) const;
-
- uint32 GetSpellXSpellVisualId(Unit const* caster = nullptr) const;
- uint32 GetSpellVisual(Unit const* caster = nullptr) const;
-
- // loading helpers
- void _InitializeExplicitTargetMask();
- bool _IsPositiveEffect(uint32 effIndex, bool deep) const;
- bool _IsPositiveSpell() const;
- static bool _IsPositiveTarget(uint32 targetA, uint32 targetB);
- void _LoadSpellSpecific();
- void _LoadAuraState();
-
- // unloading helpers
- void _UnloadImplicitTargetConditionLists();
- void _UnloadSpellEffects();
-
- SpellEffectInfoVector GetEffectsForDifficulty(uint32 difficulty) const;
- SpellEffectInfo const* GetEffect(uint32 difficulty, uint32 index) const;
- SpellEffectInfo const* GetEffect(uint32 index) const { return GetEffect(DIFFICULTY_NONE, index); }
-
-private:
- SpellEffectInfoMap _effects;
- SpellVisualMap _visuals;
- bool _hasPowerDifficultyData;
- SpellSpecificType _spellSpecific;
- AuraStateType _auraState;
+ friend class SpellMgr;
+
+ public:
+ uint32 Id;
+ uint32 CategoryId;
+ uint32 Dispel;
+ uint32 Mechanic;
+ uint32 Attributes;
+ uint32 AttributesEx;
+ uint32 AttributesEx2;
+ uint32 AttributesEx3;
+ uint32 AttributesEx4;
+ uint32 AttributesEx5;
+ uint32 AttributesEx6;
+ uint32 AttributesEx7;
+ uint32 AttributesEx8;
+ uint32 AttributesEx9;
+ uint32 AttributesEx10;
+ uint32 AttributesEx11;
+ uint32 AttributesEx12;
+ uint32 AttributesEx13;
+ uint32 AttributesCu;
+ uint64 Stances;
+ uint64 StancesNot;
+ uint32 Targets;
+ uint32 TargetCreatureType;
+ uint32 RequiresSpellFocus;
+ uint32 FacingCasterFlags;
+ uint32 CasterAuraState;
+ uint32 TargetAuraState;
+ uint32 ExcludeCasterAuraState;
+ uint32 ExcludeTargetAuraState;
+ uint32 CasterAuraSpell;
+ uint32 TargetAuraSpell;
+ uint32 ExcludeCasterAuraSpell;
+ uint32 ExcludeTargetAuraSpell;
+ SpellCastTimesEntry const* CastTimeEntry;
+ uint32 RecoveryTime;
+ uint32 CategoryRecoveryTime;
+ uint32 StartRecoveryCategory;
+ uint32 StartRecoveryTime;
+ uint32 InterruptFlags;
+ uint32 AuraInterruptFlags;
+ uint32 ChannelInterruptFlags;
+ uint32 ProcFlags;
+ uint32 ProcChance;
+ uint32 ProcCharges;
+ uint32 ProcCooldown;
+ float ProcBasePPM;
+ std::vector<SpellProcsPerMinuteModEntry const*> ProcPPMMods;
+ uint32 MaxLevel;
+ uint32 BaseLevel;
+ uint32 SpellLevel;
+ SpellDurationEntry const* DurationEntry;
+ std::vector<SpellPowerEntry const*> PowerCosts;
+ uint32 RangeIndex;
+ SpellRangeEntry const* RangeEntry;
+ float Speed;
+ uint32 StackAmount;
+ uint32 Totem[MAX_SPELL_TOTEMS];
+ int32 Reagent[MAX_SPELL_REAGENTS];
+ uint32 ReagentCount[MAX_SPELL_REAGENTS];
+ int32 EquippedItemClass;
+ int32 EquippedItemSubClassMask;
+ int32 EquippedItemInventoryTypeMask;
+ uint32 TotemCategory[MAX_SPELL_TOTEMS];
+ uint32 IconFileDataId;
+ uint32 ActiveIconFileDataId;
+ LocalizedString const* SpellName;
+ float ConeAngle;
+ float Width;
+ uint32 MaxTargetLevel;
+ uint32 MaxAffectedTargets;
+ uint32 SpellFamilyName;
+ flag128 SpellFamilyFlags;
+ uint32 DmgClass;
+ uint32 PreventionType;
+ int32 RequiredAreasID;
+ uint32 SchoolMask;
+ uint32 ChargeCategoryId;
+
+ // SpellScalingEntry
+ struct ScalingInfo
+ {
+ int32 Class;
+ uint32 MinScalingLevel;
+ uint32 MaxScalingLevel;
+ uint32 ScalesFromItemLevel;
+ } Scaling;
+
+ uint32 ExplicitTargetMask;
+ SpellChainNode const* ChainEntry;
+
+ SpellInfo(SpellInfoLoadHelper const& data, SpellEffectEntryMap const& effectsMap, SpellVisualMap&& visuals,
+ std::unordered_map<uint32, SpellEffectScalingEntry const*> const& effectScaling);
+ ~SpellInfo();
+
+ uint32 GetCategory() const;
+ bool HasEffect(uint32 difficulty, SpellEffectName effect) const;
+ bool HasEffect(SpellEffectName effect) const;
+ bool HasAura(uint32 difficulty, AuraType aura) const;
+ bool HasAreaAuraEffect(uint32 difficulty) const;
+ bool HasAreaAuraEffect() const;
+
+ inline bool HasAttribute(SpellAttr0 attribute) const { return !!(Attributes & attribute); }
+ inline bool HasAttribute(SpellAttr1 attribute) const { return !!(AttributesEx & attribute); }
+ inline bool HasAttribute(SpellAttr2 attribute) const { return !!(AttributesEx2 & attribute); }
+ inline bool HasAttribute(SpellAttr3 attribute) const { return !!(AttributesEx3 & attribute); }
+ inline bool HasAttribute(SpellAttr4 attribute) const { return !!(AttributesEx4 & attribute); }
+ inline bool HasAttribute(SpellAttr5 attribute) const { return !!(AttributesEx5 & attribute); }
+ inline bool HasAttribute(SpellAttr6 attribute) const { return !!(AttributesEx6 & attribute); }
+ inline bool HasAttribute(SpellAttr7 attribute) const { return !!(AttributesEx7 & attribute); }
+ inline bool HasAttribute(SpellAttr8 attribute) const { return !!(AttributesEx8 & attribute); }
+ inline bool HasAttribute(SpellAttr9 attribute) const { return !!(AttributesEx9 & attribute); }
+ inline bool HasAttribute(SpellAttr10 attribute) const { return !!(AttributesEx10 & attribute); }
+ inline bool HasAttribute(SpellAttr11 attribute) const { return !!(AttributesEx11 & attribute); }
+ inline bool HasAttribute(SpellAttr12 attribute) const { return !!(AttributesEx12 & attribute); }
+ inline bool HasAttribute(SpellAttr13 attribute) const { return !!(AttributesEx13 & attribute); }
+ inline bool HasAttribute(SpellCustomAttributes customAttribute) const { return !!(AttributesCu & customAttribute); }
+
+ bool IsExplicitDiscovery() const;
+ bool IsLootCrafting() const;
+ bool IsQuestTame() const;
+ bool IsProfession(uint32 difficulty = DIFFICULTY_NONE) const;
+ bool IsPrimaryProfession(uint32 difficulty = DIFFICULTY_NONE) const;
+ bool IsPrimaryProfessionFirstRank(uint32 difficulty = DIFFICULTY_NONE) const;
+ bool IsAbilityOfSkillType(uint32 skillType) const;
+
+ bool IsAffectingArea(uint32 difficulty) const;
+ bool IsTargetingArea(uint32 difficulty) const;
+ bool NeedsExplicitUnitTarget() const;
+ bool NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell, uint32 difficulty) const;
+
+ bool IsPassive() const;
+ bool IsAutocastable() const;
+ bool IsStackableWithRanks() const;
+ bool IsPassiveStackableWithRanks(uint32 difficulty) const;
+ bool IsMultiSlotAura() const;
+ bool IsStackableOnOneSlotWithDifferentCasters() const;
+ bool IsCooldownStartedOnEvent() const;
+ bool IsDeathPersistent() const;
+ bool IsRequiringDeadTarget() const;
+ bool IsAllowingDeadTarget() const;
+ bool IsGroupBuff() const;
+ bool CanBeUsedInCombat() const;
+ bool IsPositive() const;
+ bool IsPositiveEffect(uint8 effIndex) const;
+ bool IsChanneled() const;
+ bool NeedsComboPoints() const;
+ bool IsBreakingStealth() const;
+ bool IsRangedWeaponSpell() const;
+ bool IsAutoRepeatRangedSpell() const;
+ bool HasInitialAggro() const;
+
+ bool IsAffectedBySpellMods() const;
+ bool IsAffectedBySpellMod(SpellModifier const* mod) const;
+
+ bool CanPierceImmuneAura(SpellInfo const* aura) const;
+ bool CanDispelAura(SpellInfo const* aura) const;
+
+ bool IsSingleTarget() const;
+ bool IsAuraExclusiveBySpecificWith(SpellInfo const* spellInfo) const;
+ bool IsAuraExclusiveBySpecificPerCasterWith(SpellInfo const* spellInfo) const;
+
+ SpellCastResult CheckShapeshift(uint32 form) const;
+ SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player = NULL) const;
+ SpellCastResult CheckTarget(Unit const* caster, WorldObject const* target, bool implicit = true) const;
+ SpellCastResult CheckExplicitTarget(Unit const* caster, WorldObject const* target, Item const* itemTarget = NULL) const;
+ SpellCastResult CheckVehicle(Unit const* caster) const;
+ bool CheckTargetCreatureType(Unit const* target) const;
+
+ SpellSchoolMask GetSchoolMask() const;
+ uint32 GetAllEffectsMechanicMask() const;
+ uint32 GetEffectMechanicMask(uint32 effIndex) const;
+ uint32 GetSpellMechanicMaskByEffectMask(uint32 effectMask) const;
+ Mechanics GetEffectMechanic(uint32 effIndex, uint32 difficulty) const;
+ //bool HasAnyEffectMechanic() const;
+ uint32 GetDispelMask() const;
+ static uint32 GetDispelMask(DispelType type);
+ uint32 GetExplicitTargetMask() const;
+
+ AuraStateType GetAuraState() const;
+ SpellSpecificType GetSpellSpecific() const;
+
+ float GetMinRange(bool positive = false) const;
+ float GetMaxRange(bool positive = false, Unit* caster = NULL, Spell* spell = NULL) const;
+
+ int32 CalcDuration(Unit* caster = nullptr) const;
+ int32 GetDuration() const;
+ int32 GetMaxDuration() const;
+
+ uint32 GetMaxTicks(uint32 difficulty) const;
+
+ uint32 CalcCastTime(uint8 level = 0, Spell* spell = NULL) const;
+ uint32 GetRecoveryTime() const;
+
+ std::vector<SpellPowerCost> CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) const;
+
+ float CalcProcPPM(Unit* caster, int32 itemLevel) const;
+
+ bool IsRanked() const;
+ uint8 GetRank() const;
+ SpellInfo const* GetFirstRankSpell() const;
+ SpellInfo const* GetLastRankSpell() const;
+ SpellInfo const* GetNextRankSpell() const;
+ SpellInfo const* GetPrevRankSpell() const;
+ SpellInfo const* GetAuraRankForLevel(uint8 level) const;
+ bool IsRankOf(SpellInfo const* spellInfo) const;
+ bool IsDifferentRankOf(SpellInfo const* spellInfo) const;
+ bool IsHighRankOf(SpellInfo const* spellInfo) const;
+
+ uint32 GetSpellXSpellVisualId(Unit const* caster = nullptr) const;
+ uint32 GetSpellVisual(Unit const* caster = nullptr) const;
+
+ SpellEffectInfoVector GetEffectsForDifficulty(uint32 difficulty) const;
+ SpellEffectInfo const* GetEffect(uint32 difficulty, uint32 index) const;
+ SpellEffectInfo const* GetEffect(uint32 index) const { return GetEffect(DIFFICULTY_NONE, index); }
+
+ // spell diminishing returns
+ DiminishingGroup GetDiminishingReturnsGroupForSpell(bool triggered) const;
+ DiminishingReturnsType GetDiminishingReturnsGroupType(bool triggered) const;
+ DiminishingLevels GetDiminishingReturnsMaxLevel(bool triggered) const;
+ int32 GetDiminishingReturnsLimitDuration(bool triggered) const;
+
+ private:
+ // loading helpers
+ void _InitializeExplicitTargetMask();
+ bool _IsPositiveEffect(uint32 effIndex, bool deep) const;
+ bool _IsPositiveSpell() const;
+ static bool _IsPositiveTarget(uint32 targetA, uint32 targetB);
+ void _LoadSpellSpecific();
+ void _LoadAuraState();
+ void _LoadSpellDiminishInfo();
+
+ // unloading helpers
+ void _UnloadImplicitTargetConditionLists();
+ void _UnloadSpellEffects();
+
+ private:
+ SpellEffectInfoMap _effects;
+ SpellVisualMap _visuals;
+ bool _hasPowerDifficultyData;
+ SpellSpecificType _spellSpecific;
+ AuraStateType _auraState;
+
+ SpellDiminishInfo _diminishInfoNonTriggered;
+ SpellDiminishInfo _diminishInfoTriggered;
};
#endif // _SPELLINFO_H
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index f1bf941759e..ae6f9a26850 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -57,385 +57,6 @@ bool IsPartOfSkillLine(uint32 skillId, uint32 spellId)
return false;
}
-DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const* spellproto)
-{
- if (spellproto->IsPositive())
- return DIMINISHING_NONE;
-
- if (spellproto->HasAura(DIFFICULTY_NONE, SPELL_AURA_MOD_TAUNT))
- return DIMINISHING_TAUNT;
-
- switch (spellproto->Id)
- {
- case 64803: // Entrapment
- case 135373: // Entrapment
- return DIMINISHING_ROOT;
- case 24394: // Intimidation
- return DIMINISHING_STUN;
- case 118345: // Pulverize (Primal Earth Elemental)
- return DIMINISHING_STUN;
- case 118905: // Static Charge (Capacitor Totem)
- return DIMINISHING_STUN;
- case 108199: // Gorefiend's Grasp
- return DIMINISHING_AOE_KNOCKBACK;
- default:
- break;
- }
-
- // Explicit Diminishing Groups
- switch (spellproto->SpellFamilyName)
- {
- case SPELLFAMILY_GENERIC:
- break;
- case SPELLFAMILY_MAGE:
- {
- // Frostjaw -- 102051
- if (spellproto->SpellFamilyFlags[2] & 0x40000)
- return DIMINISHING_SILENCE;
-
- // Frost Nova -- 122
- if (spellproto->SpellFamilyFlags[0] & 0x40)
- return DIMINISHING_ROOT;
- // Ice Ward -- 111340
- if (spellproto->SpellFamilyFlags[0] & 0x80000 && spellproto->SpellFamilyFlags[2] & 0x2000)
- return DIMINISHING_ROOT;
- // Freeze (Water Elemental) -- 33395
- if (spellproto->SpellFamilyFlags[2] & 0x200)
- return DIMINISHING_ROOT;
-
- // Deep Freeze -- 44572
- if (spellproto->SpellFamilyFlags[1] & 0x100000)
- return DIMINISHING_STUN;
-
- // Dragon's Breath -- 31661
- if (spellproto->SpellFamilyFlags[0] & 0x800000)
- return DIMINISHING_INCAPACITATE;
- // Polymorph -- 118
- if (spellproto->SpellFamilyFlags[0] & 0x1000000)
- return DIMINISHING_INCAPACITATE;
- // Ring of Frost -- 82691
- if (spellproto->SpellFamilyFlags[2] & 0x40)
- return DIMINISHING_INCAPACITATE;
- // Ice Nova -- 157997
- if (spellproto->SpellFamilyFlags[2] & 0x800000)
- return DIMINISHING_INCAPACITATE;
- break;
- }
- case SPELLFAMILY_WARRIOR:
- {
- // Shockwave -- 132168
- if (spellproto->SpellFamilyFlags[1] & 0x8000)
- return DIMINISHING_STUN;
- // Storm Bolt -- 132169
- if (spellproto->SpellFamilyFlags[2] & 0x1000)
- return DIMINISHING_STUN;
-
- // Intimidating Shout -- 5246
- if (spellproto->SpellFamilyFlags[0] & 0x40000)
- return DIMINISHING_DISORIENT;
-
- // Hamstring -- 1715, 8 seconds in PvP (6.0)
- if (spellproto->SpellFamilyFlags[0] & 0x2)
- return DIMINISHING_LIMITONLY;
- break;
- }
- case SPELLFAMILY_WARLOCK:
- {
- // Mortal Coil -- 6789
- if (spellproto->SpellFamilyFlags[0] & 0x80000)
- return DIMINISHING_INCAPACITATE;
- // Banish -- 710
- if (spellproto->SpellFamilyFlags[1] & 0x8000000)
- return DIMINISHING_INCAPACITATE;
-
- // Fear -- 118699
- if (spellproto->SpellFamilyFlags[1] & 0x400)
- return DIMINISHING_DISORIENT;
- // Howl of Terror -- 5484
- if (spellproto->SpellFamilyFlags[1] & 0x8)
- return DIMINISHING_DISORIENT;
-
- // Shadowfury -- 30283
- if (spellproto->SpellFamilyFlags[1] & 0x1000)
- return DIMINISHING_STUN;
- // Summon Infernal -- 22703
- if (spellproto->SpellFamilyFlags[0] & 0x1000)
- return DIMINISHING_STUN;
- break;
- }
- case SPELLFAMILY_WARLOCK_PET:
- {
- // Fellash -- 115770
- // Whiplash -- 6360
- if (spellproto->SpellFamilyFlags[0] & 0x8000000)
- return DIMINISHING_AOE_KNOCKBACK;
-
- // Mesmerize (Shivarra pet) -- 115268
- // Seduction (Succubus pet) -- 6358
- if (spellproto->SpellFamilyFlags[0] & 0x2000000)
- return DIMINISHING_DISORIENT;
-
- // Axe Toss (Felguard pet) -- 89766
- if (spellproto->SpellFamilyFlags[1] & 0x4)
- return DIMINISHING_STUN;
- break;
- }
- case SPELLFAMILY_DRUID:
- {
- // Maim -- 22570
- if (spellproto->SpellFamilyFlags[1] & 0x80)
- return DIMINISHING_STUN;
- // Mighty Bash -- 5211
- if (spellproto->SpellFamilyFlags[0] & 0x2000)
- return DIMINISHING_STUN;
- // Rake -- 163505 -- no flags on the stun
- if (spellproto->Id == 163505)
- return DIMINISHING_STUN;
-
- // Incapacitating Roar -- 99, no flags on the stun, 14
- if (spellproto->SpellFamilyFlags[1] & 0x1)
- return DIMINISHING_INCAPACITATE;
-
- // Cyclone -- 33786
- if (spellproto->SpellFamilyFlags[1] & 0x20)
- return DIMINISHING_DISORIENT;
-
- // Typhoon -- 61391
- if (spellproto->SpellFamilyFlags[1] & 0x1000000)
- return DIMINISHING_AOE_KNOCKBACK;
- // Ursol's Vortex -- 118283, no family flags
- if (spellproto->Id == 118283)
- return DIMINISHING_AOE_KNOCKBACK;
-
- // Entangling Roots -- 339
- if (spellproto->SpellFamilyFlags[0] & 0x200)
- return DIMINISHING_ROOT;
- // Mass Entanglement -- 102359
- if (spellproto->SpellFamilyFlags[2] & 0x4)
- return DIMINISHING_ROOT;
-
- // Faerie Fire -- 770, 20 seconds in PvP (6.0)
- if (spellproto->SpellFamilyFlags[0] & 0x400)
- return DIMINISHING_LIMITONLY;
- break;
- }
- case SPELLFAMILY_ROGUE:
- {
- // Cheap Shot -- 1833
- if (spellproto->SpellFamilyFlags[0] & 0x400)
- return DIMINISHING_STUN;
- // Kidney Shot -- 408
- if (spellproto->SpellFamilyFlags[0] & 0x200000)
- return DIMINISHING_STUN;
-
- // Gouge -- 1776
- if (spellproto->SpellFamilyFlags[0] & 0x8)
- return DIMINISHING_INCAPACITATE;
- // Sap -- 6770
- if (spellproto->SpellFamilyFlags[0] & 0x80)
- return DIMINISHING_INCAPACITATE;
-
- // Blind -- 2094
- if (spellproto->SpellFamilyFlags[0] & 0x1000000)
- return DIMINISHING_DISORIENT;
-
- // Garrote -- 1330
- if (spellproto->SpellFamilyFlags[1] & 0x20000000)
- return DIMINISHING_SILENCE;
- break;
- }
- case SPELLFAMILY_HUNTER:
- {
- // Charge (Tenacity pet) -- 53148, no flags
- if (spellproto->Id == 53148)
- return DIMINISHING_ROOT;
- // Narrow Escape -- 136634, no flags
- if (spellproto->Id == 136634)
- return DIMINISHING_ROOT;
-
- // Binding Shot -- 117526, no flags
- if (spellproto->Id == 117526)
- return DIMINISHING_STUN;
-
- // Freezing Trap -- 3355
- if (spellproto->SpellFamilyFlags[0] & 0x8)
- return DIMINISHING_INCAPACITATE;
- // Wyvern Sting -- 19386
- if (spellproto->SpellFamilyFlags[1] & 0x1000)
- return DIMINISHING_INCAPACITATE;
- break;
- }
- case SPELLFAMILY_PALADIN:
- {
- // Repentance -- 20066
- if (spellproto->SpellFamilyFlags[0] & 0x4)
- return DIMINISHING_INCAPACITATE;
-
- // Turn Evil -- 10326
- if (spellproto->SpellFamilyFlags[1] & 0x800000)
- return DIMINISHING_DISORIENT;
-
- // Avenger's Shield -- 31935
- if (spellproto->SpellFamilyFlags[0] & 0x4000)
- return DIMINISHING_SILENCE;
-
- // Fist of Justice -- 105593
- // Hammer of Justice -- 853
- if (spellproto->SpellFamilyFlags[0] & 0x800)
- return DIMINISHING_STUN;
- // Holy Wrath -- 119072
- if (spellproto->SpellFamilyFlags[1] & 0x200000)
- return DIMINISHING_STUN;
- break;
- }
- case SPELLFAMILY_SHAMAN:
- {
- // Hex -- 51514
- if (spellproto->SpellFamilyFlags[1] & 0x8000)
- return DIMINISHING_INCAPACITATE;
-
- // Thunderstorm -- 51490
- if (spellproto->SpellFamilyFlags[1] & 0x2000)
- return DIMINISHING_AOE_KNOCKBACK;
-
- // Earthgrab Totem -- 64695
- if (spellproto->SpellFamilyFlags[2] & 0x4000)
- return DIMINISHING_ROOT;
- break;
- }
- case SPELLFAMILY_DEATHKNIGHT:
- {
- // Strangulate -- 47476
- if (spellproto->SpellFamilyFlags[0] & 0x200)
- return DIMINISHING_SILENCE;
-
- // Asphyxiate -- 108194
- if (spellproto->SpellFamilyFlags[2] & 0x100000)
- return DIMINISHING_STUN;
- // Gnaw (Ghoul) -- 91800, no flags
- if (spellproto->Id == 91800)
- return DIMINISHING_STUN;
- // Monstrous Blow (Ghoul w/ Dark Transformation active) -- 91797
- if (spellproto->Id == 91797)
- return DIMINISHING_STUN;
- break;
- }
- case SPELLFAMILY_PRIEST:
- {
- // Dominate Mind -- 605
- if (spellproto->SpellFamilyFlags[0] & 0x20000 && spellproto->GetSpellVisual() == 39068)
- return DIMINISHING_INCAPACITATE;
- // Holy Word: Chastise -- 88625
- if (spellproto->SpellFamilyFlags[2] & 0x20)
- return DIMINISHING_INCAPACITATE;
- // Psychic Horror -- 64044
- if (spellproto->SpellFamilyFlags[2] & 0x2000)
- return DIMINISHING_INCAPACITATE;
-
- // Psychic Scream -- 8122
- if (spellproto->SpellFamilyFlags[0] & 0x10000)
- return DIMINISHING_DISORIENT;
-
- // Silence -- 15487
- if (spellproto->SpellFamilyFlags[1] & 0x200000 && spellproto->SchoolMask == 32)
- return DIMINISHING_SILENCE;
- break;
- }
- case SPELLFAMILY_MONK:
- {
- // Disable -- 116706, no flags
- if (spellproto->Id == 116706)
- return DIMINISHING_ROOT;
-
- // Charging Ox Wave -- 119392
- if (spellproto->SpellFamilyFlags[1] & 0x10000)
- return DIMINISHING_STUN;
- // Fists of Fury -- 120086
- if (spellproto->SpellFamilyFlags[1] & 0x800000 && !(spellproto->SpellFamilyFlags[2] & 0x8))
- return DIMINISHING_STUN;
- // Leg Sweep -- 119381
- if (spellproto->SpellFamilyFlags[1] & 0x200)
- return DIMINISHING_STUN;
-
- // Incendiary Breath (honor talent) -- 202274, no flags
- if (spellproto->Id == 202274)
- return DIMINISHING_INCAPACITATE;
- // Paralysis -- 115078
- if (spellproto->SpellFamilyFlags[2] & 0x800000)
- return DIMINISHING_INCAPACITATE;
- break;
- }
- default:
- break;
- }
-
- return DIMINISHING_NONE;
-}
-
-DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
-{
- switch (group)
- {
- case DIMINISHING_TAUNT:
- case DIMINISHING_STUN:
- return DRTYPE_ALL;
- case DIMINISHING_LIMITONLY:
- case DIMINISHING_NONE:
- return DRTYPE_NONE;
- default:
- return DRTYPE_PLAYER;
- }
-}
-
-DiminishingLevels GetDiminishingReturnsMaxLevel(DiminishingGroup group)
-{
- switch (group)
- {
- case DIMINISHING_TAUNT:
- return DIMINISHING_LEVEL_TAUNT_IMMUNE;
- case DIMINISHING_AOE_KNOCKBACK:
- return DIMINISHING_LEVEL_2;
- default:
- return DIMINISHING_LEVEL_IMMUNE;
- }
-}
-
-int32 GetDiminishingReturnsLimitDuration(SpellInfo const* spellproto)
-{
- // Explicit diminishing duration
- switch (spellproto->SpellFamilyName)
- {
- case SPELLFAMILY_DRUID:
- {
- // Faerie Fire - 20 seconds in PvP (6.0)
- if (spellproto->SpellFamilyFlags[0] & 0x400)
- return 20 * IN_MILLISECONDS;
- break;
- }
- case SPELLFAMILY_HUNTER:
- {
- // Binding Shot - 3 seconds in PvP (6.0)
- if (spellproto->Id == 117526)
- return 3 * IN_MILLISECONDS;
- // Wyvern Sting - 6 seconds in PvP (6.0)
- if (spellproto->SpellFamilyFlags[1] & 0x1000)
- return 6 * IN_MILLISECONDS;
- break;
- }
- case SPELLFAMILY_MONK:
- {
- // Paralysis - 4 seconds in PvP regardless of if they are facing you (6.0)
- if (spellproto->SpellFamilyFlags[2] & 0x800000)
- return 4 * IN_MILLISECONDS;
- break;
- }
- default:
- break;
- }
-
- return 8 * IN_MILLISECONDS;
-}
-
SpellMgr::SpellMgr() { }
SpellMgr::~SpellMgr()
@@ -3779,6 +3400,21 @@ void SpellMgr::LoadSpellInfoSpellSpecificAndAuraState()
TC_LOG_INFO("server.loading", ">> Loaded SpellInfo SpellSpecific and AuraState in %u ms", GetMSTimeDiffToNow(oldMSTime));
}
+void SpellMgr::LoadSpellInfoDiminishing()
+{
+ uint32 oldMSTime = getMSTime();
+
+ for (SpellInfo* spellInfo : mSpellInfoMap)
+ {
+ if (!spellInfo)
+ continue;
+
+ spellInfo->_LoadSpellDiminishInfo();
+ }
+
+ TC_LOG_INFO("server.loading", ">> Loaded SpellInfo diminishing infos in %u ms", GetMSTimeDiffToNow(oldMSTime));
+}
+
void SpellMgr::LoadPetFamilySpellsStore()
{
std::unordered_map<uint32, SpellLevelsEntry const*> levelsBySpell;
diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h
index 02c7d0bbd0f..c59c3495a9b 100644
--- a/src/server/game/Spells/SpellMgr.h
+++ b/src/server/game/Spells/SpellMgr.h
@@ -564,12 +564,6 @@ inline bool IsProfessionOrRidingSkill(uint32 skill)
bool IsPartOfSkillLine(uint32 skillId, uint32 spellId);
-// spell diminishing returns
-TC_GAME_API DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const* spellproto);
-TC_GAME_API DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group);
-TC_GAME_API DiminishingLevels GetDiminishingReturnsMaxLevel(DiminishingGroup group);
-TC_GAME_API int32 GetDiminishingReturnsLimitDuration(SpellInfo const* spellproto);
-
TC_GAME_API extern PetFamilySpellsStore sPetFamilySpellsStore;
struct SpellInfoLoadHelper
@@ -716,6 +710,7 @@ class TC_GAME_API SpellMgr
void LoadSpellInfoCustomAttributes();
void LoadSpellInfoCorrections();
void LoadSpellInfoSpellSpecificAndAuraState();
+ void LoadSpellInfoDiminishing();
private:
SpellDifficultySearcherMap mSpellDifficultySearcherMap;
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 8014ee90347..4d549d47fe5 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1606,6 +1606,9 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading SpellInfo SpellSpecific and AuraState...");
sSpellMgr->LoadSpellInfoSpellSpecificAndAuraState();
+ TC_LOG_INFO("server.loading", "Loading SpellInfo diminishing infos...");
+ sSpellMgr->LoadSpellInfoDiminishing();
+
TC_LOG_INFO("server.loading", "Loading PetFamilySpellsStore Data...");
sSpellMgr->LoadPetFamilySpellsStore();