Split profiling specific handlers from Handlers.cs to Profiling.cs
This commit is contained in:
parent
8602664c0c
commit
cd8f792132
4 changed files with 473 additions and 445 deletions
|
|
@ -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 )
|
||||
|
|
|
|||
400
Scripts/Commands/Profiling.cs
Normal file
400
Scripts/Commands/Profiling.cs
Normal 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
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 ) );
|
||||
}
|
||||
|
|
|
|||
127
Server/Skills.cs
127
Server/Skills.cs
|
|
@ -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 )]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue