#W# Initial Commit: Avatars Conquest
This commit is contained in:
commit
5df497787a
7510 changed files with 416048 additions and 0 deletions
426
Scripts/Commands/GenCategorization.cs
Normal file
426
Scripts/Commands/GenCategorization.cs
Normal file
|
|
@ -0,0 +1,426 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Commands
|
||||
{
|
||||
public class Categorization
|
||||
{
|
||||
private static CategoryEntry m_RootItems, m_RootMobiles;
|
||||
|
||||
public static CategoryEntry Items
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( m_RootItems == null )
|
||||
Load();
|
||||
|
||||
return m_RootItems;
|
||||
}
|
||||
}
|
||||
|
||||
public static CategoryEntry Mobiles
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( m_RootMobiles == null )
|
||||
Load();
|
||||
|
||||
return m_RootMobiles;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "RebuildCategorization", AccessLevel.Administrator, new CommandEventHandler( RebuildCategorization_OnCommand ) );
|
||||
}
|
||||
|
||||
[Usage( "RebuildCategorization" )]
|
||||
[Description( "Rebuilds the categorization data file used by the Add command." )]
|
||||
public static void RebuildCategorization_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
CategoryEntry root = new CategoryEntry( null, "Add Menu", new CategoryEntry[]{ Items, Mobiles } );
|
||||
|
||||
Export( root, "Data/Config/objects.xml", "Objects" );
|
||||
|
||||
e.Mobile.SendMessage( "Categorization menu rebuilt." );
|
||||
}
|
||||
|
||||
public static void RecurseFindCategories( CategoryEntry ce, ArrayList list )
|
||||
{
|
||||
list.Add( ce );
|
||||
|
||||
for ( int i = 0; i < ce.SubCategories.Length; ++i )
|
||||
RecurseFindCategories( ce.SubCategories[i], list );
|
||||
}
|
||||
|
||||
public static void Export( CategoryEntry ce, string fileName, string title )
|
||||
{
|
||||
XmlTextWriter xml = new XmlTextWriter( fileName, System.Text.Encoding.UTF8 );
|
||||
|
||||
xml.Indentation = 1;
|
||||
xml.IndentChar = '\t';
|
||||
xml.Formatting = Formatting.Indented;
|
||||
|
||||
xml.WriteStartDocument( true );
|
||||
|
||||
RecurseExport( xml, ce );
|
||||
|
||||
xml.Flush();
|
||||
xml.Close();
|
||||
}
|
||||
|
||||
public static void RecurseExport( XmlTextWriter xml, CategoryEntry ce )
|
||||
{
|
||||
xml.WriteStartElement( "category" );
|
||||
|
||||
xml.WriteAttributeString( "title", ce.Title );
|
||||
|
||||
ArrayList subCats = new ArrayList( ce.SubCategories );
|
||||
|
||||
subCats.Sort( new CategorySorter() );
|
||||
|
||||
for ( int i = 0; i < subCats.Count; ++i )
|
||||
RecurseExport( xml, (CategoryEntry)subCats[i] );
|
||||
|
||||
ce.Matched.Sort( new CategorySorter() );
|
||||
|
||||
for ( int i = 0; i < ce.Matched.Count; ++i )
|
||||
{
|
||||
CategoryTypeEntry cte = (CategoryTypeEntry)ce.Matched[i];
|
||||
|
||||
xml.WriteStartElement( "object" );
|
||||
|
||||
xml.WriteAttributeString( "type", cte.Type.ToString() );
|
||||
|
||||
object obj = cte.Object;
|
||||
|
||||
if ( obj is Item )
|
||||
{
|
||||
Item item = (Item)obj;
|
||||
|
||||
int itemID = item.ItemID;
|
||||
|
||||
if ( item is BaseAddon && ((BaseAddon)item).Components.Count == 1 )
|
||||
itemID = ((AddonComponent)(((BaseAddon)item).Components[0])).ItemID;
|
||||
|
||||
if ( itemID > TileData.MaxItemValue )
|
||||
itemID = 1;
|
||||
|
||||
xml.WriteAttributeString( "gfx", XmlConvert.ToString( itemID ) );
|
||||
|
||||
int hue = item.Hue & 0x7FFF;
|
||||
|
||||
if ( (hue & 0x4000) != 0 )
|
||||
hue = 0;
|
||||
|
||||
if ( hue != 0 )
|
||||
xml.WriteAttributeString( "hue", XmlConvert.ToString( hue ) );
|
||||
|
||||
item.Delete();
|
||||
}
|
||||
else if ( obj is Mobile )
|
||||
{
|
||||
Mobile mob = (Mobile)obj;
|
||||
|
||||
int itemID = ShrinkTable.Lookup( mob, 1 );
|
||||
|
||||
xml.WriteAttributeString( "gfx", XmlConvert.ToString( itemID ) );
|
||||
|
||||
int hue = mob.Hue & 0x7FFF;
|
||||
|
||||
if ( (hue & 0x4000) != 0 )
|
||||
hue = 0;
|
||||
|
||||
if ( hue != 0 )
|
||||
xml.WriteAttributeString( "hue", XmlConvert.ToString( hue ) );
|
||||
|
||||
mob.Delete();
|
||||
}
|
||||
|
||||
xml.WriteEndElement();
|
||||
}
|
||||
|
||||
xml.WriteEndElement();
|
||||
}
|
||||
|
||||
public static void Load()
|
||||
{
|
||||
ArrayList types = new ArrayList();
|
||||
|
||||
AddTypes( Core.Assembly, types );
|
||||
|
||||
for ( int i = 0; i < ScriptCompiler.Assemblies.Length; ++i )
|
||||
AddTypes( ScriptCompiler.Assemblies[i], types );
|
||||
|
||||
m_RootItems = Load( types, "Data/Config/items.cfg" );
|
||||
m_RootMobiles = Load( types, "Data/Config/mobiles.cfg" );
|
||||
}
|
||||
|
||||
private static CategoryEntry Load( ArrayList types, string config )
|
||||
{
|
||||
CategoryLine[] lines = CategoryLine.Load( config );
|
||||
|
||||
if ( lines.Length > 0 )
|
||||
{
|
||||
int index = 0;
|
||||
CategoryEntry root = new CategoryEntry( null, lines, ref index );
|
||||
|
||||
Fill( root, types );
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
return new CategoryEntry();
|
||||
}
|
||||
|
||||
private static Type typeofItem = typeof( Item );
|
||||
private static Type typeofMobile = typeof( Mobile );
|
||||
private static Type typeofConstructable = typeof( ConstructableAttribute );
|
||||
|
||||
private static bool IsConstructable( Type type )
|
||||
{
|
||||
if ( !type.IsSubclassOf( typeofItem ) && !type.IsSubclassOf( typeofMobile ) )
|
||||
return false;
|
||||
|
||||
ConstructorInfo ctor = type.GetConstructor( Type.EmptyTypes );
|
||||
|
||||
return ( ctor != null && ctor.IsDefined( typeofConstructable, false ) );
|
||||
}
|
||||
|
||||
private static void AddTypes( Assembly asm, ArrayList types )
|
||||
{
|
||||
Type[] allTypes = asm.GetTypes();
|
||||
|
||||
for ( int i = 0; i < allTypes.Length; ++i )
|
||||
{
|
||||
Type type = allTypes[i];
|
||||
|
||||
if ( type.IsAbstract )
|
||||
continue;
|
||||
|
||||
if ( IsConstructable( type ) )
|
||||
types.Add( type );
|
||||
}
|
||||
}
|
||||
|
||||
private static void Fill( CategoryEntry root, ArrayList list )
|
||||
{
|
||||
for ( int i = 0; i < list.Count; ++i )
|
||||
{
|
||||
Type type = (Type)list[i];
|
||||
CategoryEntry match = GetDeepestMatch( root, type );
|
||||
|
||||
if ( match == null )
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
match.Matched.Add( new CategoryTypeEntry( type ) );
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static CategoryEntry GetDeepestMatch( CategoryEntry root, Type type )
|
||||
{
|
||||
if ( !root.IsMatch( type ) )
|
||||
return null;
|
||||
|
||||
for ( int i = 0; i < root.SubCategories.Length; ++i )
|
||||
{
|
||||
CategoryEntry check = GetDeepestMatch( root.SubCategories[i], type );
|
||||
|
||||
if ( check != null )
|
||||
return check;
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
public class CategorySorter : IComparer
|
||||
{
|
||||
public int Compare( object x, object y )
|
||||
{
|
||||
string a = null, b = null;
|
||||
|
||||
if ( x is CategoryEntry )
|
||||
a = ((CategoryEntry)x).Title;
|
||||
else if ( x is CategoryTypeEntry )
|
||||
a = ((CategoryTypeEntry)x).Type.Name;
|
||||
|
||||
if ( y is CategoryEntry )
|
||||
b = ((CategoryEntry)y).Title;
|
||||
else if ( y is CategoryTypeEntry )
|
||||
b = ((CategoryTypeEntry)y).Type.Name;
|
||||
|
||||
if ( a == null && b == null )
|
||||
return 0;
|
||||
|
||||
if ( a == null )
|
||||
return 1;
|
||||
|
||||
if ( b == null )
|
||||
return -1;
|
||||
|
||||
return a.CompareTo( b );
|
||||
}
|
||||
}
|
||||
|
||||
public class CategoryTypeEntry
|
||||
{
|
||||
private Type m_Type;
|
||||
private object m_Object;
|
||||
|
||||
public Type Type{ get{ return m_Type; } }
|
||||
public object Object{ get{ return m_Object; } }
|
||||
|
||||
public CategoryTypeEntry( Type type )
|
||||
{
|
||||
m_Type = type;
|
||||
m_Object = Activator.CreateInstance( type );
|
||||
}
|
||||
}
|
||||
|
||||
public class CategoryEntry
|
||||
{
|
||||
private string m_Title;
|
||||
private Type[] m_Matches;
|
||||
private CategoryEntry[] m_SubCategories;
|
||||
private CategoryEntry m_Parent;
|
||||
private ArrayList m_Matched;
|
||||
|
||||
public string Title{ get{ return m_Title; } }
|
||||
public Type[] Matches{ get{ return m_Matches; } }
|
||||
public CategoryEntry Parent{ get{ return m_Parent; } }
|
||||
public CategoryEntry[] SubCategories{ get{ return m_SubCategories; } }
|
||||
public ArrayList Matched{ get{ return m_Matched; } }
|
||||
|
||||
public CategoryEntry()
|
||||
{
|
||||
m_Title = "(empty)";
|
||||
m_Matches = new Type[0];
|
||||
m_SubCategories = new CategoryEntry[0];
|
||||
m_Matched = new ArrayList();
|
||||
}
|
||||
|
||||
public CategoryEntry( CategoryEntry parent, string title, CategoryEntry[] subCats )
|
||||
{
|
||||
m_Parent = parent;
|
||||
m_Title = title;
|
||||
m_SubCategories = subCats;
|
||||
m_Matches = new Type[0];
|
||||
m_Matched = new ArrayList();
|
||||
}
|
||||
|
||||
public bool IsMatch( Type type )
|
||||
{
|
||||
bool isMatch = false;
|
||||
|
||||
for ( int i = 0; !isMatch && i < m_Matches.Length; ++i )
|
||||
isMatch = ( type == m_Matches[i] || type.IsSubclassOf( m_Matches[i] ) );
|
||||
|
||||
return isMatch;
|
||||
}
|
||||
|
||||
public CategoryEntry( CategoryEntry parent, CategoryLine[] lines, ref int index )
|
||||
{
|
||||
m_Parent = parent;
|
||||
|
||||
string text = lines[index].Text;
|
||||
|
||||
int start = text.IndexOf( '(' );
|
||||
|
||||
if ( start < 0 )
|
||||
throw new FormatException( String.Format( "Input string not correctly formatted ('{0}')", text ) );
|
||||
|
||||
m_Title = text.Substring( 0, start ).Trim();
|
||||
|
||||
int end = text.IndexOf( ')', ++start );
|
||||
|
||||
if ( end < start )
|
||||
throw new FormatException( String.Format( "Input string not correctly formatted ('{0}')", text ) );
|
||||
|
||||
text = text.Substring( start, end-start );
|
||||
string[] split = text.Split( ';' );
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
|
||||
for ( int i = 0; i < split.Length; ++i )
|
||||
{
|
||||
Type type = ScriptCompiler.FindTypeByName( split[i].Trim() );
|
||||
|
||||
if ( type == null )
|
||||
Console.WriteLine( "Match type not found ('{0}')", split[i].Trim() );
|
||||
else
|
||||
list.Add( type );
|
||||
}
|
||||
|
||||
m_Matches = (Type[])list.ToArray( typeof( Type ) );
|
||||
list.Clear();
|
||||
|
||||
int ourIndentation = lines[index].Indentation;
|
||||
|
||||
++index;
|
||||
|
||||
while ( index < lines.Length && lines[index].Indentation > ourIndentation )
|
||||
list.Add( new CategoryEntry( this, lines, ref index ) );
|
||||
|
||||
m_SubCategories = (CategoryEntry[])list.ToArray( typeof( CategoryEntry ) );
|
||||
list.Clear();
|
||||
|
||||
m_Matched = list;
|
||||
}
|
||||
}
|
||||
|
||||
public class CategoryLine
|
||||
{
|
||||
private int m_Indentation;
|
||||
private string m_Text;
|
||||
|
||||
public int Indentation{ get{ return m_Indentation; } }
|
||||
public string Text{ get{ return m_Text; } }
|
||||
|
||||
public CategoryLine( string input )
|
||||
{
|
||||
int index;
|
||||
|
||||
for ( index = 0; index < input.Length; ++index )
|
||||
{
|
||||
if ( Char.IsLetter( input, index ) )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( index >= input.Length )
|
||||
throw new FormatException( String.Format( "Input string not correctly formatted ('{0}')", input ) );
|
||||
|
||||
m_Indentation = index;
|
||||
m_Text = input.Substring( index );
|
||||
}
|
||||
|
||||
public static CategoryLine[] Load( string path )
|
||||
{
|
||||
ArrayList list = new ArrayList();
|
||||
|
||||
if ( File.Exists( path ) )
|
||||
{
|
||||
using ( StreamReader ip = new StreamReader( path ) )
|
||||
{
|
||||
string line;
|
||||
|
||||
while ( (line = ip.ReadLine()) != null )
|
||||
list.Add( new CategoryLine( line ) );
|
||||
}
|
||||
}
|
||||
|
||||
return (CategoryLine[])list.ToArray( typeof( CategoryLine ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue