aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Spells/SpellInfo.cpp
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2016-10-17 01:52:40 -0300
committerariel- <ariel-@users.noreply.github.com>2016-10-17 01:52:40 -0300
commit9b0fa51022fba3d5ece96dd0ac8399be01ea5b0f (patch)
treeaec7c19fea709094e28d287154dff6ae6168b6ef /src/server/game/Spells/SpellInfo.cpp
parentf4a10571f74450daf26a5b0c5bd0f3114c231120 (diff)
Core/Globals: compute aura diminishing return info at startup and cache it
Core/Entities: Save diminish return on an array instead of a linked list
Diffstat (limited to 'src/server/game/Spells/SpellInfo.cpp')
-rw-r--r--src/server/game/Spells/SpellInfo.cpp333
1 files changed, 333 insertions, 0 deletions
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index ff5cd925c8c..8589a8bc98e 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -2108,6 +2108,339 @@ 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;
+ 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 120 * 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 10 * IN_MILLISECONDS;
+ };
+
+ SpellDiminishInfo triggeredInfo, normalInfo;
+ triggeredInfo.DiminishGroup = diminishingGroupCompute(true);
+ triggeredInfo.DiminishReturnType = diminishingTypeCompute(triggeredInfo.DiminishGroup);
+ triggeredInfo.DiminishMaxLevel = diminishingMaxLevelCompute(triggeredInfo.DiminishGroup);
+ triggeredInfo.DiminishDurationLimit = diminishingLimitDurationCompute(triggeredInfo.DiminishGroup);
+
+ normalInfo.DiminishGroup = diminishingGroupCompute(false);
+ normalInfo.DiminishReturnType = diminishingTypeCompute(normalInfo.DiminishGroup);
+ normalInfo.DiminishMaxLevel = diminishingMaxLevelCompute(normalInfo.DiminishGroup);
+ normalInfo.DiminishDurationLimit = diminishingLimitDurationCompute(normalInfo.DiminishGroup);
+
+ _diminishInfoTriggered = triggeredInfo;
+ _diminishInfoNonTriggered = normalInfo;
+}
+
+DiminishingGroup SpellInfo::GetDiminishingReturnsGroupForSpell(bool triggered) const
+{
+ return triggered ? _diminishInfoTriggered.DiminishGroup : _diminishInfoNonTriggered.DiminishGroup;
+}
+
+DiminishingReturnsType SpellInfo::GetDiminishingReturnsGroupType(bool triggered) const
+{
+ return triggered ? _diminishInfoTriggered.DiminishReturnType : _diminishInfoNonTriggered.DiminishReturnType;
+}
+
+DiminishingLevels SpellInfo::GetDiminishingReturnsMaxLevel(bool triggered) const
+{
+ return triggered ? _diminishInfoTriggered.DiminishMaxLevel : _diminishInfoNonTriggered.DiminishMaxLevel;
+}
+
+int32 SpellInfo::GetDiminishingReturnsLimitDuration(bool triggered) const
+{
+ return triggered ? _diminishInfoTriggered.DiminishDurationLimit : _diminishInfoNonTriggered.DiminishDurationLimit;
+}
+
float SpellInfo::GetMinRange(bool positive) const
{
if (!RangeEntry)