From a3748476e004b490194e59b78647818c3764b2fe Mon Sep 17 00:00:00 2001 From: ratkosrb Date: Wed, 12 Feb 2025 23:55:09 +0200 Subject: [PATCH] Fix chain heal interaction with spell batching. --- src/game/Spells/Spell.cpp | 25 +++++++++++++++---------- src/game/Spells/Spell.h | 2 +- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/game/Spells/Spell.cpp b/src/game/Spells/Spell.cpp index e0e7dbcb2b6..3d5ea6081fa 100644 --- a/src/game/Spells/Spell.cpp +++ b/src/game/Spells/Spell.cpp @@ -1091,11 +1091,11 @@ void Spell::CleanupTargetList() m_delayMoment = 0; } -uint32 Spell::GetSpellBatchingEffectDelay(SpellCaster const* pTarget) const +uint32 Spell::GetSpellBatchingEffectDelay(SpellCaster const* pTarget, SpellEffectIndex effIndex) const { // This tries to recreate the feeling of spell effect execution being done in batches, // by syncing the delay of effects to the world timer so they happen simultaneously. - return ((sWorld.getConfig(CONFIG_UINT32_SPELL_EFFECT_DELAY) && pTarget != m_casterUnit) ? + return ((sWorld.getConfig(CONFIG_UINT32_SPELL_EFFECT_DELAY) && (pTarget != m_casterUnit || m_spellInfo->EffectChainTarget[effIndex])) ? (sWorld.getConfig(CONFIG_UINT32_SPELL_EFFECT_DELAY) - (WorldTimer::getMSTime() % sWorld.getConfig(CONFIG_UINT32_SPELL_EFFECT_DELAY))) : 0); } @@ -1166,7 +1166,7 @@ void Spell::AddUnitTarget(Unit* pTarget, SpellEffectIndex effIndex) m_delayMoment = targetInfo.timeDelay; } else if (m_delayed) - m_delayMoment = targetInfo.timeDelay = GetSpellBatchingEffectDelay(pTarget); + m_delayMoment = targetInfo.timeDelay = GetSpellBatchingEffectDelay(pTarget, effIndex); else targetInfo.timeDelay = uint64(0); @@ -1301,7 +1301,7 @@ void Spell::AddGOTarget(GameObject* pTarget, SpellEffectIndex effIndex) m_delayMoment = targetInfo.timeDelay; } else if (m_delayed) - m_delayMoment = targetInfo.timeDelay = GetSpellBatchingEffectDelay(pTarget); + m_delayMoment = targetInfo.timeDelay = GetSpellBatchingEffectDelay(pTarget, effIndex); else targetInfo.timeDelay = uint64(0); @@ -8948,12 +8948,17 @@ void Spell::OnSpellLaunch() (m_casterUnit != unitTarget || m_casterUnit->IsInCombat())) m_casterUnit->SetInCombatWithVictim(unitTarget, false, UNIT_PVP_COMBAT_TIMER); - bool isCharge = false; - for (uint32 i : m_spellInfo->Effect) - if (i == SPELL_EFFECT_CHARGE) - isCharge = true; + int32 chargeEffectIndex = -1; + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if (m_spellInfo->Effect[i] == SPELL_EFFECT_CHARGE) + { + chargeEffectIndex = i; + break; + } + } - if (!isCharge) + if (chargeEffectIndex < 0) return; // Delay attack, otherwise player makes instant attack after cast @@ -8964,7 +8969,7 @@ void Spell::OnSpellLaunch() } bool triggerAutoAttack = unitTarget != m_casterUnit && !m_spellInfo->IsPositiveSpell() && !(m_spellInfo->Attributes & SPELL_ATTR_CANCELS_AUTO_ATTACK_COMBAT); - m_casterUnit->GetMotionMaster()->MoveCharge(unitTarget, m_delayed ? GetSpellBatchingEffectDelay(unitTarget) : 0, triggerAutoAttack); + m_casterUnit->GetMotionMaster()->MoveCharge(unitTarget, m_delayed ? GetSpellBatchingEffectDelay(unitTarget, SpellEffectIndex(chargeEffectIndex)) : 0, triggerAutoAttack); } bool Spell::HasModifierApplied(SpellModifier* mod) diff --git a/src/game/Spells/Spell.h b/src/game/Spells/Spell.h index f7be24ab40e..94a1ce23b98 100644 --- a/src/game/Spells/Spell.h +++ b/src/game/Spells/Spell.h @@ -651,7 +651,7 @@ class Spell void DoAllEffectOnTarget(ItemTargetInfo *target); bool HasValidUnitPresentInTargetList(); SpellCastResult CanOpenLock(SpellEffectIndex effIndex, uint32 lockid, SkillType& skillid, int32& reqSkillValue, int32& skillValue); - uint32 GetSpellBatchingEffectDelay(SpellCaster const* pTarget) const; + uint32 GetSpellBatchingEffectDelay(SpellCaster const* pTarget, SpellEffectIndex effIndex) const; // ------------------------------------------- //List For Triggered Spells