From 765140211b048b8a381c67b6b230fe9f5054ad7d Mon Sep 17 00:00:00 2001 From: Hondacrx Date: Sat, 31 Aug 2024 17:26:16 -0400 Subject: [PATCH] Core/Spells: Implemented SPELL_ATTR9_IGNORE_CASTER_HEALING_MODIFIERS and SPELL_ATTR13_ALWAYS_ALLOW_NEGATIVE_HEALING_PERCENT_MODIFIERS Port From (https://github.com/TrinityCore/TrinityCore/commit/96bfc5f39b4efc0c8437f97746f1a97f028c6dd4) --- .../Framework/Constants/Spells/SpellConst.cs | 4 +- Source/Game/Entities/Unit/Unit.Spells.cs | 93 +++++++++++++------ 2 files changed, 68 insertions(+), 29 deletions(-) diff --git a/Source/Framework/Constants/Spells/SpellConst.cs b/Source/Framework/Constants/Spells/SpellConst.cs index 216664125..8164c4b82 100644 --- a/Source/Framework/Constants/Spells/SpellConst.cs +++ b/Source/Framework/Constants/Spells/SpellConst.cs @@ -1990,7 +1990,7 @@ namespace Framework.Constants SuppressVisualKitErrors = 0x200000, // Suppress Visual Kit Errors (client only) SpellcastOverrideInSpellbook = 0x400000, // Spellcast Override In Spellbook (client only) JumpchargeNoFacingControl = 0x800000, // JumpCharge - no facing control - Unk24 = 0x1000000, // 24 + IgnoreCasterHealingModifiers = 0x1000000, // Ignore Caster Healing Modifiers Unk25 = 0x2000000, // 25 Unk26 = 0x4000000, // 26 Unk27 = 0x8000000, // 27 @@ -2132,7 +2132,7 @@ namespace Framework.Constants Unk23 = 0x800000, // 23 Unk24 = 0x01000000, // 24 Unk25 = 0x02000000, // 25 - Unk26 = 0x04000000, // 26 + AlwaysAllowNegativeHealingPercentModifiers = 0x04000000, // Always Allow Negative Healing Percent Modifiers DoNotAllowDisableMovementInterrupt = 0x08000000, // 27 Unk28 = 0x10000000, // 28 Unk29 = 0x20000000, // 29 diff --git a/Source/Game/Entities/Unit/Unit.Spells.cs b/Source/Game/Entities/Unit/Unit.Spells.cs index 10373b937..f835af9dd 100644 --- a/Source/Game/Entities/Unit/Unit.Spells.cs +++ b/Source/Game/Entities/Unit/Unit.Spells.cs @@ -513,6 +513,10 @@ namespace Game.Entities if (spellProto.HasAttribute(SpellAttr6.IgnoreHealingModifiers)) return 1.0f; + // Some spells don't benefit from done mods + if (spellProto.HasAttribute(SpellAttr9.IgnoreCasterHealingModifiers)) + return 1.0f; + // No bonus healing for potion spells if (spellProto.SpellFamilyName == SpellFamilyNames.Potion) return 1.0f; @@ -530,7 +534,7 @@ namespace Game.Entities DoneTotalMod *= maxModDamagePercentSchool; } - else // SPELL_AURA_MOD_HEALING_DONE_PERCENT is included in m_activePlayerData->ModHealingDonePercent for players + else // SPELL_AURA_MOD_HEALING_DONE_PERCENT is included in m_activePlayerData.ModHealingDonePercent for players DoneTotalMod *= GetTotalAuraMultiplier(AuraType.ModHealingDonePercent); // bonus against aurastate @@ -550,50 +554,85 @@ namespace Game.Entities public int SpellHealingBonusTaken(Unit caster, SpellInfo spellProto, int healamount, DamageEffectType damagetype) { + bool allowPositive = !spellProto.HasAttribute(SpellAttr6.IgnoreHealingModifiers); + bool allowNegative = !spellProto.HasAttribute(SpellAttr6.IgnoreHealingModifiers) || spellProto.HasAttribute(SpellAttr13.AlwaysAllowNegativeHealingPercentModifiers); + if (!allowPositive && !allowNegative) + return healamount; + float TakenTotalMod = 1.0f; // Healing taken percent - float minval = GetMaxNegativeAuraModifier(AuraType.ModHealingPct); - if (minval != 0) - MathFunctions.AddPct(ref TakenTotalMod, minval); - - float maxval = GetMaxPositiveAuraModifier(AuraType.ModHealingPct); - if (maxval != 0) - MathFunctions.AddPct(ref TakenTotalMod, maxval); - - // Nourish cast - if (spellProto.SpellFamilyName == SpellFamilyNames.Druid && spellProto.SpellFamilyFlags[1].HasAnyFlag(0x2000000u)) + if (allowNegative) { - // Rejuvenation, Regrowth, Lifebloom, or Wild Growth - if (GetAuraEffect(AuraType.PeriodicHeal, SpellFamilyNames.Druid, new FlagArray128(0x50, 0x4000010, 0)) != null) - // increase healing by 20% - TakenTotalMod *= 1.2f; + float minval = GetMaxNegativeAuraModifier(AuraType.ModHealingPct); + if (minval != 0) + MathFunctions.AddPct(ref TakenTotalMod, minval); + + if (damagetype == DamageEffectType.DOT) + { + // Healing over time taken percent + float minval_hot = GetMaxNegativeAuraModifier(AuraType.ModHotPct); + if (minval_hot != 0) + MathFunctions.AddPct(ref TakenTotalMod, minval_hot); + } } - if (damagetype == DamageEffectType.DOT) + if (allowPositive) { - // Healing over time taken percent - float minval_hot = (float)GetMaxNegativeAuraModifier(AuraType.ModHotPct); - if (minval_hot != 0) - MathFunctions.AddPct(ref TakenTotalMod, minval_hot); + float maxval = GetMaxPositiveAuraModifier(AuraType.ModHealingPct); + if (maxval != 0) + MathFunctions.AddPct(ref TakenTotalMod, maxval); - float maxval_hot = (float)GetMaxPositiveAuraModifier(AuraType.ModHotPct); - if (maxval_hot != 0) - MathFunctions.AddPct(ref TakenTotalMod, maxval_hot); + if (damagetype == DamageEffectType.DOT) + { + // Healing over time taken percent + float maxval_hot = GetMaxPositiveAuraModifier(AuraType.ModHotPct); + if (maxval_hot != 0) + MathFunctions.AddPct(ref TakenTotalMod, maxval_hot); + } + + // Nourish cast + if (spellProto.SpellFamilyName == SpellFamilyNames.Druid && spellProto.SpellFamilyFlags[1].HasAnyFlag(0x2000000u)) + { + // Rejuvenation, Regrowth, Lifebloom, or Wild Growth + if (GetAuraEffect(AuraType.PeriodicHeal, SpellFamilyNames.Druid, new FlagArray128(0x50, 0x4000010, 0)) != null) + // increase healing by 20% + TakenTotalMod *= 1.2f; + } } if (caster != null) { TakenTotalMod *= GetTotalAuraMultiplier(AuraType.ModHealingReceived, aurEff => { - if (caster.GetGUID() == aurEff.GetCasterGUID() && aurEff.IsAffectingSpell(spellProto)) - return true; - return false; + if (caster.GetGUID() != aurEff.GetCasterGUID() || !aurEff.IsAffectingSpell(spellProto)) + return false; + + if (aurEff.GetAmount() > 0) + { + if (!allowPositive) + return false; + } + else if (!allowNegative) + return false; + + return true; }); TakenTotalMod *= GetTotalAuraMultiplier(AuraType.ModHealingTakenFromCaster, aurEff => { - return aurEff.GetCasterGUID() == caster.GetGUID(); + if (aurEff.GetCasterGUID() != caster.GetGUID()) + return false; + + if (aurEff.GetAmount() > 0) + { + if (!allowPositive) + return false; + } + else if (!allowNegative) + return false; + + return true; }); }