diff --git a/Projects/UOContent/Items/Weapons/BaseWeapon.cs b/Projects/UOContent/Items/Weapons/BaseWeapon.cs index 03dfa60a2..4fafd73c9 100644 --- a/Projects/UOContent/Items/Weapons/BaseWeapon.cs +++ b/Projects/UOContent/Items/Weapons/BaseWeapon.cs @@ -1924,24 +1924,6 @@ namespace Server.Items lifeLeech += 50; // Additional 50% life leech for cursed weapons (necro spell) } - context = TransformationSpellHelper.GetContext(attacker); - - if (context?.Type == typeof(VampiricEmbraceSpell)) - { - lifeLeech += 20; // Vampiric embrace gives an additional 20% life leech - } - - if (context?.Type == typeof(WraithFormSpell)) - { - // Wraith form gives an additional 5-20% mana leech - var wraithLeech = 5 + (int)(15 * attacker.Skills.SpiritSpeak.Value / 100); - - // Mana leeched by the Wraith Form spell is actually stolen, not just leeched. - defender.Mana -= AOS.Scale(damageGiven, wraithLeech); - - manaLeech += wraithLeech; - } - if (lifeLeech != 0) { attacker.Hits += AOS.Scale(damageGiven, lifeLeech); diff --git a/Projects/UOContent/Misc/AOS.cs b/Projects/UOContent/Misc/AOS.cs index f9a61da7b..b52879118 100644 --- a/Projects/UOContent/Misc/AOS.cs +++ b/Projects/UOContent/Misc/AOS.cs @@ -214,6 +214,11 @@ namespace Server return 0; } + if (from != null) // sanity check + { + SpellHelper.DoLeech(totalDamage, from, m); + } + m.Damage(totalDamage, from); return totalDamage; } diff --git a/Projects/UOContent/Misc/WeightOverloading.cs b/Projects/UOContent/Misc/WeightOverloading.cs index 1a6f946fe..41c997920 100644 --- a/Projects/UOContent/Misc/WeightOverloading.cs +++ b/Projects/UOContent/Misc/WeightOverloading.cs @@ -76,7 +76,7 @@ namespace Server.Misc --from.Stam; } - if (from.Stam == 0) + if (!Core.AOS && from.Stam == 0) { from.SendLocalizedMessage(500110); // You are too fatigued to move. e.Blocked = true; diff --git a/Projects/UOContent/Mobiles/PlayerMobile.cs b/Projects/UOContent/Mobiles/PlayerMobile.cs index 1c5ec4eef..be6ffe14e 100644 --- a/Projects/UOContent/Mobiles/PlayerMobile.cs +++ b/Projects/UOContent/Mobiles/PlayerMobile.cs @@ -2839,48 +2839,44 @@ namespace Server.Mobiles public override void Damage(int amount, Mobile from = null, bool informMount = true) { - if (EvilOmenSpell.EndEffect(this)) + var damageBonus = 1.0; + + if (EvilOmenSpell.EndEffect(this) && !PainSpikeSpell.UnderEffect(this)) { - amount = (int)(amount * 1.25); + damageBonus += 0.25; } - /* Per EA's UO Herald Pub48 (ML): - * ((resist spellsx10)/20 + 10=percentage of damage resisted) - */ + var hasBloodOath = false; - if (from != null && BloodOathSpell.GetBloodOath(from) == this) + if (from != null) { - amount = (int)(amount * 1.1); - - if (amount > 35 && from is PlayerMobile) /* capped @ 35, seems no expansion */ + if (Talisman is BaseTalisman talisman && + talisman.Protection?.Type?.IsInstanceOfType(from) == true) { - amount = 35; + damageBonus -= talisman.Protection.Amount / 100.0; } - if (Core.ML) + // Is the attacker attacking the blood oath caster? + if (BloodOathSpell.GetBloodOath(from) == this) { - from.Damage((int)(amount * (1 - (from.Skills.MagicResist.Value * .5 + 10) / 100)), this); - } - else - { - from.Damage(amount, this); + hasBloodOath = true; + damageBonus += 0.2; } } - if (from != null && Talisman is BaseTalisman talisman) + base.Damage((int)(amount * damageBonus), from, informMount); + + // If the blood oath caster will die then damage is not reflected back to the attacker + if (hasBloodOath && Alive && !Deleted && !IsDeadBondedPet) { - if (talisman.Protection != null && talisman.Protection.Type != null) - { - var type = talisman.Protection.Type; + // In some expansions resisting spells reduces reflect dmg from monster blood oath + var resistReflectedDamage = !from.Player && Core.ML && !Core.HS + ? (from.Skills.MagicResist.Value * 0.5 + 10) / 100 + : 0; - if (type.IsInstanceOfType(from)) - { - amount = (int)(amount * (1 - (double)talisman.Protection.Amount / 100)); - } - } + // Reflect damage to the attacker + from.Damage((int)(amount * (1.0 - resistReflectedDamage)), this); } - - base.Damage(amount, from, informMount); } public override bool IsHarmfulCriminal(Mobile target) diff --git a/Projects/UOContent/Spells/Base/SpellHelper.cs b/Projects/UOContent/Spells/Base/SpellHelper.cs index 627ab1616..1acb95a58 100644 --- a/Projects/UOContent/Spells/Base/SpellHelper.cs +++ b/Projects/UOContent/Spells/Base/SpellHelper.cs @@ -62,7 +62,7 @@ namespace Server.Spells public static class SpellHelper { - private static readonly TimeSpan AosDamageDelay = TimeSpan.FromSeconds(1.0); + private static readonly TimeSpan AosDamageDelay = TimeSpan.FromSeconds(1.25); private static readonly TimeSpan OldDamageDelay = TimeSpan.FromSeconds(0.5); private static readonly TimeSpan CombatHeatDelay = TimeSpan.FromSeconds(30.0); @@ -1014,11 +1014,6 @@ namespace Server.Spells var damageGiven = AOS.Damage(target, from, dmg, phys, fire, cold, pois, nrgy, chaos); - if (from != null) // sanity check - { - DoLeech(damageGiven, from, target); - } - WeightOverloading.DFA = DFAlgorithm.Standard; } else @@ -1049,23 +1044,14 @@ namespace Server.Spells if (context.Type == typeof(WraithFormSpell)) { - var wraithLeech = - 5 + (int)(15 * from.Skills.SpiritSpeak.Value / 100); // Wraith form gives 5-20% mana leech - var manaLeech = AOS.Scale(damageGiven, wraithLeech); - - if (manaLeech != 0) - { - from.Mana += manaLeech; - from.PlaySound(0x44D); - } + WraithFormSpell.DoWraithLeech(from, target, damageGiven); } else if (context.Type == typeof(VampiricEmbraceSpell)) { - from.Hits += AOS.Scale(damageGiven, 20); + from.Hits += Math.Min(target.Hits, AOS.Scale(damageGiven, 20)); from.PlaySound(0x44D); } } - public static void Heal(int amount, Mobile target, Mobile from, bool message = true) { // TODO: All Healing *spells* go through ArcaneEmpowerment @@ -1159,11 +1145,6 @@ namespace Server.Spells var damageGiven = AOS.Damage(m_Target, m_From, m_Damage, m_Phys, m_Fire, m_Cold, m_Pois, m_Nrgy, m_Chaos); - if (m_From != null) // sanity check - { - DoLeech(damageGiven, m_From, m_Target); - } - WeightOverloading.DFA = DFAlgorithm.Standard; if (bcTarg != null && m_From != null) diff --git a/Projects/UOContent/Spells/Fifth/Paralyze.cs b/Projects/UOContent/Spells/Fifth/Paralyze.cs index fcc12f643..01c703fd8 100644 --- a/Projects/UOContent/Spells/Fifth/Paralyze.cs +++ b/Projects/UOContent/Spells/Fifth/Paralyze.cs @@ -41,7 +41,7 @@ namespace Server.Spells.Fifth { var secs = (int)(GetDamageSkill(Caster) / 10 - GetResistSkill(m) / 10); - if (!Core.SE) + if (!Core.AOS) { secs += 2; } diff --git a/Projects/UOContent/Spells/Necromancy/EvilOmen.cs b/Projects/UOContent/Spells/Necromancy/EvilOmen.cs index bc90da8e6..44e77800f 100644 --- a/Projects/UOContent/Spells/Necromancy/EvilOmen.cs +++ b/Projects/UOContent/Spells/Necromancy/EvilOmen.cs @@ -53,13 +53,8 @@ namespace Server.Spells.Necromancy if (!_table.ContainsKey(m)) { - var mod = new DefaultSkillMod(SkillName.MagicResist, false, 50.0); - - if (m.Skills.MagicResist.Base > 50.0) - { - m.AddSkillMod(mod); - } - + var mod = new DefaultSkillMod(SkillName.MagicResist, false, m.Skills.MagicResist.Value / 2); + m.AddSkillMod(mod); _table[m] = mod; } diff --git a/Projects/UOContent/Spells/Necromancy/PainSpike.cs b/Projects/UOContent/Spells/Necromancy/PainSpike.cs index bda27ea19..9a73e91c3 100644 --- a/Projects/UOContent/Spells/Necromancy/PainSpike.cs +++ b/Projects/UOContent/Spells/Necromancy/PainSpike.cs @@ -29,6 +29,8 @@ namespace Server.Spells.Necromancy public override bool DelayedDamage => false; + public static bool UnderEffect(Mobile m) => _table.ContainsKey(m); + public void Target(Mobile m) { if (m == null) diff --git a/Projects/UOContent/Spells/Necromancy/Strangle.cs b/Projects/UOContent/Spells/Necromancy/Strangle.cs index 129f4a5f1..39c012493 100644 --- a/Projects/UOContent/Spells/Necromancy/Strangle.cs +++ b/Projects/UOContent/Spells/Necromancy/Strangle.cs @@ -81,7 +81,7 @@ namespace Server.Spells.Necromancy var hitDelay = 5; var length = hitDelay; - while (count > 1) + while (count >= 1) { --count; if (hitDelay > 1) @@ -149,7 +149,7 @@ namespace Server.Spells.Necromancy _hitDelay = 5; _nextHit = Core.Now + TimeSpan.FromSeconds(_hitDelay); - _maxCount = _count = Math.Min(4, (int)spiritLevel); + _maxCount = _count = Math.Max(4, (int)spiritLevel); } protected override void OnTick() diff --git a/Projects/UOContent/Spells/Necromancy/WraithForm.cs b/Projects/UOContent/Spells/Necromancy/WraithForm.cs index 3d7e3ebb3..dbdc0a6e5 100644 --- a/Projects/UOContent/Spells/Necromancy/WraithForm.cs +++ b/Projects/UOContent/Spells/Necromancy/WraithForm.cs @@ -32,6 +32,19 @@ namespace Server.Spells.Necromancy public override int PoisResistOffset => 0; public override int NrgyResistOffset => -5; + public static void DoWraithLeech(Mobile wraith, Mobile defender, int damageGiven) + { + var wraithLeech = 5 + (int)(15 * wraith.Skills.SpiritSpeak.Value / 100); // Wraith form gives 5-20% mana leech + var manaLeech = Math.Min(defender.Mana, AOS.Scale(damageGiven, wraithLeech)); + + if (manaLeech != 0) + { + wraith.Mana += manaLeech; + defender.Mana -= manaLeech; + wraith.PlaySound(0x44D); + } + } + public override void DoEffect(Mobile m) { if (m is PlayerMobile mobile)