Core/Globals: compute aura diminishing return info at startup and cache it

This commit is contained in:
roc13x committed 2017-05-04 00:57:24 +01:00
1 parent 7ccd58615a
commit d30237fb1e
10 files changed
+665 -619

No files matched your search

+49 -51
View File
@@ -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)
+14 -10
View File
@@ -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
+12 -15
View File
@@ -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)
-4
View File
@@ -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;
+316
View File
@@ -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
View File
@@ -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
+15 -299
View File
@@ -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();
+1 -7
View File
@@ -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:
+3
View File
@@ -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();