/**********************************************************
RunUO 2.0 AoV C# script file
Official Age of Valor Script :: www.uovalor.com
Last modified by 
Filepath: scripts\Engines\Harvest\Lumberjacking.cs
Lines of code: 268
***********************************************************/


using System;
using Server;
using Server.Items;
using System.Collections;
using Server.Mobiles;

namespace Server.Engines.Harvest
{
	public class Lumberjacking : HarvestSystem
	{
		private static Lumberjacking m_System;

		public static Lumberjacking System
		{
			get
			{
				if ( m_System == null )
					m_System = new Lumberjacking();

				return m_System;
			}
		}

		private HarvestDefinition m_Definition;

		public HarvestDefinition Definition
		{
			get{ return m_Definition; }
		}

		private Lumberjacking()
		{
			HarvestResource[] res;
			HarvestVein[] veins;

			#region Lumberjacking
			HarvestDefinition lumber = new HarvestDefinition();

			// Resource banks are every 4x3 tiles
			lumber.BankWidth = 4;
			lumber.BankHeight = 3;

			// Every bank holds from 20 to 45 logs
			lumber.MinTotal = 40;
			lumber.MaxTotal = 65;

			// A resource bank will respawn its content every 20 to 30 minutes
			lumber.MinRespawn = TimeSpan.FromMinutes( 20.0 );
			lumber.MaxRespawn = TimeSpan.FromMinutes( 30.0 );

			// Skill checking is done on the Lumberjacking skill
			lumber.Skill = SkillName.Lumberjacking;

			// Set the list of harvestable tiles
			lumber.Tiles = m_TreeTiles;

			// Players must be within 2 tiles to harvest
			lumber.MaxRange = 2;

			// Ten logs per harvest action
			lumber.ConsumedPerHarvest = 10;
			lumber.ConsumedPerFeluccaHarvest = 20;

			// The chopping effect
			lumber.EffectActions = new int[]{ 13 };
			lumber.EffectSounds = new int[]{ 0x13E };
			lumber.EffectCounts = new int[]{ 1, 2, 2, 2, 3 };
			lumber.EffectDelay = TimeSpan.FromSeconds( 1.6 );
			lumber.EffectSoundDelay = TimeSpan.FromSeconds( 0.9 );

			lumber.NoResourcesMessage = 500493; // There's not enough wood here to harvest.
			lumber.FailMessage = 500495; // You hack at the tree for a while, but fail to produce any useable wood.
			lumber.OutOfRangeMessage = 500446; // That is too far away.
			lumber.PackFullMessage = 500497; // You can't place any wood into your backpack!
			lumber.ToolBrokeMessage = 500499; // You broke your axe.
			

			res = new HarvestResource[]
				{
					new HarvestResource( 0.0, 0.0, 100.0,      1072540, typeof( Log ) ),
					new HarvestResource( 65.0, 40.0, 110.0,  1072541, typeof( OakLog ),typeof(OakNymph) ),
					new HarvestResource( 80.0, 50.0, 115.0,  1072542, typeof( AshLog ),typeof(AshNymph) ),
					new HarvestResource( 95.0, 60.0, 120.0,  1072543, typeof( YewLog ),typeof(YewNymph) ),
					new HarvestResource( 100.0, 70.0, 125.0,1072545, typeof( BloodwoodLog ),typeof(BloodWoodNymph) ),
					new HarvestResource( 100.0, 80.0, 130.0,1072544, typeof( HeartwoodLog ),typeof(HeartWoodNymph) ),
					new HarvestResource( 100.0, 90.0, 135.0,1072546, typeof( FrostwoodLog ),typeof(FrostWoodNymph) )
				};

			veins = new HarvestVein[]
				{
					new HarvestVein( 39, 0.0, res[0], null ),  //regular
					new HarvestVein( 44.2, 0.3, res[1], res[0] ), //oak
					new HarvestVein( 37.4, 0.3, res[2], res[0] ), //ash
					new HarvestVein( 19.2, 0.3, res[3], res[0] ), //yew
					new HarvestVein( 12.8, 0.3, res[4], res[0] ), //bloodwood
					new HarvestVein( 12.5, 0.3, res[5], res[0] ),  //heartwood
					new HarvestVein( 8.9, 0.3, res[6], res[0] )	 //frostwood		
				};

			lumber.Resources = res;
			lumber.Veins = veins;
			lumber.RaceBonus = true;
			
			m_Definition = lumber;
			Definitions.Add( lumber );
			#endregion
		}

