Core/Globals: compute aura diminishing return info at startup and cache it
This commit is contained in:
1 parent
7ccd58615a
commit
d30237fb1e
10 files changed
+665
-619
No files matched your search
@@ -9447,60 +9447,56 @@ 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 15 seconds ago - reset the count.
|
||||
if (!diminish.stack && GetMSTimeDiffToNow(diminish.hitTime) > 15000)
|
||||
{
|
||||
if (i->DRGroup != group)
|
||||
continue;
|
||||
|
||||
if (!i->hitCount)
|
||||
return DIMINISHING_LEVEL_1;
|
||||
|
||||
// If last spell was cast more than 15 seconds ago - reset the count.
|
||||
if (i->stack == 0 && getMSTimeDiff(i->hitTime, getMSTime()) > 15000)
|
||||
{
|
||||
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* targetOwner = GetCharmerOrOwner();
|
||||
Unit const* casterOwner = caster->GetCharmerOrOwner();
|
||||
|
||||
// Duration of crowd control abilities on pvp target is limited by 10 sec. (2.2.0)
|
||||
if (limitduration > 0 && duration > limitduration)
|
||||
if (limitDuration > 0 && duration > limitDuration)
|
||||
{
|
||||
Unit const* target = tarGetOwner ? tarGetOwner : this;
|
||||
Unit const* target = targetOwner ? targetOwner : this;
|
||||
Unit const* source = casterOwner ? casterOwner : caster;
|
||||
|
||||
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;
|
||||
@@ -9509,7 +9505,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;
|
||||
@@ -9522,12 +9518,12 @@ float Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,
|
||||
}
|
||||
}
|
||||
// Some diminishings applies to mobs too (for example, Stun)
|
||||
else if ((GetDiminishingReturnsGroupType(group) == DRTYPE_PLAYER
|
||||
&& ((tarGetOwner ? (tarGetOwner->GetTypeId() == TYPEID_PLAYER) : (GetTypeId() == TYPEID_PLAYER))
|
||||
else if ((auraSpellInfo->GetDiminishingReturnsGroupType(triggered) == DRTYPE_PLAYER
|
||||
&& ((targetOwner ? (targetOwner->GetTypeId() == TYPEID_PLAYER) : (GetTypeId() == TYPEID_PLAYER))
|
||||
|| (GetTypeId() == TYPEID_UNIT && 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;
|
||||
@@ -9545,24 +9541,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)
|
||||
|
||||
@@ -832,11 +832,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;
|
||||
@@ -1287,7 +1291,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<uint8 /*procEffectMask*/, AuraApplication*>> AuraApplicationProcContainer;
|
||||
|
||||
@@ -1304,11 +1308,11 @@ class TC_GAME_API Unit : public WorldObject
|
||||
void CleanupBeforeRemoveFromMap(bool finalCleanup);
|
||||
void CleanupsBeforeDelete(bool finalCleanup = true) override; // used in ~Creature/~Player (or before mass creature delete to remove cross-references to already deleted units)
|
||||
|
||||
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;
|
||||
|
||||
@@ -3621,7 +3621,9 @@ enum DiminishingGroup : uint16
|
||||
DIMINISHING_SLEEP = 17,
|
||||
DIMINISHING_TAUNT = 18,
|
||||
DIMINISHING_LIMITONLY = 19,
|
||||
DIMINISHING_DRAGONS_BREATH = 20
|
||||
DIMINISHING_DRAGONS_BREATH = 20,
|
||||
|
||||
DIMINISHING_MAX
|
||||
};
|
||||
|
||||
enum SummonCategory
|
||||
|
||||
@@ -591,8 +591,6 @@ m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerO
|
||||
damage = 0;
|
||||
targetMissInfo = SPELL_MISS_NONE;
|
||||
effectHandleMode = SPELL_EFFECT_HANDLE_LAUNCH;
|
||||
m_diminishLevel = DIMINISHING_LEVEL_1;
|
||||
m_diminishGroup = DIMINISHING_NONE;
|
||||
m_damage = 0;
|
||||
m_healing = 0;
|
||||
m_procAttacker = 0;
|
||||
@@ -2617,16 +2615,19 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
|
||||
aura_effmask |= 1 << i;
|
||||
|
||||
// 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, m_triggeredByAuraSpell != nullptr);
|
||||
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)
|
||||
@@ -2669,8 +2670,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 = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
|
||||
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)
|
||||
@@ -2685,7 +2685,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()))
|
||||
@@ -3525,9 +3525,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();
|
||||
@@ -4852,7 +4849,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
|
||||
@@ -4863,7 +4860,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::HandleHolyPower(Player* caster)
|
||||
|
||||
@@ -580,10 +580,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;
|
||||
|
||||
|
||||
@@ -2326,6 +2326,322 @@ void SpellInfo::_LoadSpellSpecific()
|
||||
}();
|
||||
}
|
||||
|
||||
void SpellInfo::_LoadSpellDiminishInfo()
|
||||
{
|
||||
auto diminishingGroupCompute = [this](bool triggered) -> DiminishingGroup
|
||||
{
|
||||
if (IsPositive())
|
||||
return DIMINISHING_NONE;
|
||||
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
{
|
||||
if (Effects[i].ApplyAuraName == SPELL_AURA_MOD_TAUNT)
|
||||
return DIMINISHING_TAUNT;
|
||||
}
|
||||
|
||||
// Explicit Diminishing Groups
|
||||
switch (SpellFamilyName)
|
||||
{
|
||||
case SPELLFAMILY_GENERIC:
|
||||
{
|
||||
// Pet charge effects (Infernal Awakening, Demon Charge)
|
||||
if (SpellVisual[0] == 2816 && SpellIconID == 15)
|
||||
return DIMINISHING_CONTROLLED_STUN;
|
||||
// Frost Tomb
|
||||
else if (Id == 48400)
|
||||
return DIMINISHING_NONE;
|
||||
// Gnaw
|
||||
else if (Id == 47481)
|
||||
return DIMINISHING_CONTROLLED_STUN;
|
||||
// ToC Icehowl Arctic Breath
|
||||
else if (SpellVisual[0] == 14153)
|
||||
return DIMINISHING_NONE;
|
||||
// Black Plague
|
||||
else if (Id == 64155)
|
||||
return DIMINISHING_NONE;
|
||||
// Screams of the Dead (King Ymiron)
|
||||
else if (Id == 51750)
|
||||
return DIMINISHING_NONE;
|
||||
break;
|
||||
}
|
||||
// Event spells
|
||||
case SPELLFAMILY_UNK1:
|
||||
return DIMINISHING_NONE;
|
||||
case SPELLFAMILY_MAGE:
|
||||
{
|
||||
// Frostbite
|
||||
if (SpellFamilyFlags[1] & 0x80000000)
|
||||
return DIMINISHING_ROOT;
|
||||
// Shattered Barrier
|
||||
else if (SpellVisual[0] == 12297)
|
||||
return DIMINISHING_ROOT;
|
||||
// Deep Freeze
|
||||
else if (SpellIconID == 2939 && SpellVisual[0] == 9963)
|
||||
return DIMINISHING_CONTROLLED_STUN;
|
||||
// Frost Nova / Freeze (Water Elemental)
|
||||
else if (SpellIconID == 193)
|
||||
return DIMINISHING_CONTROLLED_ROOT;
|
||||
// Dragon's Breath
|
||||
else if (SpellFamilyFlags[0] & 0x800000)
|
||||
return DIMINISHING_DRAGONS_BREATH;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_WARRIOR:
|
||||
{
|
||||
// Hamstring - limit duration to 10s in PvP
|
||||
if (SpellFamilyFlags[0] & 0x2)
|
||||
return DIMINISHING_LIMITONLY;
|
||||
// Charge Stun (own diminishing)
|
||||
else if (SpellFamilyFlags[0] & 0x01000000)
|
||||
return DIMINISHING_CHARGE;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_WARLOCK:
|
||||
{
|
||||
// Curses/etc
|
||||
if ((SpellFamilyFlags[0] & 0x80000000) || (SpellFamilyFlags[1] & 0x200))
|
||||
return DIMINISHING_LIMITONLY;
|
||||
// Seduction
|
||||
else if (SpellFamilyFlags[1] & 0x10000000)
|
||||
return DIMINISHING_FEAR;
|
||||
// Sin and Punishment (Priest spell, don't ask)
|
||||
else if (SpellIconID == 1869)
|
||||
return DIMINISHING_NONE;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_DRUID:
|
||||
{
|
||||
// Pounce
|
||||
if (SpellFamilyFlags[0] & 0x20000)
|
||||
return DIMINISHING_OPENING_STUN;
|
||||
// Cyclone
|
||||
else if (SpellFamilyFlags[1] & 0x20)
|
||||
return DIMINISHING_CYCLONE;
|
||||
// Entangling Roots
|
||||
// Nature's Grasp
|
||||
else if (SpellFamilyFlags[0] & 0x00000200)
|
||||
return DIMINISHING_CONTROLLED_ROOT;
|
||||
// Faerie Fire
|
||||
else if (SpellFamilyFlags[0] & 0x400)
|
||||
return DIMINISHING_LIMITONLY;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_ROGUE:
|
||||
{
|
||||
// Gouge
|
||||
if (SpellFamilyFlags[0] & 0x8)
|
||||
return DIMINISHING_DISORIENT;
|
||||
// Blind
|
||||
else if (SpellFamilyFlags[0] & 0x1000000)
|
||||
return DIMINISHING_FEAR;
|
||||
// Cheap Shot
|
||||
else if (SpellFamilyFlags[0] & 0x400)
|
||||
return DIMINISHING_OPENING_STUN;
|
||||
// Crippling poison - Limit to 10 seconds in PvP (No SpellFamilyFlags)
|
||||
else if (SpellIconID == 163)
|
||||
return DIMINISHING_LIMITONLY;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_HUNTER:
|
||||
{
|
||||
// Hunter's Mark
|
||||
if ((SpellFamilyFlags[0] & 0x400) && SpellIconID == 538)
|
||||
return DIMINISHING_LIMITONLY;
|
||||
// Scatter Shot (own diminishing)
|
||||
else if ((SpellFamilyFlags[0] & 0x40000) && SpellIconID == 132)
|
||||
return DIMINISHING_SCATTER_SHOT;
|
||||
// Entrapment (own diminishing)
|
||||
else if (SpellVisual[0] == 7484 && SpellIconID == 20)
|
||||
return DIMINISHING_ENTRAPMENT;
|
||||
// Wyvern Sting mechanic is MECHANIC_SLEEP but the diminishing is DIMINISHING_DISORIENT
|
||||
else if ((SpellFamilyFlags[1] & 0x1000) && SpellIconID == 1721)
|
||||
return DIMINISHING_DISORIENT;
|
||||
// Freezing Arrow
|
||||
else if (SpellFamilyFlags[0] & 0x8)
|
||||
return DIMINISHING_DISORIENT;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_PALADIN:
|
||||
{
|
||||
// Judgement of Justice - limit duration to 10s in PvP
|
||||
if (SpellFamilyFlags[0] & 0x100000)
|
||||
return DIMINISHING_LIMITONLY;
|
||||
// Turn Evil
|
||||
else if ((SpellFamilyFlags[1] & 0x804000) && SpellIconID == 309)
|
||||
return DIMINISHING_FEAR;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_SHAMAN:
|
||||
{
|
||||
// Storm, Earth and Fire - Earthgrab
|
||||
if (SpellFamilyFlags[2] & 0x4000)
|
||||
return DIMINISHING_NONE;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_DEATHKNIGHT:
|
||||
{
|
||||
// Hungering Cold (no flags)
|
||||
if (SpellIconID == 2797)
|
||||
return DIMINISHING_DISORIENT;
|
||||
// Mark of Blood
|
||||
else if ((SpellFamilyFlags[0] & 0x10000000) && SpellIconID == 2285)
|
||||
return DIMINISHING_LIMITONLY;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Lastly - Set diminishing depending on mechanic
|
||||
uint32 mechanic = GetAllEffectsMechanicMask();
|
||||
if (mechanic & (1 << MECHANIC_CHARM))
|
||||
return DIMINISHING_MIND_CONTROL;
|
||||
if (mechanic & (1 << MECHANIC_SILENCE))
|
||||
return DIMINISHING_SILENCE;
|
||||
if (mechanic & (1 << MECHANIC_SLEEP))
|
||||
return DIMINISHING_SLEEP;
|
||||
if (mechanic & ((1 << MECHANIC_SAPPED) | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_SHACKLE)))
|
||||
return DIMINISHING_DISORIENT;
|
||||
// Mechanic Knockout, except Blast Wave
|
||||
if (mechanic & (1 << MECHANIC_KNOCKOUT) && SpellIconID != 292)
|
||||
return DIMINISHING_DISORIENT;
|
||||
if (mechanic & (1 << MECHANIC_DISARM))
|
||||
return DIMINISHING_DISARM;
|
||||
if (mechanic & (1 << MECHANIC_FEAR))
|
||||
return DIMINISHING_FEAR;
|
||||
if (mechanic & (1 << MECHANIC_STUN))
|
||||
return triggered ? DIMINISHING_STUN : DIMINISHING_CONTROLLED_STUN;
|
||||
if (mechanic & (1 << MECHANIC_BANISH))
|
||||
return DIMINISHING_BANISH;
|
||||
if (mechanic & (1 << MECHANIC_ROOT))
|
||||
return triggered ? DIMINISHING_ROOT : DIMINISHING_CONTROLLED_ROOT;
|
||||
if (mechanic & (1 << MECHANIC_HORROR))
|
||||
return DIMINISHING_HORROR;
|
||||
|
||||
return DIMINISHING_NONE;
|
||||
};
|
||||
|
||||
auto diminishingTypeCompute = [](DiminishingGroup group) -> DiminishingReturnsType
|
||||
{
|
||||
switch (group)
|
||||
{
|
||||
case DIMINISHING_TAUNT:
|
||||
case DIMINISHING_CONTROLLED_STUN:
|
||||
case DIMINISHING_STUN:
|
||||
case DIMINISHING_OPENING_STUN:
|
||||
case DIMINISHING_CYCLONE:
|
||||
case DIMINISHING_CHARGE:
|
||||
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;
|
||||
default:
|
||||
return DIMINISHING_LEVEL_IMMUNE;
|
||||
}
|
||||
};
|
||||
|
||||
auto diminishingLimitDurationCompute = [this](DiminishingGroup group) -> int32
|
||||
{
|
||||
auto isGroupDurationLimited = [group]() -> bool
|
||||
{
|
||||
switch (group)
|
||||
{
|
||||
case DIMINISHING_BANISH:
|
||||
case DIMINISHING_CONTROLLED_STUN:
|
||||
case DIMINISHING_CONTROLLED_ROOT:
|
||||
case DIMINISHING_CYCLONE:
|
||||
case DIMINISHING_DISORIENT:
|
||||
case DIMINISHING_ENTRAPMENT:
|
||||
case DIMINISHING_FEAR:
|
||||
case DIMINISHING_HORROR:
|
||||
case DIMINISHING_MIND_CONTROL:
|
||||
case DIMINISHING_OPENING_STUN:
|
||||
case DIMINISHING_ROOT:
|
||||
case DIMINISHING_STUN:
|
||||
case DIMINISHING_SLEEP:
|
||||
case DIMINISHING_LIMITONLY:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
if (!isGroupDurationLimited())
|
||||
return 0;
|
||||
|
||||
// Explicit diminishing duration
|
||||
switch (SpellFamilyName)
|
||||
{
|
||||
case SPELLFAMILY_DRUID:
|
||||
{
|
||||
// Faerie Fire - limit to 40 seconds in PvP (3.1)
|
||||
if (SpellFamilyFlags[0] & 0x400)
|
||||
return 40 * IN_MILLISECONDS;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_HUNTER:
|
||||
{
|
||||
// Wyvern Sting
|
||||
if (SpellFamilyFlags[1] & 0x1000)
|
||||
return 6 * IN_MILLISECONDS;
|
||||
// Hunter's Mark
|
||||
if (SpellFamilyFlags[0] & 0x400)
|
||||
return 30 * IN_MILLISECONDS;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_PALADIN:
|
||||
{
|
||||
// Repentance - limit to 6 seconds in PvP
|
||||
if (SpellFamilyFlags[0] & 0x4)
|
||||
return 6 * IN_MILLISECONDS;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_WARLOCK:
|
||||
{
|
||||
// Banish - limit to 6 seconds in PvP
|
||||
if (SpellFamilyFlags[1] & 0x8000000)
|
||||
return 6 * IN_MILLISECONDS;
|
||||
// Curse of Tongues - limit to 12 seconds in PvP
|
||||
else if (SpellFamilyFlags[2] & 0x800)
|
||||
return 12 * IN_MILLISECONDS;
|
||||
// Curse of Elements - limit to 120 seconds in PvP
|
||||
else if (SpellFamilyFlags[1] & 0x200)
|
||||
return 120 * 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;
|
||||
}
|
||||
|
||||
void SpellInfo::_LoadImmunityInfo()
|
||||
{
|
||||
uint32 schoolImmunityMask = 0;
|
||||
|
||||
+252
-232
@@ -313,265 +313,285 @@ struct TC_GAME_API ImmunityInfo
|
||||
boost::container::flat_set<SpellEffects> SpellEffectImmune;
|
||||
};
|
||||
|
||||
struct TC_GAME_API SpellDiminishInfo
|
||||
{
|
||||
DiminishingGroup DiminishGroup = DIMINISHING_NONE;
|
||||
DiminishingReturnsType DiminishReturnType = DRTYPE_NONE;
|
||||
DiminishingLevels DiminishMaxLevel = DIMINISHING_LEVEL_IMMUNE;
|
||||
int32 DiminishDurationLimit = 0;
|
||||
};
|
||||
|
||||
class TC_GAME_API SpellInfo
|
||||
{
|
||||
public:
|
||||
uint32 Id;
|
||||
SpellCategoryEntry const* CategoryEntry;
|
||||
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 AttributesCu;
|
||||
uint64 Stances;
|
||||
uint64 StancesNot;
|
||||
uint32 Targets;
|
||||
uint32 TargetCreatureType;
|
||||
uint32 RequiresSpellFocus;
|
||||
uint32 FacingCasterFlags;
|
||||
uint32 CasterAuraState;
|
||||
uint32 TargetAuraState;
|
||||
uint32 CasterAuraStateNot;
|
||||
uint32 TargetAuraStateNot;
|
||||
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 MaxLevel;
|
||||
uint32 BaseLevel;
|
||||
uint32 SpellLevel;
|
||||
SpellDurationEntry const* DurationEntry;
|
||||
uint32 PowerType;
|
||||
uint32 ManaCost;
|
||||
uint32 ManaCostPerlevel;
|
||||
uint32 ManaPerSecond;
|
||||
uint32 ManaCostPercentage;
|
||||
uint32 RuneCostID;
|
||||
SpellRangeEntry const* RangeEntry;
|
||||
float Speed;
|
||||
uint32 StackAmount;
|
||||
uint32 Totem[2];
|
||||
int32 Reagent[MAX_SPELL_REAGENTS];
|
||||
uint32 ReagentCount[MAX_SPELL_REAGENTS];
|
||||
int32 EquippedItemClass;
|
||||
int32 EquippedItemSubClassMask;
|
||||
int32 EquippedItemInventoryTypeMask;
|
||||
uint32 TotemCategory[2];
|
||||
uint32 SpellVisual[2];
|
||||
uint32 SpellIconID;
|
||||
uint32 ActiveIconID;
|
||||
char* SpellName;
|
||||
char* Rank;
|
||||
uint32 MaxTargetLevel;
|
||||
uint32 MaxAffectedTargets;
|
||||
uint32 SpellFamilyName;
|
||||
flag96 SpellFamilyFlags;
|
||||
uint32 DmgClass;
|
||||
uint32 PreventionType;
|
||||
int32 AreaGroupId;
|
||||
uint32 SchoolMask;
|
||||
uint32 SpellDifficultyId;
|
||||
uint32 SpellScalingId;
|
||||
uint32 SpellAuraOptionsId;
|
||||
uint32 SpellAuraRestrictionsId;
|
||||
uint32 SpellCastingRequirementsId;
|
||||
uint32 SpellCategoriesId;
|
||||
uint32 SpellClassOptionsId;
|
||||
uint32 SpellCooldownsId;
|
||||
uint32 SpellEquippedItemsId;
|
||||
uint32 SpellInterruptsId;
|
||||
uint32 SpellLevelsId;
|
||||
uint32 SpellPowerId;
|
||||
uint32 SpellReagentsId;
|
||||
uint32 SpellShapeshiftId;
|
||||
uint32 SpellTargetRestrictionsId;
|
||||
uint32 SpellTotemsId;
|
||||
// SpellScalingEntry
|
||||
int32 CastTimeMin;
|
||||
int32 CastTimeMax;
|
||||
int32 CastTimeMaxLevel;
|
||||
int32 ScalingClass;
|
||||
float CoefBase;
|
||||
int32 CoefLevelBase;
|
||||
SpellEffectInfo Effects[MAX_SPELL_EFFECTS];
|
||||
uint32 ExplicitTargetMask;
|
||||
SpellChainNode const* ChainEntry;
|
||||
friend class SpellMgr;
|
||||
|
||||
// struct access functions
|
||||
SpellTargetRestrictionsEntry const* GetSpellTargetRestrictions() const;
|
||||
SpellAuraOptionsEntry const* GetSpellAuraOptions() const;
|
||||
SpellAuraRestrictionsEntry const* GetSpellAuraRestrictions() const;
|
||||
SpellCastingRequirementsEntry const* GetSpellCastingRequirements() const;
|
||||
SpellCategoriesEntry const* GetSpellCategories() const;
|
||||
SpellClassOptionsEntry const* GetSpellClassOptions() const;
|
||||
SpellCooldownsEntry const* GetSpellCooldowns() const;
|
||||
SpellEquippedItemsEntry const* GetSpellEquippedItems() const;
|
||||
SpellInterruptsEntry const* GetSpellInterrupts() const;
|
||||
SpellLevelsEntry const* GetSpellLevels() const;
|
||||
SpellPowerEntry const* GetSpellPower() const;
|
||||
SpellReagentsEntry const* GetSpellReagents() const;
|
||||
SpellScalingEntry const* GetSpellScaling() const;
|
||||
SpellShapeshiftEntry const* GetSpellShapeshift() const;
|
||||
SpellTotemsEntry const* GetSpellTotems() const;
|
||||
public:
|
||||
uint32 Id;
|
||||
SpellCategoryEntry const* CategoryEntry;
|
||||
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 AttributesCu;
|
||||
uint64 Stances;
|
||||
uint64 StancesNot;
|
||||
uint32 Targets;
|
||||
uint32 TargetCreatureType;
|
||||
uint32 RequiresSpellFocus;
|
||||
uint32 FacingCasterFlags;
|
||||
uint32 CasterAuraState;
|
||||
uint32 TargetAuraState;
|
||||
uint32 CasterAuraStateNot;
|
||||
uint32 TargetAuraStateNot;
|
||||
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 MaxLevel;
|
||||
uint32 BaseLevel;
|
||||
uint32 SpellLevel;
|
||||
SpellDurationEntry const* DurationEntry;
|
||||
uint32 PowerType;
|
||||
uint32 ManaCost;
|
||||
uint32 ManaCostPerlevel;
|
||||
uint32 ManaPerSecond;
|
||||
uint32 ManaCostPercentage;
|
||||
uint32 RuneCostID;
|
||||
SpellRangeEntry const* RangeEntry;
|
||||
float Speed;
|
||||
uint32 StackAmount;
|
||||
uint32 Totem[2];
|
||||
int32 Reagent[MAX_SPELL_REAGENTS];
|
||||
uint32 ReagentCount[MAX_SPELL_REAGENTS];
|
||||
int32 EquippedItemClass;
|
||||
int32 EquippedItemSubClassMask;
|
||||
int32 EquippedItemInventoryTypeMask;
|
||||
uint32 TotemCategory[2];
|
||||
uint32 SpellVisual[2];
|
||||
uint32 SpellIconID;
|
||||
uint32 ActiveIconID;
|
||||
char* SpellName;
|
||||
char* Rank;
|
||||
uint32 MaxTargetLevel;
|
||||
uint32 MaxAffectedTargets;
|
||||
uint32 SpellFamilyName;
|
||||
flag96 SpellFamilyFlags;
|
||||
uint32 DmgClass;
|
||||
uint32 PreventionType;
|
||||
int32 AreaGroupId;
|
||||
uint32 SchoolMask;
|
||||
uint32 SpellDifficultyId;
|
||||
uint32 SpellScalingId;
|
||||
uint32 SpellAuraOptionsId;
|
||||
uint32 SpellAuraRestrictionsId;
|
||||
uint32 SpellCastingRequirementsId;
|
||||
uint32 SpellCategoriesId;
|
||||
uint32 SpellClassOptionsId;
|
||||
uint32 SpellCooldownsId;
|
||||
uint32 SpellEquippedItemsId;
|
||||
uint32 SpellInterruptsId;
|
||||
uint32 SpellLevelsId;
|
||||
uint32 SpellPowerId;
|
||||
uint32 SpellReagentsId;
|
||||
uint32 SpellShapeshiftId;
|
||||
uint32 SpellTargetRestrictionsId;
|
||||
uint32 SpellTotemsId;
|
||||
// SpellScalingEntry
|
||||
int32 CastTimeMin;
|
||||
int32 CastTimeMax;
|
||||
int32 CastTimeMaxLevel;
|
||||
int32 ScalingClass;
|
||||
float CoefBase;
|
||||
int32 CoefLevelBase;
|
||||
SpellEffectInfo Effects[MAX_SPELL_EFFECTS];
|
||||
uint32 ExplicitTargetMask;
|
||||
SpellChainNode const* ChainEntry;
|
||||
|
||||
SpellInfo(SpellEntry const* spellEntry, SpellEffectEntry const** effects);
|
||||
~SpellInfo();
|
||||
// struct access functions
|
||||
SpellTargetRestrictionsEntry const* GetSpellTargetRestrictions() const;
|
||||
SpellAuraOptionsEntry const* GetSpellAuraOptions() const;
|
||||
SpellAuraRestrictionsEntry const* GetSpellAuraRestrictions() const;
|
||||
SpellCastingRequirementsEntry const* GetSpellCastingRequirements() const;
|
||||
SpellCategoriesEntry const* GetSpellCategories() const;
|
||||
SpellClassOptionsEntry const* GetSpellClassOptions() const;
|
||||
SpellCooldownsEntry const* GetSpellCooldowns() const;
|
||||
SpellEquippedItemsEntry const* GetSpellEquippedItems() const;
|
||||
SpellInterruptsEntry const* GetSpellInterrupts() const;
|
||||
SpellLevelsEntry const* GetSpellLevels() const;
|
||||
SpellPowerEntry const* GetSpellPower() const;
|
||||
SpellReagentsEntry const* GetSpellReagents() const;
|
||||
SpellScalingEntry const* GetSpellScaling() const;
|
||||
SpellShapeshiftEntry const* GetSpellShapeshift() const;
|
||||
SpellTotemsEntry const* GetSpellTotems() const;
|
||||
|
||||
uint32 GetCategory() const;
|
||||
bool HasEffect(SpellEffects effect) const;
|
||||
bool HasAura(AuraType aura) const;
|
||||
bool HasAreaAuraEffect() const;
|
||||
SpellInfo(SpellEntry const* spellEntry, SpellEffectEntry const** effects);
|
||||
~SpellInfo();
|
||||
|
||||
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(SpellCustomAttributes customAttribute) const { return !!(AttributesCu & customAttribute); }
|
||||
uint32 GetCategory() const;
|
||||
bool HasEffect(SpellEffects effect) const;
|
||||
bool HasAura(AuraType aura) const;
|
||||
bool HasAreaAuraEffect() const;
|
||||
|
||||
bool IsExplicitDiscovery() const;
|
||||
bool IsLootCrafting() const;
|
||||
bool IsQuestTame() const;
|
||||
bool IsProfessionOrRiding() const;
|
||||
bool IsProfession() const;
|
||||
bool IsPrimaryProfession() const;
|
||||
bool IsPrimaryProfessionFirstRank() const;
|
||||
bool IsAbilityLearnedWithProfession() const;
|
||||
bool IsAbilityOfSkillType(uint32 skillType) 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(SpellCustomAttributes customAttribute) const { return !!(AttributesCu & customAttribute); }
|
||||
|
||||
bool IsAffectingArea() const;
|
||||
bool IsTargetingArea() const;
|
||||
bool NeedsExplicitUnitTarget() const;
|
||||
bool NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) const;
|
||||
bool IsExplicitDiscovery() const;
|
||||
bool IsLootCrafting() const;
|
||||
bool IsQuestTame() const;
|
||||
bool IsProfessionOrRiding() const;
|
||||
bool IsProfession() const;
|
||||
bool IsPrimaryProfession() const;
|
||||
bool IsPrimaryProfessionFirstRank() const;
|
||||
bool IsAbilityLearnedWithProfession() const;
|
||||
bool IsAbilityOfSkillType(uint32 skillType) const;
|
||||
|
||||
bool IsPassive() const;
|
||||
bool IsRaidMarker() const;
|
||||
bool IsAutocastable() const;
|
||||
bool IsStackableWithRanks() const;
|
||||
bool IsPassiveStackableWithRanks() 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 IsMoveAllowedChannel() const;
|
||||
bool NeedsComboPoints() const;
|
||||
bool IsNextMeleeSwingSpell() const;
|
||||
bool IsBreakingStealth() const;
|
||||
bool IsRangedWeaponSpell() const;
|
||||
bool IsAutoRepeatRangedSpell() const;
|
||||
bool HasInitialAggro() const;
|
||||
bool IsAffectingArea() const;
|
||||
bool IsTargetingArea() const;
|
||||
bool NeedsExplicitUnitTarget() const;
|
||||
bool NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) const;
|
||||
|
||||
bool IsAffected(uint32 familyName, flag96 const& familyFlags) const;
|
||||
bool IsPassive() const;
|
||||
bool IsRaidMarker() const;
|
||||
bool IsAutocastable() const;
|
||||
bool IsStackableWithRanks() const;
|
||||
bool IsPassiveStackableWithRanks() 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 IsMoveAllowedChannel() const;
|
||||
bool NeedsComboPoints() const;
|
||||
bool IsNextMeleeSwingSpell() const;
|
||||
bool IsBreakingStealth() const;
|
||||
bool IsRangedWeaponSpell() const;
|
||||
bool IsAutoRepeatRangedSpell() const;
|
||||
bool HasInitialAggro() const;
|
||||
|
||||
bool IsAffectedBySpellMods() const;
|
||||
bool IsAffectedBySpellMod(SpellModifier const* mod) const;
|
||||
bool IsAffected(uint32 familyName, flag96 const& familyFlags) const;
|
||||
|
||||
bool CanPierceImmuneAura(SpellInfo const* auraSpellInfo) const;
|
||||
bool CanDispelAura(SpellInfo const* auraSpellInfo) const;
|
||||
bool IsAffectedBySpellMods() const;
|
||||
bool IsAffectedBySpellMod(SpellModifier const* mod) const;
|
||||
|
||||
bool IsSingleTarget() const;
|
||||
bool IsAuraExclusiveBySpecificWith(SpellInfo const* spellInfo) const;
|
||||
bool IsAuraExclusiveBySpecificPerCasterWith(SpellInfo const* spellInfo) const;
|
||||
bool CanPierceImmuneAura(SpellInfo const* auraSpellInfo) const;
|
||||
bool CanDispelAura(SpellInfo const* auraSpellInfo) 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 IsSingleTarget() const;
|
||||
bool IsAuraExclusiveBySpecificWith(SpellInfo const* spellInfo) const;
|
||||
bool IsAuraExclusiveBySpecificPerCasterWith(SpellInfo const* spellInfo) const;
|
||||
|
||||
SpellSchoolMask GetSchoolMask() const;
|
||||
uint32 GetAllEffectsMechanicMask() const;
|
||||
uint32 GetEffectMechanicMask(uint8 effIndex) const;
|
||||
uint32 GetSpellMechanicMaskByEffectMask(uint32 effectMask) const;
|
||||
Mechanics GetEffectMechanic(uint8 effIndex) const;
|
||||
bool HasAnyEffectMechanic() const;
|
||||
uint32 GetDispelMask() const;
|
||||
static uint32 GetDispelMask(DispelType type);
|
||||
uint32 GetExplicitTargetMask() 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;
|
||||
|
||||
AuraStateType GetAuraState() const;
|
||||
SpellSpecificType GetSpellSpecific() const;
|
||||
SpellSchoolMask GetSchoolMask() const;
|
||||
uint32 GetAllEffectsMechanicMask() const;
|
||||
uint32 GetEffectMechanicMask(uint8 effIndex) const;
|
||||
uint32 GetSpellMechanicMaskByEffectMask(uint32 effectMask) const;
|
||||
Mechanics GetEffectMechanic(uint8 effIndex) const;
|
||||
bool HasAnyEffectMechanic() const;
|
||||
uint32 GetDispelMask() const;
|
||||
static uint32 GetDispelMask(DispelType type);
|
||||
uint32 GetExplicitTargetMask() const;
|
||||
|
||||
float GetMinRange(bool positive = false) const;
|
||||
float GetMaxRange(bool positive = false, Unit* caster = NULL, Spell* spell = NULL) const;
|
||||
AuraStateType GetAuraState() const;
|
||||
SpellSpecificType GetSpellSpecific() const;
|
||||
|
||||
int32 GetDuration() const;
|
||||
int32 GetMaxDuration() const;
|
||||
float GetMinRange(bool positive = false) const;
|
||||
float GetMaxRange(bool positive = false, Unit* caster = NULL, Spell* spell = NULL) const;
|
||||
|
||||
uint32 GetMaxTicks() const;
|
||||
int32 GetDuration() const;
|
||||
int32 GetMaxDuration() const;
|
||||
|
||||
uint32 CalcCastTime(uint8 level = 0, Spell* spell = NULL) const;
|
||||
uint32 GetRecoveryTime() const;
|
||||
uint32 GetMaxTicks() const;
|
||||
|
||||
int32 CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) 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;
|
||||
int32 CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) const;
|
||||
|
||||
// spell immunities
|
||||
void ApplyAllSpellImmunitiesTo(Unit* target, uint8 effIndex, bool apply) const;
|
||||
bool CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInfo) const;
|
||||
bool CanSpellCastOverrideAuraEffect(SpellInfo const* auraSpellInfo, uint8 auraEffIndex) 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;
|
||||
|
||||
// loading helpers
|
||||
void _InitializeExplicitTargetMask();
|
||||
bool _IsPositiveEffect(uint8 effIndex, bool deep) const;
|
||||
bool _IsPositiveSpell() const;
|
||||
static bool _IsPositiveTarget(uint32 targetA, uint32 targetB);
|
||||
void _LoadSpellSpecific();
|
||||
void _LoadAuraState();
|
||||
void _LoadImmunityInfo();
|
||||
// spell diminishing returns
|
||||
DiminishingGroup GetDiminishingReturnsGroupForSpell(bool triggered) const;
|
||||
DiminishingReturnsType GetDiminishingReturnsGroupType(bool triggered) const;
|
||||
DiminishingLevels GetDiminishingReturnsMaxLevel(bool triggered) const;
|
||||
int32 GetDiminishingReturnsLimitDuration(bool triggered) const;
|
||||
|
||||
// unloading helpers
|
||||
void _UnloadImplicitTargetConditionLists();
|
||||
// spell immunities
|
||||
void ApplyAllSpellImmunitiesTo(Unit* target, uint8 effIndex, bool apply) const;
|
||||
bool CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInfo) const;
|
||||
bool CanSpellCastOverrideAuraEffect(SpellInfo const* auraSpellInfo, uint8 auraEffIndex) const;
|
||||
|
||||
private:
|
||||
SpellSpecificType _spellSpecific;
|
||||
AuraStateType _auraState;
|
||||
private:
|
||||
// loading helpers
|
||||
void _InitializeExplicitTargetMask();
|
||||
bool _IsPositiveEffect(uint8 effIndex, bool deep) const;
|
||||
bool _IsPositiveSpell() const;
|
||||
static bool _IsPositiveTarget(uint32 targetA, uint32 targetB);
|
||||
void _LoadSpellSpecific();
|
||||
void _LoadAuraState();
|
||||
void _LoadSpellDiminishInfo();
|
||||
void _LoadImmunityInfo();
|
||||
|
||||
ImmunityInfo _immunityInfo[MAX_SPELL_EFFECTS];
|
||||
// unloading helpers
|
||||
void _UnloadImplicitTargetConditionLists();
|
||||
|
||||
SpellSpecificType _spellSpecific;
|
||||
AuraStateType _auraState;
|
||||
|
||||
SpellDiminishInfo _diminishInfoNonTriggered;
|
||||
SpellDiminishInfo _diminishInfoTriggered;
|
||||
|
||||
ImmunityInfo _immunityInfo[MAX_SPELL_EFFECTS];
|
||||
};
|
||||
|
||||
#endif // _SPELLINFO_H
|
||||
@@ -51,305 +51,6 @@ bool IsPartOfSkillLine(uint32 skillId, uint32 spellId)
|
||||
return false;
|
||||
}
|
||||
|
||||
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const* spellproto, bool triggered)
|
||||
{
|
||||
if (spellproto->IsPositive())
|
||||
return DIMINISHING_NONE;
|
||||
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
{
|
||||
if (spellproto->Effects[i].ApplyAuraName == SPELL_AURA_MOD_TAUNT)
|
||||
return DIMINISHING_TAUNT;
|
||||
}
|
||||
|
||||
// Explicit Diminishing Groups
|
||||
switch (spellproto->SpellFamilyName)
|
||||
{
|
||||
case SPELLFAMILY_GENERIC:
|
||||
{
|
||||
// Pet charge effects (Infernal Awakening, Demon Charge)
|
||||
if (spellproto->SpellVisual[0] == 2816 && spellproto->SpellIconID == 15)
|
||||
return DIMINISHING_CONTROLLED_STUN;
|
||||
// Frost Tomb
|
||||
else if (spellproto->Id == 48400)
|
||||
return DIMINISHING_NONE;
|
||||
// Gnaw
|
||||
else if (spellproto->Id == 47481)
|
||||
return DIMINISHING_CONTROLLED_STUN;
|
||||
// ToC Icehowl Arctic Breath
|
||||
else if (spellproto->SpellVisual[0] == 14153)
|
||||
return DIMINISHING_NONE;
|
||||
// Black Plague
|
||||
else if (spellproto->Id == 64155)
|
||||
return DIMINISHING_NONE;
|
||||
// Screams of the Dead (King Ymiron)
|
||||
else if (spellproto->Id == 51750)
|
||||
return DIMINISHING_NONE;
|
||||
break;
|
||||
}
|
||||
// Event spells
|
||||
case SPELLFAMILY_UNK1:
|
||||
return DIMINISHING_NONE;
|
||||
case SPELLFAMILY_MAGE:
|
||||
{
|
||||
// Frostbite
|
||||
if (spellproto->SpellFamilyFlags[1] & 0x80000000)
|
||||
return DIMINISHING_ROOT;
|
||||
// Shattered Barrier
|
||||
else if (spellproto->SpellVisual[0] == 12297)
|
||||
return DIMINISHING_ROOT;
|
||||
// Deep Freeze
|
||||
else if (spellproto->SpellIconID == 2939 && spellproto->SpellVisual[0] == 9963)
|
||||
return DIMINISHING_CONTROLLED_STUN;
|
||||
// Frost Nova / Freeze (Water Elemental)
|
||||
else if (spellproto->SpellIconID == 193)
|
||||
return DIMINISHING_CONTROLLED_ROOT;
|
||||
// Dragon's Breath
|
||||
else if (spellproto->SpellFamilyFlags[0] & 0x800000)
|
||||
return DIMINISHING_DRAGONS_BREATH;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_WARRIOR:
|
||||
{
|
||||
// Hamstring - limit duration to 10s in PvP
|
||||
if (spellproto->SpellFamilyFlags[0] & 0x2)
|
||||
return DIMINISHING_LIMITONLY;
|
||||
// Charge Stun (own diminishing)
|
||||
else if (spellproto->SpellFamilyFlags[0] & 0x01000000)
|
||||
return DIMINISHING_CHARGE;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_WARLOCK:
|
||||
{
|
||||
// Curses/etc
|
||||
if ((spellproto->SpellFamilyFlags[0] & 0x80000000) || (spellproto->SpellFamilyFlags[1] & 0x200))
|
||||
return DIMINISHING_LIMITONLY;
|
||||
// Seduction
|
||||
else if (spellproto->SpellFamilyFlags[1] & 0x10000000)
|
||||
return DIMINISHING_FEAR;
|
||||
// Sin and Punishment (Priest spell, don't ask)
|
||||
else if (spellproto->SpellIconID == 1869)
|
||||
return DIMINISHING_NONE;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_DRUID:
|
||||
{
|
||||
// Pounce
|
||||
if (spellproto->SpellFamilyFlags[0] & 0x20000)
|
||||
return DIMINISHING_OPENING_STUN;
|
||||
// Cyclone
|
||||
else if (spellproto->SpellFamilyFlags[1] & 0x20)
|
||||
return DIMINISHING_CYCLONE;
|
||||
// Entangling Roots
|
||||
// Nature's Grasp
|
||||
else if (spellproto->SpellFamilyFlags[0] & 0x00000200)
|
||||
return DIMINISHING_CONTROLLED_ROOT;
|
||||
// Faerie Fire
|
||||
else if (spellproto->SpellFamilyFlags[0] & 0x400)
|
||||
return DIMINISHING_LIMITONLY;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_ROGUE:
|
||||
{
|
||||
// Gouge
|
||||
if (spellproto->SpellFamilyFlags[0] & 0x8)
|
||||
return DIMINISHING_DISORIENT;
|
||||
// Blind
|
||||
else if (spellproto->SpellFamilyFlags[0] & 0x1000000)
|
||||
return DIMINISHING_FEAR;
|
||||
// Cheap Shot
|
||||
else if (spellproto->SpellFamilyFlags[0] & 0x400)
|
||||
return DIMINISHING_OPENING_STUN;
|
||||
// Crippling poison - Limit to 10 seconds in PvP (No SpellFamilyFlags)
|
||||
else if (spellproto->SpellIconID == 163)
|
||||
return DIMINISHING_LIMITONLY;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_HUNTER:
|
||||
{
|
||||
// Hunter's Mark
|
||||
if ((spellproto->SpellFamilyFlags[0] & 0x400) && spellproto->SpellIconID == 538)
|
||||
return DIMINISHING_LIMITONLY;
|
||||
// Scatter Shot (own diminishing)
|
||||
else if ((spellproto->SpellFamilyFlags[0] & 0x40000) && spellproto->SpellIconID == 132)
|
||||
return DIMINISHING_SCATTER_SHOT;
|
||||
// Entrapment (own diminishing)
|
||||
else if (spellproto->SpellVisual[0] == 7484 && spellproto->SpellIconID == 20)
|
||||
return DIMINISHING_ENTRAPMENT;
|
||||
// Wyvern Sting mechanic is MECHANIC_SLEEP but the diminishing is DIMINISHING_DISORIENT
|
||||
else if ((spellproto->SpellFamilyFlags[1] & 0x1000) && spellproto->SpellIconID == 1721)
|
||||
return DIMINISHING_DISORIENT;
|
||||
// Freezing Arrow
|
||||
else if (spellproto->SpellFamilyFlags[0] & 0x8)
|
||||
return DIMINISHING_DISORIENT;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_PALADIN:
|
||||
{
|
||||
// Judgement of Justice - limit duration to 10s in PvP
|
||||
if (spellproto->SpellFamilyFlags[0] & 0x100000)
|
||||
return DIMINISHING_LIMITONLY;
|
||||
// Turn Evil
|
||||
else if ((spellproto->SpellFamilyFlags[1] & 0x804000) && spellproto->SpellIconID == 309)
|
||||
return DIMINISHING_FEAR;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_SHAMAN:
|
||||
{
|
||||
// Storm, Earth and Fire - Earthgrab
|
||||
if (spellproto->SpellFamilyFlags[2] & 0x4000)
|
||||
return DIMINISHING_NONE;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_DEATHKNIGHT:
|
||||
{
|
||||
// Hungering Cold (no flags)
|
||||
if (spellproto->SpellIconID == 2797)
|
||||
return DIMINISHING_DISORIENT;
|
||||
// Mark of Blood
|
||||
else if ((spellproto->SpellFamilyFlags[0] & 0x10000000) && spellproto->SpellIconID == 2285)
|
||||
return DIMINISHING_LIMITONLY;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Lastly - Set diminishing depending on mechanic
|
||||
uint32 mechanic = spellproto->GetAllEffectsMechanicMask();
|
||||
if (mechanic & (1 << MECHANIC_CHARM))
|
||||
return DIMINISHING_MIND_CONTROL;
|
||||
if (mechanic & (1 << MECHANIC_SILENCE))
|
||||
return DIMINISHING_SILENCE;
|
||||
if (mechanic & (1 << MECHANIC_SLEEP))
|
||||
return DIMINISHING_SLEEP;
|
||||
if (mechanic & ((1 << MECHANIC_SAPPED) | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_SHACKLE)))
|
||||
return DIMINISHING_DISORIENT;
|
||||
// Mechanic Knockout, except Blast Wave
|
||||
if (mechanic & (1 << MECHANIC_KNOCKOUT) && spellproto->SpellIconID != 292)
|
||||
return DIMINISHING_DISORIENT;
|
||||
if (mechanic & (1 << MECHANIC_DISARM))
|
||||
return DIMINISHING_DISARM;
|
||||
if (mechanic & (1 << MECHANIC_FEAR))
|
||||
return DIMINISHING_FEAR;
|
||||
if (mechanic & (1 << MECHANIC_STUN))
|
||||
return triggered ? DIMINISHING_STUN : DIMINISHING_CONTROLLED_STUN;
|
||||
if (mechanic & (1 << MECHANIC_BANISH))
|
||||
return DIMINISHING_BANISH;
|
||||
if (mechanic & (1 << MECHANIC_ROOT))
|
||||
return triggered ? DIMINISHING_ROOT : DIMINISHING_CONTROLLED_ROOT;
|
||||
if (mechanic & (1 << MECHANIC_HORROR))
|
||||
return DIMINISHING_HORROR;
|
||||
|
||||
return DIMINISHING_NONE;
|
||||
}
|
||||
|
||||
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
|
||||
{
|
||||
switch (group)
|
||||
{
|
||||
case DIMINISHING_TAUNT:
|
||||
case DIMINISHING_CONTROLLED_STUN:
|
||||
case DIMINISHING_STUN:
|
||||
case DIMINISHING_OPENING_STUN:
|
||||
case DIMINISHING_CYCLONE:
|
||||
case DIMINISHING_CHARGE:
|
||||
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;
|
||||
default:
|
||||
return DIMINISHING_LEVEL_IMMUNE;
|
||||
}
|
||||
}
|
||||
|
||||
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const* spellproto)
|
||||
{
|
||||
if (!IsDiminishingReturnsGroupDurationLimited(group))
|
||||
return 0;
|
||||
|
||||
// Explicit diminishing duration
|
||||
switch (spellproto->SpellFamilyName)
|
||||
{
|
||||
case SPELLFAMILY_DRUID:
|
||||
{
|
||||
// Faerie Fire - limit to 40 seconds in PvP (3.1)
|
||||
if (spellproto->SpellFamilyFlags[0] & 0x400)
|
||||
return 40 * IN_MILLISECONDS;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_HUNTER:
|
||||
{
|
||||
// Wyvern Sting
|
||||
if (spellproto->SpellFamilyFlags[1] & 0x1000)
|
||||
return 6 * IN_MILLISECONDS;
|
||||
// Hunter's Mark
|
||||
if (spellproto->SpellFamilyFlags[0] & 0x400)
|
||||
return 30 * IN_MILLISECONDS;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_PALADIN:
|
||||
{
|
||||
// Repentance - limit to 6 seconds in PvP
|
||||
if (spellproto->SpellFamilyFlags[0] & 0x4)
|
||||
return 6 * IN_MILLISECONDS;
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_WARLOCK:
|
||||
{
|
||||
// Banish - limit to 6 seconds in PvP
|
||||
if (spellproto->SpellFamilyFlags[1] & 0x8000000)
|
||||
return 6 * IN_MILLISECONDS;
|
||||
// Curse of Tongues - limit to 12 seconds in PvP
|
||||
else if (spellproto->SpellFamilyFlags[2] & 0x800)
|
||||
return 12 * IN_MILLISECONDS;
|
||||
// Curse of Elements - limit to 120 seconds in PvP
|
||||
else if (spellproto->SpellFamilyFlags[1] & 0x200)
|
||||
return 120 * IN_MILLISECONDS;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 8 * IN_MILLISECONDS;
|
||||
}
|
||||
|
||||
bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group)
|
||||
{
|
||||
switch (group)
|
||||
{
|
||||
case DIMINISHING_BANISH:
|
||||
case DIMINISHING_CONTROLLED_STUN:
|
||||
case DIMINISHING_CONTROLLED_ROOT:
|
||||
case DIMINISHING_CYCLONE:
|
||||
case DIMINISHING_DISORIENT:
|
||||
case DIMINISHING_ENTRAPMENT:
|
||||
case DIMINISHING_FEAR:
|
||||
case DIMINISHING_HORROR:
|
||||
case DIMINISHING_MIND_CONTROL:
|
||||
case DIMINISHING_OPENING_STUN:
|
||||
case DIMINISHING_ROOT:
|
||||
case DIMINISHING_STUN:
|
||||
case DIMINISHING_SLEEP:
|
||||
case DIMINISHING_LIMITONLY:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SpellMgr::SpellMgr() { }
|
||||
|
||||
SpellMgr::~SpellMgr()
|
||||
@@ -3842,6 +3543,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::LoadSpellInfoImmunities()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
@@ -547,13 +547,6 @@ inline bool IsProfessionOrRidingSkill(uint32 skill)
|
||||
|
||||
bool IsPartOfSkillLine(uint32 skillId, uint32 spellId);
|
||||
|
||||
// spell diminishing returns
|
||||
TC_GAME_API DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const* spellproto, bool triggered);
|
||||
TC_GAME_API DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group);
|
||||
TC_GAME_API DiminishingLevels GetDiminishingReturnsMaxLevel(DiminishingGroup group);
|
||||
TC_GAME_API int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const* spellproto);
|
||||
TC_GAME_API bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group);
|
||||
|
||||
class TC_GAME_API SpellMgr
|
||||
{
|
||||
// Constructors
|
||||
@@ -686,6 +679,7 @@ class TC_GAME_API SpellMgr
|
||||
void LoadSpellInfoCustomAttributes();
|
||||
void LoadSpellInfoCorrections();
|
||||
void LoadSpellInfoSpellSpecificAndAuraState();
|
||||
void LoadSpellInfoDiminishing();
|
||||
void LoadSpellInfoImmunities();
|
||||
|
||||
private:
|
||||
|
||||
@@ -1509,6 +1509,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 SpellInfo immunity infos...");
|
||||
sSpellMgr->LoadSpellInfoImmunities();
|
||||
|
||||
|
||||
Reference in new issue
Block a user