/**********************************************************
RunUO AoV C# script file
Official Age of Valor Script :: www.uovalor.com
Last modified by Red Squirrel on Feb-13-2011 12:02:42am
Filepath: scripts\_custom\mobiles\boses\darthvader.cs
Lines of code: 469

Description: 

***********************************************************/


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

namespace Server.Mobiles
{
	public class darthvader : BaseCreature
	{
	
		public override OppositionGroup OppositionGroup
		{
			get{ return OppositionGroup.JediAndSith; }
		}
		
		private bool m_TrueForm;
		private Item m_GateItem;
		private ArrayList m_Tentacles;
		private Timer m_Timer;
		

		private static ArrayList m_Instances = new ArrayList();

		public static ArrayList Instances{ get{ return m_Instances; } }


		public static bool CanSpawn
		{
			get
			{
				return ( m_Instances.Count == 0 );
			}
		}
		
		public override WeaponAbility GetWeaponAbility()
		{
			switch ( Utility.Random( 9 ) )
			{
				default:
				case 0: return WeaponAbility.DoubleStrike;
				case 1: return WeaponAbility.WhirlwindAttack;
				case 2: return WeaponAbility.CrushingBlow;
				case 3: return WeaponAbility.ArmorIgnore;
				case 4: return WeaponAbility.MortalStrike;
				case 5: return WeaponAbility.ParalyzingBlow;
				case 6: return WeaponAbility.RidingSwipe;
				case 7: return WeaponAbility.BleedAttack;
				case 8: return WeaponAbility.Disarm;				
			}
		}
		
		
		
		//arty stuff	
		public void GiveArtifact()
		{
			ArrayList toGive = new ArrayList();
			List<DamageStore> rights = BaseCreature.GetLootingRights( this.DamageEntries, this.HitsMax );

			for ( int i = rights.Count - 1; i >= 0; --i )
			{
				DamageStore ds = rights[i];

				if ( ds.m_HasRight )
					toGive.Add( ds.m_Mobile );
			}

			
				if ( rights.Count == 0 )return;
				
				Mobile m;
				m	= rights[Utility.Random( rights.Count )].m_Mobile;
						
				m.SendMessage(200,"For your valor in defeating the sith, you have been awarded an artifact deed.");

				m.AddToBackpack( new randomartydeed() );
			
		}
		//end arty stuff
		
		
		private void SpawnSithLordOnPlayer()
		{
			if(this.Combatant!=null && this.InRange(this.Combatant,25))
			{			
				BaseCreature spawn = new sithlord();
				spawn.Team = this.Team;

				spawn.MoveToWorld( this.Combatant.Location, this.Combatant.Map );
				
				spawn.Combatant=this.Combatant;
			}
		}
		
		

		[Constructable]
		public darthvader() : base( AIType.AI_Super, FightMode.Closest, 18, 1, 0.1, 0.2 )
		{
			m_Instances.Add( this );

			Name = "Anakin";
			BodyValue = 744;
			Hue = Utility.RandomSkinHue();

			SetStr( 4900, 5000 );
			SetDex( 1025, 1035 );
			SetInt( 1000 );
			
			SetMana(10000);

			Fame = 250000;
			Karma = -225000;

			VirtualArmor = 60;

			SetDamageType( ResistanceType.Physical, 50 );
			SetDamageType( ResistanceType.Energy, 50 );

			SetResistance( ResistanceType.Physical, 20, 60 );
			SetResistance( ResistanceType.Fire, 60, 70 );
			SetResistance( ResistanceType.Cold, 60, 70 );
			SetResistance( ResistanceType.Poison, 60, 70 );
			SetResistance( ResistanceType.Energy, 60, 100 );

			SetSkill( SkillName.Wrestling, 190, 200.0 );
			SetSkill( SkillName.Swords, 195, 200.0 );
			SetSkill( SkillName.Tactics, 120.2, 140.0 );
			SetSkill( SkillName.MagicResist, 120.2, 130.0 );
			SetSkill( SkillName.Magery, 120 );
			SetSkill( SkillName.EvalInt, 120 );
			SetSkill( SkillName.Meditation, 120.0 );
			SetSkill( SkillName.Bushido, 120.0 );			 
			

			lightsaberofthesithlord weapon  = new lightsaberofthesithlord();
			if(Utility.Random(50)==5)weapon.LootType = LootType.Regular;
			AddItem(weapon);	

			BraceletOfHealth brace = new BraceletOfHealth();
			brace.LootType = LootType.Blessed;
			AddItem(brace);	



			MaleElvenRobe item1 = new MaleElvenRobe();
			item1.Hue = 1;
			AddItem(item1);


			for(int i=Utility.Random(10)+1;i>0;i--)
			{
			if(Utility.Random(1)==0)PackItem( new BallOfSummoning() );
			if(Utility.Random(1)==0)PackItem( new BagOfSending() );
			if(Utility.Random(1)==0)PackItem( new skilldeed() );
			if(0.65>Utility.RandomDouble())	PackItem(new RandomTalisman());
			}


			m_Tentacles = new ArrayList();

			m_Timer = new TeleportTimer( this );
			m_Timer.Start();
		}
		
		
		public override void OnThink()
		{
			if(0.0005>Utility.RandomDouble())SpawnSithLordOnPlayer();
			else if(m_TrueForm && 0.0025>Utility.RandomDouble())SpawnSithLordOnPlayer();			
			
			base.OnThink();
		}

