/**********************************************************
RunUO 2.0 AoV C# script file
Official Age of Valor Script :: www.uovalor.com
Last modified by 
Filepath: scripts\_custom\engines\ML Peerless + misc areas\Chief Paroxymous\Quest Mobiles\ChiefParoxysmus.cs
Lines of code: 377
***********************************************************/


using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Engines.CannedEvil;
using System.Collections.Generic;

namespace Server.Mobiles
{
	public class ChiefParoxysmus : BaseCreature
	{
       private Timer m_Timer;
	   bool minionssummoned=false;
	   Random rand = new Random(); 
       private int amount; 
	   
		[Constructable]
		public ChiefParoxysmus() : base( AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4 )
		{
			Name = "Chief Paroxysmus" ;
			Body = 256;
			//BaseSoundID = 357;

			SetStr( 1281, 1305 );
			SetDex( 591, 815 );
			SetInt( 3010, 3250 );

			SetHits( 50000, 50000 );

			SetDamage( 16, 23 );

			SetDamageType( ResistanceType.Physical, 100 );

			SetResistance( ResistanceType.Physical, 45, 60 );
			SetResistance( ResistanceType.Fire, 50, 60 );
			SetResistance( ResistanceType.Cold, 30, 40 );
			SetResistance( ResistanceType.Poison, 30, 30 );
			SetResistance( ResistanceType.Energy, 30, 40 );

			SetSkill( SkillName.MagicResist, 110.0, 110.0 );
			SetSkill( SkillName.Tactics, 120.0, 120.0 );
			SetSkill( SkillName.Wrestling, 120.0, 120.0 );
			SetSkill( SkillName.Anatomy,120,140);

			Fame = 15000;
			Karma = -15000;

			VirtualArmor = 75;
				
			
			
			m_Timer = new TeleportTimer( this );
			m_Timer.Start();		
		}
		
		public override int GetAngerSound()
		{
			return 1394;
		}


		public override int GetIdleSound()
		{
			return 1393;
		}


		public override int GetAttackSound()
		{
			return 1392;
		}


		public override int GetHurtSound()
		{
			return 1395;
		}


		public override int GetDeathSound()
		{
			return 1391;
		}		
		
