254 lines
7.8 KiB
C#
254 lines
7.8 KiB
C#
using System;
|
|
using Server.Mobiles;
|
|
using Server.Targeting;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Server.Spells.Mysticism
|
|
{
|
|
public class SpellPlagueSpell : MysticSpell
|
|
{
|
|
private static SpellInfo m_Info = new SpellInfo(
|
|
"Spell Plague", "Vas Rel Jux Ort",
|
|
230,
|
|
9022,
|
|
Reagent.DaemonBone,
|
|
Reagent.DragonBlood,
|
|
Reagent.Nightshade,
|
|
Reagent.SulfurousAsh
|
|
);
|
|
|
|
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
|
|
|
|
public SpellPlagueSpell(Mobile caster, Item scroll)
|
|
: base(caster, scroll, m_Info)
|
|
{
|
|
}
|
|
|
|
public override void OnCast()
|
|
{
|
|
Caster.Target = new InternalTarget(this);
|
|
}
|
|
|
|
public void OnTarget(object o)
|
|
{
|
|
Mobile m = o as Mobile;
|
|
|
|
if (m == null)
|
|
return;
|
|
|
|
if (!(m is PlayerMobile || m is BaseCreature))
|
|
{
|
|
Caster.SendLocalizedMessage(1080194); // Your target cannot be affected by spell plague.
|
|
}
|
|
else if (CheckResisted(m))
|
|
{
|
|
m.SendLocalizedMessage(1080199); //You resist spell plague.
|
|
Caster.SendLocalizedMessage(1080200); //Your target resists spell plague.
|
|
}
|
|
else if (CheckHSequence(m))
|
|
{
|
|
SpellHelper.CheckReflect((int)Circle, Caster, ref m);
|
|
|
|
SpellHelper.Turn(Caster, m);
|
|
|
|
Caster.PlaySound(0x658);
|
|
|
|
m.FixedParticles(0x375A, 1, 17, 9919, 1161, 7, EffectLayer.Waist);
|
|
m.FixedParticles(0x3728, 1, 13, 9502, 1161, 7, (EffectLayer)255);
|
|
|
|
if (!m_Table.ContainsKey(m) || m_Table[m] == null)
|
|
m_Table.Add(m, new List<SpellPlagueTimer>());
|
|
|
|
m_Table[m].Add(new SpellPlagueTimer(Caster, m, TimeSpan.FromSeconds(8)));
|
|
|
|
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.SpellPlague, 1031690, 1080167, TimeSpan.FromSeconds(8), m));
|
|
|
|
DoExplosion(m, Caster, true, 1);
|
|
}
|
|
|
|
FinishSequence();
|
|
}
|
|
|
|
private static Dictionary<Mobile, List<SpellPlagueTimer>> m_Table = new Dictionary<Mobile, List<SpellPlagueTimer>>();
|
|
|
|
public static bool HasSpellPlague(Mobile from)
|
|
{
|
|
foreach (KeyValuePair<Mobile, List<SpellPlagueTimer>> kvp in m_Table)
|
|
{
|
|
if (kvp.Value != null)
|
|
{
|
|
foreach (SpellPlagueTimer timer in kvp.Value)
|
|
{
|
|
if (timer.Caster == from)
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static void OnMobileDamaged(Mobile from)
|
|
{
|
|
if (m_Table.ContainsKey(from) && m_Table[from].Count > 0 && m_Table[from][0].NextUse < DateTime.UtcNow)
|
|
{
|
|
int amount = m_Table[from][0].Amount;
|
|
bool doExplosion = false;
|
|
double mod = from.Skills[SkillName.MagicResist].Value >= 70.0 ? (from.Skills[SkillName.MagicResist].Value / 1000 * 3) : 0.0;
|
|
|
|
if (mod < 0)
|
|
mod = .01;
|
|
|
|
if (amount == 0 && .90 - mod > Utility.RandomDouble())
|
|
doExplosion = true;
|
|
else if (amount == 1 && .60 - mod > Utility.RandomDouble())
|
|
doExplosion = true;
|
|
else if (amount == 2 && .30 - mod > Utility.RandomDouble())
|
|
doExplosion = true;
|
|
|
|
if (doExplosion)
|
|
{
|
|
SpellPlagueTimer timer = m_Table[from][0];
|
|
|
|
timer.NextUse = DateTime.UtcNow + TimeSpan.FromSeconds(1.5);
|
|
|
|
DoExplosion(from, timer.Caster, false, amount);
|
|
timer.Amount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void DoExplosion(Mobile from, Mobile caster, bool initial, int amount)
|
|
{
|
|
double prim = caster.Skills[SkillName.Mysticism].Value;
|
|
double sec = caster.Skills[SkillName.Imbuing].Value;
|
|
|
|
if (caster.Skills[SkillName.Focus].Value > sec)
|
|
sec = caster.Skills[SkillName.Focus].Value;
|
|
|
|
int damage = (int)((prim + sec) / 12) + Utility.RandomMinMax(1, 6);
|
|
|
|
if (amount > 1)
|
|
damage /= amount;
|
|
|
|
from.PlaySound(0x658);
|
|
|
|
from.FixedParticles(0x375A, 1, 17, 9919, 1161, 7, EffectLayer.Waist);
|
|
from.FixedParticles(0x3728, 1, 13, 9502, 1161, 7, (EffectLayer)255);
|
|
|
|
int sdiBonus = SpellHelper.GetSpellDamageBonus(caster, from, SkillName.Mysticism, from is PlayerMobile);
|
|
|
|
damage *= (100 + sdiBonus);
|
|
damage /= 100;
|
|
|
|
SpellHelper.Damage(null, TimeSpan.Zero, from, caster, damage, 0, 0, 0, 0, 0, DFAlgorithm.Standard, 100, 0);
|
|
}
|
|
|
|
public static void RemoveFromList(Mobile from)
|
|
{
|
|
if (m_Table.ContainsKey(from) && m_Table[from].Count > 0)
|
|
{
|
|
Mobile caster = m_Table[from][0].Caster;
|
|
|
|
m_Table[from].Remove(m_Table[from][0]);
|
|
|
|
if (m_Table[from].Count == 0)
|
|
{
|
|
m_Table.Remove(from);
|
|
BuffInfo.RemoveBuff(from, BuffIcon.SpellPlague);
|
|
}
|
|
|
|
foreach (KeyValuePair<Mobile, List<SpellPlagueTimer>> kvp in m_Table)
|
|
{
|
|
foreach (SpellPlagueTimer Ttimer in kvp.Value)
|
|
{
|
|
if (Ttimer.Caster == caster)
|
|
return;
|
|
}
|
|
}
|
|
|
|
BuffInfo.RemoveBuff(caster, BuffIcon.SpellPlague);
|
|
}
|
|
}
|
|
|
|
public class InternalTarget : Target
|
|
{
|
|
public SpellPlagueSpell Owner { get; set; }
|
|
|
|
public InternalTarget(SpellPlagueSpell owner)
|
|
: this(owner, false)
|
|
{
|
|
}
|
|
|
|
public InternalTarget(SpellPlagueSpell owner, bool allowland)
|
|
: base(12, allowland, TargetFlags.Harmful)
|
|
{
|
|
Owner = owner;
|
|
}
|
|
|
|
protected override void OnTarget(Mobile from, object o)
|
|
{
|
|
if (o == null)
|
|
return;
|
|
|
|
if (!from.CanSee(o))
|
|
from.SendLocalizedMessage(500237); // Target can not be seen.
|
|
else
|
|
{
|
|
SpellHelper.Turn(from, o);
|
|
Owner.OnTarget(o);
|
|
}
|
|
}
|
|
|
|
protected override void OnTargetFinish(Mobile from)
|
|
{
|
|
Owner.FinishSequence();
|
|
}
|
|
}
|
|
}
|
|
|
|
public class SpellPlagueTimer : Timer
|
|
{
|
|
private Mobile m_Caster;
|
|
private Mobile m_Owner;
|
|
private int m_Amount;
|
|
private DateTime m_NextUse;
|
|
|
|
public Mobile Caster { get { return m_Caster; } }
|
|
public int Amount
|
|
{
|
|
get { return m_Amount; }
|
|
set
|
|
{
|
|
m_Amount = value;
|
|
|
|
if (m_Amount >= 3)
|
|
EndTimer();
|
|
}
|
|
}
|
|
|
|
public DateTime NextUse { get { return m_NextUse; } set { m_NextUse = value; } }
|
|
|
|
public SpellPlagueTimer(Mobile caster, Mobile owner, TimeSpan duration)
|
|
: base(duration)
|
|
{
|
|
m_Caster = caster;
|
|
m_Owner = owner;
|
|
m_Amount = 0;
|
|
m_NextUse = DateTime.UtcNow;
|
|
this.Start();
|
|
}
|
|
|
|
protected override void OnTick()
|
|
{
|
|
EndTimer();
|
|
}
|
|
|
|
private void EndTimer()
|
|
{
|
|
this.Stop();
|
|
SpellPlagueSpell.RemoveFromList(m_Owner);
|
|
}
|
|
}
|
|
}
|