BritainKnights/Source/Region.cs

1277 lines
No EOL
28 KiB
C#

/***************************************************************************
* Region.cs
* -------------------
* begin : May 1, 2002
* copyright : (C) The RunUO Software Team
* email : info@runuo.com
*
* $Id$
*
***************************************************************************/
/***************************************************************************
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
***************************************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using Server.Network;
using Server.Targeting;
namespace Server
{
public enum MusicName
{
Invalid = -1,
OldUlt01 = 0,
Create1,
DragFlit,
OldUlt02,
OldUlt03,
OldUlt04,
OldUlt05,
OldUlt06,
Stones2,
Britain1,
Britain2,
Bucsden,
Jhelom,
LBCastle,
Linelle,
Magincia,
Minoc,
Ocllo,
Samlethe,
Serpents,
Skarabra,
Trinsic,
Vesper,
Wind,
Yew,
Cave01,
Dungeon9,
Forest_a,
InTown01,
Jungle_a,
Mountn_a,
Plains_a,
Sailing,
Swamp_a,
Tavern01,
Tavern02,
Tavern03,
Tavern04,
Combat1,
Combat2,
Combat3,
Approach,
Death,
Victory,
BTCastle,
Nujelm,
Dungeon2,
Cove,
Moonglow,
Dungeon3,
Tavern05,
Travel
}
public class Region : IComparable
{
private static List<Region> m_Regions = new List<Region>();
public static List<Region> Regions{ get{ return m_Regions; } }
public static Region Find( Point3D p, Map map )
{
if ( map == null )
return Map.Internal.DefaultRegion;
Sector sector = map.GetSector( p );
List<RegionRect> list = sector.RegionRects;
for ( int i = 0; i < list.Count; ++i )
{
RegionRect regRect = list[i];
if ( regRect.Contains( p ) )
return regRect.Region;
}
return map.DefaultRegion;
}
private static Type m_DefaultRegionType = typeof( Region );
public static Type DefaultRegionType{ get{ return m_DefaultRegionType; } set{ m_DefaultRegionType = value; } }
private static TimeSpan m_StaffLogoutDelay = TimeSpan.FromSeconds( 10.0 );
private static TimeSpan m_DefaultLogoutDelay = TimeSpan.FromMinutes( 5.0 );
public static TimeSpan StaffLogoutDelay{ get{ return m_StaffLogoutDelay; } set{ m_StaffLogoutDelay = value; } }
public static TimeSpan DefaultLogoutDelay{ get{ return m_DefaultLogoutDelay; } set{ m_DefaultLogoutDelay = value; } }
public static readonly int DefaultPriority = 50;
public static readonly int MinZ = sbyte.MinValue;
public static readonly int MaxZ = sbyte.MaxValue + 1;
public static Rectangle3D ConvertTo3D( Rectangle2D rect )
{
return new Rectangle3D( new Point3D( rect.Start, MinZ ), new Point3D( rect.End, MaxZ ) );
}
public static Rectangle3D[] ConvertTo3D( Rectangle2D[] rects )
{
Rectangle3D[] ret = new Rectangle3D[rects.Length];
for ( int i = 0; i < ret.Length; i++ )
{
ret[i] = ConvertTo3D( rects[i] );
}
return ret;
}
private string m_Name;
private Map m_Map;
private Region m_Parent;
private List<Region> m_Children = new List<Region>();
private Rectangle3D[] m_Area;
private Sector[] m_Sectors;
private bool m_Dynamic;
private int m_Priority;
private int m_ChildLevel;
private bool m_Registered;
private Point3D m_GoLocation;
private MusicName m_Music;
public string Name{ get{ return m_Name; } }
public Map Map{ get{ return m_Map; } }
public Region Parent{ get{ return m_Parent; } }
public List<Region> Children{ get{ return m_Children; } }
public Rectangle3D[] Area{ get{ return m_Area; } }
public Sector[] Sectors{ get{ return m_Sectors; } }
public bool Dynamic{ get{ return m_Dynamic; } }
public int Priority{ get{ return m_Priority; } }
public int ChildLevel{ get{ return m_ChildLevel; } }
public bool Registered{ get{ return m_Registered; } }
public Point3D GoLocation{ get{ return m_GoLocation; } set { m_GoLocation = value; } }
public MusicName Music{ get{ return m_Music; } set{ m_Music = value; } }
public bool IsDefault{ get{ return m_Map.DefaultRegion == this; } }
public virtual MusicName DefaultMusic{ get{ return m_Parent != null ? m_Parent.Music : MusicName.Invalid; } }
public Region( string name, Map map, int priority, params Rectangle2D[] area ) : this( name, map, priority, ConvertTo3D( area ) )
{
}
public Region( string name, Map map, int priority, params Rectangle3D[] area ) : this( name, map, null, area )
{
m_Priority = priority;
}
public Region( string name, Map map, Region parent, params Rectangle2D[] area ) : this( name, map, parent, ConvertTo3D( area ) )
{
}
public Region( string name, Map map, Region parent, params Rectangle3D[] area )
{
m_Name = name;
m_Map = map;
m_Parent = parent;
m_Area = area;
m_Dynamic = true;
m_Music = this.DefaultMusic;
if ( m_Parent == null )
{
m_ChildLevel = 0;
m_Priority = DefaultPriority;
}
else
{
m_ChildLevel = m_Parent.ChildLevel + 1;
m_Priority = m_Parent.Priority;
}
}
public void Register()
{
if ( m_Registered )
return;
OnRegister();
m_Registered = true;
if ( m_Parent != null )
{
m_Parent.m_Children.Add( this );
m_Parent.OnChildAdded( this );
}
m_Regions.Add( this );
m_Map.RegisterRegion( this );
List<Sector> sectors = new List<Sector>();
for ( int i = 0; i < m_Area.Length; i++ )
{
Rectangle3D rect = m_Area[i];
Point2D start = m_Map.Bound( new Point2D( rect.Start ) );
Point2D end = m_Map.Bound( new Point2D( rect.End ) );
Sector startSector = m_Map.GetSector( start );
Sector endSector = m_Map.GetSector( end );
for ( int x = startSector.X; x <= endSector.X; x++ )
{
for ( int y = startSector.Y; y <= endSector.Y; y++ )
{
Sector sector = m_Map.GetRealSector( x, y );
sector.OnEnter( this, rect );
if ( !sectors.Contains( sector ) )
sectors.Add( sector );
}
}
}
m_Sectors = sectors.ToArray();
}
public void Unregister()
{
if ( !m_Registered )
return;
OnUnregister();
m_Registered = false;
if ( m_Children.Count > 0 )
Console.WriteLine( "Warning: Unregistering region '{0}' with children", this );
if ( m_Parent != null )
{
m_Parent.m_Children.Remove( this );
m_Parent.OnChildRemoved( this );
}
m_Regions.Remove( this );
m_Map.UnregisterRegion( this );
if ( m_Sectors != null )
{
for ( int i = 0; i < m_Sectors.Length; i++ )
m_Sectors[i].OnLeave( this );
}
m_Sectors = null;
}
public bool Contains( Point3D p )
{
for ( int i = 0; i < m_Area.Length; i++ )
{
Rectangle3D rect = m_Area[i];
if ( rect.Contains( p ) )
return true;
}
return false;
}
public bool IsChildOf( Region region )
{
if ( region == null )
return false;
Region p = m_Parent;
while ( p != null )
{
if ( p == region )
return true;
p = p.m_Parent;
}
return false;
}
public Region GetRegion( Type regionType )
{
if ( regionType == null )
return null;
Region r = this;
do
{
if ( regionType.IsAssignableFrom( r.GetType() ) )
return r;
r = r.m_Parent;
}
while ( r != null );
return null;
}
public Region GetRegion( string regionName )
{
if ( regionName == null )
return null;
Region r = this;
do
{
if ( r.m_Name == regionName )
return r;
r = r.m_Parent;
}
while ( r != null );
return null;
}
public bool IsPartOf( Region region )
{
if ( this == region )
return true;
return IsChildOf( region );
}
public bool IsPartOf( Type regionType )
{
return ( GetRegion( regionType ) != null );
}
public bool IsPartOf( string regionName )
{
return ( GetRegion( regionName ) != null );
}
public virtual bool AcceptsSpawnsFrom( Region region )
{
if ( !AllowSpawn() )
return false;
if ( region == this )
return true;
if ( m_Parent != null )
return m_Parent.AcceptsSpawnsFrom( region );
return false;
}
public List<Mobile> GetPlayers()
{
List<Mobile> list = new List<Mobile>();
if ( m_Sectors != null )
{
for ( int i = 0; i < m_Sectors.Length; i++ )
{
Sector sector = m_Sectors[i];
foreach ( Mobile player in sector.Players )
{
if ( player.Region.IsPartOf( this ) )
list.Add( player );
}
}
}
return list;
}
public int GetPlayerCount()
{
int count = 0;
if ( m_Sectors != null )
{
for ( int i = 0; i < m_Sectors.Length; i++ )
{
Sector sector = m_Sectors[i];
foreach ( Mobile player in sector.Players )
{
if ( player.Region.IsPartOf( this ) )
count++;
}
}
}
return count;
}
public List<Mobile> GetMobiles()
{
List<Mobile> list = new List<Mobile>();
if ( m_Sectors != null )
{
for ( int i = 0; i < m_Sectors.Length; i++ )
{
Sector sector = m_Sectors[i];
foreach ( Mobile mobile in sector.Mobiles )
{
if ( mobile.Region.IsPartOf( this ) )
list.Add( mobile );
}
}
}
return list;
}
public int GetMobileCount()
{
int count = 0;
if ( m_Sectors != null )
{
for ( int i = 0; i < m_Sectors.Length; i++ )
{
Sector sector = m_Sectors[i];
foreach ( Mobile mobile in sector.Mobiles )
{
if ( mobile.Region.IsPartOf( this ) )
count++;
}
}
}
return count;
}
int IComparable.CompareTo( object obj )
{
if ( obj == null )
return 1;
Region reg = obj as Region;
if ( reg == null )
throw new ArgumentException( "obj is not a Region", "obj" );
// Dynamic regions go first
if ( this.Dynamic )
{
if ( !reg.Dynamic )
return -1;
}
else if ( reg.Dynamic )
{
return 1;
}
int thisPriority = this.Priority;
int regPriority = reg.Priority;
if ( thisPriority != regPriority )
return ( regPriority - thisPriority );
return ( reg.ChildLevel - this.ChildLevel );
}
public override string ToString()
{
if ( m_Name != null )
return m_Name;
else
return GetType().Name;
}
public virtual void OnRegister()
{
}
public virtual void OnUnregister()
{
}
public virtual void OnChildAdded( Region child )
{
}
public virtual void OnChildRemoved( Region child )
{
}
public virtual bool OnMoveInto( Mobile m, Direction d, Point3D newLocation, Point3D oldLocation )
{
return ( m.WalkRegion == null || AcceptsSpawnsFrom( m.WalkRegion ) );
}
public virtual void OnEnter( Mobile m )
{
}
public virtual void OnExit( Mobile m )
{
}
public virtual void MakeGuard( Mobile focus )
{
if ( m_Parent != null )
m_Parent.MakeGuard( focus );
}
public virtual Type GetResource( Type type )
{
if ( m_Parent != null )
return m_Parent.GetResource( type );
return type;
}
public virtual bool CanUseStuckMenu( Mobile m )
{
if ( m_Parent != null )
return m_Parent.CanUseStuckMenu( m );
return true;
}
public virtual void OnAggressed( Mobile aggressor, Mobile aggressed, bool criminal )
{
if ( m_Parent != null )
m_Parent.OnAggressed( aggressor, aggressed, criminal );
}
public virtual void OnDidHarmful( Mobile harmer, Mobile harmed )
{
if ( m_Parent != null )
m_Parent.OnDidHarmful( harmer, harmed );
}
public virtual void OnGotHarmful( Mobile harmer, Mobile harmed )
{
if ( m_Parent != null )
m_Parent.OnGotHarmful( harmer, harmed );
}
public virtual void OnLocationChanged( Mobile m, Point3D oldLocation )
{
if ( m_Parent != null )
m_Parent.OnLocationChanged( m, oldLocation );
}
public virtual bool OnTarget( Mobile m, Target t, object o )
{
if ( m_Parent != null )
return m_Parent.OnTarget( m, t, o );
return true;
}
public virtual bool OnCombatantChange( Mobile m, Mobile Old, Mobile New )
{
if ( m_Parent != null )
return m_Parent.OnCombatantChange( m, Old, New );
return true;
}
public virtual bool AllowHousing( Mobile from, Point3D p )
{
if ( m_Parent != null )
return m_Parent.AllowHousing( from, p );
return true;
}
public virtual bool NoMounts( Mobile from, Point3D p )
{
if ( m_Parent != null )
return m_Parent.NoMounts( from, p );
return false;
}
public virtual bool SendInaccessibleMessage( Item item, Mobile from )
{
if ( m_Parent != null )
return m_Parent.SendInaccessibleMessage( item, from );
return false;
}
public virtual bool CheckAccessibility( Item item, Mobile from )
{
if ( m_Parent != null )
return m_Parent.CheckAccessibility( item, from );
return true;
}
public virtual bool OnDecay( Item item )
{
if ( m_Parent != null )
return m_Parent.OnDecay( item );
return true;
}
public virtual bool AllowHarmful( Mobile from, Mobile target )
{
if ( m_Parent != null )
return m_Parent.AllowHarmful( from, target );
if ( Mobile.AllowHarmfulHandler != null )
return Mobile.AllowHarmfulHandler( from, target );
return true;
}
public virtual void OnCriminalAction( Mobile m, bool message )
{
if ( m_Parent != null )
m_Parent.OnCriminalAction( m, message );
else if ( message )
m.SendLocalizedMessage( 1005040 ); // You've committed a criminal act!!
}
public virtual bool AllowBeneficial( Mobile from, Mobile target )
{
if ( m_Parent != null )
return m_Parent.AllowBeneficial( from, target );
if ( Mobile.AllowBeneficialHandler != null )
return Mobile.AllowBeneficialHandler( from, target );
return true;
}
public virtual void OnBeneficialAction( Mobile helper, Mobile target )
{
if ( m_Parent != null )
m_Parent.OnBeneficialAction( helper, target );
}
public virtual void OnGotBeneficialAction( Mobile helper, Mobile target )
{
if ( m_Parent != null )
m_Parent.OnGotBeneficialAction( helper, target );
}
public virtual void SpellDamageScalar( Mobile caster, Mobile target, ref double damage )
{
if ( m_Parent != null )
m_Parent.SpellDamageScalar( caster, target, ref damage );
}
public virtual void OnSpeech( SpeechEventArgs args )
{
if ( m_Parent != null )
m_Parent.OnSpeech( args );
}
public virtual bool OnSkillUse( Mobile m, int Skill )
{
if ( m_Parent != null )
return m_Parent.OnSkillUse( m, Skill );
return true;
}
public virtual bool OnBeginSpellCast( Mobile m, ISpell s )
{
if ( m_Parent != null )
return m_Parent.OnBeginSpellCast( m, s );
return true;
}
public virtual void OnSpellCast( Mobile m, ISpell s )
{
if ( m_Parent != null )
m_Parent.OnSpellCast( m, s );
}
public virtual bool OnResurrect( Mobile m )
{
if ( m_Parent != null )
return m_Parent.OnResurrect( m );
return true;
}
public virtual bool OnBeforeDeath( Mobile m )
{
if ( m_Parent != null )
return m_Parent.OnBeforeDeath( m );
return true;
}
public virtual void OnDeath( Mobile m )
{
if ( m_Parent != null )
m_Parent.OnDeath( m );
}
public virtual bool OnDamage( Mobile m, ref int Damage )
{
if ( m_Parent != null )
return m_Parent.OnDamage( m, ref Damage );
return true;
}
public virtual bool OnHeal( Mobile m, ref int Heal )
{
if ( m_Parent != null )
return m_Parent.OnHeal( m, ref Heal );
return true;
}
public virtual bool OnDoubleClick( Mobile m, object o )
{
if ( m_Parent != null )
return m_Parent.OnDoubleClick( m, o );
return true;
}
public virtual bool OnSingleClick( Mobile m, object o )
{
if ( m_Parent != null )
return m_Parent.OnSingleClick( m, o );
return true;
}
public virtual bool AllowSpawn()
{
if ( m_Parent != null )
return m_Parent.AllowSpawn();
return true;
}
public virtual void AlterLightLevel( Mobile m, ref int global, ref int personal )
{
if ( m_Parent != null )
m_Parent.AlterLightLevel( m, ref global, ref personal );
}
public virtual TimeSpan GetLogoutDelay( Mobile m )
{
if ( m_Parent != null )
return m_Parent.GetLogoutDelay( m );
else if ( m.AccessLevel > AccessLevel.Player )
return m_StaffLogoutDelay;
else
return m_DefaultLogoutDelay;
}
internal static bool CanMove( Mobile m, Direction d, Point3D newLocation, Point3D oldLocation, Map map )
{
Region oldRegion = m.Region;
Region newRegion = Find( newLocation, map );
while ( oldRegion != newRegion )
{
if ( !newRegion.OnMoveInto( m, d, newLocation, oldLocation ) )
return false;
if ( newRegion.m_Parent == null )
return true;
newRegion = newRegion.m_Parent;
}
return true;
}
internal static void OnRegionChange( Mobile m, Region oldRegion, Region newRegion )
{
if ( newRegion != null && m.NetState != null )
{
m.CheckLightLevels( false );
if ( oldRegion == null || oldRegion.Music != newRegion.Music )
{
m.Send( PlayMusic.GetInstance( newRegion.Music ) );
}
}
Region oldR = oldRegion;
Region newR = newRegion;
while ( oldR != newR )
{
int oldRChild = ( oldR != null ? oldR.ChildLevel : -1 );
int newRChild = ( newR != null ? newR.ChildLevel : -1 );
if ( oldRChild >= newRChild )
{
oldR.OnExit( m );
oldR = oldR.Parent;
}
if ( newRChild >= oldRChild )
{
newR.OnEnter( m );
newR = newR.Parent;
}
}
}
internal static void Load()
{
if ( !System.IO.File.Exists( "Data/Config/Regions.xml" ) )
{
Console.WriteLine( "Error: Data/Config/Regions.xml does not exist" );
return;
}
Console.Write( "Regions: Loading..." );
XmlDocument doc = new XmlDocument();
doc.Load( System.IO.Path.Combine( Core.BaseDirectory, "Data/Config/Regions.xml" ) );
XmlElement root = doc["ServerRegions"];
if ( root == null )
{
Console.WriteLine( "Could not find root element 'ServerRegions' in Regions.xml" );
}
else
{
foreach ( XmlElement facet in root.SelectNodes( "Facet" ) )
{
Map map = null;
if ( ReadMap( facet, "name", ref map ) )
{
if ( map == Map.Internal )
Console.WriteLine( "Invalid internal map in a facet element" );
else
LoadRegions( facet, map, null );
}
}
}
Console.WriteLine( "done" );
}
private static void LoadRegions( XmlElement xml, Map map, Region parent )
{
foreach ( XmlElement xmlReg in xml.SelectNodes( "region" ) )
{
Type type = DefaultRegionType;
ReadType( xmlReg, "type", ref type, false );
if ( !typeof( Region ).IsAssignableFrom( type ) )
{
Console.WriteLine( "Invalid region type '{0}' in regions.xml", type.FullName );
continue;
}
Region region = null;
try
{
region = (Region) Activator.CreateInstance( type, new object[] { xmlReg, map, parent } );
}
catch ( Exception ex )
{
Console.WriteLine( "Error during the creation of region type '{0}': {1}", type.FullName, ex );
continue;
}
region.Register();
LoadRegions( xmlReg, map, region );
}
}
public Region( XmlElement xml, Map map, Region parent )
{
m_Map = map;
m_Parent = parent;
m_Dynamic = false;
if ( m_Parent == null )
{
m_ChildLevel = 0;
m_Priority = DefaultPriority;
}
else
{
m_ChildLevel = m_Parent.ChildLevel + 1;
m_Priority = m_Parent.Priority;
}
ReadString( xml, "name", ref m_Name, false );
if ( parent == null )
ReadInt32( xml, "priority", ref m_Priority, false );
int minZ = MinZ;
int maxZ = MaxZ;
XmlElement zrange = xml["zrange"];
ReadInt32( zrange, "min", ref minZ, false );
ReadInt32( zrange, "max", ref maxZ, false );
List<Rectangle3D> area = new List<Rectangle3D>();
foreach ( XmlElement xmlRect in xml.SelectNodes( "rect" ) )
{
Rectangle3D rect = new Rectangle3D();
if ( ReadRectangle3D( xmlRect, minZ, maxZ, ref rect ) )
area.Add( rect );
}
m_Area = area.ToArray();
if ( m_Area.Length == 0 )
Console.WriteLine( "Empty area for region '{0}'", this );
if ( !ReadPoint3D( xml["go"], map, ref m_GoLocation, false ) && m_Area.Length > 0 )
{
Point3D start = m_Area[0].Start;
Point3D end = m_Area[0].End;
int x = start.X + (end.X - start.X) / 2;
int y = start.Y + (end.Y - start.Y) / 2;
m_GoLocation = new Point3D( x, y, m_Map.GetAverageZ( x, y ) );
}
MusicName music = this.DefaultMusic;
ReadEnum( xml["music"], "name", ref music, false );
m_Music = music;
}
protected static string GetAttribute( XmlElement xml, string attribute, bool mandatory )
{
if ( xml == null )
{
if ( mandatory )
Console.WriteLine( "Missing element for attribute '{0}'", attribute );
return null;
}
else if ( xml.HasAttribute( attribute ) )
{
return xml.GetAttribute( attribute );
}
else
{
if ( mandatory )
Console.WriteLine( "Missing attribute '{0}' in element '{1}'", attribute, xml.Name );
return null;
}
}
public static bool ReadString( XmlElement xml, string attribute, ref string value )
{
return ReadString( xml, attribute, ref value, true );
}
public static bool ReadString( XmlElement xml, string attribute, ref string value, bool mandatory )
{
string s = GetAttribute( xml, attribute, mandatory );
if ( s == null )
return false;
value = s;
return true;
}
public static bool ReadInt32( XmlElement xml, string attribute, ref int value )
{
return ReadInt32( xml, attribute, ref value, true );
}
public static bool ReadInt32( XmlElement xml, string attribute, ref int value, bool mandatory )
{
string s = GetAttribute( xml, attribute, mandatory );
if ( s == null )
return false;
try
{
value = XmlConvert.ToInt32( s );
}
catch
{
Console.WriteLine( "Could not parse integer attribute '{0}' in element '{1}'", attribute, xml.Name );
return false;
}
return true;
}
public static bool ReadBoolean( XmlElement xml, string attribute, ref bool value )
{
return ReadBoolean( xml, attribute, ref value, true );
}
public static bool ReadBoolean( XmlElement xml, string attribute, ref bool value, bool mandatory )
{
string s = GetAttribute( xml, attribute, mandatory );
if ( s == null )
return false;
try
{
value = XmlConvert.ToBoolean( s );
}
catch
{
Console.WriteLine( "Could not parse boolean attribute '{0}' in element '{1}'", attribute, xml.Name );
return false;
}
return true;
}
public static bool ReadDateTime( XmlElement xml, string attribute, ref DateTime value )
{
return ReadDateTime( xml, attribute, ref value, true );
}
public static bool ReadDateTime( XmlElement xml, string attribute, ref DateTime value, bool mandatory )
{
string s = GetAttribute( xml, attribute, mandatory );
if ( s == null )
return false;
try
{
value = XmlConvert.ToDateTime( s, XmlDateTimeSerializationMode.Local );
}
catch
{
Console.WriteLine( "Could not parse DateTime attribute '{0}' in element '{1}'", attribute, xml.Name );
return false;
}
return true;
}
public static bool ReadTimeSpan( XmlElement xml, string attribute, ref TimeSpan value )
{
return ReadTimeSpan( xml, attribute, ref value, true );
}
public static bool ReadTimeSpan( XmlElement xml, string attribute, ref TimeSpan value, bool mandatory )
{
string s = GetAttribute( xml, attribute, mandatory );
if ( s == null )
return false;
try
{
value = XmlConvert.ToTimeSpan( s );
}
catch
{
Console.WriteLine( "Could not parse TimeSpan attribute '{0}' in element '{1}'", attribute, xml.Name );
return false;
}
return true;
}
public static bool ReadEnum<T>( XmlElement xml, string attribute, ref T value )
{
return ReadEnum( xml, attribute, ref value, true );
}
public static bool ReadEnum<T>( XmlElement xml, string attribute, ref T value, bool mandatory )
{
string s = GetAttribute( xml, attribute, mandatory );
if ( s == null )
return false;
Type type = typeof(T);
try
{
value = (T)Enum.Parse(type, s, true);
//TODO: On .NET 4.0, use Enum.TryParse
}
catch
{
Console.WriteLine( "Could not parse {0} enum attribute '{1}' in element '{2}'", type, attribute, xml.Name );
return false;
}
return true;
}
public static bool ReadMap( XmlElement xml, string attribute, ref Map value )
{
return ReadMap( xml, attribute, ref value, true );
}
public static bool ReadMap( XmlElement xml, string attribute, ref Map value, bool mandatory )
{
string s = GetAttribute( xml, attribute, mandatory );
if ( s == null )
return false;
try
{
value = Map.Parse( s );
}
catch
{
Console.WriteLine( "Could not parse Map attribute '{0}' in element '{1}'", attribute, xml.Name );
return false;
}
return true;
}
public static bool ReadType( XmlElement xml, string attribute, ref Type value )
{
return ReadType( xml, attribute, ref value, true );
}
public static bool ReadType( XmlElement xml, string attribute, ref Type value, bool mandatory )
{
string s = GetAttribute( xml, attribute, mandatory );
if ( s == null )
return false;
Type type;
try
{
type = ScriptCompiler.FindTypeByName( s, false );
}
catch
{
Console.WriteLine( "Could not parse Type attribute '{0}' in element '{1}'", attribute, xml.Name );
return false;
}
if ( type == null )
{
Console.WriteLine( "Could not find Type '{0}'", s );
return false;
}
value = type;
return true;
}
public static bool ReadPoint3D( XmlElement xml, Map map, ref Point3D value )
{
return ReadPoint3D( xml, map, ref value, true );
}
public static bool ReadPoint3D( XmlElement xml, Map map, ref Point3D value, bool mandatory )
{
int x = 0, y = 0, z = 0;
bool xyOk = ReadInt32( xml, "x", ref x, mandatory ) & ReadInt32( xml, "y", ref y, mandatory );
bool zOk = ReadInt32( xml, "z", ref z, mandatory && map == null );
if ( xyOk && ( zOk || map != null ) )
{
if ( !zOk )
z = map.GetAverageZ( x, y );
value = new Point3D( x, y, z );
return true;
}
return false;
}
public static bool ReadRectangle3D( XmlElement xml, int defaultMinZ, int defaultMaxZ, ref Rectangle3D value )
{
return ReadRectangle3D( xml, defaultMinZ, defaultMaxZ, ref value, true );
}
public static bool ReadRectangle3D( XmlElement xml, int defaultMinZ, int defaultMaxZ, ref Rectangle3D value, bool mandatory )
{
int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
if ( xml.HasAttribute( "x" ) )
{
if ( ReadInt32( xml, "x", ref x1, mandatory )
& ReadInt32( xml, "y", ref y1, mandatory )
& ReadInt32( xml, "width", ref x2, mandatory )
& ReadInt32( xml, "height", ref y2, mandatory ) )
{
x2 += x1;
y2 += y1;
}
else
{
return false;
}
}
else
{
if ( !ReadInt32( xml, "x1", ref x1, mandatory )
| !ReadInt32( xml, "y1", ref y1, mandatory )
| !ReadInt32( xml, "x2", ref x2, mandatory )
| !ReadInt32( xml, "y2", ref y2, mandatory ) )
{
return false;
}
}
int z1 = defaultMinZ;
int z2 = defaultMaxZ;
ReadInt32( xml, "zmin", ref z1, false );
ReadInt32( xml, "zmax", ref z2, false );
value = new Rectangle3D( new Point3D( x1, y1, z1 ), new Point3D( x2, y2, z2 ) );
return true;
}
}
}