		public override void GenerateLoot()
		{
			AddLoot( LootPack.SuperBoss, 7 );
			AddLoot( LootPack.Meager );
			AddLoot( LootPack.FilthyRich,3);
		}

		public override bool AutoDispel{ get{ return true; } }
		public override bool Unprovokable{ get{ return true; } }
		public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
		public override bool CanRummageCorpses{ get{ return true; } }
		public override int TreasureMapLevel{ get{ return 5; } }
		
		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 void Morph()
		{
			if ( m_TrueForm )
				return;

			m_TrueForm = true;

			Name = "Darth Vader";
			BodyValue = 311;
			Hue = 0x497;

			Hits = 150000;
			Stam = StamMax;
			Mana = ManaMax;

			ProcessDelta();

			//Say( 1049499 ); // Behold my true form!
			
			switch(Utility.Random(8))
			{
			default:
			case 0:Say("Now, you shall witness the true power of the dark side!");break;
			case 1:Say("I am your father!  Search your feelings, you know it to be true.");break;
			case 2:Say("Join the dark side, we have cookies.");break;
			case 3:Say("You are no match for the dark side!");break;
			case 4:Say("You will join us or die!");break;
			case 5:Say("There is no escape. Don't make me destroy you.");break;
			case 6:Say("If you only knew the power of the Dark Side.");break;
			case 7:Say("lol you're so screwed now son.  Yes you heard that. I AM YOUR FATHER!");break;
     		}
			
			


			Map map = this.Map;

			if ( map != null )
			{
				for ( int i = 0; i < m_Offsets.Length; i += 2 )
				{
					double rx = m_Offsets[i];
					double ry = m_Offsets[i + 1];

					int dist = 0;
					bool ok = false;
					int x = 0, y = 0, z = 0;

					while ( !ok && dist < 10 )
					{
						int rdist = 10 + dist;

						x = this.X + (int)(rx * rdist);
						y = this.Y + (int)(ry * rdist);
						z = map.GetAverageZ( x, y );

						if ( !(ok = map.CanFit( x, y, this.Z, 16, false, false ) ) )
							ok = map.CanFit( x, y, z, 16, false, false );

						if ( dist >= 0 )
							dist = -(dist + 1);
						else
							dist = -(dist - 1);
					}

					if ( !ok )
						continue;

					for(int iii=Utility.Random(4);iii>0;iii--)
					{
					BaseCreature spawn = new darkjediknight();

					spawn.Team = this.Team;

					spawn.MoveToWorld( new Point3D( x, y, z ), map );

					m_Tentacles.Add( spawn );
					}
				}
			}
		}


		public override bool AlwaysMurderer{ get{ return true; } }
		
		public darthvader( Serial serial ) : base( serial )
		{
			m_Instances.Add( this );
		}

		public override void OnAfterDelete()
		{
			m_Instances.Remove( this );

			base.OnAfterDelete();
		}

		public override bool DisallowAllMoves{ get{ return m_TrueForm; } }

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

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

			writer.Write( m_TrueForm );
			writer.Write( m_GateItem );
			writer.WriteMobileList( m_Tentacles );
		}

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

			int version = reader.ReadInt();

