/**********************************************************
RunUO 2.0 AoV C# script file
Official Age of Valor Script :: www.uovalor.com
Last modified by Red Squirrel on Jan-01-2009 11:41:35pm
Filepath: scripts\_custom\events and scenarios\misc\christmas\AbominableSnowMan.cs
Lines of code: 282
***********************************************************/


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

namespace Server.Mobiles
{
	public class AbominableSnowMan : BaseCreature
	{
       private Timer m_Timer;
	   bool minionssummoned=false;
       private int amount; 
	   
	   bool m_SendGiftsToAllHouses;
	   
		[CommandProperty( AccessLevel.GameMaster )]
		public bool SendGiftsToAllHouses
		{
			get{ return m_SendGiftsToAllHouses; }
			set{ m_SendGiftsToAllHouses = value; }
		}	   
	   
	   
		[Constructable]
		public AbominableSnowMan() : base( AIType.AI_Super, FightMode.Closest, 18, 1, 0.1, 0.1 )
		{
			Name = "An Abominable Snow Monster";
			Body = 256;
			Hue=1150;
			BaseSoundID = 357;

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

			SetHits( 50000, 50000 );

			SetDamage( 16, 23 );

			SetDamageType( ResistanceType.Physical, 0 );
			SetDamageType( ResistanceType.Cold, 100 );

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

			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);
			SetSkill( SkillName.Magery,120);
			SetSkill( SkillName.EvalInt,120);
			SetSkill( SkillName.EvalInt,120);
			SetSkill( SkillName.EvalInt,120);
			

			Fame = 1000000;
			Karma = -1000000;

			
			m_Timer = new TeleportTimer( this );
			m_Timer.Start();		
		}
		
		public override bool OnBeforeDeath()
		{
			for ( int j = 0; j < 6; j++ )
			{
				PackItem(RandomMResources.Generate());	
			}




			
			for ( int k = 0; k < Utility.RandomMinMax( 1, 3 ); k++ )
			{
				PackItem(new RandomTalisman());
			}
			
			
			
			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());		

			 for(int i=Utility.Random(4);i>0;i--)PackItem(SurpriseStocking.RandomDecoration());		

		
		
		DoSendGifts();
			 
		return base.OnBeforeDeath();
		}
		
		
		//this function drops a giftbox at every single house, first it looks for a christmas tree, if there is none, it checks for a door, if none, it  places at center of the house
		private void DoSendGifts()
		{
		if(!SendGiftsToAllHouses)return;
		
		World.Broadcast(1151, true, "You sense a surge of magic as santa delivers presents to every house in sosaria, within the blink of an eye!");
		
		//stuff
		
			ArrayList items = new ArrayList();
		
			foreach ( Item i in World.Items.Values )
			{
			if(i is BaseHouse)items.Add(i);			
			}
			
			for(int i=0;i<items.Count;i++)
			{
			BaseHouse house = items[i] as BaseHouse;
			
			if(house.Owner.AccessLevel>AccessLevel.Player)continue;
			
			Point3D placegift = house.BanLocation;			
			
			//generate and place gift
			
			PersonalGiftBox gift = new PersonalGiftBox(house.Owner);
						
			gift.MoveToWorld(placegift,house.Map);			
			
			house.LockDowns.Add(gift);
			}
		
		
		
		}
		
		
		
		
		public override void AlterSpellDamageFrom( Mobile from, ref int damage )
		{
		
			switch(Utility.Random(50))
			{		
			case 0: Say("Ha, your magic is nothing against me!");break;
			case 1: Say("I have a gift for you... your damage! hahahaha!");break;
			case 2: Say("You have nothing on me, I shall freeze you, then eat you!");break;
			case 3: Say("Mmmmm, fresh frozen meat!");break;
			case 4: Say("...Dying in a winter wonderland, sing it!");break;		
			}


		
		AOS.Damage( from, this, damage, false, 0, 0, 100, 0, 0 );
		from.FixedParticles( 0x374A, 10, 30, 5013, 1153, 2, EffectLayer.Waist );
		from.PlaySound( 0x0FC );
		
		damage/=10;
		}
		
		
		
		public override void OnThink()
		{
		base.OnThink();
		
		}
		

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

		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 AbominableSnowMan( 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 );
			
			if(attacker.Alive)DoCounter( attacker );
		}		
		
		
		
		private void DoCounter( Mobile attacker )
		{
			if ( attacker is BaseCreature && ((BaseCreature)attacker).BardProvoked )
				return;

			if ( 0.2 > Utility.RandomDouble() )
			{


				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 );

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

					m.FixedParticles( 0x374A, 10, 30, 5013, 1153, 2, EffectLayer.Waist );
					m.PlaySound( 0x0FC );
				}
			}
		}		
		
		
		
		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;
					
					
				}
			}
		}
	}
}
