From da0b406c8a9ab757cdbcadb3861434e06904de8d Mon Sep 17 00:00:00 2001 From: hondacrx Date: Fri, 16 Apr 2021 15:20:02 -0400 Subject: [PATCH] Core/Spell: implement SPELL_FAILED_AURA_BOUNCED on DR spells Port From (https://github.com/TrinityCore/TrinityCore/commit/bebc20b4de7db2fa1b80ac481902a39d92bd4dc8) --- Source/Game/Entities/Creature/Creature.cs | 3 +- Source/Game/Entities/Unit/Unit.Spells.cs | 47 +++++++++++--------- Source/Game/Spells/Spell.cs | 53 +++++++++++++++++------ 3 files changed, 68 insertions(+), 35 deletions(-) diff --git a/Source/Game/Entities/Creature/Creature.cs b/Source/Game/Entities/Creature/Creature.cs index a7938e3d6..4a9df32e2 100644 --- a/Source/Game/Entities/Creature/Creature.cs +++ b/Source/Game/Entities/Creature/Creature.cs @@ -2934,7 +2934,8 @@ namespace Game.Entities return GetCreatureTemplate().InhabitType.HasAnyFlag(InhabitType.Air); } public bool IsDungeonBoss() { return (GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.DungeonBoss)); } - + public override bool IsAffectedByDiminishingReturns() { return base.IsAffectedByDiminishingReturns() || GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.AllDiminish); } + public void SetReactState(ReactStates st) { reactState = st; diff --git a/Source/Game/Entities/Unit/Unit.Spells.cs b/Source/Game/Entities/Unit/Unit.Spells.cs index 05251dfe0..9267ed362 100644 --- a/Source/Game/Entities/Unit/Unit.Spells.cs +++ b/Source/Game/Entities/Unit/Unit.Spells.cs @@ -2711,18 +2711,17 @@ namespace Game.Entities return null; } + public virtual bool IsAffectedByDiminishingReturns() { return (GetCharmerOrOwnerPlayerOrPlayerItself() != null); } + public DiminishingLevels GetDiminishing(DiminishingGroup group) { DiminishingReturn diminish = m_Diminishing[(int)group]; if (diminish.HitCount == 0) return DiminishingLevels.Level1; - // If last spell was cast more than 18 seconds ago - reset the count. + // If last spell was cast more than 18 seconds ago - reset level. if (diminish.Stack == 0 && Time.GetMSTimeDiffToNow(diminish.HitTime) > 18 * Time.InMilliseconds) - { - diminish.HitCount = DiminishingLevels.Level1; return DiminishingLevels.Level1; - } return diminish.HitCount; } @@ -2730,12 +2729,12 @@ namespace Game.Entities public void IncrDiminishing(SpellInfo auraSpellInfo) { DiminishingGroup group = auraSpellInfo.GetDiminishingReturnsGroupForSpell(); + DiminishingLevels currentLevel = GetDiminishing(group); DiminishingLevels maxLevel = auraSpellInfo.GetDiminishingReturnsMaxLevel(); - // Checking for existing in the table DiminishingReturn diminish = m_Diminishing[(int)group]; - if (diminish.HitCount < maxLevel) - ++diminish.HitCount; + if (currentLevel < maxLevel) + diminish.HitCount = currentLevel + 1; } public bool ApplyDiminishingToDuration(SpellInfo auraSpellInfo, ref int duration, Unit caster, DiminishingLevels previousLevel) @@ -2755,8 +2754,7 @@ namespace Game.Entities Unit target = targetOwner ?? this; Unit source = casterOwner ?? caster; - if ((target.IsTypeId(TypeId.Player) || target.ToCreature().GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.AllDiminish)) - && source.IsTypeId(TypeId.Player)) + if (target.IsAffectedByDiminishingReturns() && source.IsPlayer()) duration = limitDuration; } @@ -2789,9 +2787,9 @@ namespace Game.Entities } break; case DiminishingGroup.AOEKnockback: - if ((auraSpellInfo.GetDiminishingReturnsGroupType() == DiminishingReturnsType.Player && (((targetOwner ? targetOwner : this).ToPlayer()) - || IsCreature() && ToCreature().GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.AllDiminish))) - || auraSpellInfo.GetDiminishingReturnsGroupType() == DiminishingReturnsType.All) + if (auraSpellInfo.GetDiminishingReturnsGroupType() == DiminishingReturnsType.All || + (auraSpellInfo.GetDiminishingReturnsGroupType() == DiminishingReturnsType.Player && + (targetOwner ? targetOwner.IsAffectedByDiminishingReturns() : IsAffectedByDiminishingReturns()))) { DiminishingLevels diminish = previousLevel; switch (diminish) @@ -2807,9 +2805,9 @@ namespace Game.Entities } break; default: - if ((auraSpellInfo.GetDiminishingReturnsGroupType() == DiminishingReturnsType.Player && (((targetOwner ? targetOwner : this).ToPlayer()) - || IsCreature() && ToCreature().GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.AllDiminish))) - || auraSpellInfo.GetDiminishingReturnsGroupType() == DiminishingReturnsType.All) + if (auraSpellInfo.GetDiminishingReturnsGroupType() == DiminishingReturnsType.All || + (auraSpellInfo.GetDiminishingReturnsGroupType() == DiminishingReturnsType.Player && + (targetOwner ? targetOwner.IsAffectedByDiminishingReturns() : IsAffectedByDiminishingReturns()))) { DiminishingLevels diminish = previousLevel; switch (diminish) @@ -3195,17 +3193,26 @@ namespace Game.Entities return false; } - bool HasNegativeAuraWithAttribute(SpellAttr0 flag, ObjectGuid guid = default) + public bool HasStrongerAuraWithDR(SpellInfo auraSpellInfo, Unit caster) { - foreach (var list in GetAppliedAuras()) + DiminishingGroup diminishGroup = auraSpellInfo.GetDiminishingReturnsGroupForSpell(); + DiminishingLevels level = GetDiminishing(diminishGroup); + foreach (var itr in GetAppliedAuras()) { - Aura aura = list.Value.GetBase(); - if (!list.Value.IsPositive() && aura.GetSpellInfo().HasAttribute(flag) && (guid.IsEmpty() || aura.GetCasterGUID() == guid)) + SpellInfo spellInfo = itr.Value.GetBase().GetSpellInfo(); + if (spellInfo.GetDiminishingReturnsGroupForSpell() != diminishGroup) + continue; + + int existingDuration = itr.Value.GetBase().GetMaxDuration(); + int newDuration = auraSpellInfo.GetMaxDuration(); + ApplyDiminishingToDuration(auraSpellInfo, ref newDuration, caster, level); + if (newDuration > 0 && newDuration < existingDuration) return true; } + return false; } - + public uint GetAuraCount(uint spellId) { uint count = 0; diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index 715a87b4c..49ad4f122 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -2138,9 +2138,7 @@ namespace Game.Spells diminishLevel = unit.GetDiminishing(diminishGroup); DiminishingReturnsType type = m_spellInfo.GetDiminishingReturnsGroupType(); // Increase Diminishing on unit, current informations for actually casts will use values above - if ((type == DiminishingReturnsType.Player && (unit.GetCharmerOrOwnerPlayerOrPlayerItself() - || (unit.IsCreature() && unit.ToCreature().GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.AllDiminish)))) - || type == DiminishingReturnsType.All) + if (type == DiminishingReturnsType.All || (type == DiminishingReturnsType.Player && unit.IsAffectedByDiminishingReturns())) unit.IncrDiminishing(m_spellInfo); } @@ -2716,11 +2714,9 @@ namespace Game.Spells // skip check if done already (for instant cast spells for example) if (!skipCheck) { - uint param1 = 0, param2 = 0; - SpellCastResult castResult = CheckCast(false, ref param1, ref param2); - if (castResult != SpellCastResult.SpellCastOk) + void cleanupSpell(SpellCastResult result, uint? param1 = null, uint? param2 = null) { - SendCastResult(castResult, param1, param2); + SendCastResult(result, param1, param2); SendInterrupted(0); if (modOwner) @@ -2728,6 +2724,14 @@ namespace Game.Spells Finish(false); SetExecutedCurrently(false); + } + + + uint param1 = 0, param2 = 0; + SpellCastResult castResult = CheckCast(false, ref param1, ref param2); + if (castResult != SpellCastResult.SpellCastOk) + { + cleanupSpell(castResult, param1, param2); return; } @@ -2744,18 +2748,39 @@ namespace Game.Spells { // Spell will be casted at completing the trade. Silently ignore at this place my_trade.SetSpell(m_spellInfo.Id, m_CastItem); - SendCastResult(SpellCastResult.DontReport); - SendInterrupted(0); - - modOwner.SetSpellModTakingSpell(this, false); - - Finish(false); - SetExecutedCurrently(false); + cleanupSpell(SpellCastResult.DontReport); return; } } } } + + // check diminishing returns (again, only after finish cast bar, tested on retail) + Unit target = m_targets.GetUnitTarget(); + if (target != null) + { + uint aura_effmask = 0; + for (byte i = 0; i < SpellConst.MaxEffects; ++i) + if (m_spellInfo.GetEffect(i) != null && m_spellInfo.GetEffect(i).IsUnitOwnedAuraEffect()) + aura_effmask |= 1u << i; + + if (aura_effmask != 0) + { + DiminishingGroup diminishGroup = m_spellInfo.GetDiminishingReturnsGroupForSpell(); + if (diminishGroup != 0) + { + DiminishingReturnsType type = m_spellInfo.GetDiminishingReturnsGroupType(); + if (type == DiminishingReturnsType.All || (type == DiminishingReturnsType.Player && target.IsAffectedByDiminishingReturns())) + { + if (target.HasStrongerAuraWithDR(m_spellInfo, m_originalCaster ?? m_caster)) + { + cleanupSpell(SpellCastResult.AuraBounced); + return; + } + } + } + } + } } // if the spell allows the creature to turn while casting, then adjust server-side orientation to face the target now