context: using System;
  using Server;
  using Server.Mobiles;
  using Server.Targeting;
  
  namespace Server.Items
  {
  	public class FabledFishingNet : Item
  	{
  		public override int LabelNumber { get { return 1063451; } } // a fabled fishing net
  
  		private bool m_InUse;
  
  		[Constructable]
  		public FabledFishingNet()
  			: base( 0x0DCA )
  		{
  			Weight = 1.0;
  
  			Hue = 1153;
  		}
  
  		public FabledFishingNet( Serial serial )
  			: base( serial )
  		{
  		}
  
  		public override void GetProperties( ObjectPropertyList list )
  		{
  			base.GetProperties( list );
  
  			// as if the name wasn't enough..
  			list.Add( 1063451 ); // a fabled Fishing Net
  		}
  
  		public override void Serialize( GenericWriter writer )
  		{
  			base.Serialize( writer );
  
  			writer.Write( (int) 1 ); // version
  
  			writer.Write( m_InUse );
  		}
  
  		public override void Deserialize( GenericReader reader )
  		{
  			base.Deserialize( reader );
  
  			int version = reader.ReadInt();
  
  			switch ( version )
  			{
  				case 1:
  					{
  						m_InUse = reader.ReadBool();
  
  						if ( m_InUse )
  							Delete();
  
  						break;
  					}
  			}
  
  			Stackable = false;
  		}
  
  		public override void OnDoubleClick( Mobile from )
  		{
  			if ( m_InUse )
  			{
  				from.SendLocalizedMessage( 1010483 ); // Someone is already using that net!
  			}
  			else if ( IsChildOf( from.Backpack ) )
  			{
  				from.SendLocalizedMessage( 1010484 ); // Where do you wish to use the net?
  				from.BeginTarget( -1, true, TargetFlags.None, new TargetCallback( OnTarget ) );
  			}
  			else
  			{
  				from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
  			}
  		}
  
  		public void OnTarget( Mobile from, object obj )
  		{
  			if ( Deleted || m_InUse )
  				return;
  
  			IPoint3D p3D = obj as IPoint3D;
  
  			if ( p3D == null )
  				return;
  
  			Map map = from.Map;
  
  			if ( map == null || map == Map.Internal )
  				return;
  
  			int x = p3D.X, y = p3D.Y;
  
  			if ( !from.InRange( p3D, 6 ) )
  			{
  				from.SendLocalizedMessage( 500976 ); // You need to be closer to the water to fish!
  			}
  			else if ( FullValidation( map, x, y ) )
  			{
  				Point3D p = new Point3D( x, y, map.GetAverageZ( x, y ) );
  
  				for ( int i = 1; i < Amount; ++i ) // these were stackable before, doh
  					from.AddToBackpack( new FabledFishingNet() );
  
  				m_InUse = true;
  				Movable = false;
  				MoveToWorld( p, map );
  
  				from.Animate( 12, 5, 1, true, false, 0 );
  
  				Timer.DelayCall( TimeSpan.FromSeconds( 1.5 ), TimeSpan.FromSeconds( 1.0 ), 20, new TimerStateCallback( DoEffect ), new object[] { p, 0 } );
  
  				from.SendLocalizedMessage( 1010487 ); // You plunge the net into the sea...
  			}
  			else
  			{
  				from.SendLocalizedMessage( 1010485 ); // You can only use this net in deep water!
  			}
  		}
  
  		private void DoEffect( object state )
  		{
  			if ( Deleted )
  				return;
  
  			object[] states = (object[]) state;
  
  			Point3D p = (Point3D) states[0];
  			int index = (int) states[1];
  
  			states[1] = ++index;
  
  			if ( index == 1 )
  			{
  				Effects.SendLocationEffect( p, Map, 0x352D, 16, 4 );
  				Effects.PlaySound( p, Map, 0x364 );
  			}
  			else if ( index <= 10 || index == 20 )
  			{
  				for ( int i = 0; i < 3; ++i )
  				{
  					int x, y;
  
  					switch ( Utility.Random( 8 ) )
  					{
  						default:
  						case 0: x = -1; y = -1; break;
  						case 1: x = -1; y = 0; break;
  						case 2: x = -1; y = +1; break;
  						case 3: x = 0; y = -1; break;
  						case 4: x = 0; y = +1; break;
  						case 5: x = +1; y = -1; break;
  						case 6: x = +1; y = 0; break;
  						case 7: x = +1; y = +1; break;
  					}
  
  					Effects.SendLocationEffect( new Point3D( p.X + x, p.Y + y, p.Z ), Map, 0x352D, 16, 4 );
  				}
  
  				Effects.PlaySound( p, Map, 0x364 );
  
  				if ( index == 20 )
  					FinishEffect( p );
  				else
  					this.Z -= 1;
  			}
  		}
  
  		private void FinishEffect( Point3D p )
  		{
  			int count = Utility.RandomMinMax( 5, 7 );
  
  			if ( Hue != 0x8A0 )
  				count += Utility.RandomMinMax( 1, 2 );
  
  			Map map = this.Map;
  
  			Leviathan lev = new Leviathan();
  
  			lev.MoveToWorld( p, map );
  
  			for ( int i = 0; map != null && i < count; ++i )
  			{
  				BaseCreature spawn;
  
  				switch ( Utility.Random( 4 ) )
  				{
  					default:
  					case 0: spawn = new SeaSerpent(); break;
  					case 1: spawn = new DeepSeaSerpent(); break;
  					case 2: spawn = new WaterElemental(); break;
  					case 3: spawn = new Kraken(); break;
  				}
  
  				int x = p.X, y = p.Y;
  
  				for ( int j = 0; j < 20; ++j )
  				{
  					int tx = p.X - 5 + Utility.Random( 11 );
  					int ty = p.Y - 5 + Utility.Random( 11 );
  
  					Tile t = map.Tiles.GetLandTile( tx, ty );
  
  					if ( t.Z == p.Z && ( ( t.ID >= 0xA8 && t.ID <= 0xAB ) || ( t.ID >= 0x136 && t.ID <= 0x137 ) ) && !Spells.SpellHelper.CheckMulti( new Point3D( tx, ty, p.Z ), map ) )
  					{
  						x = tx;
  						y = ty;
  						break;
  					}
  				}
  
  
gt: 				spawn.MoveToWorld( new Point3D( x, y, p.Z ), map );