			switch ( version )
			{
				case 0:
				{
					m_TrueForm = reader.ReadBool();
					m_GateItem = reader.ReadItem();
					m_Tentacles = reader.ReadMobileList();

					m_Timer = new TeleportTimer( this );
					m_Timer.Start();

					break;
				}
			}
		}

		public void GivePowerScrolls()
		{
			List<Mobile> toGive = new List<Mobile>();
			List<DamageStore> rights = BaseCreature.GetLootingRights( this.DamageEntries, this.HitsMax );

			for ( int i = rights.Count - 1; i >= 0; --i )
			{
				DamageStore ds = rights[i];

				if ( ds.m_HasRight )
					toGive.Add( ds.m_Mobile );
			}

			if ( toGive.Count == 0 )
				return;

			// Randomize
			for ( int i = 0; i < toGive.Count; ++i )
			{

				int rand = Utility.Random( toGive.Count );
				Mobile hold = toGive[i];
				toGive[i] = toGive[rand];
				toGive[rand] = hold;
			}
			
			//toGive[Utility.Random( toGive.Count )].AddToBackpack( new ChampionSkull( ChampionSkullType.Sith ) );

			for ( int i = 0; i < 1; ++i )
			{
				int level;
				double random = Utility.RandomDouble();

				if ( 0.2 >= random )
					level = 15;
				else if ( 0.6 >= random )
					level = 10;
				else
					level = 5;

				Mobile m = toGive[i % toGive.Count];

				m.SendLocalizedMessage( 1049524 ); // You have received a scroll of power!
				m.AddToBackpack( new StatCapScroll( 225 + level ) );

				if ( m is PlayerMobile )
				{
					PlayerMobile pm = (PlayerMobile)m;

					for ( int j = 0; j < pm.JusticeProtectors.Count; ++j )
					{
						Mobile prot = (Mobile)pm.JusticeProtectors[j];

						if ( prot.Map != m.Map || prot.Kills >= 5 || prot.Criminal || !JusticeVirtue.CheckMapRegion( m, prot ) )
							continue;

						int chance = 0;

						switch ( VirtueHelper.GetLevel( prot, VirtueName.Justice ) )
						{
							case VirtueLevel.Seeker: chance = 60; break;
							case VirtueLevel.Follower: chance = 80; break;
							case VirtueLevel.Knight: chance = 100; break;
						}

						if ( chance > Utility.Random( 100 ) )
						{
							prot.SendLocalizedMessage( 1049368 ); // You have been rewarded for your dedication to Justice!
							prot.AddToBackpack( new StatCapScroll( 225 + level ) );
						}
					}
				}
			}
		}

		public override bool OnBeforeDeath()
		{
			if ( m_TrueForm )
			{
				List<DamageStore> rights = BaseCreature.GetLootingRights( this.DamageEntries, this.HitsMax );
			    
				if(0.1>Utility.RandomDouble())GiveArtifact();
				
				for ( int i = rights.Count - 1; i >= 0; --i )
				{
					DamageStore ds = rights[i];

				//	if ( ds.m_HasRight && ds.m_Mobile is PlayerMobile )PlayerMobile.ChampionTitleInfo.AwardHarrowerTitle( (PlayerMobile)ds.m_Mobile );
				}

				if ( !NoKillAwards )
				{
					GivePowerScrolls();

					Map map = this.Map;

					if ( map != null )
					{
						for ( int x = -16; x <= 16; ++x )
						{
							for ( int y = -16; y <= 16; ++y )
							{
								double dist = Math.Sqrt(x*x+y*y);

								if ( dist <= 16 )
									new GoodiesTimer( map, X + x, Y + y ).Start();
							}
						}
					}

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

						if ( !m.Deleted )
							m.Kill();
					}

					m_Tentacles.Clear();

					if ( m_GateItem != null )
						m_GateItem.Delete();
				}

				return base.OnBeforeDeath();
			}
			else
			{
				Morph();
				return false;
			}
		}

		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;
				Priority=TimerPriority.TwentyFiveMS;
			}

			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( 25 ) )
				{
					if ( m != m_Owner && m.Player && m_Owner.ShouldHarm( m ) && m_Owner.InLOS( m ) )
					{
						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;
				}
			}
		}

		private class GoodiesTimer : Timer
		{
			private Map m_Map;
			private int m_X, m_Y;

			public GoodiesTimer( Map map, int x, int y ) : base( TimeSpan.FromSeconds( Utility.RandomDouble() * 10.0 ) )
			{
				m_Map = map;
				m_X = x;
				m_Y = y;
			}

			protected override void OnTick()
			{
				int z = m_Map.GetAverageZ( m_X, m_Y );
				bool canFit = m_Map.CanFit( m_X, m_Y, z, 6, false, false );

				for ( int i = -3; !canFit && i <= 3; ++i )
				{
					canFit = m_Map.CanFit( m_X, m_Y, z + i, 6, false, false );

					if ( canFit )
						z += i;
				}

				if ( !canFit )
					return;

				Gold g = new Gold( 200, 3000 );
				
				g.MoveToWorld( new Point3D( m_X, m_Y, z ), m_Map );

				if ( 0.5 >= Utility.RandomDouble() )
				{
					switch ( Utility.Random( 3 ) )
					{
						case 0: // Fire column
						{
							Effects.SendLocationParticles( EffectItem.Create( g.Location, g.Map, EffectItem.DefaultDuration ), 0x3709, 10, 30, 5052 );
							Effects.PlaySound( g, g.Map, 0x208 );

							break;
						}
						case 1: // Explosion
						{
							Effects.SendLocationParticles( EffectItem.Create( g.Location, g.Map, EffectItem.DefaultDuration ), 0x36BD, 20, 10, 5044 );
							Effects.PlaySound( g, g.Map, 0x307 );

							break;
						}
						case 2: // Ball of fire
						{
							Effects.SendLocationParticles( EffectItem.Create( g.Location, g.Map, EffectItem.DefaultDuration ), 0x36FE, 10, 10, 5052 );

							break;
						}
					}
				}
			}
		}
	}
}