fix(Core/Spells): Fixed Spiritual Attunement not working with partial… (#15767)

fix(Core/Spells): Fixed Spiritual Attunement not working with partial overheals.

Fixes #14430
This commit is contained in:
UltraNix
2023-04-02 15:13:16 +02:00
committed by GitHub
parent 4d24c412e0
commit 1acbb9ee53
3 changed files with 45 additions and 17 deletions
+29 -14
View File
@@ -6498,11 +6498,12 @@ void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit* target, uint8 /*SwingType
} }
//victim may be nullptr //victim may be nullptr
bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, Spell const* spellProc /*= nullptr*/) bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, ProcEventInfo const& eventInfo)
{ {
SpellInfo const* dummySpell = triggeredByAura->GetSpellInfo(); SpellInfo const* dummySpell = triggeredByAura->GetSpellInfo();
uint32 effIndex = triggeredByAura->GetEffIndex(); uint32 effIndex = triggeredByAura->GetEffIndex();
int32 triggerAmount = triggeredByAura->GetAmount(); int32 triggerAmount = triggeredByAura->GetAmount();
Spell const* spellProc = eventInfo.GetProcSpell();
Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : nullptr; ? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : nullptr;
@@ -7864,12 +7865,22 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
if (!procSpell || !procSpell->IsPositive()) if (!procSpell || !procSpell->IsPositive())
return false; return false;
// heal amount HealInfo const* healInfo = eventInfo.GetHealInfo();
basepoints0 = int32(CalculatePct(std::min(damage, GetMaxHealth() - GetHealth()), triggerAmount)); if (!healInfo)
target = this; {
return false;
}
if (basepoints0) uint32 effectiveHeal = healInfo->GetEffectiveHeal();
triggered_spell_id = 31786; if (effectiveHeal)
{
// heal amount
basepoints0 = int32(CalculatePct(effectiveHeal, triggerAmount));
target = this;
if (basepoints0)
triggered_spell_id = 31786;
}
break; break;
} }
// Paladin Tier 6 Trinket (Ashtongue Talisman of Zeal) // Paladin Tier 6 Trinket (Ashtongue Talisman of Zeal)
@@ -11185,16 +11196,18 @@ void Unit::UnsummonAllTotems(bool onDeath /*= false*/)
} }
} }
void Unit::SendHealSpellLog(Unit* victim, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical) void Unit::SendHealSpellLog(HealInfo const& healInfo, bool critical)
{ {
uint32 overheal = healInfo.GetHeal() - healInfo.GetEffectiveHeal();
// we guess size // we guess size
WorldPacket data(SMSG_SPELLHEALLOG, (8 + 8 + 4 + 4 + 4 + 4 + 1 + 1)); WorldPacket data(SMSG_SPELLHEALLOG, (8 + 8 + 4 + 4 + 4 + 4 + 1 + 1));
data << victim->GetPackGUID(); data << healInfo.GetTarget()->GetPackGUID();
data << GetPackGUID(); data << GetPackGUID();
data << uint32(SpellID); data << uint32(healInfo.GetSpellInfo()->Id);
data << uint32(Damage); data << uint32(healInfo.GetHeal());
data << uint32(OverHeal); data << uint32(overheal);
data << uint32(Absorb); // Absorb amount data << uint32(healInfo.GetAbsorb()); // Absorb amount
data << uint8(critical ? 1 : 0); data << uint8(critical ? 1 : 0);
data << uint8(0); // unused data << uint8(0); // unused
SendMessageToSet(&data, true); SendMessageToSet(&data, true);
@@ -11210,7 +11223,9 @@ int32 Unit::HealBySpell(HealInfo& healInfo, bool critical)
CalcHealAbsorb(healInfo); CalcHealAbsorb(healInfo);
int32 gain = Unit::DealHeal(healInfo.GetHealer(), healInfo.GetTarget(), healInfo.GetHeal()); int32 gain = Unit::DealHeal(healInfo.GetHealer(), healInfo.GetTarget(), healInfo.GetHeal());
SendHealSpellLog(healInfo.GetTarget(), healInfo.GetSpellInfo()->Id, healInfo.GetHeal(), uint32(healInfo.GetHeal() - gain), healInfo.GetAbsorb(), critical); healInfo.SetEffectiveHeal(gain);
SendHealSpellLog(healInfo, critical);
return gain; return gain;
} }
@@ -16538,7 +16553,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
case SPELL_AURA_DUMMY: case SPELL_AURA_DUMMY:
{ {
LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell id {} (triggered by {} dummy aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId()); LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell id {} (triggered by {} dummy aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId());
if (HandleDummyAuraProc(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, procSpell)) if (HandleDummyAuraProc(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, eventInfo))
takeCharges = true; takeCharges = true;
break; break;
} }
+14 -2
View File
@@ -806,6 +806,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_effectiveHeal;
uint32 m_absorb; uint32 m_absorb;
SpellInfo const* const m_spellInfo; SpellInfo const* const m_spellInfo;
SpellSchoolMask const m_schoolMask; SpellSchoolMask const m_schoolMask;
@@ -814,12 +815,17 @@ public:
: m_healer(_healer), m_target(_target), m_heal(_heal), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask) : m_healer(_healer), m_target(_target), m_heal(_heal), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask)
{ {
m_absorb = 0; m_absorb = 0;
m_effectiveHeal = 0;
} }
void AbsorbHeal(uint32 amount) void AbsorbHeal(uint32 amount)
{ {
amount = std::min(amount, GetHeal()); amount = std::min(amount, GetHeal());
m_absorb += amount; m_absorb += amount;
m_heal -= amount; m_heal -= amount;
amount = std::min(amount, GetEffectiveHeal());
m_effectiveHeal -= amount;
} }
void SetHeal(uint32 amount) void SetHeal(uint32 amount)
@@ -827,9 +833,15 @@ public:
m_heal = amount; m_heal = amount;
} }
void SetEffectiveHeal(uint32 amount)
{
m_effectiveHeal = amount;
}
[[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 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; };
[[nodiscard]] SpellSchoolMask GetSchoolMask() const { return m_schoolMask; }; [[nodiscard]] SpellSchoolMask GetSchoolMask() const { return m_schoolMask; };
@@ -1723,7 +1735,7 @@ public:
[[nodiscard]] virtual bool IsUnderWater() const; [[nodiscard]] virtual bool IsUnderWater() const;
bool isInAccessiblePlaceFor(Creature const* c) const; bool isInAccessiblePlaceFor(Creature const* c) const;
void SendHealSpellLog(Unit* victim, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical = false); void SendHealSpellLog(HealInfo const& healInfo, bool critical = false);
int32 HealBySpell(HealInfo& healInfo, bool critical = false); int32 HealBySpell(HealInfo& healInfo, bool critical = false);
void SendEnergizeSpellLog(Unit* victim, uint32 SpellID, uint32 Damage, Powers powertype); void SendEnergizeSpellLog(Unit* victim, uint32 SpellID, uint32 Damage, Powers powertype);
void EnergizeBySpell(Unit* victim, uint32 SpellID, uint32 Damage, Powers powertype); void EnergizeBySpell(Unit* victim, uint32 SpellID, uint32 Damage, Powers powertype);
@@ -2545,7 +2557,7 @@ protected:
private: private:
bool IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent, ProcEventInfo const& eventInfo); bool IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent, ProcEventInfo const& eventInfo);
bool HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, Spell const* spellProc = nullptr); bool HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, ProcEventInfo const& eventInfo);
bool HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool* handled); bool HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool* handled);
bool HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, uint32 procPhase, ProcEventInfo& eventInfo); bool HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, uint32 procPhase, ProcEventInfo& eventInfo);
bool HandleOverrideClassScriptAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 cooldown); bool HandleOverrideClassScriptAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 cooldown);
@@ -6626,8 +6626,9 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
HealInfo healInfo(caster, target, heal, GetSpellInfo(), GetSpellInfo()->GetSchoolMask()); HealInfo healInfo(caster, target, heal, GetSpellInfo(), GetSpellInfo()->GetSchoolMask());
Unit::CalcHealAbsorb(healInfo); Unit::CalcHealAbsorb(healInfo);
int32 gain = Unit::DealHeal(caster, target, healInfo.GetHeal()); int32 gain = Unit::DealHeal(caster, target, healInfo.GetHeal());
healInfo.SetEffectiveHeal(gain);
SpellPeriodicAuraLogInfo pInfo(this, healInfo.GetHeal(), healInfo.GetHeal() - gain, healInfo.GetAbsorb(), 0, 0.0f, crit); SpellPeriodicAuraLogInfo pInfo(this, healInfo.GetHeal(), healInfo.GetHeal() - healInfo.GetEffectiveHeal(), healInfo.GetAbsorb(), 0, 0.0f, crit);
target->SendPeriodicAuraLog(&pInfo); target->SendPeriodicAuraLog(&pInfo);
if (caster) if (caster)