ModernUO/Projects/UOContent/Spells/Mysticism/MysticSpell.cs
Kamron Batman a552cf4138
fix: Fixes various memory leaks and spells (#1786)
### Summary
- Fixes various memory leaks related to spells
- Fixes Spell Plague
- Added ability to determine if `sdi` should take effect for Spell Damage.
- Fixes animal form timer ticking non-stop while logged out.
2024-05-21 19:44:42 -07:00

139 lines
No EOL
3.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using Server.Items;
namespace Server.Spells.Mysticism;
public abstract class MysticSpell : Spell
{
private static int[] _manaTable = { 4, 6, 9, 11, 14, 20, 40, 50 };
private static double[] _requiredSkill = { 0.0, 8.0, 20.0, 33.0, 45.0, 58.0, 70.0, 83.0 };
public MysticSpell(Mobile caster, Item scroll, SpellInfo info) : base(caster, scroll, info)
{
}
public abstract SpellCircle Circle { get; }
public override TimeSpan CastDelayBase => TimeSpan.FromSeconds(0.5 + 0.25 * (int)Circle);
public virtual double RequiredSkill
{
get
{
var circle = (int)Circle;
if (Scroll != null)
{
circle -= 2;
}
return _requiredSkill[circle];
}
}
public override SkillName CastSkill => SkillName.Mysticism;
/*
* As per OSI Publish 64:
* Imbuing is not the only skill associated with Mysticism now.
* Players can use EITHER their Focus skill or Imbuing skill.
* Evaluate Intelligence no longer has any effect on a Mystics spell power.
*/
public override double GetDamageSkill(Mobile m) => Math.Max(m.Skills.Imbuing.Value, m.Skills.Focus.Value);
public override int GetDamageFixed(Mobile m) => Math.Max(m.Skills.Imbuing.Fixed, m.Skills.Focus.Fixed);
public override void GetCastSkills(out double min, out double max)
{
var requiredSkill = RequiredSkill;
// As per Mysticism page at the UO Herald Playguide
// This means that we have 25% success chance at min Required Skill
min = requiredSkill - 12.5;
max = requiredSkill + 37.5;
}
public override int GetMana() => Scroll is BaseWand ? 0 : _manaTable[(int)Circle];
public override bool CheckCast()
{
if (!base.CheckCast())
{
return false;
}
var mana = ScaleMana(GetMana());
if (Caster.Mana < mana)
{
// You must have at least ~1_MANA_REQUIREMENT~ Mana to use this ability.
Caster.SendLocalizedMessage(1060174, mana.ToString());
return false;
}
var requiredSkill = RequiredSkill;
if (Caster.Skills[CastSkill].Value < requiredSkill)
{
// You need at least ~1_SKILL_REQUIREMENT~ ~2_SKILL_NAME~ skill to use that ability.
Caster.SendLocalizedMessage(1063013, $"{requiredSkill:F1}\t{CastSkill}\t ");
return false;
}
return true;
}
public override void OnBeginCast()
{
base.OnBeginCast();
SendCastEffect();
}
public virtual void SendCastEffect()
{
Caster.FixedEffect(0x37C4, 10, (int)(GetCastDelay().TotalSeconds * 28), 0x66C, 3);
}
public static double GetBaseSkill(Mobile m) => m.Skills.Mysticism.Value;
public virtual bool CheckResisted(Mobile target)
{
var n = GetResistPercent(target);
n /= 100.0;
if (n <= 0.0)
{
return false;
}
if (n >= 1.0)
{
return true;
}
var maxSkill = (1 + (int)Circle) * 10;
maxSkill += (1 + (int)Circle / 6) * 25;
if (target.Skills.MagicResist.Value < maxSkill)
{
target.CheckSkill(SkillName.MagicResist, 0.0, target.Skills.MagicResist.Cap);
}
return n >= Utility.RandomDouble();
}
public virtual double GetResistPercentForCircle(Mobile target, SpellCircle circle)
{
var magicResist = target.Skills.MagicResist.Value;
var firstPercent = magicResist / 5.0;
var secondPercent = magicResist -
((Caster.Skills[CastSkill].Value - 20.0) / 5.0 + (1 + (int)circle) * 5.0);
// Seems should be about half of what stratics says.
return (firstPercent > secondPercent ? firstPercent : secondPercent) / 2.0;
}
public virtual double GetResistPercent(Mobile target) => GetResistPercentForCircle(target, Circle);
}