fix(Core/Spells): Beacon of Light no longer copies target healing modifiers (#24796)

Co-authored-by: blinkysc <blinkysc@users.noreply.github.com>
This commit is contained in:
blinkysc
2026-02-22 11:06:47 -06:00
committed by GitHub
parent f7ab757970
commit 7fadeb1141
5 changed files with 33 additions and 2 deletions

View File

@@ -386,6 +386,7 @@ private:
Unit* const m_healer; Unit* const m_healer;
Unit* const m_target; Unit* const m_target;
uint32 m_heal; uint32 m_heal;
uint32 m_healBeforeTakenMods;
uint32 m_effectiveHeal; uint32 m_effectiveHeal;
uint32 m_absorb; uint32 m_absorb;
SpellInfo const* const m_spellInfo; SpellInfo const* const m_spellInfo;
@@ -393,7 +394,7 @@ private:
uint32 m_hitMask; uint32 m_hitMask;
public: public:
explicit HealInfo(Unit* _healer, Unit* _target, uint32 _heal, SpellInfo const* _spellInfo, SpellSchoolMask _schoolMask) explicit HealInfo(Unit* _healer, Unit* _target, uint32 _heal, SpellInfo const* _spellInfo, SpellSchoolMask _schoolMask)
: m_healer(_healer), m_target(_target), m_heal(_heal), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask), m_hitMask(0) : m_healer(_healer), m_target(_target), m_heal(_heal), m_healBeforeTakenMods(0), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask), m_hitMask(0)
{ {
m_absorb = 0; m_absorb = 0;
m_effectiveHeal = 0; m_effectiveHeal = 0;
@@ -414,6 +415,11 @@ public:
m_heal = amount; m_heal = amount;
} }
void SetHealBeforeTakenMods(uint32 amount)
{
m_healBeforeTakenMods = amount;
}
void SetEffectiveHeal(uint32 amount) void SetEffectiveHeal(uint32 amount)
{ {
m_effectiveHeal = amount; m_effectiveHeal = amount;
@@ -422,6 +428,7 @@ public:
[[nodiscard]] Unit* GetHealer() const { return m_healer; } [[nodiscard]] Unit* GetHealer() const { return m_healer; }
[[nodiscard]] Unit* GetTarget() const { return m_target; } [[nodiscard]] Unit* GetTarget() const { return m_target; }
[[nodiscard]] uint32 GetHeal() const { return m_heal; } [[nodiscard]] uint32 GetHeal() const { return m_heal; }
[[nodiscard]] uint32 GetHealBeforeTakenMods() const { return m_healBeforeTakenMods; }
[[nodiscard]] uint32 GetEffectiveHeal() const { return m_effectiveHeal; } [[nodiscard]] uint32 GetEffectiveHeal() const { return m_effectiveHeal; }
[[nodiscard]] uint32 GetAbsorb() const { return m_absorb; } [[nodiscard]] uint32 GetAbsorb() const { return m_absorb; }
[[nodiscard]] SpellInfo const* GetSpellInfo() const { return m_spellInfo; }; [[nodiscard]] SpellInfo const* GetSpellInfo() const { return m_spellInfo; };

View File

@@ -649,6 +649,7 @@ Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags,
m_diminishGroup = DIMINISHING_NONE; m_diminishGroup = DIMINISHING_NONE;
m_damage = 0; m_damage = 0;
m_healing = 0; m_healing = 0;
m_damageBeforeTakenMods = 0;
m_procAttacker = 0; m_procAttacker = 0;
m_procVictim = 0; m_procVictim = 0;
m_procEx = 0; m_procEx = 0;
@@ -2337,6 +2338,7 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
targetInfo.processed = false; // Effects not apply on target targetInfo.processed = false; // Effects not apply on target
targetInfo.alive = target->IsAlive(); targetInfo.alive = target->IsAlive();
targetInfo.damage = 0; targetInfo.damage = 0;
targetInfo.damageBeforeTakenMods = 0;
targetInfo.crit = false; targetInfo.crit = false;
targetInfo.scaleAura = false; targetInfo.scaleAura = false;
if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target) if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
@@ -2712,6 +2714,17 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask()); HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
// Heal amount before SpellHealingBonusTaken, used by Beacon of Light
if (target->damageBeforeTakenMods != 0)
{
uint32 healBeforeTakenMods = uint32(-target->damageBeforeTakenMods);
if (crit)
healBeforeTakenMods = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, healBeforeTakenMods, nullptr);
healInfo.SetHealBeforeTakenMods(healBeforeTakenMods);
}
else
healInfo.SetHealBeforeTakenMods(addhealth);
// Set hitMask based on crit // Set hitMask based on crit
if (crit) if (crit)
healInfo.AddHitMask(PROC_HIT_CRITICAL); healInfo.AddHitMask(PROC_HIT_CRITICAL);
@@ -8297,6 +8310,7 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier)
{ {
m_damage = 0; m_damage = 0;
m_healing = 0; m_healing = 0;
m_damageBeforeTakenMods = 0;
HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET); HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
@@ -8322,6 +8336,7 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier)
m_damageMultipliers[i] *= multiplier[i]; m_damageMultipliers[i] *= multiplier[i];
} }
targetInfo.damage += m_damage; targetInfo.damage += m_damage;
targetInfo.damageBeforeTakenMods += m_damageBeforeTakenMods;
} }
} }

