From 14a23ac6829b3461a3e07fc08103dd109b20e18e Mon Sep 17 00:00:00 2001 From: hondacrx Date: Fri, 29 Jul 2022 18:01:57 -0400 Subject: [PATCH] Core/PacketIO: Implemented SMSG_SPELL_HEAL_ABSORB_LOG Port From (https://github.com/TrinityCore/TrinityCore/commit/53b7c4d47c35f7823f5f50578beb0140f4279e03) --- Source/Game/Entities/Unit/Unit.cs | 59 +++++++++++-------- .../Networking/Packets/CombatLogPackets.cs | 30 ++++++++++ 2 files changed, 64 insertions(+), 25 deletions(-) diff --git a/Source/Game/Entities/Unit/Unit.cs b/Source/Game/Entities/Unit/Unit.cs index 0eae0ffb4..a9c5aab09 100644 --- a/Source/Game/Entities/Unit/Unit.cs +++ b/Source/Game/Entities/Unit/Unit.cs @@ -2610,7 +2610,6 @@ namespace Game.Entities if (currentAbsorb < 0) currentAbsorb = 0; - uint tempAbsorb = (uint)currentAbsorb; // This aura type is used both by Spirit of Redemption (death not really prevented, must grant all credit immediately) and Cheat Death (death prevented) @@ -3382,17 +3381,15 @@ namespace Game.Entities vSchoolAbsorbCopy.Sort(new AbsorbAuraOrderPred()); // absorb without mana cost - for (var i = 0; i < vSchoolAbsorbCopy.Count; ++i) + for (var i = 0; i < vSchoolAbsorbCopy.Count && (damageInfo.GetDamage() > 0); ++i) { var absorbAurEff = vSchoolAbsorbCopy[i]; - if (damageInfo.GetDamage() == 0) - break; // Check if aura was removed during iteration - we don't need to work on such auras AuraApplication aurApp = absorbAurEff.GetBase().GetApplicationOfTarget(damageInfo.GetVictim().GetGUID()); if (aurApp == null) continue; - if (!Convert.ToBoolean(absorbAurEff.GetMiscValue() & (int)damageInfo.GetSchoolMask())) + if ((absorbAurEff.GetMiscValue() & (int)damageInfo.GetSchoolMask()) == 0) continue; // get amount which can be still absorbed by the aura @@ -3606,7 +3603,7 @@ namespace Game.Entities if (aurApp == null) continue; - if ((absorbAurEff.GetMiscValue() & (int)healInfo.GetSpellInfo().GetSchoolMask()) == 0) + if ((absorbAurEff.GetMiscValue() & (int)healInfo.GetSchoolMask()) == 0) continue; // get amount which can be still absorbed by the aura @@ -3622,26 +3619,38 @@ namespace Game.Entities absorbAurEff.GetBase().CallScriptEffectAbsorbHandlers(absorbAurEff, aurApp, healInfo, ref tempAbsorb, ref defaultPrevented); currentAbsorb = (int)tempAbsorb; - if (defaultPrevented) - continue; - - // currentAbsorb - damage can be absorbed by shield - // If need absorb less damage - currentAbsorb = (int)Math.Min(healInfo.GetHeal(), currentAbsorb); - - healInfo.AbsorbHeal((uint)currentAbsorb); - - tempAbsorb = (uint)currentAbsorb; - absorbAurEff.GetBase().CallScriptEffectAfterAbsorbHandlers(absorbAurEff, aurApp, healInfo, ref tempAbsorb); - - // Check if our aura is using amount to count heal - if (absorbAurEff.GetAmount() >= 0) + if (!defaultPrevented) { - // Reduce shield amount - absorbAurEff.ChangeAmount(absorbAurEff.GetAmount() - currentAbsorb); - // Aura cannot absorb anything more - remove it - if (absorbAurEff.GetAmount() <= 0) - existExpired = true; + // absorb must be smaller than the heal itself + currentAbsorb = MathFunctions.RoundToInterval(ref currentAbsorb, 0, healInfo.GetHeal()); + + healInfo.AbsorbHeal((uint)currentAbsorb); + + tempAbsorb = (uint)currentAbsorb; + absorbAurEff.GetBase().CallScriptEffectAfterAbsorbHandlers(absorbAurEff, aurApp, healInfo, ref tempAbsorb); + + // Check if our aura is using amount to count heal + if (absorbAurEff.GetAmount() >= 0) + { + // Reduce shield amount + absorbAurEff.ChangeAmount(absorbAurEff.GetAmount() - currentAbsorb); + // Aura cannot absorb anything more - remove it + if (absorbAurEff.GetAmount() <= 0) + absorbAurEff.GetBase().Remove(AuraRemoveMode.EnemySpell); + } + } + + if (currentAbsorb != 0) + { + SpellHealAbsorbLog absorbLog = new(); + absorbLog.Healer = healInfo.GetHealer() ? healInfo.GetHealer().GetGUID() : ObjectGuid.Empty; + absorbLog.Target = healInfo.GetTarget().GetGUID(); + absorbLog.AbsorbCaster = absorbAurEff.GetBase().GetCasterGUID(); + absorbLog.AbsorbedSpellID = (int)(healInfo.GetSpellInfo() != null ? healInfo.GetSpellInfo().Id : 0); + absorbLog.AbsorbSpellID = (int)absorbAurEff.GetId(); + absorbLog.Absorbed = currentAbsorb; + absorbLog.OriginalHeal = (int)healInfo.GetOriginalHeal(); + healInfo.GetTarget().SendMessageToSet(absorbLog, true); } } diff --git a/Source/Game/Networking/Packets/CombatLogPackets.cs b/Source/Game/Networking/Packets/CombatLogPackets.cs index 178951dfe..9eda6e927 100644 --- a/Source/Game/Networking/Packets/CombatLogPackets.cs +++ b/Source/Game/Networking/Packets/CombatLogPackets.cs @@ -626,6 +626,36 @@ namespace Game.Networking.Packets public bool Unk; } + class SpellHealAbsorbLog : ServerPacket + { + public SpellHealAbsorbLog() : base(ServerOpcodes.SpellHealAbsorbLog, ConnectionType.Instance) { } + + public override void Write() + { + _worldPacket.WritePackedGuid(Target); + _worldPacket.WritePackedGuid(AbsorbCaster); + _worldPacket.WritePackedGuid(Healer); + _worldPacket.WriteInt32(AbsorbSpellID); + _worldPacket.WriteInt32(AbsorbedSpellID); + _worldPacket.WriteInt32(Absorbed); + _worldPacket.WriteInt32(OriginalHeal); + _worldPacket.WriteBit(ContentTuning != null); + _worldPacket.FlushBits(); + + if (ContentTuning != null) + ContentTuning.Write(_worldPacket); + } + + public ObjectGuid Healer; + public ObjectGuid Target; + public ObjectGuid AbsorbCaster; + public int AbsorbSpellID; + public int AbsorbedSpellID; + public int Absorbed; + public int OriginalHeal; + public ContentTuningParams ContentTuning; + } + //Structs public struct SpellLogEffectPowerDrainParams {