Split profiling specific handlers from Handlers.cs to Profiling.cs

This commit is contained in:
mark 2010-12-18 10:15:17 +00:00
parent 8602664c0c
commit cd8f792132
4 changed files with 473 additions and 445 deletions

View file

@ -1,10 +1,10 @@
using System;
using System.IO;
using Server;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using Server;
using Server.Accounting;
using Server.Mobiles;
using Server.Items;
@ -17,7 +17,6 @@ using Server.Targeting;
using Server.Targets;
using Server.Gumps;
using Server.Commands.Generic;
using Server.Diagnostics;
namespace Server.Commands
{
@ -27,8 +26,6 @@ namespace Server.Commands
{
CommandSystem.Prefix = "[";
Properties.Register();
Register( "Go", AccessLevel.Counselor, new CommandEventHandler( Go_OnCommand ) );
Register( "DropHolding", AccessLevel.Counselor, new CommandEventHandler( DropHolding_OnCommand ) );
@ -71,14 +68,6 @@ namespace Server.Commands
Register( "ViewEquip", AccessLevel.GameMaster, new CommandEventHandler( ViewEquip_OnCommand ) );
Register( "DumpTimers", AccessLevel.Administrator, new CommandEventHandler( DumpTimers_OnCommand ) );
Register( "CountObjects", AccessLevel.Administrator, new CommandEventHandler( CountObjects_OnCommand ) );
Register( "ProfileWorld", AccessLevel.Administrator, new CommandEventHandler( ProfileWorld_OnCommand ) );
Register( "TraceInternal", AccessLevel.Administrator, new CommandEventHandler( TraceInternal_OnCommand ) );
Register( "TraceExpanded", AccessLevel.Administrator, new CommandEventHandler( TraceExpanded_OnCommand ) );
Register( "WriteProfiles", AccessLevel.Administrator, new CommandEventHandler( WriteProfiles_OnCommand ) );
Register( "SetProfiles", AccessLevel.Administrator, new CommandEventHandler( SetProfiles_OnCommand ) );
Register( "Light", AccessLevel.Counselor, new CommandEventHandler( Light_OnCommand ) );
Register( "Stats", AccessLevel.Counselor, new CommandEventHandler( Stats_OnCommand ) );
@ -473,382 +462,6 @@ namespace Server.Commands
}
}
[Usage( "WriteProfiles" )]
[Description( "Generates a log files containing performance diagnostic information." )]
public static void WriteProfiles_OnCommand( CommandEventArgs e )
{
try
{
using ( StreamWriter sw = new StreamWriter( "profiles.log", true ) )
{
sw.WriteLine( "# Dump on {0:f}", DateTime.Now );
sw.WriteLine( "# Core profiling for " + Core.ProfileTime );
sw.WriteLine( "# Packet send" );
BaseProfile.WriteAll( sw, PacketSendProfile.Profiles );
sw.WriteLine();
sw.WriteLine( "# Packet receive" );
BaseProfile.WriteAll( sw, PacketReceiveProfile.Profiles );
sw.WriteLine();
sw.WriteLine( "# Timer" );
BaseProfile.WriteAll( sw, TimerProfile.Profiles );
sw.WriteLine();
sw.WriteLine( "# Gump response" );
BaseProfile.WriteAll( sw, GumpProfile.Profiles );
sw.WriteLine();
sw.WriteLine( "# Target response" );
BaseProfile.WriteAll( sw, TargetProfile.Profiles );
sw.WriteLine();
}
}
catch
{
}
}
[Usage( "SetProfiles [true | false]" )]
[Description( "Enables, disables, or toggles the state of core packet and timer profiling." )]
public static void SetProfiles_OnCommand( CommandEventArgs e )
{
if ( e.Length == 1 )
Core.Profiling = e.GetBoolean( 0 );
else
Core.Profiling = !Core.Profiling;
e.Mobile.SendMessage( "Profiling has been {0}.", Core.Profiling ? "enabled" : "disabled" );
}
[Usage( "DumpTimers" )]
[Description( "Generates a log file of all currently executing timers. Used for tracing timer leaks." )]
public static void DumpTimers_OnCommand( CommandEventArgs e )
{
try
{
using ( StreamWriter sw = new StreamWriter( "timerdump.log", true ) )
Timer.DumpInfo( sw );
}
catch
{
}
}
private class CountSorter : IComparer
{
public int Compare( object x, object y )
{
DictionaryEntry a = (DictionaryEntry)x;
DictionaryEntry b = (DictionaryEntry)y;
int aCount = GetCount( a.Value );
int bCount = GetCount( b.Value );
int v = -aCount.CompareTo( bCount );
if ( v == 0 )
{
Type aType = (Type)a.Key;
Type bType = (Type)b.Key;
v = aType.FullName.CompareTo( bType.FullName );
}
return v;
}
private int GetCount( object obj )
{
if ( obj is int )
return (int) obj;
if ( obj is int[] )
{
int[] list = (int[]) obj;
int total = 0;
for ( int i = 0; i < list.Length; ++i )
total += list[i];
return total;
}
return 0;
}
}
[Usage( "CountObjects" )]
[Description( "Generates a log file detailing all item and mobile types in the world." )]
public static void CountObjects_OnCommand( CommandEventArgs e )
{
using ( StreamWriter op = new StreamWriter( "objects.log" ) )
{
Hashtable table = new Hashtable();
foreach ( Item item in World.Items.Values )
{
Type type = item.GetType();
object o = (object)table[type];
if ( o == null )
table[type] = 1;
else
table[type] = 1 + (int)o;
}
ArrayList items = new ArrayList( table );
table.Clear();
foreach ( Mobile m in World.Mobiles.Values )
{
Type type = m.GetType();
object o = (object)table[type];
if ( o == null )
table[type] = 1;
else
table[type] = 1 + (int)o;
}
ArrayList mobiles = new ArrayList( table );
items.Sort( new CountSorter() );
mobiles.Sort( new CountSorter() );
op.WriteLine( "# Object count table generated on {0}", DateTime.Now );
op.WriteLine();
op.WriteLine();
op.WriteLine( "# Items:" );
foreach ( DictionaryEntry de in items )
op.WriteLine( "{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)World.Items.Count, de.Key );
op.WriteLine();
op.WriteLine();
op.WriteLine( "#Mobiles:" );
foreach ( DictionaryEntry de in mobiles )
op.WriteLine( "{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)World.Mobiles.Count, de.Key );
}
e.Mobile.SendMessage( "Object table has been generated. See the file : <runuo root>/objects.log" );
}
[Usage( "TraceExpanded" )]
[Description( "Generates a log file describing all items using expanded memory." )]
public static void TraceExpanded_OnCommand( CommandEventArgs e )
{
Hashtable typeTable = new Hashtable();
foreach ( Item item in World.Items.Values )
{
ExpandFlag flags = item.GetExpandFlags();
if ( ( flags & ~(ExpandFlag.TempFlag | ExpandFlag.SaveFlag) ) == 0 )
continue;
Type itemType = item.GetType();
do
{
int[] countTable = typeTable[itemType] as int[];
if ( countTable == null )
typeTable[itemType] = countTable = new int[8];
if ( ( flags & ExpandFlag.Name ) != 0 )
++countTable[0];
if ( ( flags & ExpandFlag.Items ) != 0 )
++countTable[1];
if ( ( flags & ExpandFlag.Bounce ) != 0 )
++countTable[2];
if ( ( flags & ExpandFlag.Holder ) != 0 )
++countTable[3];
if ( ( flags & ExpandFlag.Blessed ) != 0 )
++countTable[4];
/*if ( ( flags & ExpandFlag.TempFlag ) != 0 )
++countTable[5];
if ( ( flags & ExpandFlag.SaveFlag ) != 0 )
++countTable[6];*/
if ( ( flags & ExpandFlag.Weight ) != 0 )
++countTable[7];
itemType = itemType.BaseType;
} while ( itemType != typeof( object ) );
}
try
{
using ( StreamWriter op = new StreamWriter( "expandedItems.log", true ) )
{
string[] names = new string[]
{
"Name",
"Items",
"Bounce",
"Holder",
"Blessed",
"TempFlag",
"SaveFlag",
"Weight"
};
ArrayList list = new ArrayList( typeTable );
list.Sort( new CountSorter() );
foreach ( DictionaryEntry de in list )
{
Type itemType = de.Key as Type;
int[] countTable = de.Value as int[];
op.WriteLine( "# {0}", itemType.FullName );
for ( int i = 0; i < countTable.Length; ++i )
{
if ( countTable[i] > 0 )
op.WriteLine( "{0}\t{1:N0}", names[i], countTable[i] );
}
op.WriteLine();
}
}
}
catch
{
}
}
[Usage( "TraceInternal" )]
[Description( "Generates a log file describing all items in the 'internal' map." )]
public static void TraceInternal_OnCommand( CommandEventArgs e )
{
int totalCount = 0;
Hashtable table = new Hashtable();
foreach ( Item item in World.Items.Values )
{
if ( item.Parent != null || item.Map != Map.Internal )
continue;
++totalCount;
Type type = item.GetType();
int[] parms = (int[])table[type];
if ( parms == null )
table[type] = parms = new int[]{ 0, 0 };
parms[0]++;
parms[1] += item.Amount;
}
using ( StreamWriter op = new StreamWriter( "internal.log" ) )
{
op.WriteLine( "# {0} items found", totalCount );
op.WriteLine( "# {0} different types", table.Count );
op.WriteLine();
op.WriteLine();
op.WriteLine( "Type\t\tCount\t\tAmount\t\tAvg. Amount" );
foreach ( DictionaryEntry de in table )
{
Type type = (Type)de.Key;
int[] parms = (int[])de.Value;
op.WriteLine( "{0}\t\t{1}\t\t{2}\t\t{3:F2}", type.Name, parms[0], parms[1], (double)parms[1] / parms[0] );
}
}
}
[Usage( "ProfileWorld" )]
[Description( "Prints the amount of data serialized for every object type in your world file." )]
public static void ProfileWorld_OnCommand( CommandEventArgs e )
{
ProfileWorld( "items", "worldprofile_items.log" );
ProfileWorld( "mobiles", "worldprofile_mobiles.log" );
}
public static void ProfileWorld( string type, string opFile )
{
try
{
ArrayList types = new ArrayList();
using ( BinaryReader bin = new BinaryReader( new FileStream( String.Format( "Saves/{0}/{0}.tdb", type ), FileMode.Open, FileAccess.Read, FileShare.Read ) ) )
{
int count = bin.ReadInt32();
for ( int i = 0; i < count; ++i )
types.Add( ScriptCompiler.FindTypeByFullName( bin.ReadString() ) );
}
long total = 0;
Hashtable table = new Hashtable();
using ( BinaryReader bin = new BinaryReader( new FileStream( String.Format( "Saves/{0}/{0}.idx", type ), FileMode.Open, FileAccess.Read, FileShare.Read ) ) )
{
int count = bin.ReadInt32();
for ( int i = 0; i < count; ++i )
{
int typeID = bin.ReadInt32();
int serial = bin.ReadInt32();
long pos = bin.ReadInt64();
int length = bin.ReadInt32();
Type objType = (Type)types[typeID];
while ( objType != null && objType != typeof( object ) )
{
object obj = table[objType];
if ( obj == null )
table[objType] = length;
else
table[objType] = length + (int)obj;
objType = objType.BaseType;
total += length;
}
}
}
ArrayList list = new ArrayList( table );
list.Sort( new CountSorter() );
using ( StreamWriter op = new StreamWriter( opFile ) )
{
op.WriteLine( "# Profile of world {0}", type );
op.WriteLine( "# Generated on {0}", DateTime.Now );
op.WriteLine();
op.WriteLine();
foreach ( DictionaryEntry de in list )
op.WriteLine( "{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)total, de.Key );
}
}
catch
{
}
}
[Usage( "ViewEquip" )]
[Description( "Lists equipment of a targeted mobile. From the list you can move, delete, or open props." )]
public static void ViewEquip_OnCommand( CommandEventArgs e )

View file

@ -0,0 +1,400 @@
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Diagnostics;
namespace Server.Commands
{
public class Profiling
{
public static void Initialize()
{
CommandSystem.Register( "DumpTimers", AccessLevel.Administrator, new CommandEventHandler( DumpTimers_OnCommand ) );
CommandSystem.Register( "CountObjects", AccessLevel.Administrator, new CommandEventHandler( CountObjects_OnCommand ) );
CommandSystem.Register( "ProfileWorld", AccessLevel.Administrator, new CommandEventHandler( ProfileWorld_OnCommand ) );
CommandSystem.Register( "TraceInternal", AccessLevel.Administrator, new CommandEventHandler( TraceInternal_OnCommand ) );
CommandSystem.Register( "TraceExpanded", AccessLevel.Administrator, new CommandEventHandler( TraceExpanded_OnCommand ) );
CommandSystem.Register( "WriteProfiles", AccessLevel.Administrator, new CommandEventHandler( WriteProfiles_OnCommand ) );
CommandSystem.Register( "SetProfiles", AccessLevel.Administrator, new CommandEventHandler( SetProfiles_OnCommand ) );
}
[Usage( "WriteProfiles" )]
[Description( "Generates a log files containing performance diagnostic information." )]
public static void WriteProfiles_OnCommand( CommandEventArgs e )
{
try
{
using ( StreamWriter sw = new StreamWriter( "profiles.log", true ) )
{
sw.WriteLine( "# Dump on {0:f}", DateTime.Now );
sw.WriteLine( "# Core profiling for " + Core.ProfileTime );
sw.WriteLine( "# Packet send" );
BaseProfile.WriteAll( sw, PacketSendProfile.Profiles );
sw.WriteLine();
sw.WriteLine( "# Packet receive" );
BaseProfile.WriteAll( sw, PacketReceiveProfile.Profiles );
sw.WriteLine();
sw.WriteLine( "# Timer" );
BaseProfile.WriteAll( sw, TimerProfile.Profiles );
sw.WriteLine();
sw.WriteLine( "# Gump response" );
BaseProfile.WriteAll( sw, GumpProfile.Profiles );
sw.WriteLine();
sw.WriteLine( "# Target response" );
BaseProfile.WriteAll( sw, TargetProfile.Profiles );
sw.WriteLine();
}
}
catch
{
}
}
[Usage( "SetProfiles [true | false]" )]
[Description( "Enables, disables, or toggles the state of core packet and timer profiling." )]
public static void SetProfiles_OnCommand( CommandEventArgs e )
{
if ( e.Length == 1 )
Core.Profiling = e.GetBoolean( 0 );
else
Core.Profiling = !Core.Profiling;
e.Mobile.SendMessage( "Profiling has been {0}.", Core.Profiling ? "enabled" : "disabled" );
}
[Usage( "DumpTimers" )]
[Description( "Generates a log file of all currently executing timers. Used for tracing timer leaks." )]
public static void DumpTimers_OnCommand( CommandEventArgs e )
{
try
{
using ( StreamWriter sw = new StreamWriter( "timerdump.log", true ) )
Timer.DumpInfo( sw );
}
catch
{
}
}
private class CountSorter : IComparer
{
public int Compare( object x, object y )
{
DictionaryEntry a = (DictionaryEntry)x;
DictionaryEntry b = (DictionaryEntry)y;
int aCount = GetCount( a.Value );
int bCount = GetCount( b.Value );
int v = -aCount.CompareTo( bCount );
if ( v == 0 )
{
Type aType = (Type)a.Key;
Type bType = (Type)b.Key;
v = aType.FullName.CompareTo( bType.FullName );
}
return v;
}
private int GetCount( object obj )
{
if ( obj is int )
return (int) obj;
if ( obj is int[] )
{
int[] list = (int[]) obj;
int total = 0;
for ( int i = 0; i < list.Length; ++i )
total += list[i];
return total;
}
return 0;
}
}
[Usage( "CountObjects" )]
[Description( "Generates a log file detailing all item and mobile types in the world." )]
public static void CountObjects_OnCommand( CommandEventArgs e )
{
using ( StreamWriter op = new StreamWriter( "objects.log" ) )
{
Hashtable table = new Hashtable();
foreach ( Item item in World.Items.Values )
{
Type type = item.GetType();
object o = (object)table[type];
if ( o == null )
table[type] = 1;
else
table[type] = 1 + (int)o;
}
ArrayList items = new ArrayList( table );
table.Clear();
foreach ( Mobile m in World.Mobiles.Values )
{
Type type = m.GetType();
object o = (object)table[type];
if ( o == null )
table[type] = 1;
else
table[type] = 1 + (int)o;
}
ArrayList mobiles = new ArrayList( table );
items.Sort( new CountSorter() );
mobiles.Sort( new CountSorter() );
op.WriteLine( "# Object count table generated on {0}", DateTime.Now );
op.WriteLine();
op.WriteLine();
op.WriteLine( "# Items:" );
foreach ( DictionaryEntry de in items )
op.WriteLine( "{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)World.Items.Count, de.Key );
op.WriteLine();
op.WriteLine();
op.WriteLine( "#Mobiles:" );
foreach ( DictionaryEntry de in mobiles )
op.WriteLine( "{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)World.Mobiles.Count, de.Key );
}
e.Mobile.SendMessage( "Object table has been generated. See the file : <runuo root>/objects.log" );
}
[Usage( "TraceExpanded" )]
[Description( "Generates a log file describing all items using expanded memory." )]
public static void TraceExpanded_OnCommand( CommandEventArgs e )
{
Hashtable typeTable = new Hashtable();
foreach ( Item item in World.Items.Values )
{
ExpandFlag flags = item.GetExpandFlags();
if ( ( flags & ~(ExpandFlag.TempFlag | ExpandFlag.SaveFlag) ) == 0 )
continue;
Type itemType = item.GetType();
do
{
int[] countTable = typeTable[itemType] as int[];
if ( countTable == null )
typeTable[itemType] = countTable = new int[8];
if ( ( flags & ExpandFlag.Name ) != 0 )
++countTable[0];
if ( ( flags & ExpandFlag.Items ) != 0 )
++countTable[1];
if ( ( flags & ExpandFlag.Bounce ) != 0 )
++countTable[2];
if ( ( flags & ExpandFlag.Holder ) != 0 )
++countTable[3];
if ( ( flags & ExpandFlag.Blessed ) != 0 )
++countTable[4];
/*if ( ( flags & ExpandFlag.TempFlag ) != 0 )
++countTable[5];
if ( ( flags & ExpandFlag.SaveFlag ) != 0 )
++countTable[6];*/
if ( ( flags & ExpandFlag.Weight ) != 0 )
++countTable[7];
itemType = itemType.BaseType;
} while ( itemType != typeof( object ) );
}
try
{
using ( StreamWriter op = new StreamWriter( "expandedItems.log", true ) )
{
string[] names = new string[]
{
"Name",
"Items",
"Bounce",
"Holder",
"Blessed",
"TempFlag",
"SaveFlag",
"Weight"
};
ArrayList list = new ArrayList( typeTable );
list.Sort( new CountSorter() );
foreach ( DictionaryEntry de in list )
{
Type itemType = de.Key as Type;
int[] countTable = de.Value as int[];
op.WriteLine( "# {0}", itemType.FullName );
for ( int i = 0; i < countTable.Length; ++i )
{
if ( countTable[i] > 0 )
op.WriteLine( "{0}\t{1:N0}", names[i], countTable[i] );
}
op.WriteLine();
}
}
}
catch
{
}
}
[Usage( "TraceInternal" )]
[Description( "Generates a log file describing all items in the 'internal' map." )]
public static void TraceInternal_OnCommand( CommandEventArgs e )
{
int totalCount = 0;
Hashtable table = new Hashtable();
foreach ( Item item in World.Items.Values )
{
if ( item.Parent != null || item.Map != Map.Internal )
continue;
++totalCount;
Type type = item.GetType();
int[] parms = (int[])table[type];
if ( parms == null )
table[type] = parms = new int[]{ 0, 0 };
parms[0]++;
parms[1] += item.Amount;
}
using ( StreamWriter op = new StreamWriter( "internal.log" ) )
{
op.WriteLine( "# {0} items found", totalCount );
op.WriteLine( "# {0} different types", table.Count );
op.WriteLine();
op.WriteLine();
op.WriteLine( "Type\t\tCount\t\tAmount\t\tAvg. Amount" );
foreach ( DictionaryEntry de in table )
{
Type type = (Type)de.Key;
int[] parms = (int[])de.Value;
op.WriteLine( "{0}\t\t{1}\t\t{2}\t\t{3:F2}", type.Name, parms[0], parms[1], (double)parms[1] / parms[0] );
}
}
}
[Usage( "ProfileWorld" )]
[Description( "Prints the amount of data serialized for every object type in your world file." )]
public static void ProfileWorld_OnCommand( CommandEventArgs e )
{
ProfileWorld( "items", "worldprofile_items.log" );
ProfileWorld( "mobiles", "worldprofile_mobiles.log" );
}
public static void ProfileWorld( string type, string opFile )
{
try
{
ArrayList types = new ArrayList();
using ( BinaryReader bin = new BinaryReader( new FileStream( String.Format( "Saves/{0}/{0}.tdb", type ), FileMode.Open, FileAccess.Read, FileShare.Read ) ) )
{
int count = bin.ReadInt32();
for ( int i = 0; i < count; ++i )
types.Add( ScriptCompiler.FindTypeByFullName( bin.ReadString() ) );
}
long total = 0;
Hashtable table = new Hashtable();
using ( BinaryReader bin = new BinaryReader( new FileStream( String.Format( "Saves/{0}/{0}.idx", type ), FileMode.Open, FileAccess.Read, FileShare.Read ) ) )
{
int count = bin.ReadInt32();
for ( int i = 0; i < count; ++i )
{
int typeID = bin.ReadInt32();
int serial = bin.ReadInt32();
long pos = bin.ReadInt64();
int length = bin.ReadInt32();
Type objType = (Type)types[typeID];
while ( objType != null && objType != typeof( object ) )
{
object obj = table[objType];
if ( obj == null )
table[objType] = length;
else
table[objType] = length + (int)obj;
objType = objType.BaseType;
total += length;
}
}
}
ArrayList list = new ArrayList( table );
list.Sort( new CountSorter() );
using ( StreamWriter op = new StreamWriter( opFile ) )
{
op.WriteLine( "# Profile of world {0}", type );
op.WriteLine( "# Generated on {0}", DateTime.Now );
op.WriteLine();
op.WriteLine();
foreach ( DictionaryEntry de in list )
op.WriteLine( "{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)total, de.Key );
}
}
catch
{
}
}
}
}

View file

@ -20,7 +20,7 @@ namespace Server.Commands
public class Properties
{
public static void Register()
public static void Initialize()
{
CommandSystem.Register( "Props", AccessLevel.Counselor, new CommandEventHandler( Props_OnCommand ) );
}

View file

@ -91,7 +91,10 @@ namespace Server
Chivalry = 51,
Bushido = 52,
Ninjitsu = 53,
Spellweaving = 54
Spellweaving = 54,
Mysticism = 55,
Imbuing = 56,
Throwing = 57
}
[PropertyObject]
@ -612,61 +615,64 @@ namespace Server
private static SkillInfo[] m_Table = new SkillInfo[55]
{
new SkillInfo( 0, "Alchemy", 0.0, 5.0, 5.0, "Alchemist", null, 0.0, 0.5, 0.5, 1.0 ),
new SkillInfo( 1, "Anatomy", 0.0, 0.0, 0.0, "Healer", null, 0.15, 0.15, 0.7, 1.0 ),
new SkillInfo( 2, "Animal Lore", 0.0, 0.0, 0.0, "Ranger", null, 0.0, 0.0, 1.0, 1.0 ),
new SkillInfo( 3, "Item Identification", 0.0, 0.0, 0.0, "Merchant", null, 0.0, 0.0, 1.0, 1.0 ),
new SkillInfo( 4, "Arms Lore", 0.0, 0.0, 0.0, "Warrior", null, 0.75, 0.15, 0.1, 1.0 ),
new SkillInfo( 5, "Parrying", 7.5, 2.5, 0.0, "Warrior", null, 0.75, 0.25, 0.0, 1.0 ),
new SkillInfo( 6, "Begging", 0.0, 0.0, 0.0, "Beggar", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 7, "Blacksmithy", 10.0, 0.0, 0.0, "Smith", null, 1.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 8, "Bowcraft/Fletching", 6.0, 16.0, 0.0, "Bowyer", null, 0.6, 1.6, 0.0, 1.0 ),
new SkillInfo( 9, "Peacemaking", 0.0, 0.0, 0.0, "Bard", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 10, "Camping", 20.0, 15.0, 15.0, "Ranger", null, 2.0, 1.5, 1.5, 1.0 ),
new SkillInfo( 11, "Carpentry", 20.0, 5.0, 0.0, "Carpenter", null, 2.0, 0.5, 0.0, 1.0 ),
new SkillInfo( 12, "Cartography", 0.0, 7.5, 7.5, "Cartographer", null, 0.0, 0.75, 0.75, 1.0 ),
new SkillInfo( 13, "Cooking", 0.0, 20.0, 30.0, "Chef", null, 0.0, 2.0, 3.0, 1.0 ),
new SkillInfo( 14, "Detecting Hidden", 0.0, 0.0, 0.0, "Scout", null, 0.0, 0.4, 0.6, 1.0 ),
new SkillInfo( 15, "Discordance", 0.0, 2.5, 2.5, "Bard", null, 0.0, 0.25, 0.25, 1.0 ),
new SkillInfo( 16, "Evaluating Intelligence", 0.0, 0.0, 0.0, "Scholar", null, 0.0, 0.0, 1.0, 1.0 ),
new SkillInfo( 17, "Healing", 6.0, 6.0, 8.0, "Healer", null, 0.6, 0.6, 0.8, 1.0 ),
new SkillInfo( 18, "Fishing", 0.0, 0.0, 0.0, "Fisherman", null, 0.5, 0.5, 0.0, 1.0 ),
new SkillInfo( 19, "Forensic Evaluation", 0.0, 0.0, 0.0, "Detective", null, 0.0, 0.2, 0.8, 1.0 ),
new SkillInfo( 20, "Herding", 16.25, 6.25, 2.5, "Shepherd", null, 1.625, 0.625, 0.25, 1.0 ),
new SkillInfo( 21, "Hiding", 0.0, 0.0, 0.0, "Rogue", null, 0.0, 0.8, 0.2, 1.0 ),
new SkillInfo( 22, "Provocation", 0.0, 4.5, 0.5, "Bard", null, 0.0, 0.45, 0.05, 1.0 ),
new SkillInfo( 23, "Inscription", 0.0, 2.0, 8.0, "Scribe", null, 0.0, 0.2, 0.8, 1.0 ),
new SkillInfo( 24, "Lockpicking", 0.0, 25.0, 0.0, "Rogue", null, 0.0, 2.0, 0.0, 1.0 ),
new SkillInfo( 25, "Magery", 0.0, 0.0, 15.0, "Mage", null, 0.0, 0.0, 1.5, 1.0 ),
new SkillInfo( 26, "Resisting Spells", 0.0, 0.0, 0.0, "Mage", null, 0.25, 0.25, 0.5, 1.0 ),
new SkillInfo( 27, "Tactics", 0.0, 0.0, 0.0, "Warrior", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 28, "Snooping", 0.0, 25.0, 0.0, "Pickpocket", null, 0.0, 2.5, 0.0, 1.0 ),
new SkillInfo( 29, "Musicianship", 0.0, 0.0, 0.0, "Bard", null, 0.0, 0.8, 0.2, 1.0 ),
new SkillInfo( 30, "Poisoning", 0.0, 4.0, 16.0, "Assassin", null, 0.0, 0.4, 1.6, 1.0 ),
new SkillInfo( 31, "Archery", 2.5, 7.5, 0.0, "Archer", null, 0.25, 0.75, 0.0, 1.0 ),
new SkillInfo( 32, "Spirit Speak", 0.0, 0.0, 0.0, "Medium", null, 0.0, 0.0, 1.0, 1.0 ),
new SkillInfo( 33, "Stealing", 0.0, 10.0, 0.0, "Rogue", null, 0.0, 1.0, 0.0, 1.0 ),
new SkillInfo( 34, "Tailoring", 3.75, 16.25, 5.0, "Tailor", null, 0.38, 1.63, 0.5, 1.0 ),
new SkillInfo( 35, "Animal Taming", 14.0, 2.0, 4.0, "Tamer", null, 1.4, 0.2, 0.4, 1.0 ),
new SkillInfo( 36, "Taste Identification", 0.0, 0.0, 0.0, "Chef", null, 0.2, 0.0, 0.8, 1.0 ),
new SkillInfo( 37, "Tinkering", 5.0, 2.0, 3.0, "Tinker", null, 0.5, 0.2, 0.3, 1.0 ),
new SkillInfo( 38, "Tracking", 0.0, 12.5, 12.5, "Ranger", null, 0.0, 1.25, 1.25, 1.0 ),
new SkillInfo( 39, "Veterinary", 8.0, 4.0, 8.0, "Veterinarian", null, 0.8, 0.4, 0.8, 1.0 ),
new SkillInfo( 40, "Swordsmanship", 7.5, 2.5, 0.0, "Swordsman", null, 0.75, 0.25, 0.0, 1.0 ),
new SkillInfo( 41, "Mace Fighting", 9.0, 1.0, 0.0, "Armsman", null, 0.9, 0.1, 0.0, 1.0 ),
new SkillInfo( 42, "Fencing", 4.5, 5.5, 0.0, "Fencer", null, 0.45, 0.55, 0.0, 1.0 ),
new SkillInfo( 43, "Wrestling", 9.0, 1.0, 0.0, "Wrestler", null, 0.9, 0.1, 0.0, 1.0 ),
new SkillInfo( 44, "Lumberjacking", 20.0, 0.0, 0.0, "Lumberjack", null, 2.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 45, "Mining", 20.0, 0.0, 0.0, "Miner", null, 2.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 46, "Meditation", 0.0, 0.0, 0.0, "Stoic", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 47, "Stealth", 0.0, 0.0, 0.0, "Rogue", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 48, "Remove Trap", 0.0, 0.0, 0.0, "Rogue", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 49, "Necromancy", 0.0, 0.0, 0.0, "Necromancer", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 50, "Focus", 0.0, 0.0, 0.0, "Stoic", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 51, "Chivalry", 0.0, 0.0, 0.0, "Paladin", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 52, "Bushido", 0.0, 0.0, 0.0, "Samurai", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 53, "Ninjitsu", 0.0, 0.0, 0.0, "Ninja", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 54, "Spellweaving", 0.0, 0.0, 0.0, "Arcanist", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 0, "Alchemy", 0.0, 5.0, 5.0, "Alchemist", null, 0.0, 0.5, 0.5, 1.0 ),
new SkillInfo( 1, "Anatomy", 0.0, 0.0, 0.0, "Healer", null, 0.15, 0.15, 0.7, 1.0 ),
new SkillInfo( 2, "Animal Lore", 0.0, 0.0, 0.0, "Ranger", null, 0.0, 0.0, 1.0, 1.0 ),
new SkillInfo( 3, "Item Identification", 0.0, 0.0, 0.0, "Merchant", null, 0.0, 0.0, 1.0, 1.0 ),
new SkillInfo( 4, "Arms Lore", 0.0, 0.0, 0.0, "Warrior", null, 0.75, 0.15, 0.1, 1.0 ),
new SkillInfo( 5, "Parrying", 7.5, 2.5, 0.0, "Warrior", null, 0.75, 0.25, 0.0, 1.0 ),
new SkillInfo( 6, "Begging", 0.0, 0.0, 0.0, "Beggar", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 7, "Blacksmithy", 10.0, 0.0, 0.0, "Smith", null, 1.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 8, "Bowcraft/Fletching", 6.0, 16.0, 0.0, "Bowyer", null, 0.6, 1.6, 0.0, 1.0 ),
new SkillInfo( 9, "Peacemaking", 0.0, 0.0, 0.0, "Bard", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 10, "Camping", 20.0, 15.0, 15.0, "Ranger", null, 2.0, 1.5, 1.5, 1.0 ),
new SkillInfo( 11, "Carpentry", 20.0, 5.0, 0.0, "Carpenter", null, 2.0, 0.5, 0.0, 1.0 ),
new SkillInfo( 12, "Cartography", 0.0, 7.5, 7.5, "Cartographer", null, 0.0, 0.75, 0.75, 1.0 ),
new SkillInfo( 13, "Cooking", 0.0, 20.0, 30.0, "Chef", null, 0.0, 2.0, 3.0, 1.0 ),
new SkillInfo( 14, "Detecting Hidden", 0.0, 0.0, 0.0, "Scout", null, 0.0, 0.4, 0.6, 1.0 ),
new SkillInfo( 15, "Discordance", 0.0, 2.5, 2.5, "Bard", null, 0.0, 0.25, 0.25, 1.0 ),
new SkillInfo( 16, "Evaluating Intelligence", 0.0, 0.0, 0.0, "Scholar", null, 0.0, 0.0, 1.0, 1.0 ),
new SkillInfo( 17, "Healing", 6.0, 6.0, 8.0, "Healer", null, 0.6, 0.6, 0.8, 1.0 ),
new SkillInfo( 18, "Fishing", 0.0, 0.0, 0.0, "Fisherman", null, 0.5, 0.5, 0.0, 1.0 ),
new SkillInfo( 19, "Forensic Evaluation", 0.0, 0.0, 0.0, "Detective", null, 0.0, 0.2, 0.8, 1.0 ),
new SkillInfo( 20, "Herding", 16.25, 6.25, 2.5, "Shepherd", null, 1.625, 0.625, 0.25, 1.0 ),
new SkillInfo( 21, "Hiding", 0.0, 0.0, 0.0, "Rogue", null, 0.0, 0.8, 0.2, 1.0 ),
new SkillInfo( 22, "Provocation", 0.0, 4.5, 0.5, "Bard", null, 0.0, 0.45, 0.05, 1.0 ),
new SkillInfo( 23, "Inscription", 0.0, 2.0, 8.0, "Scribe", null, 0.0, 0.2, 0.8, 1.0 ),
new SkillInfo( 24, "Lockpicking", 0.0, 25.0, 0.0, "Rogue", null, 0.0, 2.0, 0.0, 1.0 ),
new SkillInfo( 25, "Magery", 0.0, 0.0, 15.0, "Mage", null, 0.0, 0.0, 1.5, 1.0 ),
new SkillInfo( 26, "Resisting Spells", 0.0, 0.0, 0.0, "Mage", null, 0.25, 0.25, 0.5, 1.0 ),
new SkillInfo( 27, "Tactics", 0.0, 0.0, 0.0, "Warrior", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 28, "Snooping", 0.0, 25.0, 0.0, "Pickpocket", null, 0.0, 2.5, 0.0, 1.0 ),
new SkillInfo( 29, "Musicianship", 0.0, 0.0, 0.0, "Bard", null, 0.0, 0.8, 0.2, 1.0 ),
new SkillInfo( 30, "Poisoning", 0.0, 4.0, 16.0, "Assassin", null, 0.0, 0.4, 1.6, 1.0 ),
new SkillInfo( 31, "Archery", 2.5, 7.5, 0.0, "Archer", null, 0.25, 0.75, 0.0, 1.0 ),
new SkillInfo( 32, "Spirit Speak", 0.0, 0.0, 0.0, "Medium", null, 0.0, 0.0, 1.0, 1.0 ),
new SkillInfo( 33, "Stealing", 0.0, 10.0, 0.0, "Rogue", null, 0.0, 1.0, 0.0, 1.0 ),
new SkillInfo( 34, "Tailoring", 3.75, 16.25, 5.0, "Tailor", null, 0.38, 1.63, 0.5, 1.0 ),
new SkillInfo( 35, "Animal Taming", 14.0, 2.0, 4.0, "Tamer", null, 1.4, 0.2, 0.4, 1.0 ),
new SkillInfo( 36, "Taste Identification", 0.0, 0.0, 0.0, "Chef", null, 0.2, 0.0, 0.8, 1.0 ),
new SkillInfo( 37, "Tinkering", 5.0, 2.0, 3.0, "Tinker", null, 0.5, 0.2, 0.3, 1.0 ),
new SkillInfo( 38, "Tracking", 0.0, 12.5, 12.5, "Ranger", null, 0.0, 1.25, 1.25, 1.0 ),
new SkillInfo( 39, "Veterinary", 8.0, 4.0, 8.0, "Veterinarian", null, 0.8, 0.4, 0.8, 1.0 ),
new SkillInfo( 40, "Swordsmanship", 7.5, 2.5, 0.0, "Swordsman", null, 0.75, 0.25, 0.0, 1.0 ),
new SkillInfo( 41, "Mace Fighting", 9.0, 1.0, 0.0, "Armsman", null, 0.9, 0.1, 0.0, 1.0 ),
new SkillInfo( 42, "Fencing", 4.5, 5.5, 0.0, "Fencer", null, 0.45, 0.55, 0.0, 1.0 ),
new SkillInfo( 43, "Wrestling", 9.0, 1.0, 0.0, "Wrestler", null, 0.9, 0.1, 0.0, 1.0 ),
new SkillInfo( 44, "Lumberjacking", 20.0, 0.0, 0.0, "Lumberjack", null, 2.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 45, "Mining", 20.0, 0.0, 0.0, "Miner", null, 2.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 46, "Meditation", 0.0, 0.0, 0.0, "Stoic", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 47, "Stealth", 0.0, 0.0, 0.0, "Rogue", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 48, "Remove Trap", 0.0, 0.0, 0.0, "Rogue", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 49, "Necromancy", 0.0, 0.0, 0.0, "Necromancer", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 50, "Focus", 0.0, 0.0, 0.0, "Stoic", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 51, "Chivalry", 0.0, 0.0, 0.0, "Paladin", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 52, "Bushido", 0.0, 0.0, 0.0, "Samurai", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 53, "Ninjitsu", 0.0, 0.0, 0.0, "Ninja", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 54, "Spellweaving", 0.0, 0.0, 0.0, "Arcanist", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 55, "Mysticism", 0.0, 0.0, 0.0, "Mystic", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 56, "Imbuing", 0.0, 0.0, 0.0, "Artificer", null, 0.0, 0.0, 0.0, 1.0 ),
new SkillInfo( 57, "Throwing", 0.0, 0.0, 0.0, "Bladeweaving", null, 0.0, 0.0, 0.0, 1.0 ),
};
public static SkillInfo[] Table
@ -856,6 +862,15 @@ namespace Server
[CommandProperty( AccessLevel.Counselor )]
public Skill Spellweaving { get { return this[SkillName.Spellweaving]; } set { } }
[CommandProperty( AccessLevel.Counselor )]
public Skill Mysticism { get { return this[SkillName.Mysticism]; } set { } }
[CommandProperty( AccessLevel.Counselor )]
public Skill Imbuing { get { return this[SkillName.Imbuing]; } set { } }
[CommandProperty( AccessLevel.Counselor )]
public Skill Throwing { get { return this[SkillName.Throwing]; } set { } }
#endregion
[CommandProperty( AccessLevel.Counselor, AccessLevel.GameMaster )]