/**********************************************************
RunUO 2.0 AoV C# script file
Official Age of Valor Script :: www.uovalor.com
Last modified by 
Filepath: scripts\_custom\mobiles\Noxequus.cs
Lines of code: 365
***********************************************************/


using System;
using Server;
using Server.Items;
using Server.Mobiles;
using System.Collections;
using Server.Targeting;
using Server.Network;
using Server.Misc;

namespace Server.Mobiles
{
	[CorpseName( "a noxequus corpse" )]
	public class Noxequus: BaseMount
	{
		public override TimeSpan MountAbilityDelay { get { return TimeSpan.FromMinutes( 5.0 ); } }

		public override bool DoMountAbility( int damage, Mobile attacker )
		{
			if( Rider == null || attacker == null )	//sanity
				return false;
				
			if ( 0.4 >= Utility.RandomDouble() && Rider.Map == attacker.Map && Rider.InRange( attacker, 18 ) )
			{
				Rider.SendMessage("Your steed rears in the air as poisonous fumes errupt from its hoofs");	
				BeginNoxRide( Rider, this );
				Rider.PlaySound( 0xA9 );
				Rider.PlaySound(477);
				Effects.SendLocationParticles( EffectItem.Create( Rider.Location, Rider.Map, EffectItem.DefaultDuration ), 0x36B0, 1, 14, 0, 7, 9915, 0 );
				return true;
			}

			return false;
		}
	
		[Constructable]
		public Noxequus() : this( "a noxequus" )
		{
		}

		[Constructable]
		public Noxequus( string name ) : base( name, 793, 0x3EBB, AIType.AI_Super, FightMode.Closest, 10, 1, 0.2, 0.4 )
		{
			BaseSoundID = 0xA8;
			Hue = 63;

			SetStr( 376, 400 );
			SetDex( 91, 120 );
			SetInt( 291, 300 );

			SetHits( 220, 260 );

			SetDamage( 11, 30 );

			SetDamageType( ResistanceType.Physical, 20 );
			SetDamageType( ResistanceType.Poison, 80 );

			SetResistance( ResistanceType.Physical, 55, 75);
			SetResistance( ResistanceType.Fire, 30, 45 );
			SetResistance( ResistanceType.Cold, 15, 35 );
			SetResistance( ResistanceType.Poison, 80, 120 );
			SetResistance( ResistanceType.Energy, 15, 35 );

			SetSkill( SkillName.MagicResist, 100.0, 120.0 );
			SetSkill( SkillName.Tactics, 100.0 );
			SetSkill( SkillName.Wrestling, 100.0 );

			Fame = 20000;
			Karma = -20000;

			Tamable = true;
			ControlSlots = 2;
			MinTameSkill = 106.0;
		}

		public override void GenerateLoot()
		{
			PackItem( new Nightshade( Utility.RandomMinMax( 151, 300 ) ) );
			PackItem( new Ruby( Utility.RandomMinMax( 16, 30 ) ) );
		}

		public override bool HasBreath{ get{ return true; } } // poison breath enabled
		public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
		public override FoodType FavoriteFood{ get{ return FoodType.Meat; } }
		public override PackInstinct PackInstinct{ get{ return PackInstinct.Equine; } }
		public override int BreathPoisonDamage{ get{ return 100; } }
		public override int BreathFireDamage{ get{ return 0; } }
		public override int BreathEffectHue{ get{ return 63; } }
		
		public override void OnGaveMeleeAttack( Mobile defender )
		{
			base.OnGaveMeleeAttack( defender );

			if ( 0.1 >= Utility.RandomDouble() )
				Contaminate(defender);
		}
		
		public static void BeginNoxRide( Mobile m, Mobile from )
		{
			Timer t = (Timer)m_Table[m];

			if ( t != null )
				t.Stop();

			t = new InternalTimer( from, m );
			m_Table[m] = t;

			t.Start();
		}
		
		private class InternalTimer : Timer
		{
			private Mobile m_From;
			private Mobile m_Mobile;
			private int m_Count;

			public InternalTimer( Mobile from, Mobile m ) : base( TimeSpan.FromSeconds( 0.1 ), TimeSpan.FromSeconds( 0.1 ) )
			{
				m_From = from;
				m_Mobile = m;
				Priority = TimerPriority.TwoFiftyMS;
			}