View File

@@ -273,6 +273,7 @@ struct TargetInfo
bool crit:1; bool crit:1;
bool scaleAura:1; bool scaleAura:1;
int32 damage; int32 damage;
int32 damageBeforeTakenMods;
}; };
static const uint32 SPELL_INTERRUPT_NONPLAYER = 32747; static const uint32 SPELL_INTERRUPT_NONPLAYER = 32747;
@@ -683,6 +684,7 @@ public:
// Damage and healing in effects need just calculate // Damage and healing in effects need just calculate
int32 m_damage; // Damge in effects count here int32 m_damage; // Damge in effects count here
int32 m_healing; // Healing in effects count here int32 m_healing; // Healing in effects count here
int32 m_damageBeforeTakenMods;
// ****************************************** // ******************************************
// Spell trigger system // Spell trigger system

View File

@@ -1557,11 +1557,13 @@ void Spell::EffectHeal(SpellEffIndex effIndex)
else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] & 0x00080000) else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] & 0x00080000)
{ {
addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effIndex); addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effIndex);
m_damageBeforeTakenMods -= addhealth;
addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL); addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
} }
else if (m_spellInfo->Id != 33778) // not lifebloom else if (m_spellInfo->Id != 33778) // not lifebloom
{ {
addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex); addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex);
m_damageBeforeTakenMods -= addhealth;
addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL); addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
} }
@@ -1593,6 +1595,7 @@ void Spell::EffectHealPct(SpellEffIndex effIndex)
return; return;
uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, unitTarget->CountPctFromMaxHealth(damage), HEAL, effIndex); uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, unitTarget->CountPctFromMaxHealth(damage), HEAL, effIndex);
m_damageBeforeTakenMods -= heal;
heal = unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL); heal = unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL);
m_damage -= heal; m_damage -= heal;
@@ -1611,6 +1614,7 @@ void Spell::EffectHealMechanical(SpellEffIndex effIndex)
return; return;
uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, uint32(damage), HEAL, effIndex); uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, uint32(damage), HEAL, effIndex);
m_damageBeforeTakenMods -= heal;
m_damage -= unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL); m_damage -= unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL);
} }

View File

@@ -2148,7 +2148,10 @@ class spell_pal_light_s_beacon : public AuraScript
// Holy Light heals for 100%, Flash of Light heals for 50% // Holy Light heals for 100%, Flash of Light heals for 50%
uint32 healSpellId = procSpell->IsRankOf(sSpellMgr->AssertSpellInfo(SPELL_PALADIN_HOLY_LIGHT_R1)) ? uint32 healSpellId = procSpell->IsRankOf(sSpellMgr->AssertSpellInfo(SPELL_PALADIN_HOLY_LIGHT_R1)) ?
SPELL_PALADIN_BEACON_OF_LIGHT_FLASH : SPELL_PALADIN_BEACON_OF_LIGHT_HOLY; SPELL_PALADIN_BEACON_OF_LIGHT_FLASH : SPELL_PALADIN_BEACON_OF_LIGHT_HOLY;
int32 heal = CalculatePct(healInfo->GetHeal(), aurEff->GetAmount());
// Use heal amount before target-specific modifiers to avoid copying them
uint32 healAmount = healInfo->GetHealBeforeTakenMods();
int32 heal = CalculatePct(healAmount, aurEff->GetAmount());
Unit* beaconTarget = GetCaster(); Unit* beaconTarget = GetCaster();
if (!beaconTarget || !beaconTarget->HasAura(SPELL_PALADIN_BEACON_OF_LIGHT_AURA, eventInfo.GetActor()->GetGUID())) if (!beaconTarget || !beaconTarget->HasAura(SPELL_PALADIN_BEACON_OF_LIGHT_AURA, eventInfo.GetActor()->GetGUID()))