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)
This commit is contained in:
@@ -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)
|
||||
DiminishingReturn& diminish = m_Diminishing[group];
|
||||
if (!diminish.hitCount)
|
||||
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 (!diminish.stack && GetMSTimeDiffToNow(diminish.hitTime) > 18 * IN_MILLISECONDS)
|
||||
{
|
||||
if (i->DRGroup != group)
|
||||
continue;
|
||||
|
||||
if (!i->hitCount)
|
||||
return DIMINISHING_LEVEL_1;
|
||||
|
||||
if (!i->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);
|
||||
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)
|
||||
{
|
||||
if (i->DRGroup != group)
|
||||
continue;
|
||||
DiminishingReturn& diminish = m_Diminishing[group];
|
||||
|
||||
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;
|
||||
if (apply)
|
||||
++diminish.stack;
|
||||
else if (diminish.stack)
|
||||
{
|
||||
--diminish.stack;
|
||||
|
||||
// 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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -4597,6 +4597,8 @@ enum DiminishingGroup : uint16
|
||||
DIMINISHING_AOE_KNOCKBACK = 6,
|
||||
DIMINISHING_TAUNT = 7,
|
||||
DIMINISHING_LIMITONLY = 8,
|
||||
|
||||
DIMINISHING_MAX
|
||||
};
|
||||
|
||||
enum SummonCategory
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
+231
-208
@@ -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;
|
||||
friend class SpellMgr;
|
||||
|
||||
uint32 ExplicitTargetMask;
|
||||
SpellChainNode const* ChainEntry;
|
||||
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;
|
||||
|
||||
SpellInfo(SpellInfoLoadHelper const& data, SpellEffectEntryMap const& effectsMap, SpellVisualMap&& visuals,
|
||||
std::unordered_map<uint32, SpellEffectScalingEntry const*> const& effectScaling);
|
||||
~SpellInfo();
|
||||
// SpellScalingEntry
|
||||
struct ScalingInfo
|
||||
{
|
||||
int32 Class;
|
||||
uint32 MinScalingLevel;
|
||||
uint32 MaxScalingLevel;
|
||||
uint32 ScalesFromItemLevel;
|
||||
} Scaling;
|
||||
|
||||
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;
|
||||
uint32 ExplicitTargetMask;
|
||||
SpellChainNode const* ChainEntry;
|
||||
|
||||
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); }
|
||||
SpellInfo(SpellInfoLoadHelper const& data, SpellEffectEntryMap const& effectsMap, SpellVisualMap&& visuals,
|
||||
std::unordered_map<uint32, SpellEffectScalingEntry const*> const& effectScaling);
|
||||
~SpellInfo();
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
bool IsAffectingArea(uint32 difficulty) const;
|
||||
bool IsTargetingArea(uint32 difficulty) const;
|
||||
bool NeedsExplicitUnitTarget() const;
|
||||
bool NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell, uint32 difficulty) 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 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 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 IsAffectedBySpellMods() const;
|
||||
bool IsAffectedBySpellMod(SpellModifier const* mod) const;
|
||||
bool IsAffectingArea(uint32 difficulty) const;
|
||||
bool IsTargetingArea(uint32 difficulty) const;
|
||||
bool NeedsExplicitUnitTarget() const;
|
||||
bool NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell, uint32 difficulty) const;
|
||||
|
||||
bool CanPierceImmuneAura(SpellInfo const* aura) const;
|
||||
bool CanDispelAura(SpellInfo const* aura) 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 IsSingleTarget() const;
|
||||
bool IsAuraExclusiveBySpecificWith(SpellInfo const* spellInfo) const;
|
||||
bool IsAuraExclusiveBySpecificPerCasterWith(SpellInfo const* spellInfo) const;
|
||||
bool IsAffectedBySpellMods() const;
|
||||
bool IsAffectedBySpellMod(SpellModifier const* mod) 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;
|
||||
bool CanPierceImmuneAura(SpellInfo const* aura) const;
|
||||
bool CanDispelAura(SpellInfo const* aura) 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;
|
||||
bool IsSingleTarget() const;
|
||||
bool IsAuraExclusiveBySpecificWith(SpellInfo const* spellInfo) const;
|
||||
bool IsAuraExclusiveBySpecificPerCasterWith(SpellInfo const* spellInfo) const;
|
||||
|
||||
AuraStateType GetAuraState() const;
|
||||
SpellSpecificType GetSpellSpecific() 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;
|
||||
|
||||
float GetMinRange(bool positive = false) const;
|
||||
float GetMaxRange(bool positive = false, Unit* caster = NULL, Spell* spell = NULL) 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;
|
||||
|
||||
int32 CalcDuration(Unit* caster = nullptr) const;
|
||||
int32 GetDuration() const;
|
||||
int32 GetMaxDuration() const;
|
||||
AuraStateType GetAuraState() const;
|
||||
SpellSpecificType GetSpellSpecific() const;
|
||||
|
||||
uint32 GetMaxTicks(uint32 difficulty) const;
|
||||
float GetMinRange(bool positive = false) const;
|
||||
float GetMaxRange(bool positive = false, Unit* caster = NULL, Spell* spell = NULL) const;
|
||||
|
||||
uint32 CalcCastTime(uint8 level = 0, Spell* spell = NULL) const;
|
||||
uint32 GetRecoveryTime() const;
|
||||
int32 CalcDuration(Unit* caster = nullptr) const;
|
||||
int32 GetDuration() const;
|
||||
int32 GetMaxDuration() const;
|
||||
|
||||
std::vector<SpellPowerCost> CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) const;
|
||||
uint32 GetMaxTicks(uint32 difficulty) const;
|
||||
|
||||
float CalcProcPPM(Unit* caster, int32 itemLevel) const;
|
||||
uint32 CalcCastTime(uint8 level = 0, Spell* spell = NULL) const;
|
||||
uint32 GetRecoveryTime() 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;
|
||||
std::vector<SpellPowerCost> CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) const;
|
||||
|
||||
uint32 GetSpellXSpellVisualId(Unit const* caster = nullptr) const;
|
||||
uint32 GetSpellVisual(Unit const* caster = nullptr) const;
|
||||
float CalcProcPPM(Unit* caster, int32 itemLevel) 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();
|
||||
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;
|
||||
|
||||
// unloading helpers
|
||||
void _UnloadImplicitTargetConditionLists();
|
||||
void _UnloadSpellEffects();
|
||||
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); }
|
||||
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;
|
||||
// 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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user