		public override bool OnBeforeDeath()
		{
			for ( int j = 0; j < 6; j++ )
			{
				PackItem(RandomMResources.Generate());	
			}
			
			for (int i = 0; i < Utility.RandomMinMax(1, 2); i++)
			{
				PackItem( new PetParrotStatue (Utility.RandomList(41, 495, 567, 48, 131, 75, 1001, 1169, 1155, 1164, 1160, 1162, 2210, 1324, 1157, 1364, 1156, 2101))); //Common hues/reward
			}
			
			if (0.15 >= Utility.RandomDouble())
				PackItem( new PetParrotStatue (Utility.RandomList(1281, 1158, 1266, 1150, 1167, 1109, 33, 1420, 1644, 1359))); //Uncommon 
			else if (0.05 >= Utility.RandomDouble())
				PackItem( new PetParrotStatue (Utility.RandomList(1166, 1165, 1172, 1168, 1175, 1152, 1161, 1151, 1154, 1153, 0, 1177)));//Rare reward hues

			switch ( Utility.Random( 75 ))
            {                                   
            	case 14: PackItem( new CrimsonCinture() ); break;
            	case 31: PackItem( new SceptorOfTheChief () ); break;     
			}
			
			switch ( Utility.Random( 5 ))
            {                                   
				case 1: PackItem( new Stein () ); break;   
            	case 3: PackItem( new ParoxysmusDinner () ); break;      	
			}
			
			switch ( Utility.Random( 2 ))
            {                                   
				case 1: PackItem( new ProxySweat() ); break;
			}
			
			switch ( Utility.Random( 4 ))
            {                                   
				case 2: PackItem( new StringOfParts() ); break;
			}
			
			switch ( Utility.Random( 40 ))
            {              
				case 10: PackItem( new SwampySummoner() ); break;
				case 22: PackItem( new ChiefParoxysmusIdol() ); break;		      	
			}
			
			switch ( Utility.Random( 32 ))
            {                                   
            	case 0: PackItem( new PlateOfHonorArms() ); break;
            	case 1: PackItem( new PlateOfHonorChest() ); break;
				case 2: PackItem( new PlateOfHonorGloves () ); break;
            	case 3: PackItem( new PlateOfHonorGorget () ); break;       
				case 4: PackItem( new PlateOfHonorHelm () ); break;		
				case 5: PackItem( new PlateOfHonorLegs () ); break;		
				case 6: PackItem( new AcolyteArms() ); break;
            	case 7: PackItem( new AcolyteChest() ); break;
				case 8: PackItem( new AcolyteGloves () ); break;	
				case 9: PackItem( new AcolyteLegs () ); break;	
				case 10: PackItem( new EvocaricusSword() ); break;
            	case 11: PackItem( new MalekisHonor() ); break;
				case 12: PackItem( new GrizzleArms() ); break;
            	case 13: PackItem( new GrizzleChest() ); break;
				case 14: PackItem( new GrizzleGloves () ); break;       
				case 15: PackItem( new GrizzleHelm () ); break;		
				case 16: PackItem( new PlateOfHonorLegs () ); break;
				case 17: PackItem( new MageArmorArms() ); break;
            	case 18: PackItem( new MageArmorChest() ); break;
				case 19: PackItem( new MageArmorGloves () ); break;	
				case 20: PackItem( new MageArmorLegs () ); break;                    
				case 21: PackItem( new MyrmidonArms() ); break;
            	case 22: PackItem( new MyrmidonChest() ); break;
				case 23: PackItem( new MyrmidonGloves () ); break;
            	case 24: PackItem( new MyrmidonGorget () ); break;       
				case 25: PackItem( new MyrmidonHelm () ); break;		
				case 26: PackItem( new MyrmidonLegs () ); break;		
				case 27: PackItem( new DeathEssenceArms() ); break;
            	case 28: PackItem( new DeathEssenceChest() ); break;
				case 29: PackItem( new DeathEssenceGloves () ); break;      
				case 30: PackItem( new DeathEssenceHelm () ); break;		
				case 31: PackItem( new DeathEssenceLegs () ); break;		
			}
			
			for ( int k = 0; k < Utility.RandomMinMax( 1, 3 ); k++ )
			{
				PackItem(new RandomTalisman());
			}
			
			if (0.4 >= Utility.RandomDouble()) 
			{
				switch (Utility.RandomMinMax(0, 2 ))
				{
					case 0: PackItem(Loot.RandomMPWeapon(90,110, 0));break;
					case 1: PackItem(Loot.RandomMPWeapon(90,110, 1));break;
					case 2: PackItem(Loot.RandomMPWeapon(90,110, 2));break;      		
				}
			}
				
			if (0.10 >= Utility.RandomDouble()) 
			{
				switch (Utility.RandomMinMax(0, 2 ))
				{
					case 0: PackItem(Loot.RandomMPWeapon(110,130, 0));break;
					case 1: PackItem(Loot.RandomMPWeapon(110,130, 1));break;
					case 2: PackItem(Loot.RandomMPWeapon(110,130, 2));break;      		
				}
			}
			
			if (0.05 >= Utility.RandomDouble())
			{
				switch (Utility.RandomMinMax(0, 2 ))
				{
					case 0: PackItem(Loot.RandomMPWeapon(130,150, 0));break;
					case 1: PackItem(Loot.RandomMPWeapon(130,150, 1));break;
					case 2: PackItem(Loot.RandomMPWeapon(130,150, 2));break;      		
				}
			}
			
			if (0.8 >= Utility.RandomDouble()) PackItem( new LardOfParoxysmus(1) );	
			
			if (Map == Map.Felucca)
				amount = 12;
			else
				amount = 8;

			for (int n = 0; n < amount; n++)
			{
				switch (Utility.RandomMinMax(0, 5 ))
				{
					case 0: PackItem( new Taint(1));break;
					case 1: PackItem( new Muculent(1));break;
					case 2: PackItem( new Corruption(1));break;      		
					case 3: PackItem( new Blight (1));break;
					case 4: PackItem( new Scourge(1));break;
					case 5: PackItem( new Putrefaction(1));break;
				}
			}
			
			
			 for(int i=Utility.Random(4);i>0;i--)PackItem(RandomRecipe.Peerless());		
		
		return base.OnBeforeDeath();
		}
		
		
		