		public override bool CheckHarvest( Mobile from, Item tool )
		{
			if ( !base.CheckHarvest( from, tool ) )
				return false;

			if ( tool.Parent != from )
			{
				from.SendLocalizedMessage( 500487 ); // The axe must be equipped for any serious wood chopping.
				return false;
			}

			return true;
		}

		public override bool CheckHarvest( Mobile from, Item tool, HarvestDefinition def, object toHarvest )
		{
			if ( !base.CheckHarvest( from, tool, def, toHarvest ) )
				return false;

			if ( tool.Parent != from )
			{
				from.SendLocalizedMessage( 500487 ); // The axe must be equipped for any serious wood chopping.
				return false;
			}

			return true;
		}
		

		public override HarvestVein MutateVein( Mobile from, Item tool, HarvestDefinition def, HarvestBank bank, object toHarvest, HarvestVein vein )
		{
			if ( tool is ReapersAxe)
			{
				int veinIndex = Array.IndexOf( def.Veins, vein );

				if ( veinIndex >= 0 && veinIndex < (def.Veins.Length - 1) )
					return def.Veins[veinIndex + 1];
			}

			return base.MutateVein( from, tool, def, bank, toHarvest, vein );
		}		
		
		
		private static int[] m_Offsets = new int[]
			{
				-1, -1,
				-1,  0,
				-1,  1,
				 0, -1,
				 0,  1,         
				 1, -1,
				 1,  0,
				 1,  1
			};

