context: using System; 
  using System.Collections;
  using Server.Network; 
  using Server.Mobiles; 
  using Server.Items; 
  using Server.Gumps;
  
  namespace Server.Items.Crops 
  { 
  	public class FlaxSeed : BaseCrop 
  	{ 
  		// return true to allow planting on Dirt Item (ItemID 0x32C9)
  		// See CropHelper.cs for other overriddable types
  		public override bool CanGrowGarden{ get{ return true; } }
  		
  		[Constructable]
  		public FlaxSeed() : this( 1 )
  		{
  		}
  
  		[Constructable]
  		public FlaxSeed( int amount ) : base( 0xF27 )
  		{
  			Stackable = true; 
  			Weight = .5; 
  			Hue = 0x5E2; 
  
  			Movable = true; 
  			
  			Amount = amount;
  			Name = "a flax seed"; 
  		}
  	
  		public override void OnDoubleClick( Mobile from ) 
  		{ 
  			if ( from.Mounted && !CropHelper.CanWorkMounted )
  			{
  				from.SendMessage( "You cannot plant a seed while mounted." ); 
  				return; 
  			}
  
  			Point3D m_pnt = from.Location;
  			Map m_map = from.Map;
  
  			if ( !IsChildOf( from.Backpack ) ) 
  			{ 
  				from.SendLocalizedMessage( 1042010 ); //You must have the object in your backpack to use it. 
  				return; 
  			} 
  
  			else if ( !CropHelper.CheckCanGrow( this, m_map, m_pnt.X, m_pnt.Y ) )
  			{
  				from.SendMessage( "This seed will not grow here." ); 
  				return; 
  			}
  			
  			//check for BaseCrop on this tile
  			ArrayList cropshere = CropHelper.CheckCrop( m_pnt, m_map, 0 );
  			if ( cropshere.Count > 0 )
  			{
  				from.SendMessage( "There is already a crop growing here." ); 
  				return;
  			}
  
  			//check for over planting prohibt if 4 maybe 3 neighboring crops
  			ArrayList cropsnear = CropHelper.CheckCrop( m_pnt, m_map, 1 );
  			if ( ( cropsnear.Count > 3 ) || (( cropsnear.Count == 3 ) && Utility.RandomBool() ) )
  			{
  				from.SendMessage( "There are too many crops nearby." ); 
  				return;
  			}
  
  			if ( this.BumpZ ) ++m_pnt.Z;
  
  			if ( !from.Mounted )
  				from.Animate( 32, 5, 1, true, false, 0 ); // Bow
  
  			from.SendMessage("You plant the seed."); 
  			this.Consume(); 
  			Item item = new FlaxSeedling( from ); 
  			item.Location = m_pnt; 
  			item.Map = m_map; 
  			
  		} 
  
  		public FlaxSeed( Serial serial ) : base( serial ) 
  		{ 
  		} 
  
  		public override void Serialize( GenericWriter writer ) 
  		{ 
  			base.Serialize( writer ); 
  			writer.Write( (int) 0 ); 
  		} 
  
  		public override void Deserialize( GenericReader reader ) 
  		{ 
  			base.Deserialize( reader ); 
  			int version = reader.ReadInt(); 
  		} 
  	} 
  
  
  	public class FlaxSeedling : BaseCrop 
  	{ 
  		private static Mobile m_sower;
  		public Timer thisTimer;
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public Mobile Sower{ get{ return m_sower; } set{ m_sower = value; } }
  		
  		[Constructable] 
  		public FlaxSeedling( Mobile sower ) : base( 0x1A99 ) 
  		{ 
  			Movable = false; 
  			Name = "a flax seedling"; 
  			m_sower = sower;
  			
  			init( this );
  		} 
  
  		public static void init( FlaxSeedling plant )
  		{
  			plant.thisTimer = new CropHelper.GrowTimer( plant, typeof(FlaxCrop), plant.Sower ); 
  			plant.thisTimer.Start(); 
  		}
  
  		public override void OnDoubleClick( Mobile from ) 
  		{ 
  			if ( from.Mounted && !CropHelper.CanWorkMounted )
  			{
  				from.SendMessage( "The crop is too small to harvest while mounted." ); 
  				return; 
  			}
  
  			if ( ( Utility.RandomDouble() <= .25 ) && !( m_sower.AccessLevel > AccessLevel.Counselor ) ) 
  			{ //25% Chance
  				from.SendMessage( "You uproot the seedling." ); 
  				thisTimer.Stop();
  				this.Delete();
  			}
  			else from.SendMessage( "This crop is too young to harvest." ); 
  		}
  
  		public FlaxSeedling( Serial serial ) : base( serial ) 
  		{ 
  		} 
  
  		public override void Serialize( GenericWriter writer ) 
  		{ 
  			base.Serialize( writer ); 
  			writer.Write( (int) 0 ); 
  			writer.Write( m_sower );
  		} 
  
  		public override void Deserialize( GenericReader reader ) 
  		{ 
  			base.Deserialize( reader ); 
  			int version = reader.ReadInt(); 
  			m_sower = reader.ReadMobile();
  
  			init( this );
  		} 
  	} 
  
  	public class FlaxCrop : BaseCrop 
  	{ 
  		private const int max = 10;
  		private int fullGraphic;
  		private int pickedGraphic;
  		private DateTime lastpicked;
  
  		private Mobile m_sower;
  		private int m_yield;
  
  		public Timer regrowTimer;
  
  		private DateTime m_lastvisit;
  
  		[CommandProperty( AccessLevel.GameMaster )] 
  		public DateTime LastSowerVisit{ get{ return m_lastvisit; } }
  
  		[CommandProperty( AccessLevel.GameMaster )] // debuging
  		public bool Growing{ get{ return regrowTimer.Running; } }
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public Mobile Sower{ get{ return m_sower; } set{ m_sower = value; } }
  		
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int Yield{ get{ return m_yield; } set{ m_yield = value; } }
  
  		public int Capacity{ get{ return max; } }
  		public int FullGraphic{ get{ return fullGraphic; } set{ fullGraphic = value; } }
  		public int PickGraphic{ get{ return pickedGraphic; } set{ pickedGraphic = value; } }
  		public DateTime LastPick{ get{ return lastpicked; } set{ lastpicked = value; } }
  		
  		[Constructable] 
  		public FlaxCrop( Mobile sower ) : base(  0x1A9A ) 
  		{ 
  			Movable = false; 
  			Name = "a flax plant"; 
  
  			m_sower = sower;
  			m_lastvisit = DateTime.Now;
  
  			init( this, false );
  		}
  
  		public static void init ( FlaxCrop plant, bool full )
  		{
  			plant.PickGraphic = ( 0x1A9A );
  			plant.FullGraphic = ( 0x1A9B );
  
  			plant.LastPick = DateTime.Now;
  			plant.regrowTimer = new CropTimer( plant );
  
  			if ( full )
  			{
  				plant.Yield = plant.Capacity;
  				((Item)plant).ItemID = plant.FullGraphic;
  			}
  			else
  			{
  				plant.Yield = 0;
  				((Item)plant).ItemID = plant.PickGraphic;
  				plant.regrowTimer.Start();
  			}
  		}
  		
  		public void UpRoot( Mobile from )
  		{
  			from.SendMessage( "The crop withers away." ); 
  			if ( regrowTimer.Running )
  				regrowTimer.Stop();
  
  			this.Delete();
  		}
  
  		public override void OnDoubleClick( Mobile from ) 
  		{ 
  			if ( m_sower == null || m_sower.Deleted ) 
  				m_sower = from;
  
  			if ( from.Mounted && !CropHelper.CanWorkMounted )
  			{
  				from.SendMessage( "You cannot harvest a crop while mounted." ); 
  				return; 
  			}
  
  			if ( DateTime.Now > lastpicked.AddSeconds(3) ) // 3 seconds between picking
  			{
  				lastpicked = DateTime.Now;
  			
  				int tailorValue = (int)from.Skills[SkillName.Tailoring].Value / 20;
  				if ( tailorValue == 0 )
  				{
  					from.SendMessage( "You have no idea how to harvest this crop." ); 
  					return;
  				}
  
  				if ( from.InRange( this.GetWorldLocation(), 1 ) ) 
  				{ 
  					if ( m_yield < 1 )
  					{
  						from.SendMessage( "There is nothing here to harvest." ); 
  
  						if ( PlayerCanDestroy && !( m_sower.AccessLevel > AccessLevel.Counselor ) )
  						{  
  
gt: 							UpRootGump g = new UpRootGump( from, this );