From 2806e5d4b7b8ebeeb5a03e8378520004dbe0b18b Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 8 Oct 2022 10:39:28 -0700 Subject: [PATCH] feat: Adds reflect damage ability. Fixes magical barrier (#1184) --- Projects/Server/Mobiles/Mobile.cs | 106 +++++++++--------- Projects/UOContent/Misc/AOS.cs | 21 +++- .../Mobiles/Abilities/MonsterAbilityType.cs | 3 +- .../Abilities/ReflectPhysicalDamage.cs | 11 ++ .../Mobiles/Monsters/SE/FanDancer.cs | 9 +- 5 files changed, 86 insertions(+), 64 deletions(-) create mode 100644 Projects/UOContent/Mobiles/Abilities/ReflectPhysicalDamage.cs diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index b14496789..7a8291fde 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -5761,6 +5761,11 @@ namespace Server public virtual void Damage(int amount, Mobile from = null, bool informMount = true) { + if (amount <= 0) + { + return; + } + if (!CanBeDamaged() || Deleted) { return; @@ -5771,67 +5776,64 @@ namespace Server return; } - if (amount > 0) + var oldHits = Hits; + var newHits = oldHits - amount; + + m_Spell?.OnCasterHurt(); + + // if (m_Spell != null && m_Spell.State == SpellState.Casting) + // m_Spell.Disturb( DisturbType.Hurt, false, true ); + + if (from != null) { - var oldHits = Hits; - var newHits = oldHits - amount; + RegisterDamage(amount, from); + } - m_Spell?.OnCasterHurt(); + DisruptiveAction(); - // if (m_Spell != null && m_Spell.State == SpellState.Casting) - // m_Spell.Disturb( DisturbType.Hurt, false, true ); + Paralyzed = false; - if (from != null) - { - RegisterDamage(amount, from); - } - - DisruptiveAction(); - - Paralyzed = false; - - switch (VisibleDamageType) - { - case VisibleDamageType.Related: - { - SendVisibleDamageRelated(from, amount); - break; - } - case VisibleDamageType.Everyone: - { - SendVisibleDamageEveryone(amount); - break; - } - case VisibleDamageType.Selective: - { - SendVisibleDamageSelective(from, amount); - break; - } - } - - OnDamage(amount, from, newHits < 0); - - if (informMount) - { - Mount?.OnRiderDamaged(amount, from, newHits < 0); - } - - if (newHits < 0) - { - LastKiller = from; - - Hits = 0; - - if (oldHits >= 0) + switch (VisibleDamageType) + { + case VisibleDamageType.Related: { - Kill(); + SendVisibleDamageRelated(from, amount); + break; } - } - else + case VisibleDamageType.Everyone: + { + SendVisibleDamageEveryone(amount); + break; + } + case VisibleDamageType.Selective: + { + SendVisibleDamageSelective(from, amount); + break; + } + } + + OnDamage(amount, from, newHits < 0); + + if (informMount) + { + Mount?.OnRiderDamaged(amount, from, newHits < 0); + } + + if (newHits < 0) + { + LastKiller = from; + + Hits = 0; + + if (oldHits >= 0) { - Hits = newHits; + Kill(); } } + else + { + Hits = newHits; + } } public void SendVisibleDamageRelated(Mobile from, int amount) diff --git a/Projects/UOContent/Misc/AOS.cs b/Projects/UOContent/Misc/AOS.cs index ad077879f..18517ede7 100644 --- a/Projects/UOContent/Misc/AOS.cs +++ b/Projects/UOContent/Misc/AOS.cs @@ -194,24 +194,35 @@ namespace Server totalDamage = m.Hits; } + var bcFrom = from as BaseCreature; + if (from is { Deleted: false, Alive: true }) { var reflectPhys = AosAttributes.GetValue(m, AosAttribute.ReflectPhysical); + var reflectPhysAbility = bcFrom?.GetAbility(MonsterAbilityType.ReflectPhysicalDamage) as ReflectPhysicalDamage; - if (reflectPhys != 0 && from is BaseCreature bcFrom) + if (reflectPhysAbility + ?.CanTrigger(bcFrom, MonsterAbilityTrigger.CombatAction) == true) { - var magicalBarrier = bcFrom.GetAbility(MonsterAbilityType.MagicalBarrier); - magicalBarrier.AlterMeleeDamageFrom(bcFrom, m, ref reflectPhys); + reflectPhys += reflectPhysAbility.PercentReflected; + m.SendLocalizedMessage(1070844); // The creature repels the attack back at you. } - if (reflectPhys != 0) + if (reflectPhys > 0) { var reflectDamage = Scale( damage * phys * (100 - (ignoreArmor ? 0 : m.PhysicalResistance)) / 10000, reflectPhys ); - from.Damage(reflectDamage, m); + bcFrom + ?.GetAbility(MonsterAbilityType.MagicalBarrier) + ?.AlterMeleeDamageFrom(bcFrom, m, ref reflectDamage); + + if (reflectDamage > 0) + { + from.Damage(reflectDamage, m); + } } } diff --git a/Projects/UOContent/Mobiles/Abilities/MonsterAbilityType.cs b/Projects/UOContent/Mobiles/Abilities/MonsterAbilityType.cs index 4f5768923..9a2c7fdb4 100644 --- a/Projects/UOContent/Mobiles/Abilities/MonsterAbilityType.cs +++ b/Projects/UOContent/Mobiles/Abilities/MonsterAbilityType.cs @@ -14,5 +14,6 @@ public enum MonsterAbilityType DeathExplosion, MassDrainLife, MagicalBarrier, - EnergyBoltCounter + EnergyBoltCounter, + ReflectPhysicalDamage } diff --git a/Projects/UOContent/Mobiles/Abilities/ReflectPhysicalDamage.cs b/Projects/UOContent/Mobiles/Abilities/ReflectPhysicalDamage.cs new file mode 100644 index 000000000..ae66734ba --- /dev/null +++ b/Projects/UOContent/Mobiles/Abilities/ReflectPhysicalDamage.cs @@ -0,0 +1,11 @@ +namespace Server.Mobiles; + +public class ReflectPhysicalDamage : MonsterAbility +{ + // This is handled manually in AOS.Damage() + public override MonsterAbilityTrigger AbilityTrigger => MonsterAbilityTrigger.CombatAction; + + public override MonsterAbilityType AbilityType => MonsterAbilityType.ReflectPhysicalDamage; + + public virtual int PercentReflected => 10; +} diff --git a/Projects/UOContent/Mobiles/Monsters/SE/FanDancer.cs b/Projects/UOContent/Mobiles/Monsters/SE/FanDancer.cs index 9b6b6bf55..55d886efa 100644 --- a/Projects/UOContent/Mobiles/Monsters/SE/FanDancer.cs +++ b/Projects/UOContent/Mobiles/Monsters/SE/FanDancer.cs @@ -64,6 +64,9 @@ namespace Server.Mobiles public override bool Uncalmable => true; + private static MonsterAbility[] _abilities = { new ReflectPhysicalDamage() }; + public override MonsterAbility[] GetMonsterAbilities() => _abilities; + public override void GenerateLoot() { AddLoot(LootPack.FilthyRich); @@ -71,12 +74,6 @@ namespace Server.Mobiles AddLoot(LootPack.Gems, 2); } - /* TODO: Repel Magic - * 10% chance of repelling a melee attack (why did they call it repel magic anyway?) - * Cliloc: 1070844 - * Effect: damage is dealt to the attacker, no damage is taken by the fan dancer - */ - private void ThrowFan(Mobile to) { if (!(Utility.RandomDouble() < 0.8) || to.InRange(this, 1))