			protected override void OnTick()
			{
				if(m_Mobile==null || m_From == null)
				{			
				this.Stop();
				return;
				}
				
				if (m_Mobile.Mounted == false) EndNoxRide( m_Mobile );
				
				m_Mobile.PlaySound( 517 );
				
				Map map = m_Mobile.Map;
		
				int x;
				int y;
							
				x = m_Mobile.X;
				y = m_Mobile.Y;
				if ( !Spells.SpellHelper.CheckMulti( new Point3D( x, y, m_Mobile.Z ), map ) )
				{
					Point3D loc = new Point3D(x ,y, m_Mobile.Z);
					Item item = new tempnoxfield(m_Mobile,TimeSpan.FromSeconds(20),5,15);
					item.MoveToWorld( loc, map );
				}
				
				if ( ++m_Count == 50 ) EndNoxRide( m_Mobile );
			}
		}
		
		public static void EndNoxRide( Mobile m )
		{
		if(m==null)return;
			Timer t = (Timer)m_Table[m];

			if ( t != null )
				t.Stop();

			if(m_Table.Contains(m))	m_Table.Remove( m );

			m.SendMessage("Your steed's poison fury ends"); 
		}
		
		private static Hashtable m_Table = new Hashtable();

		public static bool IsFiery( Mobile m )
		{
			return m_Table.Contains( m );
		}
		
		public void Contaminate(Mobile from)
		{
			this.PlaySound( 0x22F );
			from.PlaySound( 0x474 );
				
			Map map = from.Map;
		
			int x;
			int y;
							
			x = from.X;
			y = from.Y;
			if ( !Spells.SpellHelper.CheckMulti( new Point3D( x, y, from.Z ), map ) )
			{
				Point3D loc = new Point3D(x ,y, from.Z);
				Item item = new tempnoxfield(this,TimeSpan.FromSeconds(20),20,30);
				item.MoveToWorld( loc, map );
			}
			
			x = from.X + 1;
			y = from.Y;
			if ( !Spells.SpellHelper.CheckMulti( new Point3D( x, y, from.Z ), map ) )
			{
				Point3D loc = new Point3D(x ,y, from.Z);
				Item item = new tempnoxfield(this,TimeSpan.FromSeconds(20),10,20);
				item.MoveToWorld( loc, map );
			}
			
			x = from.X - 1;
			y = from.Y;
			if ( !Spells.SpellHelper.CheckMulti( new Point3D( x, y, from.Z ), map ) )
			{
				Point3D loc = new Point3D(x ,y, from.Z);
				Item item = new tempnoxfield(this,TimeSpan.FromSeconds(20),10,20);
				item.MoveToWorld( loc, map );
			}
			
			x = from.X;
			y = from.Y + 1;
			if ( !Spells.SpellHelper.CheckMulti( new Point3D( x, y, from.Z ), map ) )
			{
				Point3D loc = new Point3D(x ,y, from.Z);
				Item item = new tempnoxfield(this,TimeSpan.FromSeconds(20),10,20);
				item.MoveToWorld( loc, map );
			}
			
			x = from.X;
			y = from.Y - 1;
			if ( !Spells.SpellHelper.CheckMulti( new Point3D( x, y, from.Z ), map ) )
			{
				Point3D loc = new Point3D(x ,y, from.Z);
				Item item = new tempnoxfield(this,TimeSpan.FromSeconds(20),10,20);
				item.MoveToWorld( loc, map );
			}
			
			x = from.X + 1;
			y = from.Y + 1; 
			if ( !Spells.SpellHelper.CheckMulti( new Point3D( x, y, from.Z ), map ) )
			{
				Point3D loc = new Point3D(x ,y, from.Z);
				Item item = new tempnoxfield(this,TimeSpan.FromSeconds(20),10,20);
				item.MoveToWorld( loc, map );
			}
			
			x = from.X + 1;
			y = from.Y - 1; 
			if ( !Spells.SpellHelper.CheckMulti( new Point3D( x, y, from.Z ), map ) )
			{
				Point3D loc = new Point3D(x ,y, from.Z);
				Item item = new tempnoxfield(this,TimeSpan.FromSeconds(20),10,20);
				item.MoveToWorld( loc, map );
			}
			
			x = from.X - 1;
			y = from.Y + 1;
			if ( !Spells.SpellHelper.CheckMulti( new Point3D( x, y, from.Z ), map ) )
			{
				Point3D loc = new Point3D(x ,y, from.Z);
				Item item = new tempnoxfield(this,TimeSpan.FromSeconds(20),10,20);
				item.MoveToWorld( loc, map );
			}
			
			x = from.X - 1;
			y = from.Y - 1;
			if ( !Spells.SpellHelper.CheckMulti( new Point3D( x, y, from.Z ), map ) )
			{
				Point3D loc = new Point3D(x ,y, from.Z);
				Item item = new tempnoxfield(this,TimeSpan.FromSeconds(20),10,20);
				item.MoveToWorld( loc, map );
			}
		}

