context: using System;
  using Server;
  using System.Collections.Generic;
  using System.Linq;
  using Server.Items;
  using Server.Network;
  
  namespace Server.Mobiles
  {
  	public abstract class SpecialAbility
  	{
  		public virtual int ManaCost { get { return 10;  } }
  		public virtual int MaxRange { get { return 1; } }
  		public virtual double TriggerChance { get { return 0.1; } }
          public virtual bool RequiresCombatant { get { return true; } }
  		public virtual TimeSpan CooldownDuration { get { return TimeSpan.FromSeconds(30); } }
  
          public virtual MagicalAbility RequiredSchool { get { return MagicalAbility.None; } }
          public virtual bool NaturalAbility { get { return false; } }
  
  		public virtual bool TriggerOnGotMeleeDamage { get { return false; } }
  		public virtual bool TriggerOnDoMeleeDamage { get { return false; } }
  		public virtual bool TriggerOnGotSpellDamage { get { return false; } }
  		public virtual bool TriggerOnDoSpellDamage { get { return false; } }
  		public virtual bool TriggerOnThink { get { return false; } }
          public virtual bool TriggerOnApproach { get { return false; } }
  
          public abstract void DoEffects(BaseCreature creature, Mobile defender, ref int damage);
  		
  		public SpecialAbility()
  		{
  		}
  
          public static void CheckCombatTrigger(Mobile attacker, Mobile defender, ref int damage, DamageType type)
          {
              if(defender == null)
                  return;
              
              if (attacker is BaseCreature && !((BaseCreature)attacker).Summoned)
              {
                  var bc = attacker as BaseCreature;
                  var profile = PetTrainingHelper.GetAbilityProfile(bc);
  
                  if (profile != null)
                  {
                      SpecialAbility ability = null;
  
                      var abilties = profile.EnumerateSpecialAbilities().Where(m =>
                          (type == DamageType.Melee && m.TriggerOnDoMeleeDamage) || (type >= DamageType.Spell && m.TriggerOnDoSpellDamage) &&
                          !m.IsInCooldown(attacker)).ToArray();
  
                      if (abilties != null && abilties.Length > 0)
                      {
                          ability = abilties[Utility.Random(abilties.Length)];
                      }
  
                      if (ability != null)
                      {
                         ability.Trigger(bc, defender, ref damage);
                      }
                  }
              }
  
              if (defender is BaseCreature && !((BaseCreature)defender).Summoned)
              {
                  var bc = defender as BaseCreature;
                  var profile = PetTrainingHelper.GetAbilityProfile(bc);
  
                  if (profile != null)
                  {
                      SpecialAbility ability = null;
  
                      var abilties = profile.EnumerateSpecialAbilities().Where(m =>
                          (type == DamageType.Melee && m.TriggerOnGotMeleeDamage) || (type >= DamageType.Spell && m.TriggerOnGotSpellDamage) &&
                          !m.IsInCooldown(defender)).ToArray();
  
                      if (abilties != null && abilties.Length > 0)
                      {
                          ability = abilties[Utility.Random(abilties.Length)];
                      }
  
                      if (ability != null)
                      {
                          ability.Trigger(bc, attacker, ref damage);
                      }
                  }
              }
          }
  		
  		public static bool CheckThinkTrigger(BaseCreature bc)
  		{
  			var combatant = bc.Combatant;
              var profile = PetTrainingHelper.GetAbilityProfile(bc);
  
              if (combatant is Mobile)
              {
                  if (profile != null)
                  {
                      SpecialAbility ability = null;
  
                      var abilties = profile.EnumerateSpecialAbilities().Where(m => m.TriggerOnThink && !m.IsInCooldown(bc)).ToArray();
  
                      if (abilties != null && abilties.Length > 0)
                      {
                          ability = abilties[Utility.Random(abilties.Length)];
                      }
  
                      if (ability != null)
                      {
                          int d = 0;
                          ability.Trigger(bc, (Mobile)combatant, ref d);
                      }
                  }
              }
              else
              {
                  SpecialAbility ability = null;
  
                  var abilties =
                      profile.EnumerateSpecialAbilities().Where(
                          m =>
                          m.TriggerOnThink &&
                          !m.IsInCooldown(bc) &&
                          !m.RequiresCombatant).ToArray();
  
                  if (abilties != null && abilties.Length > 0)
                  {
                      ability = abilties[Utility.Random(abilties.Length)];
                  }
  
                  if (ability != null)
                  {
                      int d = 0;
                      return ability.Trigger(bc, bc, ref d);
                  }
              }
  
              return false;
  		}
  
          public static bool CheckApproachTrigger(BaseCreature bc, Mobile mobile, Point3D oldLocation)
          {
              var profile = PetTrainingHelper.GetAbilityProfile(bc);
  
              if (profile != null)
              {
                  SpecialAbility ability = null;
  
                  var abilties = profile.EnumerateSpecialAbilities().Where(m =>
                      m.TriggerOnApproach &&
                      bc.InRange(mobile.Location, m.MaxRange) &&
                      !bc.InRange(oldLocation, m.MaxRange) &&
                      !m.IsInCooldown(bc)).ToArray();
  
                  if (abilties != null && abilties.Length > 0)
                  {
                      ability = abilties[Utility.Random(abilties.Length)];
                  }
  
                  if (ability != null)
                  {
                      int d = 0;
                      return ability.Trigger(bc, mobile, ref d);
                  }
              }
  
              return false;
          }
  		
  		public virtual bool Trigger(BaseCreature creature, Mobile defender, ref int damage)
  		{
              if (CheckMana(creature) && Validate(creature, defender) && TriggerChance >= Utility.RandomDouble())
  			{
                  creature.Mana -= ManaCost;
  
  				DoEffects(creature, defender, ref damage);
                  AddToCooldown(creature);
  
                  return true;
  			}
  
              return false;
  		}
  		
  		public virtual bool Validate(BaseCreature attacker, Mobile defender)
  		{
              if (RequiredSchool != MagicalAbility.None)
              {
                  var profile = PetTrainingHelper.GetAbilityProfile(attacker);
  
                  if (profile == null || !profile.HasAbility(RequiredSchool))
                  {
                      return false;
                  }
              }
  
  			return defender != null && defender.Alive && !defender.Deleted && !defender.IsDeadBondedPet &&
  					attacker.Alive && !attacker.IsDeadBondedPet && defender.InRange(attacker.Location, MaxRange) && 
  					defender.Map == attacker.Map && attacker.InLOS(defender) && !attacker.BardPacified && attacker.CanBeHarmful(defender);
  		}
  		
  		public bool CheckMana(Mobile m)
  		{
  			return m.Mana >= ManaCost;
  		}
  		
  		protected List<Mobile> _Cooldown;
  		
  		public bool IsInCooldown(Mobile m)
  		{
  			return _Cooldown != null && _Cooldown.Contains(m);
  		}
  		
  		public virtual void AddToCooldown(BaseCreature m)
  		{
  			if(CooldownDuration != TimeSpan.MinValue)
  			{
                  if (_Cooldown == null)
                      _Cooldown = new List<Mobile>();
  
  				_Cooldown.Add(m);
  				Timer.DelayCall<Mobile>(CooldownDuration, RemoveFromCooldown, m);
  			}
  		}
  		
  		public void RemoveFromCooldown(Mobile m)
  		{
  			_Cooldown.Remove(m);
  		}
  
          public static SpecialAbility[] Abilities { get { return _Abilities; } }
          private static SpecialAbility[] _Abilities;
  
          static SpecialAbility()
          {
              _Abilities = new SpecialAbility[29];
  
              _Abilities[0] = new AngryFire();
              _Abilities[1] = new ConductiveBlast();
              _Abilities[2] = new DragonBreath();
              _Abilities[3] = new GraspingClaw();
              _Abilities[4] = new Inferno();
              _Abilities[5] = new LightningForce();
              _Abilities[6] = new ManaDrain();
              _Abilities[7] = new RagingBreath();
              _Abilities[8] = new Repel();
              _Abilities[9] = new SearingWounds();
              _Abilities[10] = new StealLife();
              _Abilities[11] = new VenomousBite();
              _Abilities[12] = new ViciousBite();
              _Abilities[13] = new RuneCorruption();
              _Abilities[14] = new LifeLeech();
              _Abilities[15] = new StickySkin();
              _Abilities[16] = new TailSwipe();
              _Abilities[17] = new FlurryForce();
              _Abilities[18] = new Rage();
  
              // Non-Trainable
              _Abilities[19] = new Heal();
              _Abilities[20] = new HowlOfCacophony();
              _Abilities[21] = new Webbing();
              _Abilities[22] = new Anemia();
              _Abilities[23] = new BloodDisease();
              _Abilities[24] = new PoisonSpit();
              _Abilities[25] = new TrueFear();
              _Abilities[26] = new ColossalBlow();
              _Abilities[27] = new LifeDrain();
              _Abilities[28] = new ColossalRage();
          }
  
  		public static SpecialAbility AngryFire
          {
              get
              {
                  return _Abilities[0];
              }
          }
  
  		public static SpecialAbility ConductiveBlast
          {
              get
              {
                  return _Abilities[1];
              }
          }
  
  		public static SpecialAbility DragonBreath
          {
              get
              {
                  return _Abilities[2];
              }
          }
  
  		public static SpecialAbility GraspingClaw
          {
              get
              {
                  return _Abilities[3];
              }
          }
  
  		public static SpecialAbility Inferno
          {
              get
              {
                  return _Abilities[4];
              }
          }
  
  		public static SpecialAbility LightningForce
          {
              get
              {
                  return _Abilities[5];
              }
          }
  
  		public static SpecialAbility ManaDrain
          {
              get
              {
                  return _Abilities[6];
              }
          }
  
          public static SpecialAbility RagingBreath
          {
              get
              {
                  return _Abilities[7];
              }
          }
  
  		public static SpecialAbility Repel
          {
              get
              {
                  return _Abilities[8];
              }
          }
  
  		public static SpecialAbility SearingWounds
          {
              get
              {
                  return _Abilities[9];
              }
          }
  
  		public static SpecialAbility StealLife
          {
              get
              {
                  return _Abilities[10];
              }
          }
  
          public static SpecialAbility RuneCorruption
          {
              get
              {
                  return _Abilities[13];
              }
          }
  
          public static SpecialAbility LifeLeech
          {
              get
              {
                  return _Abilities[14];
              }
          }
  
          public static SpecialAbility StickySkin
          {
              get
              {
                  return _Abilities[15];
              }
          }
  
          public static SpecialAbility TailSwipe
          {
              get
              {
                  return _Abilities[16];
              }
          }
  
          public static SpecialAbility VenomousBite
          {
              get
              {
                  return _Abilities[11];
              }
          }
  
          public static SpecialAbility ViciousBite
          {
              get
              {
                  return _Abilities[12];
              }
          }
  
          public static SpecialAbility FlurryForce
          {
              get
              {
                  return _Abilities[17];
              }
          }
  
          public static SpecialAbility Rage
          {
              get
              {
                  return _Abilities[18];
              }
          }
  
          public static SpecialAbility Heal
          {
              get
              {
                  return _Abilities[19];
              }
          }
  
          public static SpecialAbility HowlOfCacophony
          {
              get
              {
                  return _Abilities[20];
              }
          }
  
          public static SpecialAbility Webbing
          {
              get
              {
                  return _Abilities[21];
              }
          }
  
          public static SpecialAbility Anemia
          {
              get
              {
                  return _Abilities[22];
              }
          }
  
          public static SpecialAbility BloodDisease
          {
              get
              {
                  return _Abilities[23];
              }
          }
  
          public static SpecialAbility PoisonSpit
          {
              get
              {
                  return _Abilities[24];
              }
          }
  
          public static SpecialAbility TrueFear
          {
              get
              {
                  return _Abilities[25];
              }
          }
  
          public static SpecialAbility ColossalBlow
          {
              get
              {
                  return _Abilities[26];
              }
          }
  
          public static SpecialAbility LifeDrain
          {
              get
              {
                  return _Abilities[27];
              }
          }
  
          public static SpecialAbility ColossalRage
          {
              get
              {
                  return _Abilities[28];
              }
          }
      }
  	
  	public class AngryFire : SpecialAbility
  	{
          public override bool TriggerOnDoMeleeDamage { get { return true; } }
          public override int ManaCost { get { return 30; } }
  
  		public AngryFire()
  		{
  		}
  		
  		public override void DoEffects(BaseCreature creature, Mobile defender, ref int damage)
  		{
              int d = Utility.RandomMinMax(30, 40);
  
              AOS.Damage(defender, creature, d, 60, 20, 0, 0, 20);
  
              defender.FixedParticles(0x3709, 10, 30, 5052, EffectLayer.LeftFoot);
              defender.PlaySound(0x208);
  
              defender.SendLocalizedMessage(1070823); // The creature hits you with its Angry Fire.    
  		}
  	}
  	
  	public class ConductiveBlast : SpecialAbility
  	{
          public override bool TriggerOnDoMeleeDamage { get { return true; } }
          public override int ManaCost { get { return 30; } }
  
          private static Dictionary<Mobile, ExpireTimer> _Table;
  
  		public ConductiveBlast()
  		{
  		}
  		
  		public override void DoEffects(BaseCreature creature, Mobile defender, ref int damage)
  		{
              ExpireTimer timer = null;
  
              if(_Table == null)
              {
                  _Table = new Dictionary<Mobile, ExpireTimer>();
              }
              
              if(_Table.ContainsKey(defender))
              {
                  timer = _Table[defender];
              }
  
              if (timer != null)
              {
                  timer.DoExpire();
                  defender.SendLocalizedMessage(1070828); // The creature continues to hinder your energy resistance!
              }
              else
                  defender.SendLocalizedMessage(1070827); // The creature's attack has made you more susceptible to energy attacks!
  
              int effect = -(defender.EnergyResistance / 2);
  
              ResistanceMod mod = new ResistanceMod(ResistanceType.Energy, effect);
  
              defender.FixedEffect(0x37B9, 10, 5);
              defender.AddResistanceMod(mod);
  
              timer = new ExpireTimer(defender, mod, TimeSpan.FromSeconds(10.0));
              timer.Start();
              _Table[defender] = timer;
  		}
  
          public static void RemoveFromTable(Mobile m)
          {
              if(_Table != null && _Table.ContainsKey(m))
              {
                  _Table.Remove(m);
              }
          }
  
          private class ExpireTimer : Timer
          {
              private readonly Mobile m_Mobile;
              private readonly ResistanceMod m_Mod;
  
              public ExpireTimer(Mobile m, ResistanceMod mod, TimeSpan delay)
                  : base(delay)
              {
                  m_Mobile = m;
                  m_Mod = mod;
                  Priority = TimerPriority.TwoFiftyMS;
              }
  
              public void DoExpire()
              {
                  m_Mobile.RemoveResistanceMod(m_Mod);
                  Stop();
                  RemoveFromTable(m_Mobile);
              }
  
              protected override void OnTick()
              {
                  m_Mobile.SendLocalizedMessage(1070829); // Your resistance to energy attacks has returned.
                  DoExpire();
              }
          }
  	}
  
      public class FlurryForce : SpecialAbility
      {
          public override bool TriggerOnDoMeleeDamage { get { return true; } }
          public override bool NaturalAbility { get { return true; } }
          public override int ManaCost { get { return 0; } }
  
          private static Dictionary<Mobile, ExpireTimer> _Table;
  
  		public FlurryForce()
  		{
  		}
  		
  		public override void DoEffects(BaseCreature creature, Mobile defender, ref int damage)
  		{
              ExpireTimer timer = null;
  
              if(_Table == null)
              {
                  _Table = new Dictionary<Mobile, ExpireTimer>();
              }
              
              if(_Table.ContainsKey(defender))
              {
                  timer = _Table[defender];
              }
  
              if (timer != null)
              {
                  timer.DoExpire();
                  defender.SendLocalizedMessage(1070851); // The creature lands another blow in your weakened state.
              }
              else
                  defender.SendLocalizedMessage(1070850); // The creature's flurry of twigs has made you more susceptible to physical attacks!
  
              int effect = -(defender.PhysicalResistance * 15 / 100);
  
              ResistanceMod mod = new ResistanceMod(ResistanceType.Physical, effect);
  
              defender.FixedEffect(0x37B9, 10, 5);
              defender.AddResistanceMod(mod);
  
              timer = new ExpireTimer(defender, mod, TimeSpan.FromSeconds(10.0));
              timer.Start();
              _Table[defender] = timer;
  		}
  
          public static void RemoveFromTable(Mobile m)
          {
              if(_Table != null && _Table.ContainsKey(m))
              {
                  _Table.Remove(m);
              }
          }
  
          private class ExpireTimer : Timer
          {
              private readonly Mobile m_Mobile;
              private readonly ResistanceMod m_Mod;
  
              public ExpireTimer(Mobile m, ResistanceMod mod, TimeSpan delay)
                  : base(delay)
              {
                  m_Mobile = m;
                  m_Mod = mod;
                  Priority = TimerPriority.TwoFiftyMS;
              }
  
              public void DoExpire()
              {
                  m_Mobile.RemoveResistanceMod(m_Mod);
                  Stop();
                  RemoveFromTable(m_Mobile);
              }
  
              protected override void OnTick()
              {
                  m_Mobile.SendLocalizedMessage(1070829); // Your resistance to energy attacks has returned.
                  DoExpire();
              }
          }
      }
  
      public class DragonBreath : SpecialAbility
      {
          public override int MaxRange { get { return 12; } }
          public override bool TriggerOnThink { get { return true; } }
          public override int ManaCost { get { return 30; } }
  
          public DragonBreath()
          {
          }
  
          public override void DoEffects(BaseCreature creature, Mobile defender, ref int damage)
          {
              DoBreath(creature, defender);
          }
  
          public override void AddToCooldown(BaseCreature m)
          {
              if (CooldownDuration != TimeSpan.MinValue)
              {
                  if (_Cooldown == null)
                      _Cooldown = new List<Mobile>();
  
                  var def = DragonBreathDefinition.GetDefinition(m);
  
                  _Cooldown.Add(m);
                  Timer.DelayCall<Mobile>(TimeSpan.FromSeconds(Utility.RandomMinMax(def.MinDelay, def.MaxDelay)), RemoveFromCooldown, m);
              }
          }
  
          public virtual void DoBreath(BaseCreature creature, Mobile target)
          {
              var def = DragonBreathDefinition.GetDefinition(creature);
  
              creature.RevealingAction();
  
              if (creature.AIObject != null)
              {
                  creature.AIObject.NextMove = Core.TickCount + (int)(def.StallTime * 1000);
              }
  
              creature.PlaySound(creature.GetAngerSound());
  
              if (Core.SA)
              {
                  creature.Animate(AnimationType.Pillage, 0);
              }
              else
              {
                  creature.Animate(def.AngerAnimation, 5, 1, true, false, 0);
              }
  
              creature.Direction = creature.GetDirectionTo(target);
  
              if (def.AttacksMultipleTargets)
              {
                  var list = Server.Spells.SpellHelper.AcquireIndirectTargets(creature, target, creature.Map, 5).OfType<Mobile>().Where(m => m.InRange(creature.Location, MaxRange)).ToList();
  
                  for (int i = 0; i < 5; i++)
                  {
                      if (list.Count == 0)
                          break;
  
                      var m = i == 0 ? target : list[Utility.Random(list.Count)];
  
                      list.Remove(m);
                      Timer.DelayCall(TimeSpan.FromSeconds(def.EffectDelay), new TimerStateCallback<BaseCreature, Mobile, DragonBreathDefinition>(BreathEffect_Callback), creature, m, def);
                  }
  
                  ColUtility.Free(list);
              }
              else
              {
                  Timer.DelayCall(TimeSpan.FromSeconds(def.EffectDelay), new TimerStateCallback<BaseCreature, Mobile, DragonBreathDefinition>(BreathEffect_Callback), creature, target, def);
              }
          }
  
          public void BreathEffect_Callback(BaseCreature creature, Mobile target, DragonBreathDefinition def)
          {
              creature.RevealingAction();
  
              if (!target.Alive || !creature.CanBeHarmful(target))
              {
                  return;
              }
  
              creature.PlaySound(def.EffectSound);
  
              Effects.SendMovingEffect(
                  creature,
                  target,
                  def.EffectItemID,
                  def.EffectSpeed,
                  def.EffectDuration,
                  def.EffectFixedDir,
                  def.EffectExplodes,
                  def.EffectHue,
                  def.EffectRenderMode);
  
              Timer.DelayCall(TimeSpan.FromSeconds(def.DamageDelay), new TimerStateCallback<BaseCreature, Mobile, DragonBreathDefinition>(BreathDamage_Callback), creature, target, def);
          }
  
          public void BreathDamage_Callback(BaseCreature creature, Mobile target, DragonBreathDefinition def)
          {
              if (target is BaseCreature && ((BaseCreature)target).BreathImmune)
              {
                  return;
              }
  
              if (creature.CanBeHarmful(target))
              {
                  creature.DoHarmful(target);
                  BreathDealDamage(creature, target, def);
              }
          }
  
          public void BreathDealDamage(BaseCreature creature, Mobile target, DragonBreathDefinition def)
          {
              if (!Server.Spells.Bushido.Evasion.CheckSpellEvasion(target))
              {
                  AOS.Damage(
                      target,
                      creature,
                      BreathComputeDamage(creature, def),
                      def.GetElementalDamage(creature, ElementType.Physical),
                      def.GetElementalDamage(creature, ElementType.Fire),
                      def.GetElementalDamage(creature, ElementType.Cold),
                      def.GetElementalDamage(creature, ElementType.Poison),
                      def.GetElementalDamage(creature, ElementType.Energy),
                      def.GetElementalDamage(creature, ElementType.Chaos),
                      def.GetElementalDamage(creature, ElementType.Direct));
              }
          }
  
          public int BreathComputeDamage(BaseCreature creature, DragonBreathDefinition def)
          {
              int damage = (int)(creature.Hits * def.DamageScalar);
  
              if (creature.IsParagon)
              {
                  damage = (int)(damage / Paragon.HitsBuff);
              }
  
              if (damage > 200)
              {
                  damage = 200;
              }
  
              return damage;
          }
  
          public class DragonBreathDefinition
          {
              public Type[] Uses { get; private set; }
  
              // Base damage given is: CurrentHitPoints * BreathDamageScalar
              public double DamageScalar { get; private set; }
  
              // Creature stops moving for 1.0 seconds while breathing
              public double StallTime { get; private set; }
  
              // Effect is sent 1.3 seconds after BreathAngerSound and BreathAngerAnimation is played
              public double EffectDelay { get; private set; }
  
              // Damage is given 1.0 seconds after effect is sent
              public double DamageDelay { get; private set; }
  
              // Damage types
              public int PhysicalDamage { get; private set; }
              public int FireDamage { get; private set; }
              public int ColdDamage { get; private set; }
              public int PoisonDamage { get; private set; }
              public int EnergyDamage { get; private set; }
              public int ChaosDamage { get; private set; }
              public int DirectDamage { get; private set; }
  
              public double MinDelay { get; private set; }
              public double MaxDelay { get; private set; }
  
              // Effect details and sound
              public int EffectItemID { get; private set; }
              public int EffectSpeed { get; private set; }
              public int EffectDuration { get; private set; }
              public bool EffectExplodes { get; private set; }
              public bool EffectFixedDir { get; private set; }
              public int EffectHue { get; private set; }
              public int EffectRenderMode { get; private set; }
  
              public int EffectSound { get; private set; }
  
              // Anger sound/animations
              public int AngerAnimation { get; private set; }
  
              public bool AttacksMultipleTargets { get; private set; }
  
              public static List<DragonBreathDefinition> Definitions { get; private set; } = new List<DragonBreathDefinition>();
  
              public static void Initialize()
              {
                  Definitions.Add(new DragonBreathDefinition(
                      Core.AOS ? 0.16 : 0.05,
                      1.0,
                      1.3,
                      1.0,
                      0, 100, 0, 0, 0, 0, 0,
                      30.0, 45.0,
                      0x36D4,
                      5,
                      0,
                      false,
                      false,
                      0,
                      0,
                      0x227,
                      12));
  
                  // Skeletal Dragon / Renowned
                  Definitions.Add(new DragonBreathDefinition(
                      Core.AOS ? 0.16 : 0.05,
                      1.0,
                      1.3,
                      1.0,
                      0, 0, 100, 0, 0, 0, 0,
                      30.0, 45.0,
                      0x36D4,
                      5,
                      0,
                      false,
                      false,
                      0x480,
                      0,
                      0x227,
                      12,
                      false,
                      new Type[] { typeof(SkeletalDragonRenowned), typeof(SkeletalDragon) }));
  
                  // Leviathan
                  Definitions.Add(new DragonBreathDefinition(
                      0.05,
                      1.0,
                      1.3,
                      1.0,
                      70, 0, 30, 0, 0, 0, 0,
                      5.0, 7.5,
                      0x36D4,
                      5,
                      0,
                      false,
                      false,
                      0x1ED,
                      0,
                      0x227,
                      12,
                      false,
                      new Type[] { typeof(Leviathan) }));
  
                  // Red Death
                  Definitions.Add(new DragonBreathDefinition(
                      0.16,
                      1.0,
                      1.3,
                      1.0,
                      0, 0, 0, 0, 0, 100, 0,
                      5.0, 7.5,
                      0x36D4,
                      5,
                      0,
                      false,
                      false,
                      0x1ED,
                      0,
                      0x227,
                      12,
                      false,
                      new Type[] { typeof(RedDeath) }));
  
                  // Frost Dragon/Drake
                  Definitions.Add(new DragonBreathDefinition(
                      Core.AOS ? 0.16 : 0.05,
                      1.0,
                      1.3,
                      1.0,
                      0, 0, 100, 0, 0, 0, 0,
                      30.0, 45.0,
                      0x36D4,
                      5,
                      0,
                      false,
                      false,
                      1264,
                      0,
                      0x227,
                      12,
                      false,
                      new Type[] { typeof(FrostDragon), typeof(ColdDrake) }));
  
                  // Antlion
                  Definitions.Add(new DragonBreathDefinition(
                      Core.AOS ? 0.16 : 0.05,
                      1.0,
                      1.3,
                      1.0,
                      0, 0, 0, 100, 0, 0, 0,
                      30.0, 45.0,
                      0x36D4,
                      5,
                      0,
                      false,
                      false,
                      0x3F,
                      0,
                      0,
                      12,
                      false,
                      new Type[] { typeof(AntLion) }));
  
                  // Rend
                  Definitions.Add(new DragonBreathDefinition(
                      0.06,
                      1.0,
                      1.3,
                      1.0,
                      0, 100, 0, 0, 0, 0, 0,
                      30.0, 45.0,
                      0x36D4,
                      5,
                      0,
                      false,
                      false,
                      0,
                      0,
                      0x227,
                      12,
                      false,
                      new Type[] { typeof(Rend) }));
  
                  // Crystal Sea Serpent
                  Definitions.Add(new DragonBreathDefinition(
                     0.55,
                     1.0,
                     1.3,
                     1.0,
                     0, 0, 50, 0, 50, 0, 0,
                     30.0, 45.0,
                     0x36D4,
                     5,
                     0,
                     false,
                     false,
                     0x1ED,
                     0,
                     0x227,
                     12,
                     false,
                     new Type[] { typeof(CrystalSeaSerpent) }));
  
                  // Crystal Hydra
                  Definitions.Add(new DragonBreathDefinition(
                      0.13,
                      1.0,
                      1.3,
                      1.0,
                      0, 0, 100, 0, 0, 0, 0,
                      5.0, 7.0,
                      0x36D4,
                      5,
                      0,
                      false,
                      false,
                      0x47E,
                      0,
                      0x56D,
                      12,
                      true,
                      new Type[] { typeof(CrystalHydra) }));
              }
  
              public static DragonBreathDefinition GetDefinition(BaseCreature bc)
              {
                  var def = Definitions.FirstOrDefault(d => d.Uses != null && d.Uses.Any(type => type == bc.GetType()));
  
                  if (def == null)
                  {
                      return Definitions[0]; // default
                  }
  
                  return def;
              }
  
              public DragonBreathDefinition(
                  double scalar,
                  double stallTime,
                  double effectDelay,
                  double damageDelay,
                  int physDamage, int fireDamage, int coldDamage, int poisonDamage, int energyDamage, int chaosDamage, int directDamage,
                  double minDelay, double maxDelay,
                  int effectID,
                  int effectDuration,
                  int effectSpeed,
                  bool explodes,
                  bool fixedDirection,
                  int effectHue,
                  int renderMode,
                  int effectSound,
                  int angerAnimation,
                  bool attacksMultiples = false,
                  Type[] uses = null)
              {
                  DamageScalar = scalar;
                  StallTime = stallTime;
                  EffectDelay = effectDelay;
                  DamageDelay = damageDelay;
  
                  PhysicalDamage = physDamage;
                  FireDamage = fireDamage;
                  ColdDamage = coldDamage;
                  PoisonDamage = poisonDamage;
                  EnergyDamage = energyDamage;
                  ChaosDamage = chaosDamage;
                  DirectDamage = directDamage;
  
                  MinDelay = minDelay;
                  MaxDelay = maxDelay;
  
                  EffectItemID = effectID;
                  EffectSpeed = effectDuration;
                  EffectExplodes = explodes;
                  EffectFixedDir = fixedDirection;
                  EffectHue = effectHue;
                  EffectRenderMode = renderMode;
                  EffectSound = effectSound;
                  AngerAnimation = angerAnimation;
                  AttacksMultipleTargets = attacksMultiples;
  
                  Uses = uses;
              }
  
              public int GetElementalDamage(BaseCreature bc, ElementType element)
              {
                  switch (element)
                  {
                      default:
                      case ElementType.Physical:
                          if (bc is IElementalCreature)
                          {
                              return ((IElementalCreature)bc).ElementType == ElementType.Physical ? 100 : 0;
                          }
                          else
                          {
                              return PhysicalDamage;
                          }
                      case ElementType.Fire:
                          if (bc is IElementalCreature)
                          {
                              return ((IElementalCreature)bc).ElementType == ElementType.Fire ? 100 : 0;
                          }
                          else
                          {
                              return FireDamage;
                          }
                      case ElementType.Cold:
                          if (bc is IElementalCreature)
                          {
                              return ((IElementalCreature)bc).ElementType == ElementType.Cold ? 100 : 0;
                          }
                          else
                          {
                              return ColdDamage;
                          }
                      case ElementType.Poison:
                          if (bc is IElementalCreature)
                          {
                              return ((IElementalCreature)bc).ElementType == ElementType.Poison ? 100 : 0;
                          }
                          else
                          {
                              return PoisonDamage;
                          }
                      case ElementType.Energy:
                          if (bc is IElementalCreature)
                          {
                              return ((IElementalCreature)bc).ElementType == ElementType.Energy ? 100 : 0;
                          }
                          else
                          {
                              return EnergyDamage;
                          }
                      case ElementType.Chaos:
                          if (bc is IElementalCreature)
                          {
                              return ((IElementalCreature)bc).ElementType == ElementType.Chaos ? 100 : 0;
                          }
                          else
                          {
                              return ChaosDamage;
                          }
                      case ElementType.Direct:
                          if (bc is IElementalCreature)
                          {
                              return ((IElementalCreature)bc).ElementType == ElementType.Direct ? 100 : 0;
                          }
                          else
                          {
                              return DirectDamage;
                          }
                  }
              }
          }
      }
  
      public class HowlOfCacophony : SpecialAbility
      {
          private static Dictionary<Mobile, InternalTimer> _Table;
          public override int ManaCost { get { return 25; } }
          public override bool TriggerOnDoMeleeDamage { get { return true; } }
  
          public HowlOfCacophony()
          {
          }
  
          public override void DoEffects(BaseCreature creature, Mobile defender, ref int damage)
          {
              if (_Table != null && _Table.ContainsKey(defender))
              {
                  return;
              }
  
              if (_Table == null)
                  _Table = new Dictionary<Mobile, InternalTimer>();
  
              _Table[defender] = new InternalTimer(defender);
  
              defender.SendSpeedControl(SpeedControlType.WalkSpeed);
              defender.SendLocalizedMessage(1072069); // // A cacophonic sound lambastes you, suppressing your ability to move.
              defender.PlaySound(0x584);
  
              BuffInfo.AddBuff(defender, new BuffInfo(BuffIcon.HowlOfCacophony, 1153793, 1153820, TimeSpan.FromSeconds(30), defender, "60\t5\t5"));
          }
  
          public static bool IsUnderEffects(Mobile m)
          {
              return _Table != null && _Table.ContainsKey(m);
          }
  
          private class InternalTimer : Timer
          {
              public Mobile Defender { get; set; }
  
              public InternalTimer(Mobile defender)
                  : base(TimeSpan.FromSeconds(30))
              {
                  Defender = defender;
                  Start();
              }
  
              protected override void OnTick()
              {
                  if (_Table != null && _Table.ContainsKey(Defender))
                  {
                      _Table.Remove(Defender);
  
                      BuffInfo.RemoveBuff(Defender, BuffIcon.HowlOfCacophony);
                      Defender.SendSpeedControl(SpeedControlType.Disable);                    
                  }
  
                  Stop();
              }
          }
      }
  
      public class GraspingClaw : SpecialAbility
  	{
          public override bool TriggerOnDoMeleeDamage { get { return true; } }
          public override int ManaCost { get { return 30; } }
  
          public static Dictionary<Mobile, ExpireTimer> _Table;
  
  		public GraspingClaw()
  		{
  		}
  		
  		public override void DoEffects(BaseCreature creature, Mobile defender, ref int damage)
  		{
              if (_Table == null)
                  _Table = new Dictionary<Mobile, ExpireTimer>();
  
              ExpireTimer timer = null;
  
              if (_Table.ContainsKey(defender))
                  timer = _Table[defender];
  
              if (timer != null)
              {
                  timer.DoExpire();
                  defender.SendLocalizedMessage(1070837); // The creature lands another blow in your weakened state.
              }
              else
                  defender.SendLocalizedMessage(1070836); // The blow from the creature's claws has made you more susceptible to physical attacks.
  
              int effect = -(defender.PhysicalResistance * 15 / 100);
  
              ResistanceMod mod = new ResistanceMod(ResistanceType.Physical, effect);
  
              defender.FixedParticles(0x373A, 10, 15, 5018, EffectLayer.Waist);
              defender.AddResistanceMod(mod);
  
              timer = new ExpireTimer(defender, mod, TimeSpan.FromSeconds(5.0));
              timer.Start();
  
              _Table[defender] = timer;
  		}
  
          public static void Expire(Mobile m)
          {
              if (_Table != null && _Table.ContainsKey(m))
              {
                  _Table.Remove(m);
              }
          }
  
          public class ExpireTimer : Timer
          {
              private readonly Mobile m_Mobile;
              private readonly ResistanceMod m_Mod;
  
              public ExpireTimer(Mobile m, ResistanceMod mod, TimeSpan delay)
                  : base(delay)
              {
                  m_Mobile = m;
                  m_Mod = mod;
                  Priority = TimerPriority.TwoFiftyMS;
              }
  
              public void DoExpire()
              {
                  m_Mobile.RemoveResistanceMod(m_Mod);
                  Stop();
  
                  Expire(m_Mobile);
              }
  
              protected override void OnTick()
              {
                  m_Mobile.SendLocalizedMessage(1070838); // Your resistance to physical attacks has returned.
                  DoExpire();
              }
          }
  	}
  	
  	public class Inferno : SpecialAbility
  	{
          public override bool TriggerOnDoMeleeDamage { get { return true; } }
          public override int ManaCost { get { return 30; } }
  
          public static Dictionary<Mobile, ExpireTimer> _Table;
  
          public Inferno()
  		{
  		}
  		
  		public override void DoEffects(BaseCreature creature, Mobile defender, ref int damage)
  		{
              if (_Table == null)
                  _Table = new Dictionary<Mobile, ExpireTimer>();
  
              ExpireTimer timer = null;
  
              if (_Table.ContainsKey(defender))
                  timer = _Table[defender];
  
              if (timer != null)
              {
                  timer.DoExpire();
              }
                  
              defender.SendLocalizedMessage(1070833); // The creature fans you with fire, reducing your resistance to fire attacks.
  
              ResistanceMod mod = new ResistanceMod(ResistanceType.Fire, -25);
  
              Effects.SendLocationParticles(defender, 0x3709, 10, 30, 5052);
              Effects.PlaySound(defender.Location, defender.Map, 0x208);
  
              timer = new ExpireTimer(defender, mod, TimeSpan.FromSeconds(6.0));
              timer.Start();
  
              AOS.Damage(defender, creature, Utility.RandomMinMax(46, 79), 0, 100, 0, 0, 0);
  
              _Table[defender] = timer;
  		}
  
          public static void Expire(Mobile m)
          {
              if (_Table != null && _Table.ContainsKey(m))
              {
                  _Table.Remove(m);
              }
          }
  
          public class ExpireTimer : Timer
          {
              private readonly Mobile m_Mobile;
              private readonly ResistanceMod m_Mod;
  
              public ExpireTimer(Mobile m, ResistanceMod mod, TimeSpan delay)
                  : base(delay)
              {
                  m_Mobile = m;
                  m_Mod = mod;
                  Priority = TimerPriority.TwoFiftyMS;
  
                  m.AddResistanceMod(mod);
              }
  
              public void DoExpire()
              {
                  m_Mobile.RemoveResistanceMod(m_Mod);
                  Stop();
  
                  Expire(m_Mobile);
              }
  
              protected override void OnTick()
              {
                  m_Mobile.SendLocalizedMessage(1070834); // Your resistance to fire attacks has returned.
                  DoExpire();
              }
          }
  	}
  	
  	public class LightningForce : SpecialAbility
  	{
          public override bool TriggerOnDoMeleeDamage { get { return true; } }
          public override int ManaCost { get { return 30; } }
  
          public LightningForce()
  		{
  		}
  		
  		public override void DoEffects(BaseCreature creature, Mobile defender, ref int damage)
  		{
              Server.Effects.SendBoltEffect(defender, true);
              AOS.Damage(defender, creature, Utility.RandomMinMax(15, 20), 0, 0, 0, 0, 100);
  		}
  	}
  	
  	public class ManaDrain : SpecialAbility
  	{
          public override bool TriggerOnGotMeleeDamage { get { return true; } }
          public override bool TriggerOnDoMeleeDamage { get { return true; } }
  
  		public ManaDrain()
  		{
  		}
  		
  		public override void DoEffects(BaseCreature creature, Mobile defender, ref int damage)
  		{
              if (creature.Map == null)
                  return;
  
              List<Mobile> list = new List<Mobile>();
              IPooledEnumerable eable = creature.GetMobilesInRange(8);
  
              foreach (Mobile m in eable)
              {
                  if (AreaEffect.ValidTarget(creature, m))
                      list.Add(m);
              }
  
              eable.Free();
  
              foreach (Mobile m in list)
              {
                  creature.DoHarmful(m, false);
  
                  m.FixedParticles(0x374A, 10, 15, 5013, 0x496, 0, EffectLayer.Waist);
                  m.PlaySound(0x231);
  
                  m.SendMessage("You feel the mana drain out of you!");
  
                  int toDrain = Utility.RandomMinMax(40, 60);
  
                  creature.Mana += toDrain;
                  m.Mana -= toDrain;
              }
  		}
  	}
  	
  	public class RagingBreath : SpecialAbility
  	{
          public static Dictionary<Mobile, InternalTimer> _Table;
          public override bool TriggerOnDoMeleeDamage { get { return true; } }
          public override int ManaCost { get { return 30; } }
  
          public RagingBreath()
  		{
  		}
  
          public override void DoEffects(BaseCreature creature, Mobile defender, ref int damage)
          {
              if (_Table == null)
                  _Table = new Dictionary<Mobile, InternalTimer>();
  
              InternalTimer timer = null;
  
              if (_Table.ContainsKey(defender))
              {
                  timer = _Table[defender];
              }
  
              if (timer != null)
              {
                  timer.Stop();
                  defender.SendLocalizedMessage(1070841); // The creature's breath continues to burn you!
              }
              else
              {
                  defender.SendLocalizedMessage(1070842); // The creature's breath is burning you!
              }
  
              int layer = 0;
  
              if (defender is BaseCreature)
              {
                  layer = 163;
              }
              else
              {
                  layer = 45;
              }
              
              Effects.SendPacket(defender.Location, defender.Map, new ParticleEffect(EffectType.FixedFrom, defender.Serial, Serial.Zero, 0x3709, defender.Location, defender.Location, 1, 15, false, false, 2735, 0, 4, 9502, 1, defender.Serial, layer, 0));
              Effects.SendPacket(defender.Location, defender.Map, new ParticleEffect(EffectType.FixedFrom, defender.Serial, Serial.Zero, 0x3709, defender.Location, defender.Location, 10, 30, false, false, 0, 0, 0, 52, 1, defender.Serial, layer, 0));
              defender.PlaySound(520);
  
              timer = new InternalTimer(creature, defender);
              timer.Start();
  
              _Table[defender] = timer;
          }
  
          public static void EndFire(Mobile m)
          {
              if (_Table != null && _Table.ContainsKey(m))
              {
                  _Table[m].Stop();
                  _Table.Remove(m);
                  m.SendLocalizedMessage(1070843); // The fiery breath dissipates.
              }
          }
  
          public class InternalTimer : Timer
          {
              public Mobile Attacker { get; set; }
              public Mobile Defender { get; set; }
  
              private int _Tick;
  
              public InternalTimer(Mobile attacker, Mobile defender)
                  : base(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1))
              {
                  Attacker = attacker;
                  Defender = defender;
              }
  
              protected override void OnTick()
              {
                  _Tick++;
  
                  if (_Tick > 10 || !Defender.Alive)
                  {
                      EndFire(Defender);
                  }
                  else
                  {
                      int layer = 0;
  
                      if (Defender is BaseCreature)
                      {
                          layer = 163;
                      }
                      else
                      {
                          layer = 45;
                      }
  
                      Effects.SendPacket(Defender.Location, Defender.Map, new ParticleEffect(EffectType.FixedFrom, Defender.Serial, Serial.Zero, 0x3709, Defender.Location, Defender.Location, 1, 15, false, false, 2735, 0, 4, 9502, 1, Defender.Serial, layer, 0));
                      AOS.Damage(Defender, Attacker, 10, 0, 100, 0, 0, 0);
                  }
              }
          }
  	}
  	
  	public class Repel : SpecialAbility
  	{
          public override bool TriggerOnGotMeleeDamage { get { return true; } }
          public override bool TriggerOnGotSpellDamage { get { return true; } }
          public override int ManaCost { get { return 30; } }
  
  		public Repel()
  		{
  		}
  		
  		public override void DoEffects(BaseCreature creature, Mobile defender, ref int damage)
  		{
              defender.SendLocalizedMessage(1070844); // The creature repels the attack back at you.
              defender.FixedEffect(0x37B9, 10, 5);
              AOS.Damage(defender, creature, damage / 2, 0, 0, 0, 0, 0, 0, 100);
  
              damage = 0;
  		}
  	}
  	
  	public class SearingWounds : SpecialAbility
  	{
  		private static Dictionary<Mobile, InternalTimer> _Table;
  		public override int ManaCost { get { return 25;  } }
          public override bool TriggerOnDoMeleeDamage { get { return true; } }
  
  		public SearingWounds()
  		{
  		}
  		
  		public override void DoEffects(BaseCreature creature, Mobile defender, ref int damage)
  		{
  			if(_Table != null && _Table.ContainsKey(defender))
  			{
  				return;
  			}
  			
  			if(_Table == null)
  				_Table = new Dictionary<Mobile, InternalTimer>();
  			
  			_Table[defender] = new InternalTimer(defender);
  
              defender.FixedParticles(0x374A, 10, 15, 5013, 0x496, 0, EffectLayer.Waist);
              defender.SendLocalizedMessage(1151177); // The searing attack cauterizes the wound on impact.
  		}
  		
  		public static bool IsUnderEffects(Mobile m)
  		{
  			return _Table != null && _Table.ContainsKey(m);
  		}
  		
  		private class InternalTimer : Timer
  		{
  			public Mobile Defender { get; set; }
  			
  			public InternalTimer(Mobile defender)
  				: base(TimeSpan.FromSeconds(10))
  			{
  				Defender = defender;
                  Start();
  			}
  			
  			protected override void OnTick()
  			{
  				if(_Table != null && _Table.ContainsKey(Defender))
  				{
  					_Table.Remove(Defender);
  				}
  
                  Stop();
  			}
  		}
  	}
  	
  	public class StealLife : SpecialAbility
  	{
          public override bool TriggerOnDoMeleeDamage { get { return true; } }
          public override int ManaCost { get { return 30; } }
  
          public StealLife()
  		{
  		}
  		
  		public override void DoEffects(BaseCreature creature, Mobile defender, ref int damage)
  		{
              defender.FixedParticles(0x374A, 1, 15, 5054, 23, 7, EffectLayer.Head);
              defender.PlaySound(0x1F9);
  
              AOS.Damage(defender, creature, damage, 0, 0, 0, 0, 100);
  
              new InternalTimer(creature, defender, damage);
  		}
  		
  		private class InternalTimer : Timer
  		{
  			public BaseCreature Attacker { get; set; }
  			public Mobile Defender { get; set; }
              public int ToHeal { get; set; }
  			
  			public InternalTimer(BaseCreature creature, Mobile defender, int toHeal)
  				: base(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5), 5)
  			{
                  Attacker = creature;
                  Defender = defender;
                  ToHeal = toHeal;
  
                  defender.FixedParticles(0x374A, 10, 15, 5013, 0x496, 0, EffectLayer.Waist);
                  defender.PlaySound(0x231);
  
  				Start();
  			}
  			
  			protected override void OnTick()
  			{
                  Defender.FixedParticles(0x374A, 10, 15, 5013, 0x496, 0, EffectLayer.Waist);
                  Attacker.Hits = Math.Min(Attacker.HitsMax, Attacker.Hits + (ToHeal / 5));
  			}
  		}
  	}
  	
  	public class VenomousBite : SpecialAbility
  	{
  		public override int ManaCost { get { return 30;  } }
          public override bool TriggerOnDoMeleeDamage { get { return true; } }
          public override MagicalAbility RequiredSchool { get { return MagicalAbility.Poisoning; } }
  
  		public VenomousBite()
  		{
  		}
  		
  		public override void DoEffects(BaseCreature creature, Mobile defender, ref int damage)
  		{
              IPooledEnumerable eable = creature.GetMobilesInRange(3);
  			List<Mobile> list = new List<Mobile>();
  			
  			list.Add(defender);
  			
  			foreach(Mobile m in eable)
  			{
                  if (AreaEffect.ValidTarget(creature, m))
                      list.Add(m);
  			}
  			
  			eable.Free();
              Poison p = creature.GetHitPoison();
  
              if (p == null)
                  return;
  
  			foreach(var m in list)
  			{
                  defender.PlaySound(0xDD);
                  defender.FixedParticles(0x3728, 244, 25, 9941, 1266, 0, EffectLayer.Waist);
  
                  m.SendLocalizedMessage(1008097, false, creature.Name); //  : poisoned you!
  
                  m.ApplyPoison(creature, p);
  			}
  
              if (creature.Controlled && list.Count > 0)
              {
                  var profile = PetTrainingHelper.GetAbilityProfile(creature);
  
                  if ((profile != null && profile.HasAbility(MagicalAbility.Poisoning)) || 0.2 > Utility.RandomDouble())
                      creature.CheckSkill(SkillName.Poisoning, 0, creature.Skills[SkillName.Poisoning].Cap);
              }
  
              ColUtility.Free(list);
  		}
  	}
  	
  	public class ViciousBite : SpecialAbility
  	{
          public override bool TriggerOnDoMeleeDamage { get { return true; } }
          public override int ManaCost { get { return 20; } }
  
          private static Dictionary<Mobile, InternalTimer> _Table;
  
  		public ViciousBite()
  		{
  		}
  		
  		public override void DoEffects(BaseCreature creature, Mobile defender, ref int damage)
  		{
  			if(_Table != null && _Table.ContainsKey(defender))
  				return;
  
  			else if (_Table == null)
  				_Table = new Dictionary<Mobile, InternalTimer>();
  			
  			defender.PlaySound(0x1324);
  			defender.SendLocalizedMessage(1234567); // The creature gives you a particular vicious bite.
              Effects.SendLocationParticles(EffectItem.Create(defender.Location, defender.Map, EffectItem.DefaultDuration), 0x37CC, 1, 40, 97, 3, 9917, 0);
  
              _Table[defender] = new InternalTimer(creature, defender);
  		}
  		
  		private class InternalTimer : Timer
  		{
  			public BaseCreature Attacker { get; set; }
  			public Mobile Defender { get; set; } 
  			
  			private int _Tick;
  			
  			public InternalTimer(BaseCreature creature, Mobile defender)
  				: base(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(20))
  			{
                  Attacker = creature;
  				Defender = defender;
  				Start();
  			}
  			
  			protected override void OnTick()
  			{
  				_Tick++;
  				
  				AOS.Damage(Defender, Attacker, _Tick * 5, 0, 0, 0, 0, 0, 0, 100);
                  Defender.SendLocalizedMessage(1112473); //Your vicious wound is festering!
  				
  				if(_Tick >= 20 || !Defender.Alive || Defender.IsDeadBondedPet)
  				{
  					Stop();
  					
  					if(_Table.ContainsKey(Defender))
  						_Table.Remove(Defender);
  				}
  			}
  		}
  	}
  	
  	public class RuneCorruption : SpecialAbility
  	{
  		public static Dictionary<Mobile, ExpireTimer> _Table;
  		
          public override bool TriggerOnDoMeleeDamage { get { return true; } }
          public override int ManaCost { get { return 30; } }
  
          public RuneCorruption()
  		{
  		}
  		
  		public override void DoEffects(BaseCreature creature, Mobile defender, ref int damage)
  		{
  			if(_Table == null)
  				_Table = new Dictionary<Mobile, ExpireTimer>();
  			
  			ExpireTimer timer = null;
  
              if (_Table.ContainsKey(creature))
                  timer = _Table[creature];
  
  
gt: 			if (timer != null)