		public override void OnThink()
		{
		base.OnThink();
		
		SummonMinions();	
		}
		
		private void SummonMinions()
		{
		if(minionssummoned)return;
			//sumon minions
			
			for(int i=Utility.Random(5);i>0;i--)
			{		
			int tmpx=X+Utility.Random(3)-1;
			int tmpy=Y+Utility.Random(3)-1;
			int tmpz = Map.GetAverageZ( tmpx, tmpy );
			
			ChiefParoxysmusMinion minion = new ChiefParoxysmusMinion();
			SetTempSummon(this,minion);
			minion.MoveToWorld(new Point3D(tmpx,tmpy,tmpz),Map);								
			}
		minionssummoned=true;
		}

		
		public override void GenerateLoot()
		{
			AddLoot( LootPack.AosUltraRich, 2 );
			AddLoot( LootPack.AosSuperBoss, 2);
			AddLoot( LootPack.FilthyRich, 3 );
		}

		public override bool AutoDispel{ get{ return true; } }
		public override bool Unprovokable{ get{ return true; } }
		public override Poison HitPoison{ get{ return Poison.Lethal; } }
		public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
		public override bool IsMLCreature { get { return true;} }
		public override bool IsMLBoss { get { return true;} }
		public override bool NoFlee { get { return true; } }		
 

		private static readonly double[] m_Offsets = new double[]
			{
				Math.Cos( 000.0 / 180.0 * Math.PI ), Math.Sin( 000.0 / 180.0 * Math.PI ),
				Math.Cos( 040.0 / 180.0 * Math.PI ), Math.Sin( 040.0 / 180.0 * Math.PI ),
				Math.Cos( 080.0 / 180.0 * Math.PI ), Math.Sin( 080.0 / 180.0 * Math.PI ),
				Math.Cos( 120.0 / 180.0 * Math.PI ), Math.Sin( 120.0 / 180.0 * Math.PI ),
				Math.Cos( 160.0 / 180.0 * Math.PI ), Math.Sin( 160.0 / 180.0 * Math.PI ),
				Math.Cos( 200.0 / 180.0 * Math.PI ), Math.Sin( 200.0 / 180.0 * Math.PI ),
				Math.Cos( 240.0 / 180.0 * Math.PI ), Math.Sin( 240.0 / 180.0 * Math.PI ),
				Math.Cos( 280.0 / 180.0 * Math.PI ), Math.Sin( 280.0 / 180.0 * Math.PI ),
				Math.Cos( 320.0 / 180.0 * Math.PI ), Math.Sin( 320.0 / 180.0 * Math.PI ),
			};

		public override void OnDeath( Container c )
		{
			base.OnDeath( c );
		}

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


		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			writer.Write( (int) 0 ); // version
			
			writer.Write((bool)minionssummoned);
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			int version = reader.ReadInt();

			minionssummoned=reader.ReadBool();
		}
		
		
		public override void OnDamagedBySpell( Mobile attacker )
		{
			base.OnDamagedBySpell( attacker );

			DoCounter( attacker );
		}

		public override void OnGotMeleeAttack( Mobile attacker )
		{
			base.OnGotMeleeAttack( attacker );
			
				//eat pets
				if(attacker is BaseCreature)
				{
				BaseCreature bc = attacker as BaseCreature;
				
				if(bc.SummonMaster!=null)bc.SummonMaster.SendLocalizedMessage(1072079);//Your pet has succumbed to the hunger of your enemy!
				if(bc.ControlMaster!=null)bc.ControlMaster.SendLocalizedMessage(1072079);//Your pet has succumbed to the hunger of your enemy!
				
				
				bc.Kill();
				Hits=HitsMaxSeed;
				}	

			if(attacker.Alive)DoCounter( attacker );
		}		
		
		
		
