fix: Blood Oath, Wraith form, & Strangle (#1153)

Fixes blood oath mechanic, and wraith form not properly leeching.
This commit is contained in:
mark1145 2022-09-02 02:19:40 +10:00 • committed by GitHub
parent c5d2a58917
commit 1e50ff9966
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 52 additions and 78 deletions

View file

@ -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);

View file

@ -214,6 +214,11 @@ namespace Server
return 0;
}
if (from != null) // sanity check
{
SpellHelper.DoLeech(totalDamage, from, m);
}
m.Damage(totalDamage, from);
return totalDamage;
}

View file

@ -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;

View file

@ -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)

View file

@ -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)

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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)

View file

@ -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()

View file

@ -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)