		public Noxequus( Serial serial ) : base( serial )
		{
		}

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );

			writer.Write( (int) 0 ); // version
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );

			int version = reader.ReadInt();

			if ( BaseSoundID <= 0 )
				BaseSoundID = 0xA8;
		}
	}
}

namespace Server.Items
{
	public class tempnoxfield : Item
	{
		private TimeSpan m_Duration;
		private int m_MinDamage;
		private int m_MaxDamage;
		private Mobile m_Owner;

		private DateTime m_Created;

		private Timer m_Timer;



		[CommandProperty( AccessLevel.GameMaster )]
		public TimeSpan Duration{ get{ return m_Duration; } set{ m_Duration = value; } }

		[CommandProperty( AccessLevel.GameMaster )]
		public Mobile Owner
		{
			get
			{
				return m_Owner;
			}
			set
			{
				m_Owner = value;
			}
		}		
		
		[CommandProperty( AccessLevel.GameMaster )]
		public int MinDamage
		{
			get
			{
				return m_MinDamage;
			}
			set
			{
				if ( value < 1 )
					value = 1;

				m_MinDamage = value;
			}
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public int MaxDamage
		{
			get
			{
				return m_MaxDamage;
			}
			set
			{
				if ( value < 1 )
					value = 1;

				if ( value < MinDamage )
					value = MinDamage;

				m_MaxDamage = value;
			}
		}

		[Constructable]
		public tempnoxfield() : this(null, TimeSpan.FromSeconds( 10.0 ), 5, 15 )
		{
		}

		public override string DefaultName { get { return "poison"; } }

		[Constructable]
		public tempnoxfield(Mobile powner, TimeSpan duration, int minDamage, int maxDamage )	: base( 14613 )
		{
			Movable = false;

			m_MinDamage = minDamage;
			m_MaxDamage = maxDamage;
			m_Created = DateTime.Now;
			m_Duration = duration;
			m_Owner=powner;

			m_Timer = Timer.DelayCall( TimeSpan.Zero, TimeSpan.FromSeconds( 1 ), new TimerCallback( OnTick ) );
		}

		public override void OnAfterDelete()
		{
			if( m_Timer != null )
				m_Timer.Stop();
		}

		private void OnTick()
		{
			DateTime now = DateTime.Now;
			TimeSpan age = now - m_Created;

			if( age > m_Duration )
				Delete();
			else
			{
				
				ArrayList toDamage = new ArrayList();

				foreach( object o in GetObjectsInRange( 0 ) )
				{		
					if ( o is Mobile || o is Item)
					{
						toDamage.Add( o );
					}				
				}

				for( int i = 0; i < toDamage.Count; i++ )
				{
					if(toDamage[i] is Mobile)
					{
						Mobile m = toDamage[i] as Mobile;

						if(m_Owner!=null && m_Owner.ShouldHarm(m))
						{
						m_Owner.DoHarmful( m );	
						Damage( m );
						}
						else if(m_Owner==null && HarmItem.ShouldHarm(m))
						{
						Damage( m );
						}					
					}
					else if(toDamage[i] is Item)
					{
					((Item)toDamage[i]).Trigger(m_Owner,this,TriggerType.Heat);
					}
				}
			}
		}



		public void Damage( Mobile m )
		{
		if(m==null)return;
		{
			m.PlaySound( 0x474 );
			m.ApplyPoison( m_Owner, Poison.Lethal );
			AOS.Damage( m,m_Owner, Utility.RandomMinMax(MinDamage,MaxDamage), 0, 0, 0, 100, 0 );
		}
		}

		public tempnoxfield( Serial serial ) : base( serial )
		{
		}

		public override void Serialize( GenericWriter writer )
		{			
		}

		public override void Deserialize( GenericReader reader )
		{
		this.Delete();
		}
	}
}
