From c23cfa4217c79d092a2bc0085be81ec74edd6df6 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 15 Mar 2025 08:50:50 +0100 Subject: [PATCH] Core/Spells: Move entering combat for caster and calculating crit chance to separate function called only once for each target instead of doing it once for every effect on every target --- src/server/game/Spells/Spell.cpp | 39 +++++++++++++++++++++++--------- src/server/game/Spells/Spell.h | 1 + 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index df1cfa4a2a..861d002abe 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -8031,6 +8031,9 @@ void Spell::HandleLaunchPhase() PrepareTargetProcessing(); + for (TargetInfo& target : m_UniqueTargetInfo) + PreprocessSpellLaunch(target); + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { float multiplier = 1.0f; @@ -8049,7 +8052,7 @@ void Spell::HandleLaunchPhase() FinishTargetProcessing(); } -void Spell::DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, uint8 effIndex) +void Spell::PreprocessSpellLaunch(TargetInfo& targetInfo) { Unit* targetUnit = m_caster->GetGUID() == targetInfo.TargetGUID ? m_caster->ToUnit() : ObjectAccessor::GetUnit(*m_caster, targetInfo.TargetGUID); if (!targetUnit) @@ -8070,6 +8073,30 @@ void Spell::DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, uin if (!unit) return; + float critChance = m_spellValue->CriticalChance; + if (m_originalCaster) + { + if (!critChance) + critChance = m_originalCaster->SpellCritChanceDone(m_spellInfo, m_spellSchoolMask, m_attackType); + critChance = unit->SpellCritChanceTaken(m_originalCaster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType); + } + + targetInfo.IsCrit = roll_chance_f(critChance); +} + +void Spell::DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, uint8 effIndex) +{ + Unit* unit = nullptr; + // In case spell hit target, do all effect on that target + if (targetInfo.MissCondition == SPELL_MISS_NONE) + unit = m_caster->GetGUID() == targetInfo.TargetGUID ? m_caster->ToUnit() : ObjectAccessor::GetUnit(*m_caster, targetInfo.TargetGUID); + // In case spell reflect from target, do all effect on caster (if hit) + else if (targetInfo.MissCondition == SPELL_MISS_REFLECT && targetInfo.ReflectResult == SPELL_MISS_NONE) + unit = m_caster->ToUnit(); + + if (!unit) + return; + m_damage = 0; m_healing = 0; @@ -8102,16 +8129,6 @@ void Spell::DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, uin targetInfo.Damage += m_damage; targetInfo.Healing += m_healing; - - float critChance = m_spellValue->CriticalChance; - if (m_originalCaster) - { - if (!critChance) - critChance = m_originalCaster->SpellCritChanceDone(m_spellInfo, m_spellSchoolMask, m_attackType); - critChance = unit->SpellCritChanceTaken(m_originalCaster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType); - } - - targetInfo.IsCrit = roll_chance_f(critChance); } void Spell::ResetCombatTimers() diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 35b28f6f63..25e7d24a73 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -756,6 +756,7 @@ class TC_GAME_API Spell void AddCorpseTarget(Corpse* target, uint32 effectMask); void AddDestTarget(SpellDestination const& dest, uint32 effIndex); + void PreprocessSpellLaunch(TargetInfo& targetInfo); SpellMissInfo PreprocessSpellHit(Unit* unit, bool scaleAura, TargetInfo& targetInfo); void DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& targetInfo);