using System; using System.Collections; using Server.Network; using Server.Items; using Server.Targeting; namespace Server.Spells.Necromancy { public class PainSpikeSpell : NecromancerSpell { private static SpellInfo m_Info = new SpellInfo( "Pain Spike", "In Sar", 203, 9031, Reagent.GraveDust, Reagent.PigIron ); public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 1.0 ); } } public override double RequiredSkill{ get{ return 20.0; } } public override int RequiredMana{ get{ return 5; } } public PainSpikeSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info ) { } public override void OnCast() { Caster.Target = new InternalTarget( this ); } public override bool DelayedDamage{ get{ return false; } } public void Target( Mobile m ) { if ( CheckHSequence( m ) ) { SpellHelper.Turn( Caster, m ); //SpellHelper.CheckReflect( (int)this.Circle, Caster, ref m ); //Irrelevent asfter AoS /* Temporarily causes intense physical pain to the target, dealing direct damage. * After 10 seconds the spell wears off, and if the target is still alive, * some of the Hit Points lost through Pain Spike are restored. */ m.FixedParticles( 0x37C4, 1, 8, 9916, 39, 3, EffectLayer.Head ); m.FixedParticles( 0x37C4, 1, 8, 9502, 39, 4, EffectLayer.Head ); m.PlaySound( 0x210 ); double damage = ((GetDamageSkill( Caster ) - GetResistSkill( m )) / 10) + (m.Player ? 18 : 30); m.CheckSkill( SkillName.MagicResist, 0.0, 120.0 ); //Skill check for gain if ( damage < 1 ) damage = 1; TimeSpan buffTime = TimeSpan.FromSeconds( 10.0 ); if( m_Table.Contains( m ) ) { damage = Utility.RandomMinMax( 3, 7 ); Timer t = m_Table[m] as Timer; if( t != null ) { t.Delay += TimeSpan.FromSeconds( 2.0 ); buffTime = t.Next - DateTime.Now; } } else { new InternalTimer( m, damage ).Start(); } BuffInfo.AddBuff( m, new BuffInfo( BuffIcon.PainSpike, 1075667, buffTime, m, Convert.ToString( (int)damage ) ) ); Misc.WeightOverloading.DFA = Misc.DFAlgorithm.PainSpike; m.Damage( (int) damage, Caster ); SpellHelper.DoLeech( (int)damage, Caster, m ); Misc.WeightOverloading.DFA = Misc.DFAlgorithm.Standard; //SpellHelper.Damage( this, m, damage, 100, 0, 0, 0, 0, Misc.DFAlgorithm.PainSpike ); } FinishSequence(); } private static Hashtable m_Table = new Hashtable(); private class InternalTimer : Timer { private Mobile m_Mobile; private int m_ToRestore; public InternalTimer( Mobile m, double toRestore ) : base( TimeSpan.FromSeconds( 10.0 ) ) { Priority = TimerPriority.OneSecond; m_Mobile = m; m_ToRestore = (int)toRestore; m_Table[m] = this; } protected override void OnTick() { m_Table.Remove( m_Mobile ); if ( m_Mobile.Alive && !m_Mobile.IsDeadBondedPet ) m_Mobile.Hits += m_ToRestore; BuffInfo.RemoveBuff( m_Mobile, BuffIcon.PainSpike ); } } private class InternalTarget : Target { private PainSpikeSpell m_Owner; public InternalTarget( PainSpikeSpell owner ) : base( Core.ML ? 10 : 12, false, TargetFlags.Harmful ) { m_Owner = owner; } protected override void OnTarget( Mobile from, object o ) { if ( o is Mobile ) m_Owner.Target( (Mobile) o ); } protected override void OnTargetFinish( Mobile from ) { m_Owner.FinishSequence(); } } } }