		private void DoCounter( Mobile attacker )
		{
			if ( attacker is BaseCreature && ((BaseCreature)attacker).BardProvoked )
				return;

			if ( 0.2 > Utility.RandomDouble() )
			{
				/* Counterattack with Hit Poison Area
				 * 20-25 damage, unresistable
				 * Lethal poison, 100% of the time
				 * Particle effect: Type: "2" From: "0x4061A107" To: "0x0" ItemId: "0x36BD" ItemIdName: "explosion" FromLocation: "(296 615, 17)" ToLocation: "(296 615, 17)" Speed: "1" Duration: "10" FixedDirection: "True" Explode: "False" Hue: "0xA6" RenderMode: "0x0" Effect: "0x1F78" ExplodeEffect: "0x1" ExplodeSound: "0x0" Serial: "0x4061A107" Layer: "255" Unknown: "0x0"
				 * Doesn't work on provoked monsters
				 */

				Mobile target = null;

				if ( attacker is BaseCreature )
				{
					Mobile m = ((BaseCreature)attacker).GetMaster();
					
					if( m != null )
						target = m;
				}

				if ( target == null || !target.InRange( this, 18 ) )
					target = attacker;

				this.Animate( 10, 4, 1, true, false, 0 );

				ArrayList targets = new ArrayList();

				foreach ( Mobile m in target.GetMobilesInRange( 8 ) )
				{
					if ( m != this && ShouldHarm( m ) && this.InLOS(m))
					{	
						targets.Add( m );
					}
				}

				for ( int i = 0; i < targets.Count; ++i )
				{
					Mobile m = (Mobile)targets[i];

					DoHarmful( m );
					
					m.PlaySound( 1396 );

					AOS.Damage( m, this, Utility.RandomMinMax( 20, 25 ), true, 0, 0, 0, 100, 0 );

					m.FixedParticles( 0x36BD, 1, 10, 0x1F78, 0xA6, 0, (EffectLayer)255 );
					m.ApplyPoison( this, Poison.Lethal );
				}
			}
		}		
		
		
		
		private class TeleportTimer : Timer
		{
			private Mobile m_Owner;

			private static int[] m_Offsets = new int[]
			{
				-1, -1,
				-1,  0,
				-1,  1,
				0, -1,
				0,  1,
				1, -1,
				1,  0,
				1,  1
			};

			public TeleportTimer( Mobile owner ) : base( TimeSpan.FromSeconds( 5.0 ), TimeSpan.FromSeconds( 5.0 ) )
			{
				m_Owner = owner;
			}

			protected override void OnTick()
			{
				if ( m_Owner.Deleted )
				{
					Stop();
					return;
				}

				Map map = m_Owner.Map;

				if ( map == null )
					return;

				if ( 0.25 < Utility.RandomDouble() )
					return;

				Mobile toTeleport = null;

				foreach ( Mobile m in m_Owner.GetMobilesInRange( 16 ) )
				{
					if ( m != m_Owner && m.Player && m_Owner.CanBeHarmful( m ) && m_Owner.InLOS( m ) && !m_Owner.InRange(m,7) )
					{
						toTeleport = m;
						break;
					}
				}

				if ( toTeleport != null )
				{
					int offset = Utility.Random( 8 ) * 2;

					Point3D to = m_Owner.Location;

						for ( int i = 0; i < m_Offsets.Length; i += 2 )
						{
							int x = m_Owner.X + m_Offsets[(offset + i) % m_Offsets.Length];
							int y = m_Owner.Y + m_Offsets[(offset + i + 1) % m_Offsets.Length];

							if ( map.CanSpawnMobile( x, y, m_Owner.Z ) )
							{
								to = new Point3D( x, y, m_Owner.Z );
								break;
							}
							else
							{
								int z = map.GetAverageZ( x, y );

								if ( map.CanSpawnMobile( x, y, z ) )
								{
									to = new Point3D( x, y, z );
									break;
								}
							}
						}

					Mobile m = toTeleport;

					Point3D from = m.Location;

					m.Location = to;

					Server.Spells.SpellHelper.Turn( m_Owner, toTeleport );
					Server.Spells.SpellHelper.Turn( toTeleport, m_Owner );

					m.ProcessDelta();

					Effects.SendLocationParticles( EffectItem.Create( from, m.Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 2023 );
					Effects.SendLocationParticles( EffectItem.Create(   to, m.Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 5023 );

					m.PlaySound( 0x1FE );

					m_Owner.Combatant = toTeleport;
					
					for(int i=0;i<2;i++)	if(0.3>Utility.RandomDouble())m_Owner.Combatant.Damage( Utility.Random(40,100), m_Owner);
					
				}
			}
		}
	}
}
