Core/Globals: cache SpellSpecific and AuraState information instead of computing them each time they're needed

(cherry picked from commit ce45e1bf95a03be6b1f42c785e4c01dd55999d33)

# Conflicts:
#	src/server/game/Spells/SpellInfo.cpp
#	src/server/game/Spells/SpellInfo.h
#	src/server/game/Spells/SpellMgr.cpp
#	src/server/game/World/World.cpp
This commit is contained in:
ariel-
2017-08-26 23:23:32 +02:00
committed by joschiwald
parent ee0e9c8578
commit c7cd9102d3
6 changed files with 267 additions and 222 deletions
+3 -3
View File
@@ -3234,7 +3234,7 @@ AuraApplication * Unit::_CreateAuraApplication(Aura* aura, uint32 effMask)
AddInterruptMask(aurSpellInfo->AuraInterruptFlags);
}
if (AuraStateType aState = aura->GetSpellInfo()->GetAuraState(GetMap()->GetDifficultyID()))
if (AuraStateType aState = aura->GetSpellInfo()->GetAuraState())
m_auraStateAuras.insert(AuraStateAurasMap::value_type(aState, aurApp));
aura->_ApplyForTarget(this, caster, aurApp);
@@ -3265,7 +3265,7 @@ void Unit::_ApplyAura(AuraApplication * aurApp, uint32 effMask)
return;
// Update target aura state flag
if (AuraStateType aState = aura->GetSpellInfo()->GetAuraState(GetMap()->GetDifficultyID()))
if (AuraStateType aState = aura->GetSpellInfo()->GetAuraState())
ModifyAuraState(aState, true);
if (aurApp->GetRemoveMode())
@@ -3320,7 +3320,7 @@ void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMo
}
bool auraStateFound = false;
AuraStateType auraState = aura->GetSpellInfo()->GetAuraState(GetMap()->GetDifficultyID());
AuraStateType auraState = aura->GetSpellInfo()->GetAuraState();
if (auraState)
{
bool canBreak = false;
+237 -218
View File
@@ -1148,6 +1148,9 @@ SpellInfo::SpellInfo(SpellInfoLoadHelper const& data, SpellEffectEntryMap const&
ChainEntry = NULL;
ExplicitTargetMask = 0;
_spellSpecific = SPELL_SPECIFIC_NORMAL;
_auraState = AURA_STATE_NONE;
}
SpellInfo::~SpellInfo()
@@ -2203,249 +2206,265 @@ uint32 SpellInfo::GetExplicitTargetMask() const
return ExplicitTargetMask;
}
AuraStateType SpellInfo::GetAuraState(uint32 difficulty) const
AuraStateType SpellInfo::GetAuraState() const
{
// Seals
if (GetSpellSpecific() == SPELL_SPECIFIC_SEAL)
return AURA_STATE_JUDGEMENT;
return _auraState;
}
// Conflagrate aura state on Immolate and Shadowflame
if (SpellFamilyName == SPELLFAMILY_WARLOCK &&
// Immolate
((SpellFamilyFlags[0] & 4) ||
// Shadowflame
(SpellFamilyFlags[2] & 2)))
return AURA_STATE_CONFLAGRATE;
// Faerie Fire (druid versions)
if (SpellFamilyName == SPELLFAMILY_DRUID && SpellFamilyFlags[0] & 0x400)
return AURA_STATE_FAERIE_FIRE;
// Sting (hunter's pet ability)
if (GetCategory() == 1133)
return AURA_STATE_FAERIE_FIRE;
// Victorious
if (SpellFamilyName == SPELLFAMILY_WARRIOR && SpellFamilyFlags[1] & 0x00040000)
return AURA_STATE_WARRIOR_VICTORY_RUSH;
// Swiftmend state on Regrowth & Rejuvenation
if (SpellFamilyName == SPELLFAMILY_DRUID && SpellFamilyFlags[0] & 0x50)
return AURA_STATE_SWIFTMEND;
// Deadly poison aura state
if (SpellFamilyName == SPELLFAMILY_ROGUE && SpellFamilyFlags[0] & 0x10000)
return AURA_STATE_DEADLY_POISON;
// Enrage aura state
if (Dispel == DISPEL_ENRAGE)
return AURA_STATE_ENRAGE;
// Bleeding aura state
if (GetAllEffectsMechanicMask() & 1<<MECHANIC_BLEED)
return AURA_STATE_BLEEDING;
if (GetSchoolMask() & SPELL_SCHOOL_MASK_FROST)
for (SpellEffectInfo const* effect : GetEffectsForDifficulty(difficulty))
if (effect && effect->IsAura() && (effect->ApplyAuraName == SPELL_AURA_MOD_STUN
|| effect->ApplyAuraName == SPELL_AURA_MOD_ROOT))
return AURA_STATE_FROZEN;
switch (Id)
void SpellInfo::_LoadAuraState()
{
_auraState = [this]()->AuraStateType
{
case 71465: // Divine Surge
case 50241: // Evasive Charges
return AURA_STATE_UNKNOWN22;
default:
break;
}
// Seals
if (GetSpellSpecific() == SPELL_SPECIFIC_SEAL)
return AURA_STATE_JUDGEMENT;
return AURA_STATE_NONE;
// Conflagrate aura state on Immolate and Shadowflame
if (SpellFamilyName == SPELLFAMILY_WARLOCK &&
// Immolate
((SpellFamilyFlags[0] & 4) ||
// Shadowflame
(SpellFamilyFlags[2] & 2)))
return AURA_STATE_CONFLAGRATE;
// Faerie Fire (druid versions)
if (SpellFamilyName == SPELLFAMILY_DRUID && SpellFamilyFlags[0] & 0x400)
return AURA_STATE_FAERIE_FIRE;
// Sting (hunter's pet ability)
if (GetCategory() == 1133)
return AURA_STATE_FAERIE_FIRE;
// Victorious
if (SpellFamilyName == SPELLFAMILY_WARRIOR && SpellFamilyFlags[1] & 0x00040000)
return AURA_STATE_WARRIOR_VICTORY_RUSH;
// Swiftmend state on Regrowth & Rejuvenation
if (SpellFamilyName == SPELLFAMILY_DRUID && SpellFamilyFlags[0] & 0x50)
return AURA_STATE_SWIFTMEND;
// Deadly poison aura state
if (SpellFamilyName == SPELLFAMILY_ROGUE && SpellFamilyFlags[0] & 0x10000)
return AURA_STATE_DEADLY_POISON;
// Enrage aura state
if (Dispel == DISPEL_ENRAGE)
return AURA_STATE_ENRAGE;
// Bleeding aura state
if (GetAllEffectsMechanicMask() & 1<<MECHANIC_BLEED)
return AURA_STATE_BLEEDING;
if (GetSchoolMask() & SPELL_SCHOOL_MASK_FROST)
for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
for (SpellEffectInfo const* effect : itr->second)
if (effect && (effect->IsAura(SPELL_AURA_MOD_STUN) || effect->IsAura(SPELL_AURA_MOD_ROOT)))
return AURA_STATE_FROZEN;
switch (Id)
{
case 71465: // Divine Surge
case 50241: // Evasive Charges
return AURA_STATE_UNKNOWN22;
default:
break;
}
return AURA_STATE_NONE;
}();
}
SpellSpecificType SpellInfo::GetSpellSpecific() const
{
switch (SpellFamilyName)
return _spellSpecific;
};
void SpellInfo::_LoadSpellSpecific()
{
_spellSpecific = [this]()->SpellSpecificType
{
case SPELLFAMILY_GENERIC:
switch (SpellFamilyName)
{
// Food / Drinks (mostly)
if (AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED)
case SPELLFAMILY_GENERIC:
{
bool food = false;
bool drink = false;
for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
// Food / Drinks (mostly)
if (AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED)
{
for (SpellEffectInfo const* effect : itr->second)
bool food = false;
bool drink = false;
for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
{
if (!effect || !effect->IsAura())
continue;
switch (effect->ApplyAuraName)
for (SpellEffectInfo const* effect : itr->second)
{
// Food
case SPELL_AURA_MOD_REGEN:
case SPELL_AURA_OBS_MOD_HEALTH:
food = true;
break;
// Drink
case SPELL_AURA_MOD_POWER_REGEN:
case SPELL_AURA_OBS_MOD_POWER:
drink = true;
break;
default:
break;
if (!effect || !effect->IsAura())
continue;
switch (effect->ApplyAuraName)
{
// Food
case SPELL_AURA_MOD_REGEN:
case SPELL_AURA_OBS_MOD_HEALTH:
food = true;
break;
// Drink
case SPELL_AURA_MOD_POWER_REGEN:
case SPELL_AURA_OBS_MOD_POWER:
drink = true;
break;
default:
break;
}
}
}
}
if (food && drink)
return SPELL_SPECIFIC_FOOD_AND_DRINK;
else if (food)
return SPELL_SPECIFIC_FOOD;
else if (drink)
return SPELL_SPECIFIC_DRINK;
}
// scrolls effects
else
{
SpellInfo const* firstRankSpellInfo = GetFirstRankSpell();
switch (firstRankSpellInfo->Id)
if (food && drink)
return SPELL_SPECIFIC_FOOD_AND_DRINK;
else if (food)
return SPELL_SPECIFIC_FOOD;
else if (drink)
return SPELL_SPECIFIC_DRINK;
}
// scrolls effects
else
{
case 8118: // Strength
case 8099: // Stamina
case 8112: // Spirit
case 8096: // Intellect
case 8115: // Agility
case 8091: // Armor
return SPELL_SPECIFIC_SCROLL;
case 12880: // Enrage (Enrage)
case 57518: // Enrage (Wrecking Crew)
return SPELL_SPECIFIC_WARRIOR_ENRAGE;
SpellInfo const* firstRankSpellInfo = GetFirstRankSpell();
switch (firstRankSpellInfo->Id)
{
case 8118: // Strength
case 8099: // Stamina
case 8112: // Spirit
case 8096: // Intellect
case 8115: // Agility
case 8091: // Armor
return SPELL_SPECIFIC_SCROLL;
case 12880: // Enrage (Enrage)
case 57518: // Enrage (Wrecking Crew)
return SPELL_SPECIFIC_WARRIOR_ENRAGE;
}
}
break;
}
break;
}
case SPELLFAMILY_MAGE:
{
// family flags 18(Molten), 25(Frost/Ice), 28(Mage)
if (SpellFamilyFlags[0] & 0x12040000)
return SPELL_SPECIFIC_MAGE_ARMOR;
// Arcane brillance and Arcane intelect (normal check fails because of flags difference)
if (SpellFamilyFlags[0] & 0x400)
return SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE;
SpellEffectInfo const* effect = GetEffect(DIFFICULTY_NONE, EFFECT_0);
if (effect && (SpellFamilyFlags[0] & 0x1000000) && effect->ApplyAuraName == SPELL_AURA_MOD_CONFUSE)
return SPELL_SPECIFIC_MAGE_POLYMORPH;
break;
}
case SPELLFAMILY_WARRIOR:
{
if (Id == 12292) // Death Wish
return SPELL_SPECIFIC_WARRIOR_ENRAGE;
break;
}
case SPELLFAMILY_WARLOCK:
{
// Warlock (Bane of Doom | Bane of Agony | Bane of Havoc)
if (Id == 603 || Id == 980 || Id == 80240)
return SPELL_SPECIFIC_BANE;
// only warlock curses have this
if (Dispel == DISPEL_CURSE)
return SPELL_SPECIFIC_CURSE;
// Warlock (Demon Armor | Demon Skin | Fel Armor)
if (SpellFamilyFlags[1] & 0x20000020 || SpellFamilyFlags[2] & 0x00000010)
return SPELL_SPECIFIC_WARLOCK_ARMOR;
//seed of corruption and corruption
if (SpellFamilyFlags[1] & 0x10 || SpellFamilyFlags[0] & 0x2)
return SPELL_SPECIFIC_WARLOCK_CORRUPTION;
break;
}
case SPELLFAMILY_PRIEST:
{
// Divine Spirit and Prayer of Spirit
if (SpellFamilyFlags[0] & 0x20)
return SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT;
break;
}
case SPELLFAMILY_HUNTER:
{
// only hunter stings have this
if (Dispel == DISPEL_POISON)
return SPELL_SPECIFIC_STING;
// only hunter aspects have this (but not all aspects in hunter family)
if (SpellFamilyFlags & flag128(0x00200000, 0x00000000, 0x00001010, 0x00000000))
return SPELL_SPECIFIC_ASPECT;
break;
}
case SPELLFAMILY_PALADIN:
{
// Collection of all the seal family flags. No other paladin spell has any of those.
if (SpellFamilyFlags[1] & 0xA2000800)
return SPELL_SPECIFIC_SEAL;
if (SpellFamilyFlags[0] & 0x00002190)
return SPELL_SPECIFIC_HAND;
// Judgement
if (Id == 20271)
return SPELL_SPECIFIC_JUDGEMENT;
// only paladin auras have this (for palaldin class family)
if (SpellFamilyFlags[2] & 0x00000020)
return SPELL_SPECIFIC_AURA;
break;
}
case SPELLFAMILY_SHAMAN:
{
// family flags 10 (Lightning), 42 (Earth), 37 (Water), proc shield from T2 8 pieces bonus
if (SpellFamilyFlags[1] & 0x420
|| SpellFamilyFlags[0] & 0x00000400
|| Id == 23552)
return SPELL_SPECIFIC_ELEMENTAL_SHIELD;
break;
}
case SPELLFAMILY_DEATHKNIGHT:
if (Id == 48266 || Id == 48263 || Id == 48265)
return SPELL_SPECIFIC_PRESENCE;
break;
}
for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
{
for (SpellEffectInfo const* effect : itr->second)
{
if (effect && effect->Effect == SPELL_EFFECT_APPLY_AURA)
case SPELLFAMILY_MAGE:
{
switch (effect->ApplyAuraName)
// family flags 18(Molten), 25(Frost/Ice), 28(Mage)
if (SpellFamilyFlags[0] & 0x12040000)
return SPELL_SPECIFIC_MAGE_ARMOR;
// Arcane brillance and Arcane intelect (normal check fails because of flags difference)
if (SpellFamilyFlags[0] & 0x400)
return SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE;
SpellEffectInfo const* effect = GetEffect(DIFFICULTY_NONE, EFFECT_0);
if (effect && (SpellFamilyFlags[0] & 0x1000000) && effect->ApplyAuraName == SPELL_AURA_MOD_CONFUSE)
return SPELL_SPECIFIC_MAGE_POLYMORPH;
break;
}
case SPELLFAMILY_WARRIOR:
{
if (Id == 12292) // Death Wish
return SPELL_SPECIFIC_WARRIOR_ENRAGE;
break;
}
case SPELLFAMILY_WARLOCK:
{
// Warlock (Bane of Doom | Bane of Agony | Bane of Havoc)
if (Id == 603 || Id == 980 || Id == 80240)
return SPELL_SPECIFIC_BANE;
// only warlock curses have this
if (Dispel == DISPEL_CURSE)
return SPELL_SPECIFIC_CURSE;
// Warlock (Demon Armor | Demon Skin | Fel Armor)
if (SpellFamilyFlags[1] & 0x20000020 || SpellFamilyFlags[2] & 0x00000010)
return SPELL_SPECIFIC_WARLOCK_ARMOR;
//seed of corruption and corruption
if (SpellFamilyFlags[1] & 0x10 || SpellFamilyFlags[0] & 0x2)
return SPELL_SPECIFIC_WARLOCK_CORRUPTION;
break;
}
case SPELLFAMILY_PRIEST:
{
// Divine Spirit and Prayer of Spirit
if (SpellFamilyFlags[0] & 0x20)
return SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT;
break;
}
case SPELLFAMILY_HUNTER:
{
// only hunter stings have this
if (Dispel == DISPEL_POISON)
return SPELL_SPECIFIC_STING;
// only hunter aspects have this (but not all aspects in hunter family)
if (SpellFamilyFlags & flag128(0x00200000, 0x00000000, 0x00001010, 0x00000000))
return SPELL_SPECIFIC_ASPECT;
break;
}
case SPELLFAMILY_PALADIN:
{
// Collection of all the seal family flags. No other paladin spell has any of those.
if (SpellFamilyFlags[1] & 0xA2000800)
return SPELL_SPECIFIC_SEAL;
if (SpellFamilyFlags[0] & 0x00002190)
return SPELL_SPECIFIC_HAND;
// Judgement
if (Id == 20271)
return SPELL_SPECIFIC_JUDGEMENT;
// only paladin auras have this (for palaldin class family)
if (SpellFamilyFlags[2] & 0x00000020)
return SPELL_SPECIFIC_AURA;
break;
}
case SPELLFAMILY_SHAMAN:
{
// family flags 10 (Lightning), 42 (Earth), 37 (Water), proc shield from T2 8 pieces bonus
if (SpellFamilyFlags[1] & 0x420
|| SpellFamilyFlags[0] & 0x00000400
|| Id == 23552)
return SPELL_SPECIFIC_ELEMENTAL_SHIELD;
break;
}
case SPELLFAMILY_DEATHKNIGHT:
if (Id == 48266 || Id == 48263 || Id == 48265)
return SPELL_SPECIFIC_PRESENCE;
break;
}
for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
{
for (SpellEffectInfo const* effect : itr->second)
{
if (effect && effect->Effect == SPELL_EFFECT_APPLY_AURA)
{
case SPELL_AURA_MOD_CHARM:
case SPELL_AURA_MOD_POSSESS_PET:
case SPELL_AURA_MOD_POSSESS:
case SPELL_AURA_AOE_CHARM:
return SPELL_SPECIFIC_CHARM;
case SPELL_AURA_TRACK_CREATURES:
/// @workaround For non-stacking tracking spells (We need generic solution)
if (Id == 30645) // Gas Cloud Tracking
return SPELL_SPECIFIC_NORMAL;
case SPELL_AURA_TRACK_RESOURCES:
case SPELL_AURA_TRACK_STEALTHED:
return SPELL_SPECIFIC_TRACKER;
switch (effect->ApplyAuraName)
{
case SPELL_AURA_MOD_CHARM:
case SPELL_AURA_MOD_POSSESS_PET:
case SPELL_AURA_MOD_POSSESS:
case SPELL_AURA_AOE_CHARM:
return SPELL_SPECIFIC_CHARM;
case SPELL_AURA_TRACK_CREATURES:
/// @workaround For non-stacking tracking spells (We need generic solution)
if (Id == 30645) // Gas Cloud Tracking
return SPELL_SPECIFIC_NORMAL;
case SPELL_AURA_TRACK_RESOURCES:
case SPELL_AURA_TRACK_STEALTHED:
return SPELL_SPECIFIC_TRACKER;
}
}
}
}
}
return SPELL_SPECIFIC_NORMAL;
return SPELL_SPECIFIC_NORMAL;
}();
}
float SpellInfo::GetMinRange(bool positive) const
+6 -1
View File
@@ -506,7 +506,7 @@ public:
static uint32 GetDispelMask(DispelType type);
uint32 GetExplicitTargetMask() const;
AuraStateType GetAuraState(uint32 difficulty) const;
AuraStateType GetAuraState() const;
SpellSpecificType GetSpellSpecific() const;
float GetMinRange(bool positive = false) const;
@@ -544,6 +544,8 @@ public:
bool _IsPositiveEffect(uint32 effIndex, bool deep) const;
bool _IsPositiveSpell() const;
static bool _IsPositiveTarget(uint32 targetA, uint32 targetB);
void _LoadSpellSpecific();
void _LoadAuraState();
// unloading helpers
void _UnloadImplicitTargetConditionLists();
@@ -553,9 +555,12 @@ public:
SpellEffectInfo const* GetEffect(uint32 difficulty, uint32 index) const;
SpellEffectInfo const* GetEffect(uint32 index) const { return GetEffect(DIFFICULTY_NONE, index); }
private:
SpellEffectInfoMap _effects;
SpellVisualMap _visuals;
bool _hasPowerDifficultyData;
SpellSpecificType _spellSpecific;
AuraStateType _auraState;
};
#endif // _SPELLINFO_H
+17
View File
@@ -3746,6 +3746,23 @@ void SpellMgr::LoadSpellInfoCorrections()
TC_LOG_INFO("server.loading", ">> Loaded SpellInfo corrections in %u ms", GetMSTimeDiffToNow(oldMSTime));
}
void SpellMgr::LoadSpellInfoSpellSpecificAndAuraState()
{
uint32 oldMSTime = getMSTime();
for (SpellInfo* spellInfo : mSpellInfoMap)
{
if (!spellInfo)
continue;
// AuraState depends on SpellSpecific
spellInfo->_LoadSpellSpecific();
spellInfo->_LoadAuraState();
}
TC_LOG_INFO("server.loading", ">> Loaded SpellInfo SpellSpecific and AuraState in %u ms", GetMSTimeDiffToNow(oldMSTime));
}
void SpellMgr::LoadPetFamilySpellsStore()
{
std::unordered_map<uint32, SpellLevelsEntry const*> levelsBySpell;
+1
View File
@@ -714,6 +714,7 @@ class TC_GAME_API SpellMgr
void UnloadSpellInfoImplicitTargetConditionLists();
void LoadSpellInfoCustomAttributes();
void LoadSpellInfoCorrections();
void LoadSpellInfoSpellSpecificAndAuraState();
private:
SpellDifficultySearcherMap mSpellDifficultySearcherMap;
+3
View File
@@ -1603,6 +1603,9 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading SpellInfo custom attributes...");
sSpellMgr->LoadSpellInfoCustomAttributes();
TC_LOG_INFO("server.loading", "Loading SpellInfo SpellSpecific and AuraState...");
sSpellMgr->LoadSpellInfoSpellSpecificAndAuraState();
TC_LOG_INFO("server.loading", "Loading PetFamilySpellsStore Data...");
sSpellMgr->LoadPetFamilySpellsStore();