context: using System;
  using System.IO;
  using System.Collections;
  using System.Collections.Generic;
  using Server;
  using Server.Mobiles;
  using Server.Network;
  using Server.Targeting;
  using Server.ContextMenus;
  
  namespace Server.Items
  {
  	public class TreasureMap : MapItem
  	{
  		private int m_Level;
  		private bool m_Completed;
  		private Mobile m_CompletedBy;
  		private Mobile m_Decoder;
  		private Map m_Map;
  		private Point2D m_Location;
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int Level{ get{ return m_Level; } set{ m_Level = value; InvalidateProperties(); } }
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public bool Completed{ get{ return m_Completed; } set{ m_Completed = value; InvalidateProperties(); } }
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public Mobile CompletedBy{ get{ return m_CompletedBy; } set{ m_CompletedBy = value; InvalidateProperties(); } }
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public Mobile Decoder{ get{ return m_Decoder; } set{ m_Decoder = value; InvalidateProperties(); } }
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public Map ChestMap{ get{ return m_Map; } set{ m_Map = value; InvalidateProperties(); } }
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public Point2D ChestLocation{ get{ return m_Location; } set{ m_Location = value; } }
  
  		private static Point2D[] m_Locations;
  		private static Point2D[] m_HavenLocations;
  
  		private static Type[][] m_SpawnTypes = new Type[][]
  		{
  			new Type[]{ typeof( HeadlessOne ), typeof( Skeleton ) },
  			new Type[]{ typeof( Mongbat ), typeof( Ratman ), typeof( HeadlessOne ), typeof( Skeleton ), typeof( Zombie ) },
  			new Type[]{ typeof( OrcishMage ), typeof( Gargoyle ), typeof( Gazer ), typeof( HellHound ), typeof( EarthElemental ) },
  			new Type[]{ typeof( Lich ), typeof( OgreLord ), typeof( DreadSpider ), typeof( AirElemental ), typeof( FireElemental ) },
  			new Type[]{ typeof( DreadSpider ), typeof( LichLord ), typeof( Daemon ), typeof( ElderGazer ), typeof( OgreLord ) },
  			new Type[]{ typeof( LichLord ), typeof( Daemon ), typeof( ElderGazer ), typeof( PoisonElemental ), typeof( BloodElemental ) },
  			new Type[]{ typeof( AncientWyrm ), typeof( Balron ), typeof( BloodElemental ), typeof( PoisonElemental ), typeof( Titan ) }
  		};
  
  		public const double LootChance = 0.01; // 1% chance to appear as loot
  
  		public static Point2D GetRandomLocation()
  		{
  			if ( m_Locations == null )
  				LoadLocations();
  
  			if ( m_Locations.Length > 0 )
  				return m_Locations[Utility.Random( m_Locations.Length )];
  
  			return Point2D.Zero;
  		}
  
  		public static Point2D GetRandomHavenLocation()
  		{
  			if ( m_HavenLocations == null )
  				LoadLocations();
  
  			if ( m_HavenLocations.Length > 0 )
  				return m_HavenLocations[Utility.Random( m_HavenLocations.Length )];
  
  			return Point2D.Zero;
  		}
  
  		private static void LoadLocations()
  		{
  			string filePath = Path.Combine( Core.BaseDirectory, "Data/treasure.cfg" );
  
  			List<Point2D> list = new List<Point2D>();
  			List<Point2D> havenList = new List<Point2D>();
  
  			if ( File.Exists( filePath ) )
  			{
  				using ( StreamReader ip = new StreamReader( filePath ) )
  				{
  					string line;
  
  					while ( (line = ip.ReadLine()) != null )
  					{
  						try
  						{
  							string[] split = line.Split( ' ' );
  
  							int x = Convert.ToInt32( split[0] ), y = Convert.ToInt32( split[1] );
  
  							Point2D loc = new Point2D( x, y );
  							list.Add( loc );
  
  							if ( IsInHavenIsland( loc ) )
  								havenList.Add( loc );
  						}
  						catch
  						{
  						}
  					}
  				}
  			}
  
  			m_Locations = list.ToArray();
  			m_HavenLocations = havenList.ToArray();
  		}
  
  		public static bool IsInHavenIsland( IPoint2D loc )
  		{
  			return ( loc.X >= 3314 && loc.X <= 3814 && loc.Y >= 2345 && loc.Y <= 3095 );
  		}
  
  		public static BaseCreature Spawn( int level, Point3D p, bool guardian )
  		{
  			if ( level >= 0 && level < m_SpawnTypes.Length )
  			{
  				BaseCreature bc;
  
  				try
  				{
  					bc = (BaseCreature)Activator.CreateInstance( m_SpawnTypes[level][Utility.Random( m_SpawnTypes[level].Length )] );
  				}
  				catch
  				{
  					return null;
  				}
  
  				bc.Home = p;
  				bc.RangeHome = 5;
  
  				if ( guardian && level == 0 )
  				{
  					bc.Name = "a chest guardian";
  					bc.Hue = 0x835;
  				}
  
  				return bc;
  			}
  
  			return null;
  		}
  
  		public static BaseCreature Spawn( int level, Point3D p, Map map, Mobile target, bool guardian )
  		{
  			if ( map == null )
  				return null;
  
  			BaseCreature c = Spawn( level, p, guardian );
  
  			if ( c != null )
  			{
  				bool spawned = false;
  
  				for ( int i = 0; !spawned && i < 10; ++i )
  				{
  					int x = p.X - 3 + Utility.Random( 7 );
  					int y = p.Y - 3 + Utility.Random( 7 );
  
  					if ( map.CanSpawnMobile( x, y, p.Z ) )
  					{
  						c.MoveToWorld( new Point3D( x, y, p.Z ), map );
  						spawned = true;
  					}
  					else
  					{
  						int z = map.GetAverageZ( x, y );
  
  						if ( map.CanSpawnMobile( x, y, z ) )
  						{
  							c.MoveToWorld( new Point3D( x, y, z ), map );
  							spawned = true;
  						}
  					}
  				}
  
  				if ( !spawned )
  				{
  					c.Delete();
  					return null;
  				}
  
  				if ( target != null )
  					c.Combatant = target;
  
  				return c;
  			}
  
  			return null;
  		}
  
  		[Constructable]
  		public TreasureMap( int level, Map map )
  		{
  			m_Level = level;
  			m_Map = map;
  
  			if ( level == 0 )
  
gt: 				m_Location = GetRandomHavenLocation();