		public override void OnHarvestFinished( Mobile from, Item tool, HarvestDefinition def, HarvestVein vein, HarvestBank bank, HarvestResource resource, object harvested )
		{
			if ( (tool is ReapersAxe || 0.005>Utility.RandomDouble()) && 0.1 > Utility.RandomDouble() )
			{
				HarvestResource res = vein.PrimaryResource;

				if ( res == resource && res.Types.Length >= 2 )
				{
					try
					{
						Map map = from.Map;

						if ( map == null )
							return;

						BaseCreature spawned = Activator.CreateInstance( res.Types[1], new object[]{ 25 } ) as BaseCreature;

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

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

								if ( map.CanSpawnMobile( x, y, from.Z ) )
								{
									spawned.MoveToWorld( new Point3D( x, y, from.Z ), map );
									spawned.OnAfterSpawn();
									spawned.SetCombatantTimed(from,TimeSpan.FromSeconds(2));
									return;
								}
								else
								{
									int z = map.GetAverageZ( x, y );

									if ( map.CanSpawnMobile( x, y, z ) )
									{
										spawned.MoveToWorld( new Point3D( x, y, z ), map );
										spawned.OnAfterSpawn();
										spawned.SetCombatantTimed(from,TimeSpan.FromSeconds(2));
										return;
									}
								}
							}

							spawned.MoveToWorld( from.Location, from.Map );
							spawned.OnAfterSpawn();
							spawned.SetCombatantTimed(from,TimeSpan.FromSeconds(2));
						}
					}
					catch
					{
					}
				}
			}
		}		
		
		

		public override void OnBadHarvestTarget( Mobile from, Item tool, object toHarvest )
		{
			from.SendLocalizedMessage( 500489 ); // You can't use an axe on that.
		}

		#region Mondain's Legacy
		public override bool Give( Mobile m, Item item, bool placeAtFeet )
		{
					//rare chance to hit a hornets nest - that will teach those AFKers!					
					if(0.00013>Utility.RandomDouble())
					{
					m.SendMessage("You hit a hornet's nest!");
					
					new HornetNest().MoveToWorld(m.Location,m.Map);					
					}
		
		
			if ( m.Skills.Lumberjacking.Value >= 100 )
			{				
				if ( Utility.RandomDouble() < 0.15 )
				{					
					Item sitem = null;
					int message = 0;
					double chance = Utility.RandomDouble();
					
					if ( chance < 0.025 ) // not completely sure
					{
						sitem = new BrilliantAmber();
						message = 1072551; // You found a parasitic plant!
					}
					else if ( chance < 0.05 )
					{
						sitem = new ParasiticPlant();
						message = 1072549; // You found a parasitic plant!
					}
					else if ( chance < 0.35 )		
					{
						if ( Utility.RandomBool() )
						{
							sitem = new Switch();
							message = 1072547; // You found a switch!
						}
						else
						{
							sitem = new LuminescentFungi();
							message = 1072550; // You found a luminescent fungi!
						}
					}			
					else
					{
						sitem = new BarkFragment();
						message = 1072548; // You found a bark fragment!
					}	
					
				
					
					if ( item != null && !m.PlaceInBackpack( sitem ) && placeAtFeet )
					{						
						ArrayList atFeet = new ArrayList();
	
						foreach ( Item obj in m.GetItemsInRange( 0 ) )
							atFeet.Add( obj );
			
						for ( int i = 0; i < atFeet.Count; ++i )
						{
							Item check = (Item)atFeet[i];
			
							if ( check.StackWith( m, sitem, false ) )
								return base.Give( m, item, placeAtFeet );
						}
			
						sitem.MoveToWorld( m.Location, m.Map );
					}
						
					m.SendLocalizedMessage( message );
				}				
			}			
			
			return base.Give( m, item, placeAtFeet );
		}
		#endregion		
		
		public static void Initialize()
		{
			Array.Sort( m_TreeTiles );
		}

		#region Tile lists
		private static int[] m_TreeTiles = new int[]
			{
				0x4CCA, 0x4CCB, 0x4CCC, 0x4CCD, 0x4CD0, 0x4CD3, 0x4CD6, 0x4CD8,
				0x4CDA, 0x4CDD, 0x4CE0, 0x4CE3, 0x4CE6, 0x4CF8, 0x4CFB, 0x4CFE,
				0x4D01, 0x4D41, 0x4D42, 0x4D43, 0x4D44, 0x4D57, 0x4D58, 0x4D59,
				0x4D5A, 0x4D5B, 0x4D6E, 0x4D6F, 0x4D70, 0x4D71, 0x4D72, 0x4D84,
				0x4D85, 0x4D86, 0x52B5, 0x52B6, 0x52B7, 0x52B8, 0x52B9, 0x52BA,
				0x52BB, 0x52BC, 0x52BD,

				0x4CCE, 0x4CCF, 0x4CD1, 0x4CD2, 0x4CD4, 0x4CD5, 0x4CD7, 0x4CD9,
				0x4CDB, 0x4CDC, 0x4CDE, 0x4CDF, 0x4CE1, 0x4CE2, 0x4CE4, 0x4CE5,
				0x4CE7, 0x4CE8, 0x4CF9, 0x4CFA, 0x4CFC, 0x4CFD, 0x4CFF, 0x4D00,
				0x4D02, 0x4D03, 0x4D45, 0x4D46, 0x4D47, 0x4D48, 0x4D49, 0x4D4A,
				0x4D4B, 0x4D4C, 0x4D4D, 0x4D4E, 0x4D4F, 0x4D50, 0x4D51, 0x4D52,
				0x4D53, 0x4D5C, 0x4D5D, 0x4D5E, 0x4D5F, 0x4D60, 0x4D61, 0x4D62,
				0x4D63, 0x4D64, 0x4D65, 0x4D66, 0x4D67, 0x4D68, 0x4D69, 0x4D73,
				0x4D74, 0x4D75, 0x4D76, 0x4D77, 0x4D78, 0x4D79, 0x4D7A, 0x4D7B,
				0x4D7C, 0x4D7D, 0x4D7E, 0x4D7F, 0x4D87, 0x4D88, 0x4D89, 0x4D8A,
				0x4D8B, 0x4D8C, 0x4D8D, 0x4D8E, 0x4D8F, 0x4D90, 0x4D95, 0x4D96,
				0x4D97, 0x4D99, 0x4D9A, 0x4D9B, 0x4D9D, 0x4D9E, 0x4D9F, 0x4DA1,
				0x4DA2, 0x4DA3, 0x4DA5, 0x4DA6, 0x4DA7, 0x4DA9, 0x4DAA, 0x4DAB,
				0x52BE, 0x52BF, 0x52C0, 0x52C1, 0x52C2, 0x52C3, 0x52C4, 0x52C5,
				0x52C6, 0x52C7
			};
		#endregion
	}
}