#W# Initial Commit: Avatars Conquest

This commit is contained in:
WarrentyExpired 2026-07-04 10:35:30 -04:00
commit 5df497787a
7510 changed files with 416048 additions and 0 deletions

View file

@ -0,0 +1,46 @@
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using Server;
using Server.Misc;
namespace Server
{
public class AccessRestrictions
{
public static void Initialize()
{
EventSink.SocketConnect += new SocketConnectEventHandler( EventSink_SocketConnect );
}
private static void EventSink_SocketConnect( SocketConnectEventArgs e )
{
try
{
IPAddress ip = ((IPEndPoint)e.Socket.RemoteEndPoint).Address;
if ( Firewall.IsBlocked( ip ) )
{
Console.WriteLine( "Client: {0}: Firewall blocked connection attempt.", ip );
e.AllowConnection = false;
return;
}
else if ( IPLimiter.SocketBlock && !IPLimiter.Verify( ip ) )
{
Console.WriteLine( "Client: {0}: Past IP limit threshold", ip );
using ( StreamWriter op = new StreamWriter( "ipLimits.log", true ) )
op.WriteLine( "{0}\tPast IP limit threshold\t{1}", ip, DateTime.Now );
e.AllowConnection = false;
return;
}
}
catch
{
e.AllowConnection = false;
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,148 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using Server;
using Server.Network;
namespace Server.Accounting
{
public class AccountAttackLimiter
{
public static bool Enabled = true;
public static void Initialize()
{
if ( !Enabled )
return;
PacketHandlers.RegisterThrottler( 0x80, new ThrottlePacketCallback( Throttle_Callback ) );
PacketHandlers.RegisterThrottler( 0x91, new ThrottlePacketCallback( Throttle_Callback ) );
PacketHandlers.RegisterThrottler( 0xCF, new ThrottlePacketCallback( Throttle_Callback ) );
}
public static bool Throttle_Callback( NetState ns )
{
InvalidAccountAccessLog accessLog = FindAccessLog( ns );
if ( accessLog == null )
return true;
return ( DateTime.Now >= (accessLog.LastAccessTime + ComputeThrottle( accessLog.Counts )) );
}
private static List<InvalidAccountAccessLog> m_List = new List<InvalidAccountAccessLog>();
public static InvalidAccountAccessLog FindAccessLog( NetState ns )
{
if ( ns == null )
return null;
IPAddress ipAddress = ns.Address;
for ( int i = 0; i < m_List.Count; ++i )
{
InvalidAccountAccessLog accessLog = m_List[i];
if ( accessLog.HasExpired )
m_List.RemoveAt( i-- );
else if ( accessLog.Address.Equals( ipAddress ) )
return accessLog;
}
return null;
}
public static void RegisterInvalidAccess( NetState ns )
{
if ( ns == null || !Enabled )
return;
InvalidAccountAccessLog accessLog = FindAccessLog( ns );
if ( accessLog == null )
m_List.Add( accessLog = new InvalidAccountAccessLog( ns.Address ) );
accessLog.Counts += 1;
accessLog.RefreshAccessTime();
if ( accessLog.Counts >= 3 ) {
try {
using ( StreamWriter op = new StreamWriter( "throttle.log", true ) ) {
op.WriteLine(
"{0}\t{1}\t{2}",
DateTime.Now,
ns,
accessLog.Counts
);
}
}
catch {
}
}
}
public static TimeSpan ComputeThrottle( int counts )
{
if ( counts >= 15 )
return TimeSpan.FromMinutes( 5.0 );
if ( counts >= 10 )
return TimeSpan.FromMinutes( 1.0 );
if ( counts >= 5 )
return TimeSpan.FromSeconds( 20.0 );
if ( counts >= 3 )
return TimeSpan.FromSeconds( 10.0 );
if ( counts >= 1 )
return TimeSpan.FromSeconds( 2.0 );
return TimeSpan.Zero;
}
}
public class InvalidAccountAccessLog
{
private IPAddress m_Address;
private DateTime m_LastAccessTime;
private int m_Counts;
public IPAddress Address
{
get{ return m_Address; }
set{ m_Address = value; }
}
public DateTime LastAccessTime
{
get{ return m_LastAccessTime; }
set{ m_LastAccessTime = value; }
}
public bool HasExpired
{
get{ return ( DateTime.Now >= ( m_LastAccessTime + TimeSpan.FromHours( 1.0 ) ) ); }
}
public int Counts
{
get{ return m_Counts; }
set{ m_Counts = value; }
}
public void RefreshAccessTime()
{
m_LastAccessTime = DateTime.Now;
}
public InvalidAccountAccessLog( IPAddress address )
{
m_Address = address;
RefreshAccessTime();
}
}
}

View file

@ -0,0 +1,77 @@
using System;
using System.Xml;
namespace Server.Accounting
{
public class AccountComment
{
private string m_AddedBy;
private string m_Content;
private DateTime m_LastModified;
/// <summary>
/// A string representing who added this comment.
/// </summary>
public string AddedBy
{
get{ return m_AddedBy; }
}
/// <summary>
/// Gets or sets the body of this comment. Setting this value will reset LastModified.
/// </summary>
public string Content
{
get{ return m_Content; }
set{ m_Content = value; m_LastModified = DateTime.Now; }
}
/// <summary>
/// The date and time when this account was last modified -or- the comment creation time, if never modified.
/// </summary>
public DateTime LastModified
{
get{ return m_LastModified; }
}
/// <summary>
/// Constructs a new AccountComment instance.
/// </summary>
/// <param name="addedBy">Initial AddedBy value.</param>
/// <param name="content">Initial Content value.</param>
public AccountComment( string addedBy, string content )
{
m_AddedBy = addedBy;
m_Content = content;
m_LastModified = DateTime.Now;
}
/// <summary>
/// Deserializes an AccountComment instance from an xml element.
/// </summary>
/// <param name="node">The XmlElement instance from which to deserialize.</param>
public AccountComment( XmlElement node )
{
m_AddedBy = Utility.GetAttribute( node, "addedBy", "empty" );
m_LastModified = Utility.GetXMLDateTime( Utility.GetAttribute( node, "lastModified" ), DateTime.Now );
m_Content = Utility.GetText( node, "" );
}
/// <summary>
/// Serializes this AccountComment instance to an XmlTextWriter.
/// </summary>
/// <param name="xml">The XmlTextWriter instance from which to serialize.</param>
public void Save( XmlTextWriter xml )
{
xml.WriteStartElement( "comment" );
xml.WriteAttributeString( "addedBy", m_AddedBy );
xml.WriteAttributeString( "lastModified", XmlConvert.ToString( m_LastModified, XmlDateTimeSerializationMode.Local ) );
xml.WriteString( m_Content );
xml.WriteEndElement();
}
}
}

View file

@ -0,0 +1,372 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using Server;
using Server.Accounting;
using Server.Commands;
using Server.Engines.Help;
using Server.Network;
using Server.Regions;
namespace Server.Misc
{
public enum PasswordProtection
{
None,
Crypt,
NewCrypt
}
public class AccountHandler
{
private static int MaxAccountsPerIP = Server.Misc.Settings.MaxAccountsPerIP();
private static bool AutoAccountCreation = Server.Misc.Settings.AutoAccountCreation();
private static bool RestrictDeletion = Server.Misc.Settings.RestrictDeletion();
private static TimeSpan DeleteDelay = TimeSpan.FromDays( Server.Misc.Settings.DeleteDelay() );
public static PasswordProtection ProtectPasswords = PasswordProtection.NewCrypt;
private static AccessLevel m_LockdownLevel;
public static AccessLevel LockdownLevel
{
get{ return m_LockdownLevel; }
set{ m_LockdownLevel = value; }
}
private static CityInfo[] StartingCities = new CityInfo[]
{
new CityInfo( " ", " ", 1150168, 2081, 1585, 0 ),
};
private static bool PasswordCommandEnabled = true;
public static void Initialize()
{
EventSink.DeleteRequest += new DeleteRequestEventHandler( EventSink_DeleteRequest );
EventSink.AccountLogin += new AccountLoginEventHandler( EventSink_AccountLogin );
EventSink.GameLogin += new GameLoginEventHandler( EventSink_GameLogin );
if ( PasswordCommandEnabled )
CommandSystem.Register( "Password", AccessLevel.Player, new CommandEventHandler( Password_OnCommand ) );
}
[Usage( "Password <newPassword> <repeatPassword>" )]
[Description( "Changes the password of the commanding players account. Requires the same C-class IP address as the account's creator." )]
public static void Password_OnCommand( CommandEventArgs e )
{
Mobile from = e.Mobile;
Account acct = from.Account as Account;
if ( acct == null )
return;
IPAddress[] accessList = acct.LoginIPs;
if ( accessList.Length == 0 )
return;
NetState ns = from.NetState;
if ( ns == null )
return;
if ( e.Length == 0 )
{
from.SendMessage( "You must specify the new password." );
return;
}
else if ( e.Length == 1 )
{
from.SendMessage( "To prevent potential typing mistakes, you must type the password twice. Use the format:" );
from.SendMessage( "Password \"(newPassword)\" \"(repeated)\"" );
return;
}
string pass = e.GetString( 0 );
string pass2 = e.GetString( 1 );
if ( pass != pass2 )
{
from.SendMessage( "The passwords do not match." );
return;
}
bool isSafe = true;
for ( int i = 0; isSafe && i < pass.Length; ++i )
isSafe = ( pass[i] >= 0x20 && pass[i] < 0x80 );
if ( !isSafe )
{
from.SendMessage( "That is not a valid password." );
return;
}
try
{
IPAddress ipAddress = ns.Address;
if ( Utility.IPMatchClassC( accessList[0], ipAddress ) )
{
acct.SetPassword( pass );
from.SendMessage( "The password to your account has changed." );
}
else
{
PageEntry entry = PageQueue.GetEntry( from );
if ( entry != null )
{
if ( entry.Message.StartsWith( "[Automated: Change Password]" ) )
from.SendMessage( "You already have a password change request in the help system queue." );
else
from.SendMessage( "Your IP address does not match that which created this account." );
}
else if ( PageQueue.CheckAllowedToPage( from ) )
{
from.SendMessage( "Your IP address does not match that which created this account. A page has been entered into the help system on your behalf." );
from.SendLocalizedMessage( 501234, "", 0x35 ); /* The next available Counselor/Game Master will respond as soon as possible.
* Please check your Journal for messages every few minutes.
*/
PageQueue.Enqueue( new PageEntry( from, String.Format( "[Automated: Change Password]<br>Desired password: {0}<br>Current IP address: {1}<br>Account IP address: {2}", pass, ipAddress, accessList[0] ), PageType.Account ) );
}
}
}
catch
{
}
}
private static void EventSink_DeleteRequest( DeleteRequestEventArgs e )
{
NetState state = e.State;
int index = e.Index;
Account acct = state.Account as Account;
if ( acct == null )
{
state.Dispose();
}
else if ( index < 0 || index >= acct.Length )
{
state.Send( new DeleteResult( DeleteResultType.BadRequest ) );
state.Send( new CharacterListUpdate( acct ) );
}
else
{
Mobile m = acct[index];
if ( m == null )
{
state.Send( new DeleteResult( DeleteResultType.CharNotExist ) );
state.Send( new CharacterListUpdate( acct ) );
}
else if ( m.NetState != null )
{
state.Send( new DeleteResult( DeleteResultType.CharBeingPlayed ) );
state.Send( new CharacterListUpdate( acct ) );
}
else if ( RestrictDeletion && DateTime.Now < (m.CreationTime + DeleteDelay) )
{
state.Send( new DeleteResult( DeleteResultType.CharTooYoung ) );
state.Send( new CharacterListUpdate( acct ) );
}
else
{
Console.WriteLine( "Client: {0}: Deleting character {1} (0x{2:X})", state, index, m.Serial.Value );
acct.Comments.Add( new AccountComment( "System", String.Format( "Character #{0} {1} deleted by {2}", index + 1, m, state ) ) );
m.Delete();
state.Send( new CharacterListUpdate( acct ) );
}
}
}
public static bool CanCreate( IPAddress ip )
{
if ( !IPTable.ContainsKey( ip ) )
return true;
return ( IPTable[ip] < MaxAccountsPerIP );
}
private static Dictionary<IPAddress, Int32> m_IPTable;
public static Dictionary<IPAddress, Int32> IPTable
{
get
{
if ( m_IPTable == null )
{
m_IPTable = new Dictionary<IPAddress, Int32>();
foreach ( Account a in Accounts.GetAccounts() )
if ( a.LoginIPs.Length > 0 )
{
IPAddress ip = a.LoginIPs[0];
if ( m_IPTable.ContainsKey( ip ) )
m_IPTable[ip]++;
else
m_IPTable[ip] = 1;
}
}
return m_IPTable;
}
}
private static Account CreateAccount( NetState state, string un, string pw )
{
if ( un.Length == 0 || pw.Length == 0 )
return null;
bool isSafe = true;
for ( int i = 0; isSafe && i < un.Length; ++i )
isSafe = ( un[i] >= 0x20 && un[i] < 0x80 );
for ( int i = 0; isSafe && i < pw.Length; ++i )
isSafe = ( pw[i] >= 0x20 && pw[i] < 0x80 );
if ( !isSafe )
return null;
if ( !CanCreate( state.Address ) )
{
Console.WriteLine( "Login: {0}: Account '{1}' not created, ip already has {2} account{3}.", state, un, MaxAccountsPerIP, MaxAccountsPerIP == 1 ? "" : "s" );
return null;
}
Console.WriteLine( "Login: {0}: Creating new account '{1}'", state, un );
Account a = new Account( un, pw );
return a;
}
public static void EventSink_AccountLogin( AccountLoginEventArgs e )
{
if ( !IPLimiter.SocketBlock && !IPLimiter.Verify( e.State.Address ) )
{
e.Accepted = false;
e.RejectReason = ALRReason.InUse;
Console.WriteLine( "Login: {0}: Past IP limit threshold", e.State );
using ( StreamWriter op = new StreamWriter( "ipLimits.log", true ) )
op.WriteLine( "{0}\tPast IP limit threshold\t{1}", e.State, DateTime.Now );
return;
}
string un = e.Username;
string pw = e.Password;
e.Accepted = false;
Account acct = Accounts.GetAccount( un ) as Account;
if ( acct == null )
{
if ( AutoAccountCreation && un.Trim().Length > 0 ) //To prevent someone from making an account of just '' or a bunch of meaningless spaces
{
e.State.Account = acct = CreateAccount( e.State, un, pw );
e.Accepted = acct == null ? false : acct.CheckAccess( e.State );
if ( !e.Accepted )
e.RejectReason = ALRReason.BadComm;
}
else
{
Console.WriteLine( "Login: {0}: Invalid username '{1}'", e.State, un );
e.RejectReason = ALRReason.Invalid;
}
}
else if ( !acct.HasAccess( e.State ) )
{
Console.WriteLine( "Login: {0}: Access denied for '{1}'", e.State, un );
e.RejectReason = ( m_LockdownLevel > AccessLevel.Player ? ALRReason.BadComm : ALRReason.BadPass );
}
else if ( !acct.CheckPassword( pw ) )
{
Console.WriteLine( "Login: {0}: Invalid password for '{1}'", e.State, un );
e.RejectReason = ALRReason.BadPass;
}
else if ( acct.Banned )
{
Console.WriteLine( "Login: {0}: Banned account '{1}'", e.State, un );
e.RejectReason = ALRReason.Blocked;
}
else
{
Console.WriteLine( "Login: {0}: Valid credentials for '{1}'", e.State, un );
e.State.Account = acct;
e.Accepted = true;
acct.LogAccess( e.State );
}
if ( !e.Accepted )
AccountAttackLimiter.RegisterInvalidAccess( e.State );
}
public static void EventSink_GameLogin( GameLoginEventArgs e )
{
if ( !IPLimiter.SocketBlock && !IPLimiter.Verify( e.State.Address ) )
{
e.Accepted = false;
Console.WriteLine( "Login: {0}: Past IP limit threshold", e.State );
using ( StreamWriter op = new StreamWriter( "ipLimits.log", true ) )
op.WriteLine( "{0}\tPast IP limit threshold\t{1}", e.State, DateTime.Now );
return;
}
string un = e.Username;
string pw = e.Password;
Account acct = Accounts.GetAccount( un ) as Account;
if ( acct == null )
{
e.Accepted = false;
}
else if ( !acct.HasAccess( e.State ) )
{
Console.WriteLine( "Login: {0}: Access denied for '{1}'", e.State, un );
e.Accepted = false;
}
else if ( !acct.CheckPassword( pw ) )
{
Console.WriteLine( "Login: {0}: Invalid password for '{1}'", e.State, un );
e.Accepted = false;
}
else if ( acct.Banned )
{
Console.WriteLine( "Login: {0}: Banned account '{1}'", e.State, un );
e.Accepted = false;
}
else
{
acct.LogAccess( e.State );
Console.WriteLine( "Login: {0}: Account '{1}' at character list", e.State, un );
e.State.Account = acct;
e.Accepted = true;
e.CityInfo = StartingCities;
}
if ( !e.Accepted )
AccountAttackLimiter.RegisterInvalidAccess( e.State );
}
}
}

View file

@ -0,0 +1,61 @@
using System;
using System.Xml;
namespace Server.Accounting
{
public class AccountTag
{
private string m_Name, m_Value;
/// <summary>
/// Gets or sets the name of this tag.
/// </summary>
public string Name
{
get{ return m_Name; }
set{ m_Name = value; }
}
/// <summary>
/// Gets or sets the value of this tag.
/// </summary>
public string Value
{
get{ return m_Value; }
set{ m_Value = value; }
}
/// <summary>
/// Constructs a new AccountTag instance with a specific name and value.
/// </summary>
/// <param name="name">Initial name.</param>
/// <param name="value">Initial value.</param>
public AccountTag( string name, string value )
{
m_Name = name;
m_Value = value;
}
/// <summary>
/// Deserializes an AccountTag instance from an xml element.
/// </summary>
/// <param name="node">The XmlElement instance from which to deserialize.</param>
public AccountTag( XmlElement node )
{
m_Name = Utility.GetAttribute( node, "name", "empty" );
m_Value = Utility.GetText( node, "" );
}
/// <summary>
/// Serializes this AccountTag instance to an XmlTextWriter.
/// </summary>
/// <param name="xml">The XmlTextWriter instance from which to serialize.</param>
public void Save( XmlTextWriter xml )
{
xml.WriteStartElement( "tag" );
xml.WriteAttributeString( "name", m_Name );
xml.WriteString( m_Value );
xml.WriteEndElement();
}
}
}

View file

@ -0,0 +1,110 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;
namespace Server.Accounting
{
public class Accounts
{
private static Dictionary<string, IAccount> m_Accounts = new Dictionary<string, IAccount>();
public static void Configure()
{
EventSink.WorldLoad += new WorldLoadEventHandler( Load );
EventSink.WorldSave += new WorldSaveEventHandler( Save );
}
static Accounts()
{
}
public static int Count { get { return m_Accounts.Count; } }
public static ICollection<IAccount> GetAccounts()
{
#if !MONO
return m_Accounts.Values;
#else
return new List<IAccount>( m_Accounts.Values );
#endif
}
public static IAccount GetAccount( string username )
{
IAccount a;
m_Accounts.TryGetValue( username, out a );
return a;
}
public static void Add( IAccount a )
{
m_Accounts[a.Username] = a;
}
public static void Remove( string username )
{
m_Accounts.Remove( username );
}
public static void Load()
{
m_Accounts = new Dictionary<string, IAccount>( 32, StringComparer.OrdinalIgnoreCase );
string filePath = Path.Combine( "Saves/Accounts", "accounts.xml" );
if ( !File.Exists( filePath ) )
return;
XmlDocument doc = new XmlDocument();
doc.Load( filePath );
XmlElement root = doc["accounts"];
foreach ( XmlElement account in root.GetElementsByTagName( "account" ) )
{
try
{
Account acct = new Account( account );
}
catch
{
Console.WriteLine( "Warning: Account instance load failed" );
}
}
}
public static void Save( WorldSaveEventArgs e )
{
if ( !Directory.Exists( "Saves/Accounts" ) )
Directory.CreateDirectory( "Saves/Accounts" );
string filePath = Path.Combine( "Saves/Accounts", "accounts.xml" );
using ( StreamWriter op = new StreamWriter( filePath ) )
{
XmlTextWriter xml = new XmlTextWriter( op );
xml.Formatting = Formatting.Indented;
xml.IndentChar = '\t';
xml.Indentation = 1;
xml.WriteStartDocument( true );
xml.WriteStartElement( "accounts" );
xml.WriteAttributeString( "count", m_Accounts.Count.ToString() );
foreach ( Account a in GetAccounts() )
a.Save( xml );
xml.WriteEndElement();
xml.Close();
}
}
}
}

View file

@ -0,0 +1,344 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
namespace Server
{
public class Firewall
{
#region Firewall Entries
public interface IFirewallEntry
{
bool IsBlocked( IPAddress address );
}
public class IPFirewallEntry : IFirewallEntry
{
IPAddress m_Address;
public IPFirewallEntry( IPAddress address )
{
m_Address = address;
}
public bool IsBlocked( IPAddress address )
{
return m_Address.Equals( address );
}
public override string ToString()
{
return m_Address.ToString();
}
public override bool Equals( object obj )
{
if( obj is IPAddress )
{
return obj.Equals( m_Address );
}
else if( obj is string )
{
IPAddress otherAddress;
if( IPAddress.TryParse( (string)obj, out otherAddress ) )
return otherAddress.Equals( m_Address );
}
else if( obj is IPFirewallEntry )
{
return m_Address.Equals( ((IPFirewallEntry)obj).m_Address );
}
return false;
}
public override int GetHashCode()
{
return m_Address.GetHashCode();
}
}
public class CIDRFirewallEntry : IFirewallEntry
{
IPAddress m_CIDRPrefix;
int m_CIDRLength;
public CIDRFirewallEntry( IPAddress cidrPrefix, int cidrLength )
{
m_CIDRPrefix = cidrPrefix;
m_CIDRLength = cidrLength;
}
public bool IsBlocked( IPAddress address )
{
return Utility.IPMatchCIDR( m_CIDRPrefix, address, m_CIDRLength );
}
public override string ToString()
{
return String.Format( "{0}/{1}", m_CIDRPrefix, m_CIDRLength );
}
public override bool Equals( object obj )
{
if( obj is string )
{
string entry= (string)obj;
string[] str = entry.Split( '/' );
if( str.Length == 2 )
{
IPAddress cidrPrefix;
if( IPAddress.TryParse( str[0], out cidrPrefix ) )
{
int cidrLength;
if( int.TryParse( str[1], out cidrLength ) )
return m_CIDRPrefix.Equals( cidrPrefix ) && m_CIDRLength.Equals( cidrLength );
}
}
}
else if( obj is CIDRFirewallEntry )
{
CIDRFirewallEntry entry = obj as CIDRFirewallEntry;
return m_CIDRPrefix.Equals( entry.m_CIDRPrefix ) && m_CIDRLength.Equals( entry.m_CIDRLength );
}
return false;
}
public override int GetHashCode()
{
return m_CIDRPrefix.GetHashCode() ^ m_CIDRLength.GetHashCode();
}
}
public class WildcardIPFirewallEntry : IFirewallEntry
{
string m_Entry;
bool m_Valid = true;
public WildcardIPFirewallEntry( string entry )
{
m_Entry = entry;
}
public bool IsBlocked( IPAddress address )
{
if( !m_Valid )
return false; //Why process if it's invalid? it'll return false anyway after processing it.
return Utility.IPMatch( m_Entry, address, ref m_Valid );
}
public override string ToString()
{
return m_Entry.ToString();
}
public override bool Equals( object obj )
{
if( obj is string )
return obj.Equals( m_Entry );
else if( obj is WildcardIPFirewallEntry )
return m_Entry.Equals( ((WildcardIPFirewallEntry)obj).m_Entry );
return false;
}
public override int GetHashCode()
{
return m_Entry.GetHashCode();
}
}
#endregion
private static List<IFirewallEntry> m_Blocked;
static Firewall()
{
m_Blocked = new List<IFirewallEntry>();
string path = "firewall.cfg";
if ( File.Exists( path ) )
{
using ( StreamReader ip = new StreamReader( path ) )
{
string line;
while ( (line = ip.ReadLine()) != null )
{
line = line.Trim();
if ( line.Length == 0 )
continue;
m_Blocked.Add( ToFirewallEntry( line ) );
/*
object toAdd;
IPAddress addr;
if( IPAddress.TryParse( line, out addr ) )
toAdd = addr;
else
toAdd = line;
m_Blocked.Add( toAdd.ToString() );
* */
}
}
}
}
public static List<IFirewallEntry> List
{
get
{
return m_Blocked;
}
}
public static IFirewallEntry ToFirewallEntry( object entry )
{
if( entry is IFirewallEntry )
return (IFirewallEntry)entry;
else if( entry is IPAddress )
return new IPFirewallEntry( (IPAddress)entry );
else if( entry is string )
return ToFirewallEntry( (string)entry );
return null;
}
public static IFirewallEntry ToFirewallEntry( string entry )
{
IPAddress addr;
if( IPAddress.TryParse( entry, out addr ) )
return new IPFirewallEntry( addr );
//Try CIDR parse
string[] str = entry.Split( '/' );
if( str.Length == 2 )
{
IPAddress cidrPrefix;
if( IPAddress.TryParse( str[0], out cidrPrefix ) )
{
int cidrLength;
if( int.TryParse( str[1], out cidrLength ) )
return new CIDRFirewallEntry( cidrPrefix, cidrLength );
}
}
return new WildcardIPFirewallEntry( entry );
}
public static void RemoveAt( int index )
{
m_Blocked.RemoveAt( index );
Save();
}
public static void Remove( object obj )
{
IFirewallEntry entry = ToFirewallEntry( obj );
if( entry != null )
{
m_Blocked.Remove( entry );
Save();
}
}
public static void Add( object obj )
{
if( obj is IPAddress )
Add( (IPAddress)obj );
else if( obj is string )
Add( (string)obj );
else if( obj is IFirewallEntry )
Add( (IFirewallEntry)obj );
}
public static void Add( IFirewallEntry entry )
{
if( !m_Blocked.Contains( entry ) )
m_Blocked.Add( entry );
Save();
}
public static void Add( string pattern )
{
IFirewallEntry entry = ToFirewallEntry( pattern );
if( !m_Blocked.Contains( entry ) )
m_Blocked.Add( entry );
Save();
}
public static void Add( IPAddress ip )
{
IFirewallEntry entry = new IPFirewallEntry( ip );
if( !m_Blocked.Contains( entry ) )
m_Blocked.Add( entry );
Save();
}
public static void Save()
{
string path = "firewall.cfg";
using ( StreamWriter op = new StreamWriter( path ) )
{
for ( int i = 0; i < m_Blocked.Count; ++i )
op.WriteLine( m_Blocked[i] );
}
}
public static bool IsBlocked( IPAddress ip )
{
for( int i = 0; i < m_Blocked.Count; i++ )
{
if( m_Blocked[i].IsBlocked( ip ) )
return true;
}
return false;
/*
bool contains = false;
for ( int i = 0; !contains && i < m_Blocked.Count; ++i )
{
if ( m_Blocked[i] is IPAddress )
contains = ip.Equals( m_Blocked[i] );
else if ( m_Blocked[i] is String )
{
string s = (string)m_Blocked[i];
contains = Utility.IPMatchCIDR( s, ip );
if( !contains )
contains = Utility.IPMatch( s, ip );
}
}
return contains;
* */
}
}
}

View file

@ -0,0 +1,59 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using Server;
using Server.Network;
namespace Server.Misc
{
public class IPLimiter
{
public static bool Enabled = true;
public static bool SocketBlock = true; // true to block at connection, false to block at login request
public static int MaxAddresses = 10;
public static IPAddress[] Exemptions = new IPAddress[] //For hosting services where there are cases where IPs can be proxied
{
//IPAddress.Parse( "127.0.0.1" ),
};
public static bool IsExempt( IPAddress ip )
{
for ( int i = 0; i < Exemptions.Length; i++ )
{
if ( ip.Equals( Exemptions[i] ) )
return true;
}
return false;
}
public static bool Verify( IPAddress ourAddress )
{
if ( !Enabled || IsExempt( ourAddress ) )
return true;
List<NetState> netStates = NetState.Instances;
int count = 0;
for ( int i = 0; i < netStates.Count; ++i )
{
NetState compState = netStates[i];
if ( ourAddress.Equals( compState.Address ) )
{
++count;
if ( count >= MaxAddresses )
return false;
}
}
return true;
}
}
}

604
Scripts/Commands/Add.cs Normal file
View file

@ -0,0 +1,604 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Server;
using Server.Items;
using Server.Network;
using Server.Targeting;
using CPA = Server.CommandPropertyAttribute;
namespace Server.Commands
{
public class Add
{
public static void Initialize()
{
CommandSystem.Register( "Tile", AccessLevel.GameMaster, new CommandEventHandler( Tile_OnCommand ) );
CommandSystem.Register( "TileRXYZ", AccessLevel.GameMaster, new CommandEventHandler( TileRXYZ_OnCommand ) );
CommandSystem.Register( "TileXYZ", AccessLevel.GameMaster, new CommandEventHandler( TileXYZ_OnCommand ) );
CommandSystem.Register( "TileZ", AccessLevel.GameMaster, new CommandEventHandler( TileZ_OnCommand ) );
}
public static void Invoke( Mobile from, Point3D start, Point3D end, string[] args )
{
Invoke( from, start, end, args, null );
}
public static void Invoke( Mobile from, Point3D start, Point3D end, string[] args, List<Container> packs )
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat( "{0} {1} building ", from.AccessLevel, CommandLogging.Format( from ) );
if ( start == end )
sb.AppendFormat( "at {0} in {1}", start, from.Map );
else
sb.AppendFormat( "from {0} to {1} in {2}", start, end, from.Map );
sb.Append( ":" );
for ( int i = 0; i < args.Length; ++i )
sb.AppendFormat( " \"{0}\"", args[i] );
CommandLogging.WriteLine( from, sb.ToString() );
string name = args[0];
FixArgs( ref args );
string[,] props = null;
for ( int i = 0; i < args.Length; ++i )
{
if ( Insensitive.Equals( args[i], "set" ) )
{
int remains = args.Length - i - 1;
if ( remains >= 2 )
{
props = new string[remains / 2, 2];
remains /= 2;
for ( int j = 0; j < remains; ++j )
{
props[j, 0] = args[i + (j * 2) + 1];
props[j, 1] = args[i + (j * 2) + 2];
}
FixSetString( ref args, i );
}
break;
}
}
Type type = ScriptCompiler.FindTypeByName( name );
if ( !IsEntity( type ) ) {
from.SendMessage( "No type with that name was found." );
return;
}
DateTime time = DateTime.Now;
int built = BuildObjects( from, type, start, end, args, props, packs );
if ( built > 0 )
from.SendMessage( "{0} object{1} generated in {2:F1} seconds.", built, built != 1 ? "s" : "", (DateTime.Now - time).TotalSeconds );
else
SendUsage( type, from );
}
public static void FixSetString( ref string[] args, int index )
{
string[] old = args;
args = new string[index];
Array.Copy( old, 0, args, 0, index );
}
public static void FixArgs( ref string[] args )
{
string[] old = args;
args = new string[args.Length - 1];
Array.Copy( old, 1, args, 0, args.Length );
}
public static int BuildObjects( Mobile from, Type type, Point3D start, Point3D end, string[] args, string[,] props, List<Container> packs )
{
Utility.FixPoints( ref start, ref end );
PropertyInfo[] realProps = null;
if ( props != null )
{
realProps = new PropertyInfo[props.GetLength( 0 )];
PropertyInfo[] allProps = type.GetProperties( BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public );
for ( int i = 0; i < realProps.Length; ++i )
{
PropertyInfo thisProp = null;
string propName = props[i, 0];
for ( int j = 0; thisProp == null && j < allProps.Length; ++j )
{
if ( Insensitive.Equals( propName, allProps[j].Name ) )
thisProp = allProps[j];
}
if ( thisProp == null )
{
from.SendMessage( "Property not found: {0}", propName );
}
else
{
CPA attr = Properties.GetCPA( thisProp );
if ( attr == null )
from.SendMessage( "Property ({0}) not found.", propName );
else if ( from.AccessLevel < attr.WriteLevel )
from.SendMessage( "Setting this property ({0}) requires at least {1} access level.", propName, Mobile.GetAccessLevelName( attr.WriteLevel ) );
else if ( !thisProp.CanWrite || attr.ReadOnly )
from.SendMessage( "Property ({0}) is read only.", propName );
else
realProps[i] = thisProp;
}
}
}
ConstructorInfo[] ctors = type.GetConstructors();
for ( int i = 0; i < ctors.Length; ++i )
{
ConstructorInfo ctor = ctors[i];
if ( !IsConstructable( ctor, from.AccessLevel ) )
continue;
ParameterInfo[] paramList = ctor.GetParameters();
if ( args.Length == paramList.Length )
{
object[] paramValues = ParseValues( paramList, args );
if ( paramValues == null )
continue;
int built = Build( from, start, end, ctor, paramValues, props, realProps, packs );
if ( built > 0 )
return built;
}
}
return 0;
}
public static object[] ParseValues( ParameterInfo[] paramList, string[] args )
{
object[] values = new object[args.Length];
for ( int i = 0; i < args.Length; ++i )
{
object value = ParseValue( paramList[i].ParameterType, args[i] );
if ( value != null )
values[i] = value;
else
return null;
}
return values;
}
public static object ParseValue( Type type, string value )
{
try
{
if ( IsEnum( type ) )
{
return Enum.Parse( type, value, true );
}
else if ( IsType( type ) )
{
return ScriptCompiler.FindTypeByName( value );
}
else if ( IsParsable( type ) )
{
return ParseParsable( type, value );
}
else
{
object obj = value;
if ( value != null && value.StartsWith( "0x" ) )
{
if ( IsSignedNumeric( type ) )
obj = Convert.ToInt64( value.Substring( 2 ), 16 );
else if ( IsUnsignedNumeric( type ) )
obj = Convert.ToUInt64( value.Substring( 2 ), 16 );
obj = Convert.ToInt32( value.Substring( 2 ), 16 );
}
if ( obj == null && !type.IsValueType )
return null;
else
return Convert.ChangeType( obj, type );
}
}
catch
{
return null;
}
}
public static IEntity Build( Mobile from, ConstructorInfo ctor, object[] values, string[,] props, PropertyInfo[] realProps, ref bool sendError )
{
object built = ctor.Invoke( values );
if ( built != null && realProps != null )
{
bool hadError = false;
for ( int i = 0; i < realProps.Length; ++i )
{
if ( realProps[i] == null )
continue;
string result = Properties.InternalSetValue( from, built, built, realProps[i], props[i, 1], props[i, 1], false );
if ( result != "Property has been set." )
{
if ( sendError )
from.SendMessage( result );
hadError = true;
}
}
if ( hadError )
sendError = false;
}
return (IEntity)built;
}
public static int Build( Mobile from, Point3D start, Point3D end, ConstructorInfo ctor, object[] values, string[,] props, PropertyInfo[] realProps, List<Container> packs )
{
try
{
Map map = from.Map;
int objectCount = ( packs == null ? (((end.X - start.X) + 1) * ((end.Y - start.Y) + 1)) : packs.Count );
if ( objectCount >= 20 )
from.SendMessage( "Constructing {0} objects, please wait.", objectCount );
bool sendError = true;
StringBuilder sb = new StringBuilder();
sb.Append( "Serials: " );
if ( packs != null )
{
for ( int i = 0; i < packs.Count; ++i )
{
IEntity built = Build( from, ctor, values, props, realProps, ref sendError );
sb.AppendFormat( "0x{0:X}; ", built.Serial.Value );
if ( built is Item ) {
Container pack = packs[i];
pack.DropItem( (Item)built );
}
else if ( built is Mobile ) {
Mobile m = (Mobile)built;
m.MoveToWorld( new Point3D( start.X, start.Y, start.Z ), map );
}
}
}
else
{
for ( int x = start.X; x <= end.X; ++x )
{
for ( int y = start.Y; y <= end.Y; ++y )
{
IEntity built = Build( from, ctor, values, props, realProps, ref sendError );
sb.AppendFormat( "0x{0:X}; ", built.Serial.Value );
if ( built is Item ) {
Item item = (Item)built;
item.MoveToWorld( new Point3D( x, y, start.Z ), map );
}
else if ( built is Mobile ) {
Mobile m = (Mobile)built;
m.MoveToWorld( new Point3D( x, y, start.Z ), map );
}
}
}
}
CommandLogging.WriteLine( from, sb.ToString() );
return objectCount;
}
catch ( Exception ex )
{
Console.WriteLine(ex);
return 0;
}
}
public static void SendUsage( Type type, Mobile from )
{
ConstructorInfo[] ctors = type.GetConstructors();
bool foundCtor = false;
for ( int i = 0; i < ctors.Length; ++i )
{
ConstructorInfo ctor = ctors[i];
if ( !IsConstructable( ctor, from.AccessLevel ) )
continue;
if ( !foundCtor )
{
foundCtor = true;
from.SendMessage( "Usage:" );
}
SendCtor( type, ctor, from );
}
if ( !foundCtor )
from.SendMessage( "That type is not marked constructable." );
}
public static void SendCtor( Type type, ConstructorInfo ctor, Mobile from )
{
ParameterInfo[] paramList = ctor.GetParameters();
StringBuilder sb = new StringBuilder();
sb.Append( type.Name );
for ( int i = 0; i < paramList.Length; ++i )
{
if ( i != 0 )
sb.Append( ',' );
sb.Append( ' ' );
sb.Append( paramList[i].ParameterType.Name );
sb.Append( ' ' );
sb.Append( paramList[i].Name );
}
from.SendMessage( sb.ToString() );
}
public class AddTarget : Target
{
private string[] m_Args;
public AddTarget( string[] args ) : base( -1, true, TargetFlags.None )
{
m_Args = args;
}
protected override void OnTarget( Mobile from, object o )
{
IPoint3D p = o as IPoint3D;
if ( p != null )
{
if ( p is Item )
p = ((Item)p).GetWorldTop();
else if ( p is Mobile )
p = ((Mobile)p).Location;
Point3D point = new Point3D( p );
Add.Invoke( from, point, point, m_Args );
}
}
}
private class TileState
{
public bool m_UseFixedZ;
public int m_FixedZ;
public string[] m_Args;
public TileState( string[] args ) : this( false, 0, args )
{
}
public TileState( int fixedZ, string[] args ) : this( true, fixedZ, args )
{
}
public TileState( bool useFixedZ, int fixedZ, string[] args )
{
m_UseFixedZ = useFixedZ;
m_FixedZ = fixedZ;
m_Args = args;
}
}
private static void TileBox_Callback( Mobile from, Map map, Point3D start, Point3D end, object state )
{
TileState ts = (TileState)state;
if ( ts.m_UseFixedZ )
start.Z = end.Z = ts.m_FixedZ;
Invoke( from, start, end, ts.m_Args );
}
[Usage( "Tile <name> [params] [set {<propertyName> <value> ...}]" )]
[Description( "Tiles an item or npc by name into a targeted bounding box. Optional constructor parameters. Optional set property list." )]
public static void Tile_OnCommand( CommandEventArgs e )
{
if ( e.Length >= 1 )
BoundingBoxPicker.Begin( e.Mobile, new BoundingBoxCallback( TileBox_Callback ), new TileState( e.Arguments ) );
else
e.Mobile.SendMessage( "Format: Add <type> [params] [set {<propertyName> <value> ...}]" );
}
[Usage( "TileRXYZ <x> <y> <w> <h> <z> <name> [params] [set {<propertyName> <value> ...}]" )]
[Description( "Tiles an item or npc by name into a given bounding box, (x, y) parameters are relative to your characters position. Optional constructor parameters. Optional set property list." )]
public static void TileRXYZ_OnCommand( CommandEventArgs e )
{
if ( e.Length >= 6 )
{
Point3D p = new Point3D( e.Mobile.X + e.GetInt32( 0 ), e.Mobile.Y + e.GetInt32( 1 ), e.Mobile.Z + e.GetInt32( 4 ) );
Point3D p2 = new Point3D( p.X + e.GetInt32( 2 ) - 1, p.Y + e.GetInt32( 3 ) - 1, p.Z );
string[] subArgs = new string[e.Length - 5];
for ( int i = 0; i < subArgs.Length; ++i )
subArgs[i] = e.Arguments[i + 5];
Add.Invoke( e.Mobile, p, p2, subArgs );
}
else
{
e.Mobile.SendMessage( "Format: TileRXYZ <x> <y> <w> <h> <z> <type> [params] [set {<propertyName> <value> ...}]" );
}
}
[Usage( "TileXYZ <x> <y> <w> <h> <z> <name> [params] [set {<propertyName> <value> ...}]" )]
[Description( "Tiles an item or npc by name into a given bounding box. Optional constructor parameters. Optional set property list." )]
public static void TileXYZ_OnCommand( CommandEventArgs e )
{
if ( e.Length >= 6 )
{
Point3D p = new Point3D( e.GetInt32( 0 ), e.GetInt32( 1 ), e.GetInt32( 4 ) );
Point3D p2 = new Point3D( p.X + e.GetInt32( 2 ) - 1, p.Y + e.GetInt32( 3 ) - 1, e.GetInt32( 4 ) );
string[] subArgs = new string[e.Length - 5];
for ( int i = 0; i < subArgs.Length; ++i )
subArgs[i] = e.Arguments[i + 5];
Add.Invoke( e.Mobile, p, p2, subArgs );
}
else
{
e.Mobile.SendMessage( "Format: TileXYZ <x> <y> <w> <h> <z> <type> [params] [set {<propertyName> <value> ...}]" );
}
}
[Usage( "TileZ <z> <name> [params] [set {<propertyName> <value> ...}]" )]
[Description( "Tiles an item or npc by name into a targeted bounding box at a fixed Z location. Optional constructor parameters. Optional set property list." )]
public static void TileZ_OnCommand( CommandEventArgs e )
{
if ( e.Length >= 2 )
{
string[] subArgs = new string[e.Length - 1];
for ( int i = 0; i < subArgs.Length; ++i )
subArgs[i] = e.Arguments[i + 1];
BoundingBoxPicker.Begin( e.Mobile, new BoundingBoxCallback( TileBox_Callback ), new TileState( e.GetInt32( 0 ), subArgs ) );
}
else
{
e.Mobile.SendMessage( "Format: TileZ <z> <type> [params] [set {<propertyName> <value> ...}]" );
}
}
private static Type m_EntityType = typeof( IEntity );
public static bool IsEntity( Type t )
{
return m_EntityType.IsAssignableFrom( t );
}
private static Type m_ConstructableType = typeof( ConstructableAttribute );
public static bool IsConstructable( ConstructorInfo ctor, AccessLevel accessLevel )
{
object[] attrs = ctor.GetCustomAttributes( m_ConstructableType, false );
if ( attrs.Length == 0 )
return false;
return accessLevel >= ((ConstructableAttribute)attrs[0]).AccessLevel;
}
private static Type m_EnumType = typeof( Enum );
public static bool IsEnum( Type type )
{
return type.IsSubclassOf( m_EnumType );
}
private static Type m_TypeType = typeof( Type );
public static bool IsType( Type type )
{
return ( type == m_TypeType || type.IsSubclassOf( m_TypeType ) );
}
private static Type m_ParsableType = typeof( ParsableAttribute );
public static bool IsParsable( Type type )
{
return type.IsDefined( m_ParsableType, false );
}
private static Type[] m_ParseTypes = new Type[]{ typeof( string ) };
private static object[] m_ParseArgs = new object[1];
public static object ParseParsable( Type type, string value )
{
MethodInfo method = type.GetMethod( "Parse", m_ParseTypes );
m_ParseArgs[0] = value;
return method.Invoke( null, m_ParseArgs );
}
private static Type[] m_SignedNumerics = new Type[]
{
typeof( Int64 ),
typeof( Int32 ),
typeof( Int16 ),
typeof( SByte )
};
public static bool IsSignedNumeric( Type type )
{
for ( int i = 0; i < m_SignedNumerics.Length; ++i )
if ( type == m_SignedNumerics[i] )
return true;
return false;
}
private static Type[] m_UnsignedNumerics = new Type[]
{
typeof( UInt64 ),
typeof( UInt32 ),
typeof( UInt16 ),
typeof( Byte )
};
public static bool IsUnsignedNumeric( Type type )
{
for ( int i = 0; i < m_UnsignedNumerics.Length; ++i )
if ( type == m_UnsignedNumerics[i] )
return true;
return false;
}
}
}

View file

@ -0,0 +1,907 @@
/*
Package Name: CEO's Yet Another Arya Addon Generator (YAAAG)
Author: CEO
Version: 1.2
Public Release: 09/25/07
Purpose: Generates AddOns from statics, items, and tiles. Oh my!
*/
/* Modified to work with the new SA & High Seas items by Hammerhand */
// If you're using an SVN that supports List<> methods (remove the //s) to use those instead of arrays or add them for RC1.
#define RC2
//#define DEBUG
#undef DEBUG
using System;
using System.Collections;
using System.IO;
using Server;
using Server.Items;
using Server.Gumps;
using Server.Commands;
using System.Collections.Generic;
using Server.ContextMenus;
using Server.Network;
using Server.Targeting;
namespace Arya.Misc
{
public class AddonGenerator
{
/// <summary>
/// Set this value if you wish the scripts to be output somewhere else rather than in the default RunUO\TheBox
/// directory. This should be a full valid path on your computer
///
/// Example:
///
/// private static string m_CustomOutputDirector = @"C:\Program Files\RunUO\Scripts\Custom\Addons";
/// </summary>
private static string m_CustomOutputDirectory = null;
#region Template
private const string m_SimpleCode = @"
for (int i = 0; i < m_AddOnSimpleComponents.Length / 4; i++)
AddComponent( new AddonComponent( m_AddOnSimpleComponents[i,0] ), m_AddOnSimpleComponents[i,1], m_AddOnSimpleComponents[i,2], m_AddOnSimpleComponents[i,3] );";
private const string m_ComplexCode = @"
for (int i = 0; i < m_AddOnComplexComponents.Length / 6; i++)
AddComplexComponent( (BaseAddon)this, m_AddOnComplexComponents[i,0], m_AddOnComplexComponents[i,1], m_AddOnComplexComponents[i,2], m_AddOnComplexComponents[i,3], m_AddOnComplexComponents[i,4], m_AddOnComplexComponents[i,5] );";
private const string m_ComplexNameCode = @"
private static void AddComplexComponent(BaseAddon addon, int item, int xoffset, int yoffset, int zoffset, int hue, int lightsource)
{
AddComplexComponent(addon, item, xoffset, yoffset, zoffset, hue, lightsource, null, 1);
}
private static void AddComplexComponent(BaseAddon addon, int item, int xoffset, int yoffset, int zoffset, int hue, int lightsource, string name, int amount)
{
AddonComponent ac;
ac = new AddonComponent(item);
if (name != null && name.Length > 0)
ac.Name = name;
if (hue != 0)
ac.Hue = hue;
if (amount > 1)
{
ac.Stackable = true;
ac.Amount = amount;
}
if (lightsource != -1)
ac.Light = (LightType) lightsource;
addon.AddComponent(ac, xoffset, yoffset, zoffset);
}";
private const string m_Template = @"
////////////////////////////////////////
// //
// Generated by CEO's YAAAG - Ver 2 //
// (Yet Another Arya Addon Generator) //
// Modified by Hammerhand for //
// SA & High Seas content //
// //
////////////////////////////////////////
using System;
using Server;
using Server.Items;
namespace {namespace}
{
public class {name}Addon : BaseAddon
{
{simplelist}
{complexlist}
public override BaseAddonDeed Deed
{
get
{
return new {name}AddonDeed();
}
}
[ Constructable ]
public {name}Addon()
{
{simplecomponentscode}
{complexcomponentscode}
{namedcomponentscode}
}
public {name}Addon( Serial serial ) : base( serial )
{
}
{complexnamecomponentscode}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 ); // Version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class {name}AddonDeed : BaseAddonDeed
{
public override BaseAddon Addon
{
get
{
return new {name}Addon();
}
}
[Constructable]
public {name}AddonDeed()
{
Name = ""{name}"";
}
public {name}AddonDeed( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 ); // Version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}";
#endregion
public static void Initialize()
{
CommandSystem.Register("AddonGen", AccessLevel.Administrator, new CommandEventHandler(OnAddonGen));
}
#region Command
[Usage("AddonGen [<name> [namespace]]"),
Description("Brings up the addon script generator gump. When used with the name (and eventually namespace) parameter generates an addon script from the targeted region.")]
private static void OnAddonGen(CommandEventArgs e)
{
object[] state = new object[18];
state[0] = "";
state[1] = "Server.Items";
state[2] = true;
state[3] = false;
state[4] = false;
state[5] = true;
state[6] = true;
state[7] = true;
state[8] = true;
state[9] = -128;
state[10] = 127;
state[11] = state[13] = state[15] = 2;
state[12] = state[14] = state[16] = 36653;
if (e.Arguments.Length > 0)
{
state[0] = e.Arguments[0];
if (e.Arguments.Length > 1)
state[1] = e.Arguments[1];
}
e.Mobile.SendGump(new InternalGump(e.Mobile, state));
}
#endregion
private static void PickerCallback(Mobile from, Map map, Point3D start, Point3D end, object state)
{
object[] args = state as object[];
int m_SimpleComponents = 0;
int m_ComplexComponents = 0;
int m_NamedComponents = 0;
int m_TotalComponents = 0;
if (start.X > end.X)
{
int x = start.X;
start.X = end.X;
end.X = x;
}
if (start.Y > end.Y)
{
int y = start.Y;
start.Y = end.Y;
end.Y = y;
}
Rectangle2D bounds = new Rectangle2D(start, end);
string name = args[0] as string;
string ns = args[1] as string;
bool getStatics = (bool)args[2];
bool getItems = (bool)args[3];
bool getTiles = (bool)args[4];
bool includeStaticRange = (bool)args[5];
bool includeItemRange = (bool)args[6];
bool includeTileRange = (bool)args[7];
bool includeZRange = (bool)args[8];
bool generateTest = (bool)args[17];
sbyte min = sbyte.MinValue;
sbyte max = sbyte.MaxValue;
int minStaticID = 2;
int maxStaticID = 36653;
int minItemID = 2;
int maxItemID = 36653;
int minTileID = 2;
int maxTileID = 36653;
try { min = sbyte.Parse(args[9] as string); }
catch { }
try { max = sbyte.Parse(args[10] as string); }
catch { }
try { minStaticID = int.Parse(args[11] as string); }
catch { }
try { maxStaticID = int.Parse(args[12] as string); }
catch { }
try { minItemID = int.Parse(args[13] as string); }
catch { }
try { maxItemID = int.Parse(args[14] as string); }
catch { }
try { minTileID = int.Parse(args[15] as string); }
catch { }
try { maxTileID = int.Parse(args[16] as string); }
catch { }
Hashtable tiles = new Hashtable();
if (getTiles)
{
for (int x = start.X; x <= end.X; x++)
{
for (int y = start.Y; y <= end.Y; y++)
{
#if RC2
StaticTile[] stlist = map.Tiles.GetStaticTiles(x, y, true);
List<Server.StaticTile> list = new List<Server.StaticTile>();
List<Server.StaticTile> remove = new List<Server.StaticTile>();
#else
ArrayList list = map.GetTilesAt(new Point2D(x, y), false, false, true);
ArrayList remove = new ArrayList();
#endif
foreach (StaticTile t in stlist)
{
list.Add(t);
int id = t.ID - 36653;
if (id < 2 || id > 36653)
remove.Add(t);
else if (includeZRange && (t.Z < min || t.Z > max))
remove.Add(t);
else if (!includeZRange && (t.Z >= min && t.Z <= max))
remove.Add(t);
else if (includeTileRange && (id < minTileID || id > maxTileID))
remove.Add(t);
else if (!includeTileRange && (id >= minTileID && id <= maxTileID))
remove.Add(t);
}
foreach (StaticTile t in remove)
{
list.Remove(t);
}
if (list != null && list.Count > 0)
{
tiles[new Point2D(x, y)] = list;
}
}
}
}
IPooledEnumerable en = map.GetItemsInBounds(bounds);
ArrayList target = new ArrayList();
bool fail = false;
try
{
foreach (object o in en)
{
if (getStatics)
{
Static s = o as Static;
if (s == null)
{ }
else if (s.Deleted)
{ }
else if (includeZRange && (s.Z < min || s.Z > max))
continue;
else if (!includeZRange && (s.Z >= min && s.Z <= max))
continue;
else if (includeStaticRange && (s.ItemID < minStaticID || s.ItemID > maxStaticID))
continue;
else if (!includeStaticRange && (s.ItemID >= minStaticID && s.ItemID <= maxStaticID))
continue;
else
{
target.Add(o);
#if DEBUG
Console.WriteLine("Static={0}:{1}", s.GetType().ToString(), s.ItemID);
#endif
continue;
}
}
if (getItems)
{
Static s = o as Static;
if (s != null) // Don't want a static
continue;
Item i = o as Item;
if (i == null)
continue;
else if (i.Deleted)
continue;
else if (i is BaseAddon) // Not a good idea to add a BaseAddOn for obvious reasons
continue;
else if (i.ItemID < 2 || i.ItemID > 36653) // This is not an Item within the normal artwork.. multi... etc.. Toss it
continue;
else if (includeZRange && (i.Z < min || i.Z > max))
continue;
else if (!includeZRange && (i.Z >= min && i.Z <= max))
continue;
else if (includeItemRange && (i.ItemID < minItemID || i.ItemID > maxItemID))
continue;
else if (!includeItemRange && (i.ItemID >= minItemID && i.ItemID <= maxItemID))
continue;
#if DEBUG
Console.WriteLine("item={0}:{1}, {2}-map{3}", i.GetType().ToString(), i.ItemID, i.Deleted, i.Map);
#endif
target.Add(o);
}
}
}
catch (Exception err)
{
Console.WriteLine(err.ToString());
from.SendMessage(0x40, "The targeted components have been modified. Please retry.");
fail = true;
}
finally
{
en.Free();
}
if (fail)
return;
if (target.Count == 0 && tiles.Keys.Count == 0)
{
from.SendMessage(0x40, "No components have been selected.");
from.SendGump(new InternalGump(from, args));
return;
}
// Get center
Point3D center = new Point3D();
center.Z = 127;
int x1 = bounds.End.X;
int y1 = bounds.End.Y;
int x2 = bounds.Start.X;
int y2 = bounds.Start.Y;
// Get correct bounds
foreach (Item item in target)
{
if (item.Z < center.Z)
{
center.Z = item.Z;
}
x1 = Math.Min(x1, item.X);
y1 = Math.Min(y1, item.Y);
x2 = Math.Max(x2, item.X);
y2 = Math.Max(y2, item.Y);
}
CEOIdentifyAddon IdentifyAddon = null;
if (generateTest)
IdentifyAddon = new CEOIdentifyAddon("init");
foreach (Point2D p in tiles.Keys)
{
#if RC2
List<Server.StaticTile> list = tiles[p] as List<Server.StaticTile>;
#else
ArrayList list = tiles[p] as ArrayList;
#endif
if (list == null)
{
Console.WriteLine("The list is null... ");
return;
}
foreach (StaticTile t in list)
{
if (t.Z < center.Z)
{
center.Z = t.Z;
}
}
x1 = Math.Min(x1, p.X);
y1 = Math.Min(y1, p.Y);
x2 = Math.Max(x2, p.X);
y2 = Math.Max(y2, p.Y);
}
center.X = x1 + ((x2 - x1) / 2);
center.Y = y1 + ((y2 - y1) / 2);
// Build items
System.Text.StringBuilder nc = new System.Text.StringBuilder();
nc.Append("\n");
System.Text.StringBuilder sl = new System.Text.StringBuilder();
sl.Append("private static int[,] m_AddOnSimpleComponents = new int[,] {\n\t\t\t ");
System.Text.StringBuilder cl = new System.Text.StringBuilder();
cl.Append("private static int[,] m_AddOnComplexComponents = new int[,] {\n\t\t\t ");
System.Text.StringBuilder sc = new System.Text.StringBuilder();
sc.Append("// ");
System.Text.StringBuilder cc = new System.Text.StringBuilder();
cc.Append("// ");
int simplecount = 0;
int complexcount = 0;
// Tiles
foreach (Point2D p in tiles.Keys)
{
#if RC2
List<Server.StaticTile> list = tiles[p] as List<Server.StaticTile>;
#else
ArrayList list = tiles[p] as ArrayList;
#endif
int xOffset = p.X - center.X;
int yOffset = p.Y - center.Y;
foreach (StaticTile t in list)
{
int zOffset = t.Z - center.Z;
int id = t.ID - 36653;
m_SimpleComponents++;
simplecount++;
m_TotalComponents++;
sc.AppendFormat("{0}\t ", m_TotalComponents);
if (simplecount > 1)
sl.Append(", ");
sl.Append("{");
sl.AppendFormat("{0}, {1}, {2}, {3}", id, xOffset, yOffset, zOffset);
sl.Append("}");
if (simplecount % 3 == 0)
{
sl.AppendFormat("{0}\n\t\t\t", sc.ToString());
sc.Length = 0;
sc.Append("// ");
}
if (generateTest)
AddIdentifyAddOnComponent(IdentifyAddon, id, xOffset, yOffset, zOffset, 0, -1, string.Format("({0}):{1},{2},{3}", m_TotalComponents, xOffset, yOffset, zOffset), 0);
}
}
// Statics & Items
foreach (Item item in target)
{
if (item.Deleted)
continue;
int xOffset = item.X - center.X;
int yOffset = item.Y - center.Y;
int zOffset = item.Z - center.Z;
int id = item.ItemID;
if (((item.ItemData.Flags & TileFlag.LightSource) == TileFlag.LightSource) || (item.Hue != 0) || (item.Name != null) || item.Amount > 1) // Use old method
{
if (item.Name != null || item.Amount != 0) // Have to do this one the old method
{
m_NamedComponents++;
m_TotalComponents++;
int lightsource = -1;
if ((item.ItemData.Flags & TileFlag.LightSource) == TileFlag.LightSource)
lightsource = (int)item.Light;
nc.AppendFormat("\t\t\tAddComplexComponent( (BaseAddon) this, {0}, {1}, {2}, {3}, {4}, {5}, \"{6}\", {7});// {8}\n", id, xOffset, yOffset, zOffset, item.Hue, lightsource, item.Name, item.Amount, m_TotalComponents);
if (generateTest)
AddIdentifyAddOnComponent(IdentifyAddon, id, xOffset, yOffset, zOffset, item.Hue, -1, string.Format("({0},{1}): {2}, {3}, {4}", m_TotalComponents, id, xOffset, yOffset, zOffset), item.Amount);
}
else //if (item.Hue != 0 || (item.ItemData.Flags & TileFlag.LightSource) == TileFlag.LightSource)
{
int lightsource = -1;
if ((item.ItemData.Flags & TileFlag.LightSource) == TileFlag.LightSource)
lightsource = (int)item.Light;
m_ComplexComponents++;
m_TotalComponents++;
cc.AppendFormat("{0}\t", m_TotalComponents);
complexcount++;
if (complexcount > 1)
cl.Append(", ");
cl.Append("{");
cl.AppendFormat("{0}, {1}, {2}, {3}, {4}, {5} ", id, xOffset, yOffset, zOffset, item.Hue, lightsource);
cl.Append("}");
if (complexcount % 3 == 0)
{
cl.AppendFormat("{0}\n\t\t\t", cc.ToString());
cc.Length = 0;
cc.Append("// ");
}
if (generateTest)
AddIdentifyAddOnComponent(IdentifyAddon, id, xOffset, yOffset, zOffset, item.Hue, -1, string.Format("({0},{1}): {2}, {3}, {4}", m_TotalComponents, id, xOffset, yOffset, zOffset), 0);
}
}
else // Add data to static table
{
m_SimpleComponents++;
m_TotalComponents++;
sc.AppendFormat("{0}\t", m_TotalComponents);
simplecount++;
if (simplecount > 1)
sl.Append(", ");
sl.Append("{");
sl.AppendFormat("{0}, {1}, {2}, {3}", id, xOffset, yOffset, zOffset);
sl.Append("}");
if (simplecount % 3 == 0)
{
sl.AppendFormat("{0}\n\t\t\t", sc.ToString());
sc.Length = 0;
sc.Append("// ");
}
if (generateTest)
AddIdentifyAddOnComponent(IdentifyAddon, id, xOffset, yOffset, zOffset, item.Hue, -1, string.Format("({0},{1}): {2}, {3}, {4}", m_TotalComponents, id, xOffset, yOffset, zOffset), 0);
}
}
if (sc.Length > 4)
sl.AppendFormat("{0}\n", sc.ToString());
if (cc.Length > 4)
cl.AppendFormat("{0}\n", cc.ToString());
if (m_SimpleComponents > 0)
sl.Append("\t\t};\n\n");
if (m_ComplexComponents > 0)
cl.Append("\t\t};\n\n");
string output = m_Template.Replace("{name}", name);
output = output.Replace("{simplelist}", m_SimpleComponents > 0 ? sl.ToString() : "");
output = output.Replace("{simplecomponentscode}", m_SimpleComponents > 0 ? m_SimpleCode : "");
output = output.Replace("{complexlist}", m_ComplexComponents > 0 ? cl.ToString() : "");
output = output.Replace("{complexcomponentscode}", m_ComplexComponents > 0 ? m_ComplexCode : "");
output = output.Replace("{namedcomponentscode}", m_NamedComponents > 0 ? nc.ToString() : "");
output = output.Replace("{complexnamecomponentscode}", (m_ComplexComponents > 0 || m_NamedComponents > 0) ? m_ComplexNameCode : "");
output = output.Replace("{namespace}", ns);
StreamWriter writer = null;
string path = null;
if (m_CustomOutputDirectory != null)
path = Path.Combine(m_CustomOutputDirectory, string.Format(@"TheBox\{0}Addon.cs", name));
else
path = Path.Combine(Core.BaseDirectory, string.Format(@"TheBox\{0}Addon.cs", name));
fail = false;
try
{
string folder = Path.GetDirectoryName(path);
if (!Directory.Exists(folder))
{
Directory.CreateDirectory(folder);
}
writer = new StreamWriter(path, false);
writer.Write(output);
}
catch
{
from.SendMessage(0x40, "An error occurred when writing the file.");
fail = true;
}
finally
{
if (writer != null)
writer.Close();
}
if (!fail)
{
from.SendMessage(0x40, "Script saved to {0}", path);
from.SendMessage(0x40, "Total components in AddOn: {0}", m_TotalComponents);
if (generateTest && IdentifyAddon != null)
{
from.SendMessage(0x37, "Now target a land tile to place a your addon.");
from.Target = new InternalTarget(IdentifyAddon);
}
}
}
private static void AddIdentifyAddOnComponent(CEOIdentifyAddon ai, int item, int xoffset, int yoffset, int zoffset, int hue, int lightsource, string name, int amount)
{
if (ai == null)
return;
AddonComponent ac;
ac = new AddonComponent(item);
if (name != null && name.Length > 0)
ac.Name = name;
if (hue != 0)
ac.Hue = hue;
if (amount > 1) // Note: a warning will show on the console regarding a non-stackable item....
{
ac.Stackable = true;
ac.Amount = amount;
}
if (lightsource != -1)
ac.Light = (LightType)lightsource;
ai.AddComponent(ac, xoffset, yoffset, zoffset);
}
private class InternalTarget : Target
{
private CEOIdentifyAddon m_IdentifyAddon;
public InternalTarget(CEOIdentifyAddon IdentifyAddon)
: base(12, false, TargetFlags.None)
{
m_IdentifyAddon = IdentifyAddon;
CheckLOS = true;
AllowGround = true;
DisallowMultis = true;
Range = 15;
}
protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType)
{
if (m_IdentifyAddon != null)
m_IdentifyAddon.Delete();
}
protected override void OnTarget(Mobile from, object o)
{
if (o != null)
{
if (o is LandTarget)
{
LandTarget l = o as LandTarget;
m_IdentifyAddon.MoveToWorld(l.Location, from.Map);
}
else
{
from.SendMessage(37, "Use must target a land tile to place your addon.");
if (m_IdentifyAddon != null)
m_IdentifyAddon.Delete();
}
}
}
}
#region Gump
private class InternalGump : Gump
{
private const int LabelHue = 0x480;
private const int TitleHue = 0x35;
private object[] m_State;
public InternalGump(Mobile m, object[] state)
: base(100, 50)
{
m.CloseGump(typeof(InternalGump));
m_State = state;
MakeGump();
}
private void MakeGump()
{
Closable = true;
Disposable = true;
Dragable = true;
Resizable = false;
AddPage(0);
AddBackground(0, 0, 440, 260, 9260);
//AddAlphaRegion(10, 10, 430, 260); //uncomment this line if you like see-thru menus
AddHtml(0, 15, 440, 20, Center(Color("CEO's Yet Another Arya Addon Generator(YAAAG)", 0x000080)), false, false);
int x = 40;
AddLabel(20, x, LabelHue, @"Name");
AddImageTiled(95, x, 165, 18, 9274);
AddTextEntry(95, x, 165, 20, LabelHue, 0, m_State[0] as string); // Name
x += 20;
AddLabel(20, x, LabelHue, @"Namespace");
AddImageTiled(95, x, 165, 18, 9274);
AddTextEntry(95, x, 165, 20, LabelHue, 1, m_State[1] as string); // Namespace
AddLabel(340, x, TitleHue, @"ID Range");
x += 20;
AddLabel(20, x, TitleHue, @"Export");
AddLabel(170, x, TitleHue, @"ID Range");
AddLabel(320, x, TitleHue, @"Include/Exclude");
x += 25;
// Export Statics, Items, and Tiles
string[] exportString = new string[] { "Statics", "Items", "Tiles" };
for (int i = 0; i < 3; i++)
{
DisplayExportLine(x, i, ((bool)m_State[i + 2]), ((bool)m_State[i + 5]), exportString[i], m_State[11 + (i * 2)].ToString(), m_State[12 + (i * 2)].ToString());
x += (i < 2 ? 25 : 15);
}
AddImageTiled(15, x + 15, 420, 1, 9304);
x += 25;
// Z Range
AddCheck(350, x, 9026, 9027, ((bool)m_State[8]), 6);
AddLabel(20, x, LabelHue, @"Z Range");
AddImageTiled(115, x + 15, 50, 1, 9274);
AddTextEntry(115, x - 5, 50, 20, LabelHue, 2, m_State[9].ToString());
AddLabel(185, x, LabelHue, @"to");
AddImageTiled(225, x + 15, 50, 1, 9274);
AddTextEntry(225, x - 5, 50, 20, LabelHue, 3, m_State[10].ToString());
x += 25;
// Buttons
AddButton(20, x, 4020, 4021, 0, GumpButtonType.Reply, 0);
AddLabel(55, x, LabelHue, @"Cancel");
AddButton(155, x, 4005, 4006, 1, GumpButtonType.Reply, 0);
AddLabel(195, x, LabelHue, @"Generate");
AddButton(300, x, 4005, 4006, 2, GumpButtonType.Reply, 0);
AddLabel(340, x, LabelHue, @"Test & Gen");
}
private void DisplayExportLine(int x, int index, bool state, bool include, string heading, string min, string max)
{
AddCheck(20, x, 9026, 9027, state, index);
AddLabel(40, x, LabelHue, heading);
AddImageTiled(115, x + 15, 50, 1, 9274);
AddTextEntry(115, x - 5, 50, 20, LabelHue, 4 + (index * 2), min);// Tile ID Min
AddLabel(185, x, LabelHue, @"to");
AddImageTiled(225, x + 15, 50, 1, 9274);
AddTextEntry(225, x - 5, 50, 20, LabelHue, 5 + (index * 2), max);// Tile ID Max
AddCheck(350, x, 9026, 9027, include, index + 3); // Include or Exclude compare?
}
private string Center(string text)
{
return String.Format("<CENTER>{0}</CENTER>", text);
}
private string Color(string text, int color)
{
return String.Format("<BASEFONT COLOR=#{0:X6}>{1}</COLOR>", color, text);
}
public override void OnResponse(Server.Network.NetState sender, RelayInfo info)
{
if (info.ButtonID == 0)
return;
else if (info.ButtonID == 1)
m_State[17] = false;
else
m_State[17] = true;
foreach (TextRelay text in info.TextEntries)
m_State[text.EntryID < 2 ? text.EntryID : text.EntryID + 7] = text.Text;
// Reset checks
for (int x = 2; x <= 8; x++)
m_State[x] = false;
foreach (int check in info.Switches)
m_State[check + 2] = true; // Offset by 2 in the state object
if (Verify(sender.Mobile, m_State))
{
BoundingBoxPicker.Begin(sender.Mobile, new BoundingBoxCallback(AddonGenerator.PickerCallback), m_State);
}
else
{
sender.Mobile.SendMessage(0x40, "Please review the generation parameters, some are invalid.");
sender.Mobile.SendGump(new InternalGump(sender.Mobile, m_State));
}
}
private static bool Verify(Mobile from, object[] state)
{
if (state[0] == null || (state[0] as string).Length == 0)
{
from.SendMessage(0x40, "Name field is invalid or missing.");
return false;
}
if (state[1] == null || (state[1] as string).Length == 0)
{
from.SendMessage(0x40, "Namespace field is invalid or missing.");
return false;
}
if (!((bool)state[2] || (bool)state[3] || (bool)state[4]))
{
from.SendMessage(0x40, "You must have least one Export button selected. (Static/Items/Tiles)");
return false;
}
string[] errors = new string[] {"Z Range Min", "Z Range Max","Static Min ID", "Static Max ID",
"Item Min ID", "Item Max ID", "Tile Min ID", "Tile Max ID"};
for (int x = 0; x < 8; x++)
if (!CheckNumber(x < 2 ? 0 : 1, state[x + 9] as string, errors[x], from))
return false;
return true;
}
private static bool CheckNumber(int numType, string number, string error, Mobile from)
{
sbyte sbyteTemp;
int intTemp;
try
{
if (numType == 0)
sbyteTemp = sbyte.Parse(number);
else
intTemp = int.Parse(number);
}
catch
{
from.SendMessage(0x40, "There's a problem with the {0} field.", error);
return false;
}
return true;
}
}
#endregion
}
}
#region CEOIdentifyAddon
namespace Server.Items
{
public class CEOIdentifyAddon : BaseAddon
{
[Constructable]
public CEOIdentifyAddon(string init)
{
// Nothing really here, just prevents adding a null contruct via [add command
}
[Constructable]
public CEOIdentifyAddon()
{
this.Delete();
}
public CEOIdentifyAddon(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // Version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (this.Map == null || this.Map == Map.Internal)
this.Delete(); // Remove it because it's most
}
public void ReDeed(Mobile m)
{
this.Delete();
}
}
}
#endregion

View file

@ -0,0 +1,47 @@
using System;
using Server;
using System.Collections;
using System.Collections.Generic;
using Server.Misc;
using Server.Items;
using Server.Network;
using Server.Commands;
using Server.Commands.Generic;
using Server.Mobiles;
using Server.Accounting;
using Server.Regions;
using System.IO;
using Server.Targeting;
using System.Text;
namespace Server.Scripts.Commands
{
public class AreaLog
{
public static void Initialize()
{
CommandSystem.Register("AreaLog", AccessLevel.Counselor, new CommandEventHandler( AreaLogs ));
}
[Usage("AreaLog")]
[Description("Records the x and y coordinates of an area.")]
public static void AreaLogs( CommandEventArgs e )
{
e.Mobile.SendMessage( "What area do you want to log?" );
BeginArea( e.Mobile );
}
public static void BeginArea( Mobile mob )
{
BoundingBoxPicker.Begin(mob, new BoundingBoxCallback(Area_Callback), new object[]{ "area.txt" } );
}
private static void Area_Callback(Mobile mob, Map map, Point3D start, Point3D end, object state )
{
StreamWriter w = File.AppendText("area.txt");
w.WriteLine( "<rect x=\"" + (start.X - 0) + "\" y=\"" + (start.Y - 0) + "\" width=\"" + ( end.X - start.X + 1 ) + "\" height=\"" + ( end.Y - start.Y + 1 ) + "\" />" );
w.Close();
mob.SendMessage( ( start.X - 1 ) + " " + ( start.Y - 1 ) + " " + ( end.X + 1 ) + " " + ( end.Y + 1 ) );
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server;
using System.Collections;
using System.Collections.Generic;
using Server.Misc;
using Server.Items;
using Server.Network;
using Server.Commands;
using Server.Commands.Generic;
using Server.Mobiles;
using Server.Accounting;
using Server.Regions;
using System.IO;
using Server.Targeting;
namespace Server.Scripts.Commands
{
public class BodyTypes
{
public static void Initialize()
{
CommandSystem.Register("BodyTypes", AccessLevel.Counselor, new CommandEventHandler( BodyTypess ));
}
[Usage("BodyTypes")]
[Description("Increments a nearby creature's body by 1 point.")]
public static void BodyTypess( CommandEventArgs e )
{
foreach ( Mobile m in (e.Mobile).GetMobilesInRange( 5 ) )
{
if ( m is BaseCreature )
{
m.BodyValue = m.BodyValue + 1;
m.Say( "" + m.BodyValue + "" );
}
}
}
}
}

View file

@ -0,0 +1,43 @@
using Server.Accounting;
using Server.Commands.Generic;
using Server.Commands;
using Server.Items;
using Server.Misc;
using Server.Mobiles;
using Server.Network;
using Server.Regions;
using Server;
using System.Collections.Generic;
using System.Collections;
using System.IO;
using System;
namespace Server.Scripts.Commands
{
public class BuildWorld
{
public static void Initialize()
{
CommandSystem.Register("BuildWorld", AccessLevel.Counselor, new CommandEventHandler( BuildWorlds ));
}
[Usage("BuildWorld")]
[Description("This cleans up the world and rebuilds it, leaving players intact.")]
public static void BuildWorlds( CommandEventArgs e )
{
Server.Commands.Decorate.Decorate_OnCommand( e );
Server.SpawnGenerator.Parse( e.Mobile, "towns.map" );
Server.SpawnGenerator.Parse( e.Mobile, "graveyards.map" );
Server.SpawnGenerator.Parse( e.Mobile, "land.map" );
Server.SpawnGenerator.Parse( e.Mobile, "dungeons.map" );
Server.SpawnGenerator.Parse( e.Mobile, "labyrinths.map" );
Server.SpawnGenerator.Parse( e.Mobile, "mazes.map" );
if ( Server.Misc.Settings.PopulateTowns() ){ Server.SpawnGenerator.Parse( e.Mobile, "citizens.map" ); }
Server.Regions.SpawnEntry.RespawnAllRegions_OnCommand( e );
e.Mobile.SendMessage( "The world has been rebuilt." );
}
}
}

View file

@ -0,0 +1,57 @@
using System;
using Server;
using System.Collections;
using System.Collections.Generic;
using Server.Misc;
using Server.Items;
using Server.Network;
using Server.Commands;
using Server.Commands.Generic;
using Server.Mobiles;
using Server.Accounting;
using Server.Regions;
using System.IO;
namespace Server.Scripts.Commands
{
public class FaceLog
{
public static void Initialize()
{
CommandSystem.Register("FaceLog", AccessLevel.Counselor, new CommandEventHandler( FaceLogs ));
}
[Usage("FaceLog")]
[Description("Records the x, y, and z coordinates of the caller...along with the map they are in.")]
public static void FaceLogs( CommandEventArgs e )
{
Mobile m = e.Mobile;
string sX = m.X.ToString();
string sY = m.Y.ToString();
string sZ = m.Z.ToString();
string sRegion = m.Region.Name;
string sMap = "Map.Britannia";
if ( m.Map == Map.Underworld ){ sMap = "Map.Underworld"; }
string sDirection = "East";
if ( m.Direction == Direction.North ){ sDirection = "North"; }
else if ( m.Direction == Direction.Right ){ sDirection = "Right"; }
else if ( m.Direction == Direction.East ){ sDirection = "East"; }
else if ( m.Direction == Direction.Down ){ sDirection = "Down"; }
else if ( m.Direction == Direction.South ){ sDirection = "South"; }
else if ( m.Direction == Direction.Left ){ sDirection = "Left"; }
else if ( m.Direction == Direction.West ){ sDirection = "West"; }
else if ( m.Direction == Direction.Up ){ sDirection = "Up"; }
StreamWriter w = File.AppendText("facing.txt");
w.WriteLine( sRegion + "\t" + "(" + sX + ", " + sY + ", " + sZ + ")\t" + sMap + "\t" + sDirection );
w.Close();
m.SendMessage( sRegion + " " + "(" + sX + ", " + sY + ", " + sZ + ") " + sMap + " " + sDirection );
}
}
}

View file

@ -0,0 +1,331 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Commands;
using Server.Targeting;
namespace Server.Misc
{
public class Dumps
{
public const int Version = 200; // Script version (do not change)
public static string FilePath = @".\Export\";
public static void Initialize()
{
CommandSystem.Register("FullExport" , AccessLevel.Administrator, new CommandEventHandler(FullExport_OnCommand));
CommandSystem.Register("FullEx" , AccessLevel.Administrator, new CommandEventHandler(FullExport_OnCommand));
}
[Usage( "FullExport [string filename]" )]
[Aliases( "FullEx" )]
[Description( "Exports statics to a cfg decoration file." )]
public static void FullExport_OnCommand(CommandEventArgs e )
{
if( e.Arguments.Length > 0 )
BeginStaEx(e.Mobile, e.ArgString );
else
e.Mobile.SendMessage("Format: FullExport [string filename]" );
}
public static void BeginStaEx(Mobile mob, string file )
{
Export(mob, file, new Rectangle2D(new Point2D(0, 0), new Point2D(7168, 4096)));
}
private static void Export(Mobile mob, string file, Rectangle2D rect)
{
Map map = mob.Map;
if( !Directory.Exists(FilePath) )
Directory.CreateDirectory(FilePath);
using(StreamWriter op = new StreamWriter(String.Format(@".\Export\{0}.cfg", file)))
{
mob.SendMessage("Exporting statics...");
IPooledEnumerable eable = mob.Map.GetItemsInBounds(rect);
int i = 0;
try
{
foreach(Item item in eable)
{
if( item == null || item.Deleted )
continue;
if( item is AddonComponent && !(item is DartBoard) )
continue;
if ( item.Weight >= 0 && !(item is BaseMulti) )
{
string s = Construct(item);
if( !s.Substring(0, s.IndexOf(' ')+1).Contains("+") ) // Make sure this isn't an InternalItem of a class...
{
op.WriteLine(s);
op.WriteLine("{0} {1} {2}", item.X, item.Y, item.Z);
op.WriteLine();
i++;
}
}
}
mob.SendMessage("You exported {0} statics from this facet.", i);
}
catch(Exception e){ mob.SendMessage(e.Message); }
eable.Free();
}
}
public static List<string[]> List = new List<string[]>();
public static void Add(string s){ Add(s, ""); }
public static void Add(string s1, string s2)
{
List.Add(new string[]{s1, s2});
}
public static string Construct(Item item)
{
string s;
int itemID = item.ItemID;
if( item is BaseAddon )
for( int i = 0; i < ((BaseAddon)item).Components.Count; i++ )
if( ((BaseAddon)item).Components[i].Offset == Point3D.Zero )
{
itemID = ((BaseAddon)item).Components[i].ItemID;
break;
}
if( item is LocalizedStatic )
Add("LabelNumber", ((LocalizedStatic)item).Number.ToString());
else if( item is LocalizedSign )
Add("LabelNumber", ((LocalizedSign)item).Number.ToString());
else if( item is AnkhWest )
Add("Bloodied", (item.ItemID == 0x1D98).ToString());
else if( item is AnkhNorth )
Add("Bloodied", (item.ItemID == 0x1E5D).ToString());
else if( item is WarningItem )
{
Add("Range", ((WarningItem)item).Range.ToString());
if( VS(((WarningItem)item).WarningString) )
Add("WarningString", ((WarningItem)item).WarningString);
Add("WarningNumber", ((WarningItem)item).WarningNumber.ToString());
if( item is HintItem )
{
if( VS(((HintItem)item).HintString) )
Add("HintString", ((HintItem)item).HintString);
Add("HintNumber", ((HintItem)item).HintNumber.ToString());
}
Add("Range", ((WarningItem)item).ResetDelay.ToString());
}
else if( item.GetType().IsSubclassOf(typeof(BaseBeverage)) )
Add("Content", ((BaseBeverage)item).Content.ToString());
else if( item.GetType().IsSubclassOf(typeof(BaseDoor)) )
{
if ( ( item.ItemID == 0x3B1 ) )
{
Add("Facing", "WestSS");
}
else if ( ( item.ItemID == 0x3B2 ) )
{
Add("Facing", "SouthSW");
}
else if ( ( item.ItemID == 1663 ) ||
( item.ItemID == 1743 ) ||
( item.ItemID == 1695 ) ||
( item.ItemID == 1711 ) ||
( item.ItemID == 1759 ) ||
( item.ItemID == 1775 ) ||
( item.ItemID == 2115 ) ||
( item.ItemID == 2160 ) ||
( item.ItemID == 1727 ) ||
( item.ItemID == 846 ) ||
( item.ItemID == 830 ) ||
( item.ItemID == 798 ) ||
( item.ItemID == 242 ) ||
( item.ItemID == 814 ) ||
( item.ItemID == 862 ) ||
( item.ItemID == 2134 ) ||
( item.ItemID == 2094 ) ||
( item.ItemID == 1679 ) ||
( item.ItemID == 8183 ) )
{
Add("Facing", "NorthCCW");
}
else if ( ( item.ItemID == 1661 ) ||
( item.ItemID == 1741 ) ||
( item.ItemID == 1693 ) ||
( item.ItemID == 1709 ) ||
( item.ItemID == 1757 ) ||
( item.ItemID == 1773 ) ||
( item.ItemID == 2113 ) ||
( item.ItemID == 2158 ) ||
( item.ItemID == 1725 ) ||
( item.ItemID == 844 ) ||
( item.ItemID == 828 ) ||
( item.ItemID == 796 ) ||
( item.ItemID == 240 ) ||
( item.ItemID == 812 ) ||
( item.ItemID == 860 ) ||
( item.ItemID == 2132 ) ||
( item.ItemID == 2092 ) ||
( item.ItemID == 1677 ) ||
( item.ItemID == 8181 ) )
{
Add("Facing", "SouthCW");
}
else
{
Add("Facing", GetFacing(((BaseDoor)item).Offset).ToString());
}
}
if( item is BaseLight )
{
if( !((BaseLight)item).Burning )
Add("Unlit", String.Empty);
if( !((BaseLight)item).Protected )
Add("Unprotected", String.Empty);
}
else if( item is Spawner )
{
Spawner sp = (Spawner)item;
for(int i = 0; i < sp.SpawnNames.Count; i++)
if( VS(sp.SpawnNames[i]) )
Add("Spawn", sp.SpawnNames[i]);
// if( sp.MinDelay > TimeSpan.Zero )
Add("MinDelay", sp.MinDelay.ToString());
// if( sp.MaxDelay > TimeSpan.Zero )
Add("MaxDelay", sp.MaxDelay.ToString());
// if( sp.NextSpawn > TimeSpan.Zero )
//Add("NextSpawn", sp.NextSpawn.ToString());
// if( sp.Count > 0 )
Add("Count", sp.Count.ToString());
// if( sp.Team > 0 )
//Add("Team", sp.Team.ToString());
// if( sp.HomeRange > 0 )
Add("HomeRange", sp.HomeRange.ToString());
// if( sp.Running )
Add("Running", sp.Running.ToString());
// if( sp.Group )
Add("Group", sp.Group.ToString());
}
else if( item is Teleporter )
{
Teleporter tp = (Teleporter)item;
if( item is SkillTeleporter )
{
SkillTeleporter st = (SkillTeleporter)item;
Add("Skill", st.Skill.ToString());
// "RequiredFixedPoint" == Required * 0.1 ?
Add("Required", st.Required.ToString());
if( VS(st.MessageString) )
Add("MessageString", st.MessageString);
Add("MessageNumber", st.MessageNumber.ToString());
}
else if( item is KeywordTeleporter )
{
KeywordTeleporter kt = (KeywordTeleporter)item;
if( VS(kt.Substring) )
Add("Substring", kt.Substring);
Add("Keyword", kt.Keyword.ToString());
Add("Range", kt.Range.ToString());
}
Add("PointDest", tp.PointDest.ToString());
if( tp.MapDest != null )
Add("MapDest", tp.MapDest.ToString());
Add("Creatures", tp.Creatures.ToString());
Add("SourceEffect", tp.SourceEffect.ToString());
Add("DestEffect", tp.DestEffect.ToString());
Add("SoundID", tp.SoundID.ToString());
Add("Delay", tp.Delay.ToString());
}
if( item.Light != LightType.ArchedWindowEast )
Add("Light", item.Light.ToString());
if( item.Hue > 0 )
Add("Hue", item.Hue.ToString());
if( VS(item.Name) )
Add("Name", item.Name);
if( item.Amount > 1 )
Add("Amount", item.Amount.ToString());
s = String.Format("{0} {1}", ConstructType(item), itemID);
if( List.Count > 0 )
{
s += " (";
for( int i = 0; i < List.Count; i++ )
{
if( List[i][1] == String.Empty )
s += String.Format("{0}{1}", List[i][0], (i < List.Count-1 ? "; " : String.Empty));
else
s += String.Format("{0}={1}{2}", List[i][0], List[i][1], (i < List.Count-1 ? "; " : String.Empty));
}
s += ")";
}
List.Clear();
return s;
}
public static bool VS(string s)
{
if( s == null || s == String.Empty )
return false;
return true;
}
public static string ConstructType(Item item)
{
string s = item.GetType().ToString();
if( s.LastIndexOf('.') > -1 )
s = s.Remove(0, s.LastIndexOf('.')+1);
return s;
}
public static DoorFacing GetFacing(Point3D p)
{
DoorFacing facing = DoorFacing.WestCW;
for(int i = 0; i < m_Offsets.Length; i++)
{
if( p == m_Offsets[i] )
{
facing = (DoorFacing)i;
break;
}
}
return facing;
}
private static Point3D[] m_Offsets = new Point3D[]
{
new Point3D(-1, 1, 0 ),
new Point3D( 1, 1, 0 ),
new Point3D(-1, 0, 0 ),
new Point3D( 1,-1, 0 ),
new Point3D( 1, 1, 0 ),
new Point3D( 1,-1, 0 ),
new Point3D( 0, 0, 0 ),
new Point3D( 0,-1, 0 ),
new Point3D( 0, 0, 0 ),
new Point3D( 0, 0, 0 ),
new Point3D( 0, 0, 0 ),
new Point3D( 0, 0, 0 )
};
}
}

View file

@ -0,0 +1,54 @@
using System;
using Server;
using System.Collections;
using System.Collections.Generic;
using Server.Misc;
using Server.Items;
using Server.Network;
using Server.Commands;
using Server.Commands.Generic;
using Server.Mobiles;
using Server.Accounting;
using Server.Regions;
using System.IO;
using Server.Targeting;
namespace Server.Scripts.Commands
{
public class GetLevel
{
public static void Initialize()
{
CommandSystem.Register("GetLevel", AccessLevel.Counselor, new CommandEventHandler( GetLevels ));
}
[Usage("GetLevel")]
[Description("Gets the level of the creature.")]
public static void GetLevels( CommandEventArgs e )
{
e.Mobile.SendMessage( "What target do you want to inspect?" );
e.Mobile.Target = new InternalTarget();
}
private class InternalTarget : Target
{
public InternalTarget() : base ( 8, false, TargetFlags.None )
{
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( targeted is Mobile )
{
Mobile m = (Mobile)targeted;
from.SendMessage( "" + BaseCreature.MyLevel( m ) + "" );
}
else
{
from.SendMessage( "Not a valid creature!" );
}
}
}
}
}

View file

@ -0,0 +1,45 @@
using System;
using Server;
using System.Collections;
using System.Collections.Generic;
using Server.Misc;
using Server.Items;
using Server.Network;
using Server.Commands;
using Server.Commands.Generic;
using Server.Mobiles;
using Server.Accounting;
using Server.Regions;
using System.IO;
namespace Server.Scripts.Commands
{
public class GoLog
{
public static void Initialize()
{
CommandSystem.Register("GoLog", AccessLevel.Counselor, new CommandEventHandler( GoLogs ));
}
[Usage("GoLog")]
[Description("Records the x, y, and z coordinates of the caller...for the go menu.")]
public static void GoLogs( CommandEventArgs e )
{
string sX = e.Mobile.X.ToString();
string sY = e.Mobile.Y.ToString();
string sZ = e.Mobile.Z.ToString();
string sRegion = e.Mobile.Region.Name;
string sMap = "Map.Britannia";
if ( e.Mobile.Map == Map.Underworld ){ sMap = "Map.Underworld"; }
StreamWriter w = File.AppendText("go.txt");
w.WriteLine( "<child name=\"xxxxxxxxx\" x=\"" + sX + "\" y=\"" + sY + "\" z=\"" + sZ + "\" />" );
w.Close();
e.Mobile.SendMessage( sRegion + " " + "(" + sX + ", " + sY + ", " + sZ + ") " + sMap );
}
}
}

View file

@ -0,0 +1,59 @@
using System;
using Server;
using System.Collections;
using System.Collections.Generic;
using Server.Misc;
using Server.Items;
using Server.Network;
using Server.Commands;
using Server.Commands.Generic;
using Server.Mobiles;
using Server.Accounting;
using Server.Regions;
using System.IO;
namespace Server.Scripts.Commands
{
public class PointLog
{
public static void Initialize()
{
CommandSystem.Register("PointLog", AccessLevel.Counselor, new CommandEventHandler( PointLogs ));
}
[Usage("PointLog")]
[Description("Records the x, y, and z coordinates of the caller...along with the map they are in.")]
public static void PointLogs( CommandEventArgs e )
{
string sX = e.Mobile.X.ToString();
string sY = e.Mobile.Y.ToString();
string sZ = e.Mobile.Z.ToString();
string sRegion = e.Mobile.Region.Name;
string sMap = "Map.Britannia";
if ( e.Mobile.Map == Map.Underworld ){ sMap = "Map.Underworld"; }
StreamWriter w = File.AppendText("points.txt");
w.WriteLine( sRegion + "\t" + "(" + sX + ", " + sY + ", " + sZ + ")\t" + sMap );
w.Close();
e.Mobile.SendMessage( sRegion + " " + "(" + sX + ", " + sY + ", " + sZ + ") " + sMap );
}
}
public class ContainerLog
{
public static void ContainerLogs( int x, int y, int item, int gump, Mobile from )
{
StreamWriter w = File.AppendText("containers.txt");
w.WriteLine( "X\tY\tItemID\tGump" );
w.WriteLine( "" + x + "\t" + y + "\t" + item + "\t" + gump + "" );
w.Close();
from.SendMessage( "" + x + " --- " + y + " --- " + item + " --- " + gump + "" );
}
}
}

View file

@ -0,0 +1,339 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Commands;
using Server.Targeting;
namespace Server.Misc
{
public class Exporters
{
public const int Version = 200; // Script version (do not change)
public static string FilePath = @".\Export\";
public static void Initialize()
{
CommandSystem.Register("StaticExport" , AccessLevel.Administrator, new CommandEventHandler(StaticExport_OnCommand));
CommandSystem.Register("StaEx" , AccessLevel.Administrator, new CommandEventHandler(StaticExport_OnCommand));
}
[Usage( "StaticExport [string filename]" )]
[Aliases( "StaEx" )]
[Description( "Exports statics to a cfg decoration file." )]
public static void StaticExport_OnCommand(CommandEventArgs e )
{
if( e.Arguments.Length > 0 )
BeginStaEx(e.Mobile, e.ArgString );
else
e.Mobile.SendMessage("Format: StaticExport [string filename]" );
}
public static void BeginStaEx(Mobile mob, string file )
{
BoundingBoxPicker.Begin(mob, new BoundingBoxCallback(StaExBox_Callback), new object[]{ file });
}
private static void StaExBox_Callback(Mobile mob, Map map, Point3D start, Point3D end, object state)
{
object[] states = (object[])state;
string file = (string)states[0];
Export(mob, file, new Rectangle2D(new Point2D(start.X, start.Y), new Point2D(end.X+1, end.Y+1)));
}
private static void Export(Mobile mob, string file, Rectangle2D rect)
{
Map map = mob.Map;
if( !Directory.Exists(FilePath) )
Directory.CreateDirectory(FilePath);
using(StreamWriter op = new StreamWriter(String.Format(@".\Export\{0}.cfg", file)))
{
mob.SendMessage("Exporting statics...");
IPooledEnumerable eable = mob.Map.GetItemsInBounds(rect);
int i = 0;
try
{
foreach(Item item in eable)
{
if( item == null || item.Deleted )
continue;
if( item is AddonComponent && !(item is DartBoard) )
continue;
if ( item.Weight >= 0 && !(item is BaseMulti) )
{
string s = Construct(item);
if( !s.Substring(0, s.IndexOf(' ')+1).Contains("+") ) // Make sure this isn't an InternalItem of a class...
{
op.WriteLine(s);
op.WriteLine("{0} {1} {2}", item.X, item.Y, item.Z);
op.WriteLine();
i++;
}
}
}
mob.SendMessage("You exported {0} statics from this facet.", i);
}
catch(Exception e){ mob.SendMessage(e.Message); }
eable.Free();
}
}
public static List<string[]> List = new List<string[]>();
public static void Add(string s){ Add(s, ""); }
public static void Add(string s1, string s2)
{
List.Add(new string[]{s1, s2});
}
public static string Construct(Item item)
{
string s;
int itemID = item.ItemID;
if( item is BaseAddon )
for( int i = 0; i < ((BaseAddon)item).Components.Count; i++ )
if( ((BaseAddon)item).Components[i].Offset == Point3D.Zero )
{
itemID = ((BaseAddon)item).Components[i].ItemID;
break;
}
if( item is LocalizedStatic )
Add("LabelNumber", ((LocalizedStatic)item).Number.ToString());
else if( item is LocalizedSign )
Add("LabelNumber", ((LocalizedSign)item).Number.ToString());
else if( item is AnkhWest )
Add("Bloodied", (item.ItemID == 0x1D98).ToString());
else if( item is AnkhNorth )
Add("Bloodied", (item.ItemID == 0x1E5D).ToString());
else if( item is WarningItem )
{
Add("Range", ((WarningItem)item).Range.ToString());
if( VS(((WarningItem)item).WarningString) )
Add("WarningString", ((WarningItem)item).WarningString);
Add("WarningNumber", ((WarningItem)item).WarningNumber.ToString());
if( item is HintItem )
{
if( VS(((HintItem)item).HintString) )
Add("HintString", ((HintItem)item).HintString);
Add("HintNumber", ((HintItem)item).HintNumber.ToString());
}
Add("Range", ((WarningItem)item).ResetDelay.ToString());
}
else if( item.GetType().IsSubclassOf(typeof(BaseBeverage)) )
Add("Content", ((BaseBeverage)item).Content.ToString());
else if( item.GetType().IsSubclassOf(typeof(BaseDoor)) )
{
if ( ( item.ItemID == 0x3B1 ) )
{
Add("Facing", "WestSS");
}
else if ( ( item.ItemID == 0x3B2 ) )
{
Add("Facing", "SouthSW");
}
else if ( ( item.ItemID == 1663 ) ||
( item.ItemID == 1743 ) ||
( item.ItemID == 1695 ) ||
( item.ItemID == 1711 ) ||
( item.ItemID == 1759 ) ||
( item.ItemID == 1775 ) ||
( item.ItemID == 2115 ) ||
( item.ItemID == 2160 ) ||
( item.ItemID == 1727 ) ||
( item.ItemID == 846 ) ||
( item.ItemID == 830 ) ||
( item.ItemID == 798 ) ||
( item.ItemID == 242 ) ||
( item.ItemID == 814 ) ||
( item.ItemID == 862 ) ||
( item.ItemID == 2134 ) ||
( item.ItemID == 2094 ) ||
( item.ItemID == 1679 ) ||
( item.ItemID == 8183 ) )
{
Add("Facing", "NorthCCW");
}
else if ( ( item.ItemID == 1661 ) ||
( item.ItemID == 1741 ) ||
( item.ItemID == 1693 ) ||
( item.ItemID == 1709 ) ||
( item.ItemID == 1757 ) ||
( item.ItemID == 1773 ) ||
( item.ItemID == 2113 ) ||
( item.ItemID == 2158 ) ||
( item.ItemID == 1725 ) ||
( item.ItemID == 844 ) ||
( item.ItemID == 828 ) ||
( item.ItemID == 796 ) ||
( item.ItemID == 240 ) ||
( item.ItemID == 812 ) ||
( item.ItemID == 860 ) ||
( item.ItemID == 2132 ) ||
( item.ItemID == 2092 ) ||
( item.ItemID == 1677 ) ||
( item.ItemID == 8181 ) )
{
Add("Facing", "SouthCW");
}
else
{
Add("Facing", GetFacing(((BaseDoor)item).Offset).ToString());
}
}
if( item is BaseLight )
{
if( !((BaseLight)item).Burning )
Add("Unlit", String.Empty);
if( !((BaseLight)item).Protected )
Add("Unprotected", String.Empty);
}
else if( item is Spawner )
{
Spawner sp = (Spawner)item;
for(int i = 0; i < sp.SpawnNames.Count; i++)
if( VS(sp.SpawnNames[i]) )
Add("Spawn", sp.SpawnNames[i]);
// if( sp.MinDelay > TimeSpan.Zero )
Add("MinDelay", sp.MinDelay.ToString());
// if( sp.MaxDelay > TimeSpan.Zero )
Add("MaxDelay", sp.MaxDelay.ToString());
// if( sp.NextSpawn > TimeSpan.Zero )
//Add("NextSpawn", sp.NextSpawn.ToString());
// if( sp.Count > 0 )
Add("Count", sp.Count.ToString());
// if( sp.Team > 0 )
//Add("Team", sp.Team.ToString());
// if( sp.HomeRange > 0 )
Add("HomeRange", sp.HomeRange.ToString());
// if( sp.Running )
Add("Running", sp.Running.ToString());
// if( sp.Group )
Add("Group", sp.Group.ToString());
}
else if( item is Teleporter )
{
Teleporter tp = (Teleporter)item;
if( item is SkillTeleporter )
{
SkillTeleporter st = (SkillTeleporter)item;
Add("Skill", st.Skill.ToString());
// "RequiredFixedPoint" == Required * 0.1 ?
Add("Required", st.Required.ToString());
if( VS(st.MessageString) )
Add("MessageString", st.MessageString);
Add("MessageNumber", st.MessageNumber.ToString());
}
else if( item is KeywordTeleporter )
{
KeywordTeleporter kt = (KeywordTeleporter)item;
if( VS(kt.Substring) )
Add("Substring", kt.Substring);
Add("Keyword", kt.Keyword.ToString());
Add("Range", kt.Range.ToString());
}
Add("PointDest", tp.PointDest.ToString());
if( tp.MapDest != null )
Add("MapDest", tp.MapDest.ToString());
Add("Creatures", tp.Creatures.ToString());
Add("SourceEffect", tp.SourceEffect.ToString());
Add("DestEffect", tp.DestEffect.ToString());
Add("SoundID", tp.SoundID.ToString());
Add("Delay", tp.Delay.ToString());
}
if( item.Light != LightType.ArchedWindowEast )
Add("Light", item.Light.ToString());
if( item.Hue > 0 )
Add("Hue", item.Hue.ToString());
if( VS(item.Name) )
Add("Name", item.Name);
if( item.Amount > 1 )
Add("Amount", item.Amount.ToString());
s = String.Format("{0} {1}", ConstructType(item), itemID);
if( List.Count > 0 )
{
s += " (";
for( int i = 0; i < List.Count; i++ )
{
if( List[i][1] == String.Empty )
s += String.Format("{0}{1}", List[i][0], (i < List.Count-1 ? "; " : String.Empty));
else
s += String.Format("{0}={1}{2}", List[i][0], List[i][1], (i < List.Count-1 ? "; " : String.Empty));
}
s += ")";
}
List.Clear();
return s;
}
public static bool VS(string s)
{
if( s == null || s == String.Empty )
return false;
return true;
}
public static string ConstructType(Item item)
{
string s = item.GetType().ToString();
if( s.LastIndexOf('.') > -1 )
s = s.Remove(0, s.LastIndexOf('.')+1);
return s;
}
public static DoorFacing GetFacing(Point3D p)
{
DoorFacing facing = DoorFacing.WestCW;
for(int i = 0; i < m_Offsets.Length; i++)
{
if( p == m_Offsets[i] )
{
facing = (DoorFacing)i;
break;
}
}
return facing;
}
private static Point3D[] m_Offsets = new Point3D[]
{
new Point3D(-1, 1, 0 ),
new Point3D( 1, 1, 0 ),
new Point3D(-1, 0, 0 ),
new Point3D( 1,-1, 0 ),
new Point3D( 1, 1, 0 ),
new Point3D( 1,-1, 0 ),
new Point3D( 0, 0, 0 ),
new Point3D( 0,-1, 0 ),
new Point3D( 0, 0, 0 ),
new Point3D( 0, 0, 0 ),
new Point3D( 0, 0, 0 ),
new Point3D( 0, 0, 0 )
};
}
}

View file

@ -0,0 +1,82 @@
using System;
using Server;
using System.Collections;
using System.Collections.Generic;
using Server.Misc;
using Server.Items;
using Server.Network;
using Server.Commands;
using Server.Commands.Generic;
using Server.Mobiles;
using Server.Accounting;
using Server.Regions;
using System.IO;
using Server.Targeting;
namespace Server.Scripts.Commands
{
public class TargetLog
{
public static void Initialize()
{
CommandSystem.Register("TargetLog", AccessLevel.Counselor, new CommandEventHandler( TargetLogs ));
}
[Usage("TargetLog")]
[Description("Records the x, y, and z coordinates of the caller...along with the map they are in.")]
public static void TargetLogs( CommandEventArgs e )
{
e.Mobile.SendMessage( "What target do you want to log?" );
e.Mobile.Target = new InternalTarget();
}
private class InternalTarget : Target
{
public InternalTarget() : base ( 8, false, TargetFlags.None )
{
}
protected override void OnTarget( Mobile from, object targeted )
{
string sX = "";
string sY = "";
string sZ = "";
string sItem = "";
if ( targeted is Item )
{
sX = ((Item)targeted).X.ToString();
sY = ((Item)targeted).Y.ToString();
sZ = ((Item)targeted).Z.ToString();
sItem = ((Item)targeted).ItemID.ToString();
}
else if ( targeted is StaticTarget )
{
sX = ((StaticTarget)targeted).X.ToString();
sY = ((StaticTarget)targeted).Y.ToString();
sZ = ((StaticTarget)targeted).Z.ToString();
sItem = ((StaticTarget)targeted).ItemID.ToString();
}
string sRegion = from.Region.Name;
string sMap = "Map.Britannia";
if ( from.Map == Map.Underworld ){ sMap = "Map.Underworld"; }
if ( sX != "" )
{
StreamWriter w = File.AppendText("targets.txt");
w.WriteLine( sRegion + "\t" + sItem + "\t" + sX + "\t" + sY + "\t" + sZ + "\t" + sMap );
w.Close();
from.SendMessage( sRegion + " " + sItem + " " + sX + " " + sY + " " + sZ + " " + sMap );
}
else
{
from.SendMessage( "Target failed to log!" );
}
}
}
}
}

View file

@ -0,0 +1,40 @@
using System;
namespace Server
{
public class UsageAttribute : Attribute
{
private string m_Usage;
public string Usage{ get{ return m_Usage; } }
public UsageAttribute( string usage )
{
m_Usage = usage;
}
}
public class DescriptionAttribute : Attribute
{
private string m_Description;
public string Description{ get{ return m_Description; } }
public DescriptionAttribute( string description )
{
m_Description = description;
}
}
public class AliasesAttribute : Attribute
{
private string[] m_Aliases;
public string[] Aliases{ get{ return m_Aliases; } }
public AliasesAttribute( params string[] aliases )
{
m_Aliases = aliases;
}
}
}

458
Scripts/Commands/Batch.cs Normal file
View file

@ -0,0 +1,458 @@
using System;
using System.Reflection;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Network;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Commands
{
public class Batch : BaseCommand
{
private BaseCommandImplementor m_Scope;
private string m_Condition;
private ArrayList m_BatchCommands;
public BaseCommandImplementor Scope
{
get{ return m_Scope; }
set{ m_Scope = value; }
}
public string Condition
{
get{ return m_Condition; }
set{ m_Condition = value; }
}
public ArrayList BatchCommands
{
get{ return m_BatchCommands; }
}
public Batch()
{
Commands = new string[]{ "Batch" };
ListOptimized = true;
m_BatchCommands = new ArrayList();
m_Condition = "";
}
public override void ExecuteList( CommandEventArgs e, ArrayList list )
{
if ( list.Count == 0 )
{
LogFailure( "Nothing was found to use this command on." );
return;
}
try
{
BaseCommand[] commands = new BaseCommand[m_BatchCommands.Count];
CommandEventArgs[] eventArgs = new CommandEventArgs[m_BatchCommands.Count];
for ( int i = 0; i < m_BatchCommands.Count; ++i )
{
BatchCommand bc = (BatchCommand)m_BatchCommands[i];
string commandString, argString;
string[] args;
bc.GetDetails( out commandString, out argString, out args );
BaseCommand command = m_Scope.Commands[commandString];
commands[i] = command;
eventArgs[i] = new CommandEventArgs( e.Mobile, commandString, argString, args );
if ( command == null )
{
e.Mobile.SendMessage( "That is either an invalid command name or one that does not support this modifier: {0}.", commandString );
return;
}
else if ( e.Mobile.AccessLevel < command.AccessLevel )
{
e.Mobile.SendMessage( "You do not have access to that command: {0}.", commandString );
return;
}
else if ( !command.ValidateArgs( m_Scope, eventArgs[i] ) )
{
return;
}
}
for ( int i = 0; i < commands.Length; ++i )
{
BaseCommand command = commands[i];
BatchCommand bc = (BatchCommand)m_BatchCommands[i];
if ( list.Count > 20 )
CommandLogging.Enabled = false;
ArrayList usedList;
if ( Utility.InsensitiveCompare( bc.Object, "Current" ) == 0 )
{
usedList = list;
}
else
{
Hashtable propertyChains = new Hashtable();
usedList = new ArrayList( list.Count );
for ( int j = 0; j < list.Count; ++j )
{
object obj = list[j];
if ( obj == null )
continue;
Type type = obj.GetType();
PropertyInfo[] chain = (PropertyInfo[])propertyChains[type];
string failReason = "";
if ( chain == null && !propertyChains.Contains( type ) )
propertyChains[type] = chain = Properties.GetPropertyInfoChain( e.Mobile, type, bc.Object, PropertyAccess.Read, ref failReason );
if ( chain == null )
continue;
PropertyInfo endProp = Properties.GetPropertyInfo( ref obj, chain, ref failReason );
if ( endProp == null )
continue;
try
{
obj = endProp.GetValue( obj, null );
if ( obj != null )
usedList.Add( obj );
}
catch
{
}
}
}
command.ExecuteList( eventArgs[i], usedList );
if ( list.Count > 20 )
CommandLogging.Enabled = true;
command.Flush( e.Mobile, list.Count > 20 );
}
}
catch ( Exception ex )
{
e.Mobile.SendMessage( ex.Message );
}
}
public bool Run( Mobile from )
{
if ( m_Scope == null )
{
from.SendMessage( "You must select the batch command scope." );
return false;
}
else if ( m_Condition.Length > 0 && !m_Scope.SupportsConditionals )
{
from.SendMessage( "This command scope does not support conditionals." );
return false;
}
else if ( m_Condition.Length > 0 && !Utility.InsensitiveStartsWith( m_Condition, "where" ) )
{
from.SendMessage( "The condition field must start with \"where\"." );
return false;
}
string[] args = CommandSystem.Split( m_Condition );
m_Scope.Process( from, this, args );
return true;
}
public static void Initialize()
{
CommandSystem.Register( "Batch", AccessLevel.Counselor, new CommandEventHandler( Batch_OnCommand ) );
}
[Usage( "Batch" )]
[Description( "Allows multiple commands to be run at the same time." )]
public static void Batch_OnCommand( CommandEventArgs e )
{
Batch batch = new Batch();
e.Mobile.SendGump( new BatchGump( e.Mobile, batch ) );
}
}
public class BatchCommand
{
private string m_Command;
private string m_Object;
public string Command
{
get{ return m_Command; }
set{ m_Command = value; }
}
public string Object
{
get{ return m_Object; }
set{ m_Object = value; }
}
public void GetDetails( out string command, out string argString, out string[] args )
{
int indexOf = m_Command.IndexOf( ' ' );
if ( indexOf >= 0 )
{
argString = m_Command.Substring( indexOf + 1 );
command = m_Command.Substring( 0, indexOf );
args = CommandSystem.Split( argString );
}
else
{
argString = "";
command = m_Command.ToLower();
args = new string[0];
}
}
public BatchCommand( string command, string obj )
{
m_Command = command;
m_Object = obj;
}
}
public class BatchGump : BaseGridGump
{
private Mobile m_From;
private Batch m_Batch;
public BatchGump( Mobile from, Batch batch ) : base( 30, 30 )
{
m_From = from;
m_Batch = batch;
Render();
}
public void Render()
{
AddNewPage();
/* Header */
AddEntryHeader( 20 );
AddEntryHtml( 180, Center( "Batch Commands" ) );
AddEntryHeader( 20 );
AddNewLine();
AddEntryHeader( 9 );
AddEntryLabel( 191, "Run Batch" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, GetButtonID( 1, 0, 0 ), ArrowRightWidth, ArrowRightHeight );
AddNewLine();
AddBlankLine();
/* Scope */
AddEntryHeader( 20 );
AddEntryHtml( 180, Center( "Scope" ) );
AddEntryHeader( 20 );
AddNewLine();
AddEntryHeader( 9 );
AddEntryLabel( 191, m_Batch.Scope == null ? "Select Scope" : m_Batch.Scope.Accessors[0] );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, GetButtonID( 1, 0, 1 ), ArrowRightWidth, ArrowRightHeight );
AddNewLine();
AddBlankLine();
/* Condition */
AddEntryHeader( 20 );
AddEntryHtml( 180, Center( "Condition" ) );
AddEntryHeader( 20 );
AddNewLine();
AddEntryHeader( 9 );
AddEntryText( 202, 0, m_Batch.Condition );
AddEntryHeader( 9 );
AddNewLine();
AddBlankLine();
/* Commands */
AddEntryHeader( 20 );
AddEntryHtml( 180, Center( "Commands" ) );
AddEntryHeader( 20 );
for ( int i = 0; i < m_Batch.BatchCommands.Count; ++i )
{
BatchCommand bc = (BatchCommand)m_Batch.BatchCommands[i];
AddNewLine();
AddImageTiled( CurrentX, CurrentY, 9, 2, 0x24A8 );
AddImageTiled( CurrentX, CurrentY + 2, 2, EntryHeight + OffsetSize + EntryHeight - 4, 0x24A8 );
AddImageTiled( CurrentX, CurrentY + EntryHeight + OffsetSize + EntryHeight - 2, 9, 2, 0x24A8 );
AddImageTiled( CurrentX + 3, CurrentY + 3, 6, EntryHeight + EntryHeight - 4 - OffsetSize, HeaderGumpID );
IncreaseX( 9 );
AddEntryText( 202, 1+(i*2), bc.Command );
AddEntryHeader( 9, 2 );
AddNewLine();
IncreaseX( 9 );
AddEntryText( 202, 2+(i*2), bc.Object );
}
AddNewLine();
AddEntryHeader( 9 );
AddEntryLabel( 191, "Add New Command" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, GetButtonID( 1, 0, 2 ), ArrowRightWidth, ArrowRightHeight );
FinishPage();
}
public override void OnResponse( NetState sender, RelayInfo info )
{
int type, index;
if ( !SplitButtonID( info.ButtonID, 1, out type, out index ) )
return;
TextRelay entry = info.GetTextEntry( 0 );
if ( entry != null )
m_Batch.Condition = entry.Text;
for ( int i = m_Batch.BatchCommands.Count - 1; i >= 0; --i )
{
BatchCommand sc = (BatchCommand)m_Batch.BatchCommands[i];
entry = info.GetTextEntry( 1 + (i * 2) );
if ( entry != null )
sc.Command = entry.Text;
entry = info.GetTextEntry( 2 + (i * 2) );
if ( entry != null )
sc.Object = entry.Text;
if ( sc.Command.Length == 0 && sc.Object.Length == 0 )
m_Batch.BatchCommands.RemoveAt( i );
}
switch ( type )
{
case 0: // main
{
switch ( index )
{
case 0: // run
{
m_Batch.Run( m_From );
break;
}
case 1: // set scope
{
m_From.SendGump( new BatchScopeGump( m_From, m_Batch ) );
return;
}
case 2: // add command
{
m_Batch.BatchCommands.Add( new BatchCommand( "", "" ) );
break;
}
}
break;
}
}
m_From.SendGump( new BatchGump( m_From, m_Batch ) );
}
}
public class BatchScopeGump : BaseGridGump
{
private Mobile m_From;
private Batch m_Batch;
public BatchScopeGump( Mobile from, Batch batch ) : base( 30, 30 )
{
m_From = from;
m_Batch = batch;
Render();
}
public void Render()
{
AddNewPage();
/* Header */
AddEntryHeader( 20 );
AddEntryHtml( 140, Center( "Change Scope" ) );
AddEntryHeader( 20 );
/* Options */
for ( int i = 0; i < BaseCommandImplementor.Implementors.Count; ++i )
{
BaseCommandImplementor impl = BaseCommandImplementor.Implementors[i];
if ( m_From.AccessLevel < impl.AccessLevel )
continue;
AddNewLine();
AddEntryLabel( 20 + OffsetSize + 140, impl.Accessors[0] );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, GetButtonID( 1, 0, i ), ArrowRightWidth, ArrowRightHeight );
}
FinishPage();
}
public override void OnResponse( NetState sender, RelayInfo info )
{
int type, index;
if ( SplitButtonID( info.ButtonID, 1, out type, out index ) )
{
switch ( type )
{
case 0:
{
if ( index < BaseCommandImplementor.Implementors.Count )
{
BaseCommandImplementor impl = BaseCommandImplementor.Implementors[index];
if ( m_From.AccessLevel >= impl.AccessLevel )
m_Batch.Scope = impl;
}
break;
}
}
}
m_From.SendGump( new BatchGump( m_From, m_Batch ) );
}
}
}

View file

@ -0,0 +1,68 @@
using System;
using Server;
using Server.Targeting;
namespace Server
{
public delegate void BoundingBoxCallback( Mobile from, Map map, Point3D start, Point3D end, object state );
public class BoundingBoxPicker
{
public static void Begin( Mobile from, BoundingBoxCallback callback, object state )
{
from.SendMessage( "Target the first location of the bounding box." );
from.Target = new PickTarget( callback, state );
}
private class PickTarget : Target
{
private Point3D m_Store;
private bool m_First;
private Map m_Map;
private BoundingBoxCallback m_Callback;
private object m_State;
public PickTarget( BoundingBoxCallback callback, object state ) : this( Point3D.Zero, true, null, callback, state )
{
}
public PickTarget( Point3D store, bool first, Map map, BoundingBoxCallback callback, object state ) : base( -1, true, TargetFlags.None )
{
m_Store = store;
m_First = first;
m_Map = map;
m_Callback = callback;
m_State = state;
}
protected override void OnTarget( Mobile from, object targeted )
{
IPoint3D p = targeted as IPoint3D;
if ( p == null )
return;
else if ( p is Item )
p = ((Item)p).GetWorldTop();
if ( m_First )
{
from.SendMessage( "Target another location to complete the bounding box." );
from.Target = new PickTarget( new Point3D( p ), false, from.Map, m_Callback, m_State );
}
else if ( from.Map != m_Map )
{
from.SendMessage( "Both locations must reside on the same map." );
}
else if ( m_Map != null && m_Map != Map.Internal && m_Callback != null )
{
Point3D start = m_Store;
Point3D end = new Point3D( p );
Utility.FixPoints( ref start, ref end );
m_Callback( from, m_Map, start, end, m_State );
}
}
}
}
}

View file

@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
namespace Server.Commands
{
public class ConvertPlayers
{
public static void Initialize()
{
CommandSystem.Register( "ConvertPlayers", AccessLevel.Administrator, new CommandEventHandler( Convert_OnCommand ) );
}
public static void Convert_OnCommand( CommandEventArgs e )
{
e.Mobile.SendMessage( "Converting all players to PlayerMobile. You will be disconnected. Please Restart the server after the world has finished saving." );
List<Mobile> mobs = new List<Mobile>( World.Mobiles.Values );
int count = 0;
foreach ( Mobile m in mobs )
{
if ( m.Player && !(m is PlayerMobile ) )
{
count++;
if ( m.NetState != null )
m.NetState.Dispose();
PlayerMobile pm = new PlayerMobile( m.Serial );
pm.DefaultMobileInit();
List<Item> copy = new List<Item>( m.Items );
for (int i=0;i<copy.Count;i++)
pm.AddItem( copy[i] );
CopyProps( pm, m );
for (int i=0;i<m.Skills.Length;i++)
{
pm.Skills[i].Base = m.Skills[i].Base;
pm.Skills[i].SetLockNoRelay( m.Skills[i].Lock );
}
World.Mobiles[m.Serial] = pm;
}
}
if ( count > 0 )
{
NetState.ProcessDisposedQueue();
World.Save();
Console.WriteLine( "{0} players have been converted to PlayerMobile. {1}.", count, Core.Service ? "The server is now restarting" : "Press any key to restart the server" );
if ( !Core.Service )
Console.ReadKey( true );
Core.Kill( true );
}
else
{
e.Mobile.SendMessage( "Couldn't find any Players to convert." );
}
}
private static void CopyProps( Mobile to, Mobile from )
{
Type type = typeof( Mobile );
PropertyInfo[] props = type.GetProperties( BindingFlags.Public | BindingFlags.Instance );
for (int p=0;p<props.Length;p++)
{
PropertyInfo prop = props[p];
if ( prop.CanRead && prop.CanWrite )
{
try
{
prop.SetValue( to, prop.GetValue( from, null ), null );
}
catch
{
}
}
}
}
}
}

1005
Scripts/Commands/Decorate.cs Normal file

File diff suppressed because it is too large Load diff

1858
Scripts/Commands/Docs.cs Normal file

File diff suppressed because it is too large Load diff

147
Scripts/Commands/Dupe.cs Normal file
View file

@ -0,0 +1,147 @@
using System;
using System.Reflection;
using Server.Items;
using Server.Targeting;
namespace Server.Commands
{
public class Dupe
{
public static void Initialize()
{
CommandSystem.Register( "Dupe", AccessLevel.GameMaster, new CommandEventHandler( Dupe_OnCommand ) );
CommandSystem.Register( "DupeInBag", AccessLevel.GameMaster, new CommandEventHandler( DupeInBag_OnCommand ) );
}
[Usage( "Dupe [amount]" )]
[Description( "Dupes a targeted item." )]
private static void Dupe_OnCommand( CommandEventArgs e )
{
int amount = 1;
if ( e.Length >= 1 )
amount = e.GetInt32( 0 );
e.Mobile.Target = new DupeTarget( false, amount > 0 ? amount : 1 );
e.Mobile.SendMessage( "What do you wish to dupe?" );
}
[Usage( "DupeInBag <count>" )]
[Description( "Dupes an item at it's current location (count) number of times." )]
private static void DupeInBag_OnCommand( CommandEventArgs e )
{
int amount = 1;
if ( e.Length >= 1 )
amount = e.GetInt32( 0 );
e.Mobile.Target = new DupeTarget( true, amount > 0 ? amount : 1 );
e.Mobile.SendMessage( "What do you wish to dupe?" );
}
private class DupeTarget : Target
{
private bool m_InBag;
private int m_Amount;
public DupeTarget( bool inbag, int amount )
: base( 15, false, TargetFlags.None )
{
m_InBag = inbag;
m_Amount = amount;
}
protected override void OnTarget( Mobile from, object targ )
{
bool done = false;
if ( !( targ is Item ) )
{
from.SendMessage( "You can only dupe items." );
return;
}
CommandLogging.WriteLine( from, "{0} {1} duping {2} (inBag={3}; amount={4})", from.AccessLevel, CommandLogging.Format( from ), CommandLogging.Format( targ ), m_InBag, m_Amount );
Item copy = (Item)targ;
Container pack;
if ( m_InBag )
{
if ( copy.Parent is Container )
pack = (Container)copy.Parent;
else if ( copy.Parent is Mobile )
pack = ( (Mobile)copy.Parent ).Backpack;
else
pack = null;
}
else
pack = from.Backpack;
Type t = copy.GetType();
//ConstructorInfo[] info = t.GetConstructors();
ConstructorInfo c = t.GetConstructor( Type.EmptyTypes );
if ( c != null )
{
try
{
from.SendMessage( "Duping {0}...", m_Amount );
for ( int i = 0; i < m_Amount; i++ )
{
object o = c.Invoke( null );
if ( o != null && o is Item )
{
Item newItem = (Item)o;
CopyProperties( newItem, copy );//copy.Dupe( item, copy.Amount );
copy.OnAfterDuped( newItem );
newItem.Parent = null;
if ( pack != null )
pack.DropItem( newItem );
else
newItem.MoveToWorld( from.Location, from.Map );
newItem.InvalidateProperties();
CommandLogging.WriteLine( from, "{0} {1} duped {2} creating {3}", from.AccessLevel, CommandLogging.Format( from ), CommandLogging.Format( targ ), CommandLogging.Format( newItem ) );
}
}
from.SendMessage( "Done" );
done = true;
}
catch
{
from.SendMessage( "Error!" );
return;
}
}
if ( !done )
{
from.SendMessage( "Unable to dupe. Item must have a 0 parameter constructor." );
}
}
}
public static void CopyProperties( Item dest, Item src )
{
PropertyInfo[] props = src.GetType().GetProperties();
for ( int i = 0; i < props.Length; i++ )
{
try
{
if ( props[i].CanRead && props[i].CanWrite )
{
//Console.WriteLine( "Setting {0} = {1}", props[i].Name, props[i].GetValue( src, null ) );
props[i].SetValue( dest, props[i].GetValue( src, null ), null );
}
}
catch
{
//Console.WriteLine( "Denied" );
}
}
}
}
}

View 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 ) );
}
}
}

View file

@ -0,0 +1,205 @@
using System;
using System.Collections;
using Server;
using Server.Gumps;
namespace Server.Commands.Generic
{
public enum ObjectTypes
{
Both,
Items,
Mobiles,
All
}
public abstract class BaseCommand
{
private string[] m_Commands;
private AccessLevel m_AccessLevel;
private CommandSupport m_Implementors;
private ObjectTypes m_ObjectTypes;
private bool m_ListOptimized;
private string m_Usage;
private string m_Description;
public bool ListOptimized
{
get{ return m_ListOptimized; }
set{ m_ListOptimized = value; }
}
public string[] Commands
{
get{ return m_Commands; }
set{ m_Commands = value; }
}
public string Usage
{
get{ return m_Usage; }
set{ m_Usage = value; }
}
public string Description
{
get{ return m_Description; }
set{ m_Description = value; }
}
public AccessLevel AccessLevel
{
get{ return m_AccessLevel; }
set{ m_AccessLevel = value; }
}
public ObjectTypes ObjectTypes
{
get{ return m_ObjectTypes; }
set{ m_ObjectTypes = value; }
}
public CommandSupport Supports
{
get{ return m_Implementors; }
set{ m_Implementors = value; }
}
public BaseCommand()
{
m_Responses = new ArrayList();
m_Failures = new ArrayList();
}
public static bool IsAccessible( Mobile from, object obj )
{
if ( from.AccessLevel >= AccessLevel.Administrator || obj == null )
return true;
Mobile mob;
if ( obj is Mobile )
mob = (Mobile)obj;
else if ( obj is Item )
mob = ((Item)obj).RootParent as Mobile;
else
mob = null;
if ( mob == null || mob == from || from.AccessLevel > mob.AccessLevel )
return true;
return false;
}
public virtual void ExecuteList( CommandEventArgs e, ArrayList list )
{
for ( int i = 0; i < list.Count; ++i )
Execute( e, list[i] );
}
public virtual void Execute( CommandEventArgs e, object obj )
{
}
public virtual bool ValidateArgs( BaseCommandImplementor impl, CommandEventArgs e )
{
return true;
}
private ArrayList m_Responses, m_Failures;
private class MessageEntry
{
public string m_Message;
public int m_Count;
public MessageEntry( string message )
{
m_Message = message;
m_Count = 1;
}
public override string ToString()
{
if ( m_Count > 1 )
return String.Format( "{0} ({1})", m_Message, m_Count );
return m_Message;
}
}
public void AddResponse( string message )
{
for ( int i = 0; i < m_Responses.Count; ++i )
{
MessageEntry entry = (MessageEntry)m_Responses[i];
if ( entry.m_Message == message )
{
++entry.m_Count;
return;
}
}
if ( m_Responses.Count == 10 )
return;
m_Responses.Add( new MessageEntry( message ) );
}
public void AddResponse( Gump gump )
{
m_Responses.Add( gump );
}
public void LogFailure( string message )
{
for ( int i = 0; i < m_Failures.Count; ++i )
{
MessageEntry entry = (MessageEntry)m_Failures[i];
if ( entry.m_Message == message )
{
++entry.m_Count;
return;
}
}
if ( m_Failures.Count == 10 )
return;
m_Failures.Add( new MessageEntry( message ) );
}
public void Flush( Mobile from, bool flushToLog )
{
if ( m_Responses.Count > 0 )
{
for ( int i = 0; i < m_Responses.Count; ++i )
{
object obj = m_Responses[i];
if ( obj is MessageEntry )
{
from.SendMessage( ((MessageEntry)obj).ToString() );
if ( flushToLog )
CommandLogging.WriteLine( from, ((MessageEntry)obj).ToString() );
}
else if ( obj is Gump )
{
from.SendGump( (Gump) obj );
}
}
}
else
{
for ( int i = 0; i < m_Failures.Count; ++i )
from.SendMessage( ((MessageEntry)m_Failures[i]).ToString() );
}
m_Responses.Clear();
m_Failures.Clear();
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,570 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Server;
using Server.Gumps;
using Server.Network;
using Server.Targeting;
using Server.Targets;
namespace Server.Commands.Generic
{
public class InterfaceCommand : BaseCommand
{
public InterfaceCommand()
{
AccessLevel = AccessLevel.GameMaster;
Supports = CommandSupport.Complex | CommandSupport.Simple;
Commands = new string[]{ "Interface" };
ObjectTypes = ObjectTypes.Both;
Usage = "Interface [view <properties ...>]";
Description = "Opens an interface to interact with matched objects. Generally used with condition arguments.";
ListOptimized = true;
}
public override void ExecuteList( CommandEventArgs e, ArrayList list )
{
if ( list.Count > 0 )
{
List<string> columns = new List<string>();
columns.Add( "Object" );
if ( e.Length > 0 )
{
int offset = 0;
if ( Insensitive.Equals( e.GetString( 0 ), "view" ) )
++offset;
while ( offset < e.Length )
columns.Add( e.GetString( offset++ ) );
}
e.Mobile.SendGump( new InterfaceGump( e.Mobile, columns.ToArray(), list, 0, null ) );
}
else
{
AddResponse( "No matching objects found." );
}
}
}
public class InterfaceGump : BaseGridGump
{
private Mobile m_From;
private string[] m_Columns;
private ArrayList m_List;
private int m_Page;
private object m_Select;
private const int EntriesPerPage = 15;
public InterfaceGump( Mobile from, string[] columns, ArrayList list, int page, object select ) : base( 30, 30 )
{
m_From = from;
m_Columns = columns;
m_List = list;
m_Page = page;
m_Select = select;
Render();
}
public void Render()
{
AddNewPage();
if ( m_Page > 0 )
AddEntryButton( 20, ArrowLeftID1, ArrowLeftID2, 1, ArrowLeftWidth, ArrowLeftHeight );
else
AddEntryHeader( 20 );
AddEntryHtml( 40 + ( m_Columns.Length * 130 ) - 20 + ( ( m_Columns.Length - 2 ) * OffsetSize ), Center( String.Format( "Page {0} of {1}", m_Page+1, (m_List.Count + EntriesPerPage - 1) / EntriesPerPage ) ) );
if ( (m_Page + 1) * EntriesPerPage < m_List.Count )
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 2, ArrowRightWidth, ArrowRightHeight );
else
AddEntryHeader( 20 );
if ( m_Columns.Length > 1 )
{
AddNewLine();
for ( int i = 0; i < m_Columns.Length; ++i )
{
if ( i > 0 && m_List.Count > 0 )
{
object obj = m_List[0];
if ( obj != null )
{
string failReason = null;
PropertyInfo[] chain = Properties.GetPropertyInfoChain( m_From, obj.GetType(), m_Columns[i], PropertyAccess.Read, ref failReason );
if ( chain != null && chain.Length > 0 )
{
m_Columns[i] = "";
for ( int j = 0; j < chain.Length; ++j )
{
if ( j > 0 )
m_Columns[i] += '.';
m_Columns[i] += chain[j].Name;
}
}
}
}
AddEntryHtml( 130 + ( i == 0 ? 40 : 0 ), m_Columns[i] );
}
AddEntryHeader( 20 );
}
for ( int i = m_Page * EntriesPerPage, line = 0; line < EntriesPerPage && i < m_List.Count; ++i, ++line )
{
AddNewLine();
object obj = m_List[i];
bool isDeleted = false;
if ( obj is Item )
{
Item item = (Item)obj;
if ( !(isDeleted = item.Deleted) )
AddEntryHtml( 40 + 130, item.GetType().Name );
}
else if ( obj is Mobile )
{
Mobile mob = (Mobile)obj;
if ( !(isDeleted = mob.Deleted) )
AddEntryHtml( 40 + 130, mob.Name );
}
if ( isDeleted )
{
AddEntryHtml( 40 + 130, "(deleted)" );
for ( int j = 1; j < m_Columns.Length; ++j )
AddEntryHtml( 130, "---" );
AddEntryHeader( 20 );
}
else
{
for ( int j = 1; j < m_Columns.Length; ++j )
{
object src = obj;
string value;
string failReason = "";
PropertyInfo[] chain = Properties.GetPropertyInfoChain( m_From, src.GetType(), m_Columns[j], PropertyAccess.Read, ref failReason );
if ( chain == null || chain.Length == 0 )
{
value = "---";
}
else
{
PropertyInfo p = Properties.GetPropertyInfo( ref src, chain, ref failReason );
if ( p == null )
value = "---";
else
value = PropertiesGump.ValueToString( src, p );
}
AddEntryHtml( 130, value );
}
bool isSelected = ( m_Select != null && obj == m_Select );
AddEntryButton( 20, ( isSelected ? 9762 : ArrowRightID1 ), ( isSelected ? 9763 : ArrowRightID2 ), 3 + i, ArrowRightWidth, ArrowRightHeight );
}
}
FinishPage();
}
public override void OnResponse( NetState sender, RelayInfo info )
{
switch ( info.ButtonID )
{
case 1:
{
if ( m_Page > 0 )
m_From.SendGump( new InterfaceGump( m_From, m_Columns, m_List, m_Page - 1, m_Select ) );
break;
}
case 2:
{
if ( (m_Page + 1) * EntriesPerPage < m_List.Count )
m_From.SendGump( new InterfaceGump( m_From, m_Columns, m_List, m_Page + 1, m_Select ) );
break;
}
default:
{
int v = info.ButtonID - 3;
if ( v >= 0 && v < m_List.Count )
{
object obj = m_List[v];
if ( !BaseCommand.IsAccessible( m_From, obj ) )
{
m_From.SendMessage( "That is not accessible." );
m_From.SendGump( new InterfaceGump( m_From, m_Columns, m_List, m_Page, m_Select ) );
break;
}
if ( obj is Item && !((Item)obj).Deleted )
m_From.SendGump( new InterfaceItemGump( m_From, m_Columns, m_List, m_Page, (Item) obj ) );
else if ( obj is Mobile && !((Mobile)obj).Deleted )
m_From.SendGump( new InterfaceMobileGump( m_From, m_Columns, m_List, m_Page, (Mobile) obj ) );
else
m_From.SendGump( new InterfaceGump( m_From, m_Columns, m_List, m_Page, m_Select ) );
}
break;
}
}
}
}
public class InterfaceItemGump : BaseGridGump
{
private Mobile m_From;
private string[] m_Columns;
private ArrayList m_List;
private int m_Page;
private Item m_Item;
public InterfaceItemGump( Mobile from, string[] columns, ArrayList list, int page, Item item ) : base( 30, 30 )
{
m_From = from;
m_Columns = columns;
m_List = list;
m_Page = page;
m_Item = item;
Render();
}
public void Render()
{
AddNewPage();
AddEntryButton( 20, ArrowLeftID1, ArrowLeftID2, 1, ArrowLeftWidth, ArrowLeftHeight );
AddEntryHtml( 160, m_Item.GetType().Name );
AddEntryHeader( 20 );
AddNewLine();
AddEntryHtml( 20 + OffsetSize + 160, "Properties" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 2, ArrowRightWidth, ArrowRightHeight );
AddNewLine();
AddEntryHtml( 20 + OffsetSize + 160, "Delete" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 3, ArrowRightWidth, ArrowRightHeight );
AddNewLine();
AddEntryHtml( 20 + OffsetSize + 160, "Go there" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 4, ArrowRightWidth, ArrowRightHeight );
AddNewLine();
AddEntryHtml( 20 + OffsetSize + 160, "Move to target" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 5, ArrowRightWidth, ArrowRightHeight );
AddNewLine();
AddEntryHtml( 20 + OffsetSize + 160, "Bring to pack" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 6, ArrowRightWidth, ArrowRightHeight );
FinishPage();
}
private void InvokeCommand( string ip )
{
CommandSystem.Handle( m_From, String.Format( "{0}{1}", CommandSystem.Prefix, ip ) );
}
public override void OnResponse( NetState sender, RelayInfo info )
{
if ( m_Item.Deleted )
{
m_From.SendGump( new InterfaceGump( m_From, m_Columns, m_List, m_Page, m_Item ) );
return;
}
else if ( !BaseCommand.IsAccessible( m_From, m_Item ) )
{
m_From.SendMessage( "That is no longer accessible." );
m_From.SendGump( new InterfaceGump( m_From, m_Columns, m_List, m_Page, m_Item ) );
return;
}
switch ( info.ButtonID )
{
case 0:
case 1:
{
m_From.SendGump( new InterfaceGump( m_From, m_Columns, m_List, m_Page, m_Item ) );
break;
}
case 2: // Properties
{
m_From.SendGump( new InterfaceItemGump( m_From, m_Columns, m_List, m_Page, m_Item ) );
m_From.SendGump( new PropertiesGump( m_From, m_Item ) );
break;
}
case 3: // Delete
{
CommandLogging.WriteLine( m_From, "{0} {1} deleting {2}", m_From.AccessLevel, CommandLogging.Format( m_From ), CommandLogging.Format( m_Item ) );
m_Item.Delete();
m_From.SendGump( new InterfaceGump( m_From, m_Columns, m_List, m_Page, m_Item ) );
break;
}
case 4: // Go there
{
m_From.SendGump( new InterfaceItemGump( m_From, m_Columns, m_List, m_Page, m_Item ) );
InvokeCommand( String.Format( "Go {0}", m_Item.Serial.Value ) );
break;
}
case 5: // Move to target
{
m_From.SendGump( new InterfaceItemGump( m_From, m_Columns, m_List, m_Page, m_Item ) );
m_From.Target = new MoveTarget( m_Item );
break;
}
case 6: // Bring to pack
{
Mobile owner = m_Item.RootParent as Mobile;
if ( owner != null && (owner.Map != null && owner.Map != Map.Internal) && !BaseCommand.IsAccessible( m_From, owner ) /* !m_From.CanSee( owner )*/ )
{
m_From.SendMessage( "You can not get what you can not see." );
}
else if ( owner != null && (owner.Map == null || owner.Map == Map.Internal) && owner.Hidden && owner.AccessLevel >= m_From.AccessLevel )
{
m_From.SendMessage( "You can not get what you can not see." );
}
else
{
m_From.SendGump( new InterfaceItemGump( m_From, m_Columns, m_List, m_Page, m_Item ) );
m_From.AddToBackpack( m_Item );
}
break;
}
}
}
}
public class InterfaceMobileGump : BaseGridGump
{
private Mobile m_From;
private string[] m_Columns;
private ArrayList m_List;
private int m_Page;
private Mobile m_Mobile;
public InterfaceMobileGump( Mobile from, string[] columns, ArrayList list, int page, Mobile mob )
: base( 30, 30 )
{
m_From = from;
m_Columns = columns;
m_List = list;
m_Page = page;
m_Mobile = mob;
Render();
}
public void Render()
{
AddNewPage();
AddEntryButton( 20, ArrowLeftID1, ArrowLeftID2, 1, ArrowLeftWidth, ArrowLeftHeight );
AddEntryHtml( 160, m_Mobile.Name );
AddEntryHeader( 20 );
AddNewLine();
AddEntryHtml( 20 + OffsetSize + 160, "Properties" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 2, ArrowRightWidth, ArrowRightHeight );
if ( !m_Mobile.Player )
{
AddNewLine();
AddEntryHtml( 20 + OffsetSize + 160, "Delete" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 3, ArrowRightWidth, ArrowRightHeight );
}
if ( m_Mobile != m_From )
{
AddNewLine();
AddEntryHtml( 20 + OffsetSize + 160, "Go to there" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 4, ArrowRightWidth, ArrowRightHeight );
AddNewLine();
AddEntryHtml( 20 + OffsetSize + 160, "Bring them here" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 5, ArrowRightWidth, ArrowRightHeight );
}
AddNewLine();
AddEntryHtml( 20 + OffsetSize + 160, "Move to target" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 6, ArrowRightWidth, ArrowRightHeight );
if ( m_From == m_Mobile || m_From.AccessLevel > m_Mobile.AccessLevel )
{
AddNewLine();
if ( m_Mobile.Alive )
{
AddEntryHtml( 20 + OffsetSize + 160, "Kill" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 7, ArrowRightWidth, ArrowRightHeight );
}
else
{
AddEntryHtml( 20 + OffsetSize + 160, "Resurrect" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 8, ArrowRightWidth, ArrowRightHeight );
}
}
if ( m_Mobile.NetState != null )
{
AddNewLine();
AddEntryHtml( 20 + OffsetSize + 160, "Client" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 9, ArrowRightWidth, ArrowRightHeight );
}
FinishPage();
}
private void InvokeCommand( string ip )
{
CommandSystem.Handle( m_From, String.Format( "{0}{1}", CommandSystem.Prefix, ip ) );
}
public override void OnResponse( NetState sender, RelayInfo info )
{
if ( m_Mobile.Deleted )
{
m_From.SendGump( new InterfaceGump( m_From, m_Columns, m_List, m_Page, m_Mobile ) );
return;
}
else if ( !BaseCommand.IsAccessible( m_From, m_Mobile ) )
{
m_From.SendMessage( "That is no longer accessible." );
m_From.SendGump( new InterfaceGump( m_From, m_Columns, m_List, m_Page, m_Mobile ) );
return;
}
switch ( info.ButtonID )
{
case 0:
case 1:
{
m_From.SendGump( new InterfaceGump( m_From, m_Columns, m_List, m_Page, m_Mobile ) );
break;
}
case 2: // Properties
{
m_From.SendGump( new InterfaceMobileGump( m_From, m_Columns, m_List, m_Page, m_Mobile ) );
m_From.SendGump( new PropertiesGump( m_From, m_Mobile ) );
break;
}
case 3: // Delete
{
if ( !m_Mobile.Player )
{
CommandLogging.WriteLine( m_From, "{0} {1} deleting {2}", m_From.AccessLevel, CommandLogging.Format( m_From ), CommandLogging.Format( m_Mobile ) );
m_Mobile.Delete();
m_From.SendGump( new InterfaceGump( m_From, m_Columns, m_List, m_Page, m_Mobile ) );
}
break;
}
case 4: // Go there
{
m_From.SendGump( new InterfaceMobileGump( m_From, m_Columns, m_List, m_Page, m_Mobile ) );
InvokeCommand( String.Format( "Go {0}", m_Mobile.Serial.Value ) );
break;
}
case 5: // Bring them here
{
if ( m_From.Map == null || m_From.Map == Map.Internal )
{
m_From.SendMessage( "You cannot bring that person here." );
}
else
{
m_From.SendGump( new InterfaceMobileGump( m_From, m_Columns, m_List, m_Page, m_Mobile ) );
m_Mobile.MoveToWorld( m_From.Location, m_From.Map );
}
break;
}
case 6: // Move to target
{
m_From.SendGump( new InterfaceMobileGump( m_From, m_Columns, m_List, m_Page, m_Mobile ) );
m_From.Target = new MoveTarget( m_Mobile );
break;
}
case 7: // Kill
{
if ( m_From == m_Mobile || m_From.AccessLevel > m_Mobile.AccessLevel )
m_Mobile.Kill();
m_From.SendGump( new InterfaceMobileGump( m_From, m_Columns, m_List, m_Page, m_Mobile ) );
break;
}
case 8: // Res
{
if ( m_From == m_Mobile || m_From.AccessLevel > m_Mobile.AccessLevel )
{
m_Mobile.PlaySound( 0x214 );
m_Mobile.FixedEffect( 0x376A, 10, 16 );
m_Mobile.Resurrect();
}
m_From.SendGump( new InterfaceMobileGump( m_From, m_Columns, m_List, m_Page, m_Mobile ) );
break;
}
case 9: // Client
{
m_From.SendGump( new InterfaceMobileGump( m_From, m_Columns, m_List, m_Page, m_Mobile ) );
if ( m_Mobile.NetState != null )
m_From.SendGump( new ClientGump( m_From, m_Mobile.NetState ) );
break;
}
}
}
}
}

View file

@ -0,0 +1,184 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace Server.Commands.Generic
{
public delegate BaseExtension ExtensionConstructor();
public sealed class ExtensionInfo
{
private static Dictionary<string, ExtensionInfo> m_Table = new Dictionary<string, ExtensionInfo>( StringComparer.InvariantCultureIgnoreCase );
public static Dictionary<string, ExtensionInfo> Table
{
get { return m_Table; }
}
public static void Register( ExtensionInfo ext )
{
m_Table[ext.m_Name] = ext;
}
private int m_Order;
private string m_Name;
private int m_Size;
private ExtensionConstructor m_Constructor;
public int Order
{
get { return m_Order; }
}
public string Name
{
get { return m_Name; }
}
public int Size
{
get { return m_Size; }
}
public bool IsFixedSize
{
get { return ( m_Size >= 0 ); }
}
public ExtensionConstructor Constructor
{
get { return m_Constructor; }
}
public ExtensionInfo( int order, string name, int size, ExtensionConstructor constructor )
{
m_Name = name;
m_Size = size;
m_Order = order;
m_Constructor = constructor;
}
}
public sealed class Extensions : List<BaseExtension>
{
public Extensions()
{
}
public bool IsValid( object obj )
{
for ( int i = 0; i < this.Count; ++i )
{
if ( !this[i].IsValid( obj ) )
return false;
}
return true;
}
public void Filter( ArrayList list )
{
for ( int i = 0; i < this.Count; ++i )
this[i].Filter( list );
}
public static Extensions Parse( Mobile from, ref string[] args )
{
Extensions parsed = new Extensions();
int size = args.Length;
Type baseType = null;
for ( int i = args.Length - 1; i >= 0; --i )
{
ExtensionInfo extInfo = null;
if ( !ExtensionInfo.Table.TryGetValue( args[i], out extInfo ) )
continue;
if ( extInfo.IsFixedSize && i != ( size - extInfo.Size - 1 ) )
throw new Exception( "Invalid extended argument count." );
BaseExtension ext = extInfo.Constructor();
ext.Parse( from, args, i + 1, size - i - 1 );
if ( ext is WhereExtension )
baseType = ( ext as WhereExtension ).Conditional.Type;
parsed.Add( ext );
size = i;
}
parsed.Sort( delegate( BaseExtension a, BaseExtension b )
{
return ( a.Order - b.Order );
} );
AssemblyEmitter emitter = null;
foreach ( BaseExtension update in parsed )
update.Optimize( from, baseType, ref emitter );
if ( size != args.Length )
{
string[] old = args;
args = new string[size];
for ( int i = 0; i < args.Length; ++i )
args[i] = old[i];
}
return parsed;
}
}
public abstract class BaseExtension
{
public abstract ExtensionInfo Info { get; }
public string Name
{
get { return Info.Name; }
}
public int Size
{
get { return Info.Size; }
}
public bool IsFixedSize
{
get { return Info.IsFixedSize; }
}
public int Order
{
get { return Info.Order; }
}
public virtual void Optimize( Mobile from, Type baseType, ref AssemblyEmitter assembly )
{
}
public virtual void Parse( Mobile from, string[] arguments, int offset, int size )
{
}
public virtual bool IsValid( object obj )
{
return true;
}
public virtual void Filter( ArrayList list )
{
}
}
}

View file

@ -0,0 +1,569 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using Server;
namespace Server.Commands.Generic
{
public interface IConditional
{
bool Verify( object obj );
}
public interface ICondition
{
// Invoked during the constructor
void Construct( TypeBuilder typeBuilder, ILGenerator il, int index );
// Target object will be loaded on the stack
void Compile( MethodEmitter emitter );
}
public sealed class TypeCondition : ICondition
{
public static TypeCondition Default = new TypeCondition();
void ICondition.Construct( TypeBuilder typeBuilder, ILGenerator il, int index )
{
}
void ICondition.Compile( MethodEmitter emitter )
{
// The object was safely cast to be the conditionals type
// If it's null, then the type cast didn't work...
emitter.LoadNull();
emitter.Compare( OpCodes.Ceq );
emitter.LogicalNot();
}
}
public sealed class PropertyValue
{
private Type m_Type;
private object m_Value;
private FieldInfo m_Field;
public Type Type
{
get { return m_Type; }
}
public object Value
{
get { return m_Value; }
}
public FieldInfo Field
{
get { return m_Field; }
}
public bool HasField
{
get { return ( m_Field != null ); }
}
public PropertyValue( Type type, object value )
{
m_Type = type;
m_Value = value;
}
public void Load( MethodEmitter method )
{
if ( m_Field != null )
{
method.LoadArgument( 0 );
method.LoadField( m_Field );
}
else if ( m_Value == null )
{
method.LoadNull( m_Type );
}
else
{
if ( m_Value is int )
method.Load( (int) m_Value );
else if ( m_Value is long )
method.Load( (long) m_Value );
else if ( m_Value is float )
method.Load( (float) m_Value );
else if ( m_Value is double )
method.Load( (double) m_Value );
else if ( m_Value is char )
method.Load( (char) m_Value );
else if ( m_Value is bool )
method.Load( (bool) m_Value );
else if ( m_Value is string )
method.Load( (string) m_Value );
else if ( m_Value is Enum )
method.Load( (Enum) m_Value );
else
throw new InvalidOperationException( "Unrecognized comparison value." );
}
}
public void Acquire( TypeBuilder typeBuilder, ILGenerator il, string fieldName )
{
if ( m_Value is string )
{
string toParse = (string) m_Value;
if ( !m_Type.IsValueType && toParse == "null" )
{
m_Value = null;
}
else if ( m_Type == typeof( string ) )
{
if ( toParse == @"@""null""" )
toParse = "null";
m_Value = toParse;
}
else if ( m_Type.IsEnum )
{
m_Value = Enum.Parse( m_Type, toParse, true );
}
else
{
MethodInfo parseMethod = null;
object[] parseArgs = null;
MethodInfo parseNumber = m_Type.GetMethod(
"Parse",
BindingFlags.Public | BindingFlags.Static,
null,
new Type[] { typeof( string ), typeof( NumberStyles ) },
null
);
if ( parseNumber != null )
{
NumberStyles style = NumberStyles.Integer;
if ( Insensitive.StartsWith( toParse, "0x" ) )
{
style = NumberStyles.HexNumber;
toParse = toParse.Substring( 2 );
}
parseMethod = parseNumber;
parseArgs = new object[] { toParse, style };
}
else
{
MethodInfo parseGeneral = m_Type.GetMethod(
"Parse",
BindingFlags.Public | BindingFlags.Static,
null,
new Type[] { typeof( string ) },
null
);
parseMethod = parseGeneral;
parseArgs = new object[] { toParse };
}
if ( parseMethod != null )
{
m_Value = parseMethod.Invoke( null, parseArgs );
if ( !m_Type.IsPrimitive )
{
m_Field = typeBuilder.DefineField(
fieldName,
m_Type,
FieldAttributes.Private | FieldAttributes.InitOnly
);
il.Emit( OpCodes.Ldarg_0 );
il.Emit( OpCodes.Ldstr, toParse );
if ( parseArgs.Length == 2 ) // dirty evil hack :-(
il.Emit( OpCodes.Ldc_I4, (int) parseArgs[1] );
il.Emit( OpCodes.Call, parseMethod );
il.Emit( OpCodes.Stfld, m_Field );
}
}
else
{
throw new InvalidOperationException(
String.Format(
"Unable to convert string \"{0}\" into type '{1}'.",
m_Value,
m_Type
)
);
}
}
}
}
}
public abstract class PropertyCondition : ICondition
{
protected Property m_Property;
protected bool m_Not;
public PropertyCondition( Property property, bool not )
{
m_Property = property;
m_Not = not;
}
public abstract void Construct( TypeBuilder typeBuilder, ILGenerator il, int index );
public abstract void Compile( MethodEmitter emitter );
}
public enum StringOperator
{
Equal,
NotEqual,
Contains,
StartsWith,
EndsWith
}
public sealed class StringCondition : PropertyCondition
{
private StringOperator m_Operator;
private PropertyValue m_Value;
private bool m_IgnoreCase;
public StringCondition( Property property, bool not, StringOperator op, object value, bool ignoreCase )
: base( property, not )
{
m_Operator = op;
m_Value = new PropertyValue( property.Type, value );
m_IgnoreCase = ignoreCase;
}
public override void Construct( TypeBuilder typeBuilder, ILGenerator il, int index )
{
m_Value.Acquire( typeBuilder, il, "v" + index );
}
public override void Compile( MethodEmitter emitter )
{
bool inverse = false;
string methodName;
switch ( m_Operator )
{
case StringOperator.Equal:
methodName = "Equals";
break;
case StringOperator.NotEqual:
methodName = "Equals";
inverse = true;
break;
case StringOperator.Contains:
methodName = "Contains";
break;
case StringOperator.StartsWith:
methodName = "StartsWith";
break;
case StringOperator.EndsWith:
methodName = "EndsWith";
break;
default:
throw new InvalidOperationException( "Invalid string comparison operator." );
}
if ( m_IgnoreCase || methodName == "Equals" )
{
Type type = ( m_IgnoreCase ? typeof( Insensitive ) : typeof( String ) );
emitter.BeginCall(
type.GetMethod(
methodName,
BindingFlags.Public | BindingFlags.Static,
null,
new Type[]
{
typeof( string ),
typeof( string )
},
null
)
);
emitter.Chain( m_Property );
m_Value.Load( emitter );
emitter.FinishCall();
}
else
{
Label notNull = emitter.CreateLabel();
Label moveOn = emitter.CreateLabel();
LocalBuilder temp = emitter.AcquireTemp( m_Property.Type );
emitter.Chain( m_Property );
emitter.StoreLocal( temp );
emitter.LoadLocal( temp );
emitter.BranchIfTrue( notNull );
emitter.Load( false );
emitter.Pop();
emitter.Branch( moveOn );
emitter.MarkLabel( notNull );
emitter.LoadLocal( temp );
emitter.BeginCall(
typeof( string ).GetMethod(
methodName,
BindingFlags.Public | BindingFlags.Instance,
null,
new Type[]
{
typeof( string )
},
null
)
);
m_Value.Load( emitter );
emitter.FinishCall();
emitter.MarkLabel( moveOn );
}
if ( m_Not != inverse )
emitter.LogicalNot();
}
}
public enum ComparisonOperator
{
Equal,
NotEqual,
Greater,
GreaterEqual,
Lesser,
LesserEqual
}
public sealed class ComparisonCondition : PropertyCondition
{
private ComparisonOperator m_Operator;
private PropertyValue m_Value;
public ComparisonCondition( Property property, bool not, ComparisonOperator op, object value )
: base( property, not )
{
m_Operator = op;
m_Value = new PropertyValue( property.Type, value );
}
public override void Construct( TypeBuilder typeBuilder, ILGenerator il, int index )
{
m_Value.Acquire( typeBuilder, il, "v" + index );
}
public override void Compile( MethodEmitter emitter )
{
emitter.Chain( m_Property );
bool inverse = false;
bool couldCompare =
emitter.CompareTo( 1, delegate()
{
m_Value.Load( emitter );
} );
if ( couldCompare )
{
emitter.Load( 0 );
switch ( m_Operator )
{
case ComparisonOperator.Equal:
emitter.Compare( OpCodes.Ceq );
break;
case ComparisonOperator.NotEqual:
emitter.Compare( OpCodes.Ceq );
inverse = true;
break;
case ComparisonOperator.Greater:
emitter.Compare( OpCodes.Cgt );
break;
case ComparisonOperator.GreaterEqual:
emitter.Compare( OpCodes.Clt );
inverse = true;
break;
case ComparisonOperator.Lesser:
emitter.Compare( OpCodes.Clt );
break;
case ComparisonOperator.LesserEqual:
emitter.Compare( OpCodes.Cgt );
inverse = true;
break;
default:
throw new InvalidOperationException( "Invalid comparison operator." );
}
}
else
{
// This type is -not- comparable
// We can only support == and != operations
m_Value.Load( emitter );
switch ( m_Operator )
{
case ComparisonOperator.Equal:
emitter.Compare( OpCodes.Ceq );
break;
case ComparisonOperator.NotEqual:
emitter.Compare( OpCodes.Ceq );
inverse = true;
break;
case ComparisonOperator.Greater:
case ComparisonOperator.GreaterEqual:
case ComparisonOperator.Lesser:
case ComparisonOperator.LesserEqual:
throw new InvalidOperationException( "Property does not support relational comparisons." );
default:
throw new InvalidOperationException( "Invalid operator." );
}
}
if ( m_Not != inverse )
emitter.LogicalNot();
}
}
public static class ConditionalCompiler
{
public static IConditional Compile( AssemblyEmitter assembly, Type objectType, ICondition[] conditions, int index )
{
TypeBuilder typeBuilder = assembly.DefineType(
"__conditional" + index,
TypeAttributes.Public,
typeof( object )
);
#region Constructor
{
ConstructorBuilder ctor = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
Type.EmptyTypes
);
ILGenerator il = ctor.GetILGenerator();
// : base()
il.Emit( OpCodes.Ldarg_0 );
il.Emit( OpCodes.Call, typeof( object ).GetConstructor( Type.EmptyTypes ) );
for ( int i = 0; i < conditions.Length; ++i )
conditions[i].Construct( typeBuilder, il, i );
// return;
il.Emit( OpCodes.Ret );
}
#endregion
#region IComparer
typeBuilder.AddInterfaceImplementation( typeof( IConditional ) );
MethodBuilder compareMethod;
#region Compare
{
MethodEmitter emitter = new MethodEmitter( typeBuilder );
emitter.Define(
/* name */ "Verify",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof( bool ),
/* params */ new Type[] { typeof( object ) } );
LocalBuilder obj = emitter.CreateLocal( objectType );
LocalBuilder eq = emitter.CreateLocal( typeof( bool ) );
emitter.LoadArgument( 1 );
emitter.CastAs( objectType );
emitter.StoreLocal( obj );
Label done = emitter.CreateLabel();
for ( int i = 0; i < conditions.Length; ++i )
{
if ( i > 0 )
{
emitter.LoadLocal( eq );
emitter.BranchIfFalse( done );
}
emitter.LoadLocal( obj );
conditions[i].Compile( emitter );
emitter.StoreLocal( eq );
}
emitter.MarkLabel( done );
emitter.LoadLocal( eq );
emitter.Return();
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof( IConditional ).GetMethod(
"Verify",
new Type[]
{
typeof( object )
}
)
);
compareMethod = emitter.Method;
}
#endregion
#endregion
Type conditionalType = typeBuilder.CreateType();
return (IConditional) Activator.CreateInstance( conditionalType );
}
}
}

View file

@ -0,0 +1,249 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using Server;
namespace Server.Commands.Generic
{
public static class DistinctCompiler
{
public static IComparer Compile( AssemblyEmitter assembly, Type objectType, Property[] props )
{
TypeBuilder typeBuilder = assembly.DefineType(
"__distinct",
TypeAttributes.Public,
typeof( object )
);
#region Constructor
{
ConstructorBuilder ctor = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
Type.EmptyTypes
);
ILGenerator il = ctor.GetILGenerator();
// : base()
il.Emit( OpCodes.Ldarg_0 );
il.Emit( OpCodes.Call, typeof( object ).GetConstructor( Type.EmptyTypes ) );
// return;
il.Emit( OpCodes.Ret );
}
#endregion
#region IComparer
typeBuilder.AddInterfaceImplementation( typeof( IComparer ) );
MethodBuilder compareMethod;
#region Compare
{
MethodEmitter emitter = new MethodEmitter( typeBuilder );
emitter.Define(
/* name */ "Compare",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof( int ),
/* params */ new Type[] { typeof( object ), typeof( object ) } );
LocalBuilder a = emitter.CreateLocal( objectType );
LocalBuilder b = emitter.CreateLocal( objectType );
LocalBuilder v = emitter.CreateLocal( typeof( int ) );
emitter.LoadArgument( 1 );
emitter.CastAs( objectType );
emitter.StoreLocal( a );
emitter.LoadArgument( 2 );
emitter.CastAs( objectType );
emitter.StoreLocal( b );
emitter.Load( 0 );
emitter.StoreLocal( v );
Label end = emitter.CreateLabel();
for ( int i = 0; i < props.Length; ++i )
{
if ( i > 0 )
{
emitter.LoadLocal( v );
emitter.BranchIfTrue( end ); // if ( v != 0 ) return v;
}
Property prop = props[i];
emitter.LoadLocal( a );
emitter.Chain( prop );
bool couldCompare =
emitter.CompareTo( 1, delegate()
{
emitter.LoadLocal( b );
emitter.Chain( prop );
} );
if ( !couldCompare )
throw new InvalidOperationException( "Property is not comparable." );
emitter.StoreLocal( v );
}
emitter.MarkLabel( end );
emitter.LoadLocal( v );
emitter.Return();
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof( IComparer ).GetMethod(
"Compare",
new Type[]
{
typeof( object ),
typeof( object )
}
)
);
compareMethod = emitter.Method;
}
#endregion
#endregion
#region IEqualityComparer
typeBuilder.AddInterfaceImplementation( typeof( IEqualityComparer<object> ) );
#region Equals
{
MethodEmitter emitter = new MethodEmitter( typeBuilder );
emitter.Define(
/* name */ "Equals",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof( bool ),
/* params */ new Type[] { typeof( object ), typeof( object ) } );
emitter.Generator.Emit( OpCodes.Ldarg_0 );
emitter.Generator.Emit( OpCodes.Ldarg_1 );
emitter.Generator.Emit( OpCodes.Ldarg_2 );
emitter.Generator.Emit( OpCodes.Call, compareMethod );
emitter.Generator.Emit( OpCodes.Ldc_I4_0 );
emitter.Generator.Emit( OpCodes.Ceq );
emitter.Generator.Emit( OpCodes.Ret );
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof( IEqualityComparer<object> ).GetMethod(
"Equals",
new Type[]
{
typeof( object ),
typeof( object )
}
)
);
}
#endregion
#region GetHashCode
{
MethodEmitter emitter = new MethodEmitter( typeBuilder );
emitter.Define(
/* name */ "GetHashCode",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof( int ),
/* params */ new Type[] { typeof( object ) } );
LocalBuilder obj = emitter.CreateLocal( objectType );
emitter.LoadArgument( 1 );
emitter.CastAs( objectType );
emitter.StoreLocal( obj );
for ( int i = 0; i < props.Length; ++i )
{
Property prop = props[i];
emitter.LoadLocal( obj );
emitter.Chain( prop );
Type active = emitter.Active;
MethodInfo getHashCode = active.GetMethod( "GetHashCode", Type.EmptyTypes );
if ( getHashCode == null )
getHashCode = typeof( object ).GetMethod( "GetHashCode", Type.EmptyTypes );
if ( active != typeof( int ) )
{
if ( !active.IsValueType )
{
LocalBuilder value = emitter.AcquireTemp( active );
Label valueNotNull = emitter.CreateLabel();
Label done = emitter.CreateLabel();
emitter.StoreLocal( value );
emitter.LoadLocal( value );
emitter.BranchIfTrue( valueNotNull );
emitter.Load( 0 );
emitter.Pop( typeof( int ) );
emitter.Branch( done );
emitter.MarkLabel( valueNotNull );
emitter.LoadLocal( value );
emitter.Call( getHashCode );
emitter.ReleaseTemp( value );
emitter.MarkLabel( done );
}
else
{
emitter.Call( getHashCode );
}
}
if ( i > 0 )
emitter.Xor();
}
emitter.Return();
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof( IEqualityComparer<object> ).GetMethod(
"GetHashCode",
new Type[]
{
typeof( object )
}
)
);
}
#endregion
#endregion
Type comparerType = typeBuilder.CreateType();
return (IComparer) Activator.CreateInstance( comparerType );
}
}
}

View file

@ -0,0 +1,172 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using Server;
namespace Server.Commands.Generic
{
public sealed class OrderInfo
{
private Property m_Property;
private int m_Order;
public Property Property
{
get { return m_Property; }
set { m_Property = value; }
}
public bool IsAscending
{
get { return ( m_Order > 0 ); }
set { m_Order = ( value ? +1 : -1 ); }
}
public bool IsDescending
{
get { return ( m_Order < 0 ); }
set { m_Order = ( value ? -1 : +1 ); }
}
public int Sign
{
get { return Math.Sign( m_Order ); }
set
{
m_Order = Math.Sign( value );
if ( m_Order == 0 )
throw new InvalidOperationException( "Sign cannot be zero." );
}
}
public OrderInfo( Property property, bool isAscending )
{
m_Property = property;
this.IsAscending = isAscending;
}
}
public static class SortCompiler
{
public static IComparer Compile( AssemblyEmitter assembly, Type objectType, OrderInfo[] orders )
{
TypeBuilder typeBuilder = assembly.DefineType(
"__sort",
TypeAttributes.Public,
typeof( object )
);
#region Constructor
{
ConstructorBuilder ctor = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
Type.EmptyTypes
);
ILGenerator il = ctor.GetILGenerator();
// : base()
il.Emit( OpCodes.Ldarg_0 );
il.Emit( OpCodes.Call, typeof( object ).GetConstructor( Type.EmptyTypes ) );
// return;
il.Emit( OpCodes.Ret );
}
#endregion
#region IComparer
typeBuilder.AddInterfaceImplementation( typeof( IComparer ) );
MethodBuilder compareMethod;
#region Compare
{
MethodEmitter emitter = new MethodEmitter( typeBuilder );
emitter.Define(
/* name */ "Compare",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof( int ),
/* params */ new Type[] { typeof( object ), typeof( object ) } );
LocalBuilder a = emitter.CreateLocal( objectType );
LocalBuilder b = emitter.CreateLocal( objectType );
LocalBuilder v = emitter.CreateLocal( typeof( int ) );
emitter.LoadArgument( 1 );
emitter.CastAs( objectType );
emitter.StoreLocal( a );
emitter.LoadArgument( 2 );
emitter.CastAs( objectType );
emitter.StoreLocal( b );
emitter.Load( 0 );
emitter.StoreLocal( v );
Label end = emitter.CreateLabel();
for ( int i = 0; i < orders.Length; ++i )
{
if ( i > 0 )
{
emitter.LoadLocal( v );
emitter.BranchIfTrue( end ); // if ( v != 0 ) return v;
}
OrderInfo orderInfo = orders[i];
Property prop = orderInfo.Property;
int sign = orderInfo.Sign;
emitter.LoadLocal( a );
emitter.Chain( prop );
bool couldCompare =
emitter.CompareTo( sign, delegate()
{
emitter.LoadLocal( b );
emitter.Chain( prop );
} );
if ( !couldCompare )
throw new InvalidOperationException( "Property is not comparable." );
emitter.StoreLocal( v );
}
emitter.MarkLabel( end );
emitter.LoadLocal( v );
emitter.Return();
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof( IComparer ).GetMethod(
"Compare",
new Type[]
{
typeof( object ),
typeof( object )
}
)
);
compareMethod = emitter.Method;
}
#endregion
#endregion
Type comparerType = typeBuilder.CreateType();
return (IComparer) Activator.CreateInstance( comparerType );
}
}
}

View file

@ -0,0 +1,89 @@
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace Server.Commands.Generic
{
public sealed class DistinctExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo( 30, "Distinct", -1, delegate() { return new DistinctExtension(); } );
public static void Initialize()
{
ExtensionInfo.Register( ExtInfo );
}
public override ExtensionInfo Info
{
get { return ExtInfo; }
}
private List<Property> m_Properties;
private IComparer m_Comparer;
public DistinctExtension()
{
m_Properties = new List<Property>();
}
public override void Optimize( Mobile from, Type baseType, ref AssemblyEmitter assembly )
{
if ( baseType == null )
throw new Exception( "Distinct extension may only be used in combination with an object conditional." );
foreach ( Property prop in m_Properties )
{
prop.BindTo( baseType, PropertyAccess.Read );
prop.CheckAccess( from );
}
if ( assembly == null )
assembly = new AssemblyEmitter( "__dynamic", false );
m_Comparer = DistinctCompiler.Compile( assembly, baseType, m_Properties.ToArray() );
}
public override void Parse( Mobile from, string[] arguments, int offset, int size )
{
if ( size < 1 )
throw new Exception( "Invalid distinction syntax." );
int end = offset + size;
while ( offset < end )
{
string binding = arguments[offset++];
m_Properties.Add( new Property( binding ) );
}
}
public override void Filter( ArrayList list )
{
if ( m_Comparer == null )
throw new InvalidOperationException( "The extension must first be optimized." );
ArrayList copy = new ArrayList( list );
copy.Sort( m_Comparer );
list.Clear();
object last = null;
for ( int i = 0; i < copy.Count; ++i )
{
object obj = copy[i];
if ( last == null || m_Comparer.Compare( obj, last ) != 0 )
{
list.Add( obj );
last = obj;
}
}
}
}
}

View file

@ -0,0 +1,46 @@
using System;
using System.Collections;
using System.Text;
namespace Server.Commands.Generic
{
public sealed class LimitExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo( 80, "Limit", 1, delegate() { return new LimitExtension(); } );
public static void Initialize()
{
ExtensionInfo.Register( ExtInfo );
}
public override ExtensionInfo Info
{
get { return ExtInfo; }
}
private int m_Limit;
public int Limit
{
get { return m_Limit; }
}
public LimitExtension()
{
}
public override void Parse( Mobile from, string[] arguments, int offset, int size )
{
m_Limit = Utility.ToInt32( arguments[offset] );
if ( m_Limit < 0 )
throw new Exception( "Limit cannot be less than zero." );
}
public override void Filter( ArrayList list )
{
if ( list.Count > m_Limit )
list.RemoveRange( m_Limit, list.Count - m_Limit );
}
}
}

View file

@ -0,0 +1,109 @@
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace Server.Commands.Generic
{
public sealed class SortExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo( 40, "Order", -1, delegate() { return new SortExtension(); } );
public static void Initialize()
{
ExtensionInfo.Register( ExtInfo );
}
public override ExtensionInfo Info
{
get { return ExtInfo; }
}
private List<OrderInfo> m_Orders;
private IComparer m_Comparer;
public SortExtension()
{
m_Orders = new List<OrderInfo>();
}
public override void Optimize( Mobile from, Type baseType, ref AssemblyEmitter assembly )
{
if ( baseType == null )
throw new Exception( "The ordering extension may only be used in combination with an object conditional." );
foreach ( OrderInfo order in m_Orders )
{
order.Property.BindTo( baseType, PropertyAccess.Read );
order.Property.CheckAccess( from );
}
if ( assembly == null )
assembly = new AssemblyEmitter( "__dynamic", false );
m_Comparer = SortCompiler.Compile( assembly, baseType, m_Orders.ToArray() );
}
public override void Parse( Mobile from, string[] arguments, int offset, int size )
{
if ( size < 1 )
throw new Exception( "Invalid ordering syntax." );
if ( Insensitive.Equals( arguments[offset], "by" ) )
{
++offset;
--size;
if ( size < 1 )
throw new Exception( "Invalid ordering syntax." );
}
int end = offset + size;
while ( offset < end )
{
string binding = arguments[offset++];
bool isAscending = true;
if ( offset < end )
{
string next = arguments[offset];
switch ( next.ToLower() )
{
case "+":
case "up":
case "asc":
case "ascending":
isAscending = true;
++offset;
break;
case "-":
case "down":
case "desc":
case "descending":
isAscending = false;
++offset;
break;
}
}
Property property = new Property( binding );
m_Orders.Add( new OrderInfo( property, isAscending ) );
}
}
public override void Filter( ArrayList list )
{
if ( m_Comparer == null )
throw new InvalidOperationException( "The extension must first be optimized." );
list.Sort( m_Comparer );
}
}
}

View file

@ -0,0 +1,55 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Server.Commands;
namespace Server.Commands.Generic
{
public sealed class WhereExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo( 20, "Where", -1, delegate() { return new WhereExtension(); } );
public static void Initialize()
{
ExtensionInfo.Register( ExtInfo );
}
public override ExtensionInfo Info
{
get { return ExtInfo; }
}
private ObjectConditional m_Conditional;
public ObjectConditional Conditional
{
get { return m_Conditional; }
}
public WhereExtension()
{
}
public override void Optimize( Mobile from, Type baseType, ref AssemblyEmitter assembly )
{
if ( baseType == null )
throw new InvalidOperationException( "Insanity." );
m_Conditional.Compile( ref assembly );
}
public override void Parse( Mobile from, string[] arguments, int offset, int size )
{
if ( size < 1 )
throw new Exception( "Invalid condition syntax." );
m_Conditional = ObjectConditional.ParseDirect( from, arguments, offset, size );
}
public override bool IsValid( object obj )
{
return m_Conditional.CheckCondition( obj );
}
}
}

View file

@ -0,0 +1,128 @@
using System;
using System.Collections;
using Server;
using Server.Targeting;
namespace Server.Commands.Generic
{
public class AreaCommandImplementor : BaseCommandImplementor
{
public AreaCommandImplementor()
{
Accessors = new string[]{ "Area", "Group" };
SupportRequirement = CommandSupport.Area;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Area <command> [condition]";
Description = "Invokes the command on all appropriate objects in a targeted area. Optional condition arguments can further restrict the set of objects.";
}
public override void Process( Mobile from, BaseCommand command, string[] args )
{
BoundingBoxPicker.Begin( from, new BoundingBoxCallback( OnTarget ), new object[]{ command, args } );
}
public void OnTarget( Mobile from, Map map, Point3D start, Point3D end, object state )
{
try
{
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
Rectangle2D rect = new Rectangle2D( start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1 );
Extensions ext = Extensions.Parse( from, ref args );
bool items, mobiles;
if ( !CheckObjectTypes( command, ext, out items, out mobiles ) )
return;
IPooledEnumerable eable;
if ( items && mobiles )
eable = map.GetObjectsInBounds( rect );
else if ( items )
eable = map.GetItemsInBounds( rect );
else if ( mobiles )
eable = map.GetMobilesInBounds( rect );
else
return;
ArrayList objs = new ArrayList();
foreach ( object obj in eable )
{
if ( mobiles && obj is Mobile && !BaseCommand.IsAccessible( from, obj ) )
continue;
if ( ext.IsValid( obj ) )
objs.Add( obj );
}
eable.Free();
ext.Filter( objs );
RunCommand( from, objs, command, args );
}
catch ( Exception ex )
{
from.SendMessage( ex.Message );
}
}
public void OnTarget( Mobile from, object targeted, object state )
{
try
{
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
switch ( command.ObjectTypes )
{
case ObjectTypes.Both:
{
if ( !(targeted is Item) && !(targeted is Mobile) )
{
from.SendMessage( "This command does not work on that." );
return;
}
break;
}
case ObjectTypes.Items:
{
if ( !(targeted is Item) )
{
from.SendMessage( "This command only works on items." );
return;
}
break;
}
case ObjectTypes.Mobiles:
{
if ( !(targeted is Mobile) )
{
from.SendMessage( "This command only works on mobiles." );
return;
}
break;
}
}
RunCommand( from, targeted, command, args );
from.BeginTarget( -1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback( OnTarget ), new object[]{ command, args } );
}
catch ( Exception ex )
{
from.SendMessage( ex.Message );
}
}
}
}

View file

@ -0,0 +1,338 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Server;
namespace Server.Commands.Generic
{
[Flags]
public enum CommandSupport
{
Single = 0x0001,
Global = 0x0002,
Online = 0x0004,
Multi = 0x0008,
Area = 0x0010,
Self = 0x0020,
Region = 0x0040,
Contained = 0x0080,
All = Single | Global | Online | Multi | Area | Self | Region | Contained,
AllMobiles = All & ~Contained,
AllNPCs = All & ~(Online | Self | Contained),
AllItems = All & ~(Online | Self | Region),
Simple = Single | Multi,
Complex = Global | Online | Area | Region | Contained
}
public abstract class BaseCommandImplementor
{
public static void RegisterImplementors()
{
Register( new RegionCommandImplementor() );
Register( new GlobalCommandImplementor() );
Register( new OnlineCommandImplementor() );
Register( new SingleCommandImplementor() );
Register( new SerialCommandImplementor() );
Register( new MultiCommandImplementor() );
Register( new AreaCommandImplementor() );
Register( new SelfCommandImplementor() );
Register( new ContainedCommandImplementor() );
}
private string[] m_Accessors;
private AccessLevel m_AccessLevel;
private CommandSupport m_SupportRequirement;
private Dictionary<string, BaseCommand> m_Commands;
private string m_Usage;
private string m_Description;
private bool m_SupportsConditionals;
public bool SupportsConditionals
{
get{ return m_SupportsConditionals; }
set{ m_SupportsConditionals = value; }
}
public string[] Accessors
{
get{ return m_Accessors; }
set{ m_Accessors = value; }
}
public string Usage
{
get{ return m_Usage; }
set{ m_Usage = value; }
}
public string Description
{
get{ return m_Description; }
set{ m_Description = value; }
}
public AccessLevel AccessLevel
{
get{ return m_AccessLevel; }
set{ m_AccessLevel = value; }
}
public CommandSupport SupportRequirement
{
get{ return m_SupportRequirement; }
set{ m_SupportRequirement = value; }
}
public Dictionary<string, BaseCommand> Commands
{
get{ return m_Commands; }
}
public BaseCommandImplementor()
{
m_Commands = new Dictionary<string, BaseCommand>( StringComparer.OrdinalIgnoreCase );
}
public virtual void Compile( Mobile from, BaseCommand command, ref string[] args, ref object obj )
{
obj = null;
}
public virtual void Register( BaseCommand command )
{
for ( int i = 0; i < command.Commands.Length; ++i )
m_Commands[command.Commands[i]] = command;
}
public bool CheckObjectTypes( BaseCommand command, Extensions ext, out bool items, out bool mobiles )
{
items = mobiles = false;
ObjectConditional cond = ObjectConditional.Empty;
foreach ( BaseExtension check in ext )
{
if ( check is WhereExtension )
{
cond = ( check as WhereExtension ).Conditional;
break;
}
}
bool condIsItem = cond.IsItem;
bool condIsMobile = cond.IsMobile;
switch ( command.ObjectTypes )
{
case ObjectTypes.All:
case ObjectTypes.Both:
{
if ( condIsItem )
items = true;
if ( condIsMobile )
mobiles = true;
break;
}
case ObjectTypes.Items:
{
if ( condIsItem )
{
items = true;
}
else if ( condIsMobile )
{
command.LogFailure( "You may not use a mobile type condition for this command." );
return false;
}
break;
}
case ObjectTypes.Mobiles:
{
if ( condIsMobile )
{
mobiles = true;
}
else if ( condIsItem )
{
command.LogFailure( "You may not use an item type condition for this command." );
return false;
}
break;
}
}
return true;
}
public void RunCommand( Mobile from, BaseCommand command, string[] args )
{
try
{
object obj = null;
Compile( from, command, ref args, ref obj );
RunCommand( from, obj, command, args );
}
catch ( Exception ex )
{
from.SendMessage( ex.Message );
}
}
public string GenerateArgString( string[] args )
{
if ( args.Length == 0 )
return "";
// NOTE: this does not preserve the case where quotation marks are used on a single word
StringBuilder sb = new StringBuilder();
for ( int i = 0; i < args.Length; ++i )
{
if ( i > 0 )
sb.Append( ' ' );
if ( args[i].IndexOf( ' ' ) >= 0 )
{
sb.Append( '"' );
sb.Append( args[i] );
sb.Append( '"' );
}
else
{
sb.Append( args[i] );
}
}
return sb.ToString();
}
public void RunCommand( Mobile from, object obj, BaseCommand command, string[] args )
{
// try
// {
CommandEventArgs e = new CommandEventArgs( from, command.Commands[0], GenerateArgString( args ), args );
if ( !command.ValidateArgs( this, e ) )
return;
bool flushToLog = false;
if ( obj is ArrayList )
{
ArrayList list = (ArrayList)obj;
if ( list.Count > 20 )
CommandLogging.Enabled = false;
else if ( list.Count == 0 )
command.LogFailure( "Nothing was found to use this command on." );
command.ExecuteList( e, list );
if ( list.Count > 20 )
{
flushToLog = true;
CommandLogging.Enabled = true;
}
}
else if ( obj != null )
{
if ( command.ListOptimized )
{
ArrayList list = new ArrayList();
list.Add( obj );
command.ExecuteList( e, list );
}
else
{
command.Execute( e, obj );
}
}
command.Flush( from, flushToLog );
// }
// catch ( Exception ex )
// {
// from.SendMessage( ex.Message );
// }
}
public virtual void Process( Mobile from, BaseCommand command, string[] args )
{
RunCommand( from, command, args );
}
public virtual void Execute( CommandEventArgs e )
{
if ( e.Length >= 1 )
{
BaseCommand command = null;
m_Commands.TryGetValue( e.GetString( 0 ), out command );
if ( command == null )
{
e.Mobile.SendMessage( "That is either an invalid command name or one that does not support this modifier." );
}
else if ( e.Mobile.AccessLevel < command.AccessLevel )
{
e.Mobile.SendMessage( "You do not have access to that command." );
}
else
{
string[] oldArgs = e.Arguments;
string[] args = new string[oldArgs.Length - 1];
for ( int i = 0; i < args.Length; ++i )
args[i] = oldArgs[i + 1];
Process( e.Mobile, command, args );
}
}
else
{
e.Mobile.SendMessage( "You must supply a command name." );
}
}
public void Register()
{
if ( m_Accessors == null )
return;
for ( int i = 0; i < m_Accessors.Length; ++i )
CommandSystem.Register( m_Accessors[i], m_AccessLevel, new CommandEventHandler( Execute ) );
}
public static void Register( BaseCommandImplementor impl )
{
m_Implementors.Add( impl );
impl.Register();
}
private static List<BaseCommandImplementor> m_Implementors;
public static List<BaseCommandImplementor> Implementors
{
get
{
if ( m_Implementors == null )
{
m_Implementors = new List<BaseCommandImplementor>();
RegisterImplementors();
}
return m_Implementors;
}
}
}
}

View file

@ -0,0 +1,85 @@
using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Targeting;
namespace Server.Commands.Generic
{
public class ContainedCommandImplementor : BaseCommandImplementor
{
public ContainedCommandImplementor()
{
Accessors = new string[]{ "Contained" };
SupportRequirement = CommandSupport.Contained;
AccessLevel = AccessLevel.GameMaster;
Usage = "Contained <command> [condition]";
Description = "Invokes the command on all child items in a targeted container. Optional condition arguments can further restrict the set of objects.";
}
public override void Process( Mobile from, BaseCommand command, string[] args )
{
if ( command.ValidateArgs( this, new CommandEventArgs( from, command.Commands[0], GenerateArgString( args ), args ) ) )
from.BeginTarget( -1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback( OnTarget ), new object[]{ command, args } );
}
public void OnTarget( Mobile from, object targeted, object state )
{
if ( !BaseCommand.IsAccessible( from, targeted ) )
{
from.SendMessage( "That is not accessible." );
return;
}
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
if ( command.ObjectTypes == ObjectTypes.Mobiles )
return; // sanity check
if ( !(targeted is Container) )
{
from.SendMessage( "That is not a container." );
}
else
{
try
{
Extensions ext = Extensions.Parse( from, ref args );
bool items, mobiles;
if ( !CheckObjectTypes( command, ext, out items, out mobiles ) )
return;
if ( !items )
{
from.SendMessage( "This command only works on items." );
return;
}
Container cont = (Container)targeted;
Item[] found = cont.FindItemsByType( typeof( Item ), true );
ArrayList list = new ArrayList();
for ( int i = 0; i < found.Length; ++i )
{
if ( ext.IsValid( found[i] ) )
list.Add( found[i] );
}
ext.Filter( list );
RunCommand( from, list, command, args );
}
catch ( Exception e )
{
from.SendMessage( e.Message );
}
}
}
}
}

View file

@ -0,0 +1,60 @@
using System;
using System.Collections;
using Server;
namespace Server.Commands.Generic
{
public class GlobalCommandImplementor : BaseCommandImplementor
{
public GlobalCommandImplementor()
{
Accessors = new string[]{ "Global" };
SupportRequirement = CommandSupport.Global;
SupportsConditionals = true;
AccessLevel = AccessLevel.Administrator;
Usage = "Global <command> [condition]";
Description = "Invokes the command on all appropriate objects in the world. Optional condition arguments can further restrict the set of objects.";
}
public override void Compile( Mobile from, BaseCommand command, ref string[] args, ref object obj )
{
try
{
Extensions ext = Extensions.Parse( from, ref args );
bool items, mobiles;
if ( !CheckObjectTypes( command, ext, out items, out mobiles ) )
return;
ArrayList list = new ArrayList();
if ( items )
{
foreach ( Item item in World.Items.Values )
{
if ( ext.IsValid( item ) )
list.Add( item );
}
}
if ( mobiles )
{
foreach ( Mobile mob in World.Mobiles.Values )
{
if ( ext.IsValid( mob ) )
list.Add( mob );
}
}
ext.Filter( list );
obj = list;
}
catch ( Exception ex )
{
from.SendMessage( ex.Message );
}
}
}
}

View file

@ -0,0 +1,77 @@
using System;
using System.Collections;
using Server;
using Server.Targeting;
namespace Server.Commands.Generic
{
public class MultiCommandImplementor : BaseCommandImplementor
{
public MultiCommandImplementor()
{
Accessors = new string[]{ "Multi", "m" };
SupportRequirement = CommandSupport.Multi;
AccessLevel = AccessLevel.Counselor;
Usage = "Multi <command>";
Description = "Invokes the command on multiple targeted objects.";
}
public override void Process( Mobile from, BaseCommand command, string[] args )
{
if ( command.ValidateArgs( this, new CommandEventArgs( from, command.Commands[0], GenerateArgString( args ), args ) ) )
from.BeginTarget( -1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback( OnTarget ), new object[]{ command, args } );
}
public void OnTarget( Mobile from, object targeted, object state )
{
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
if ( !BaseCommand.IsAccessible( from, targeted ) )
{
from.SendMessage( "That is not accessible." );
from.BeginTarget( -1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback( OnTarget ), new object[]{ command, args } );
return;
}
switch ( command.ObjectTypes )
{
case ObjectTypes.Both:
{
if ( !(targeted is Item) && !(targeted is Mobile) )
{
from.SendMessage( "This command does not work on that." );
return;
}
break;
}
case ObjectTypes.Items:
{
if ( !(targeted is Item) )
{
from.SendMessage( "This command only works on items." );
return;
}
break;
}
case ObjectTypes.Mobiles:
{
if ( !(targeted is Mobile) )
{
from.SendMessage( "This command only works on mobiles." );
return;
}
break;
}
}
RunCommand( from, targeted, command, args );
from.BeginTarget( -1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback( OnTarget ), new object[]{ command, args } );
}
}
}

View file

@ -0,0 +1,266 @@
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Targeting;
using CPA = Server.CommandPropertyAttribute;
namespace Server.Commands.Generic
{
public sealed class ObjectConditional
{
private static readonly Type typeofItem = typeof( Item );
private static readonly Type typeofMobile = typeof( Mobile );
private Type m_ObjectType;
private ICondition[][] m_Conditions;
private IConditional[] m_Conditionals;
public Type Type
{
get { return m_ObjectType; }
}
public bool IsItem
{
get { return ( m_ObjectType == null || m_ObjectType == typeofItem || m_ObjectType.IsSubclassOf( typeofItem ) ); }
}
public bool IsMobile
{
get { return ( m_ObjectType == null || m_ObjectType == typeofMobile || m_ObjectType.IsSubclassOf( typeofMobile ) ); }
}
public static readonly ObjectConditional Empty = new ObjectConditional( null, null );
public bool HasCompiled
{
get { return ( m_Conditionals != null ); }
}
public void Compile( ref AssemblyEmitter emitter )
{
if ( emitter == null )
emitter = new AssemblyEmitter( "__dynamic", false );
m_Conditionals = new IConditional[m_Conditions.Length];
for ( int i = 0; i < m_Conditionals.Length; ++i )
m_Conditionals[i] = ConditionalCompiler.Compile( emitter, m_ObjectType, m_Conditions[i], i );
}
public bool CheckCondition( object obj )
{
if ( m_ObjectType == null )
return true; // null type means no condition
if ( !HasCompiled )
{
AssemblyEmitter emitter = null;
Compile( ref emitter );
}
for ( int i = 0; i < m_Conditionals.Length; ++i )
{
if ( m_Conditionals[i].Verify( obj ) )
return true;
}
return false; // all conditions false
}
public static ObjectConditional Parse( Mobile from, ref string[] args )
{
string[] conditionArgs = null;
for ( int i = 0; i < args.Length; ++i )
{
if ( Insensitive.Equals( args[i], "where" ) )
{
string[] origArgs = args;
args = new string[i];
for ( int j = 0; j < args.Length; ++j )
args[j] = origArgs[j];
conditionArgs = new string[origArgs.Length - i - 1];
for ( int j = 0; j < conditionArgs.Length; ++j )
conditionArgs[j] = origArgs[i + j + 1];
break;
}
}
return ParseDirect( from, conditionArgs, 0, conditionArgs.Length );
}
public static ObjectConditional ParseDirect( Mobile from, string[] args, int offset, int size )
{
if ( args == null || size == 0 )
return ObjectConditional.Empty;
int index = 0;
Type objectType = ScriptCompiler.FindTypeByName( args[offset + index], true );
if ( objectType == null )
throw new Exception( String.Format( "No type with that name ({0}) was found.", args[offset + index] ) );
++index;
List<ICondition[]> conditions = new List<ICondition[]>();
List<ICondition> current = new List<ICondition>();
current.Add( TypeCondition.Default );
while ( index < size )
{
string cur = args[offset + index];
bool inverse = false;
if ( Insensitive.Equals( cur, "not" ) || cur == "!" )
{
inverse = true;
++index;
if ( index >= size )
throw new Exception( "Improperly formatted object conditional." );
}
else if ( Insensitive.Equals( cur, "or" ) || cur == "||" )
{
if ( conditions.Count > 1 )
{
conditions.Add( current.ToArray() );
current.Clear();
current.Add( TypeCondition.Default );
}
++index;
continue;
}
string binding = args[offset + index];
index++;
if ( index >= size )
throw new Exception( "Improperly formatted object conditional." );
string oper = args[offset + index];
index++;
if ( index >= size )
throw new Exception( "Improperly formatted object conditional." );
string val = args[offset + index];
index++;
Property prop = new Property( binding );
prop.BindTo( objectType, PropertyAccess.Read );
prop.CheckAccess( from );
ICondition condition = null;
switch ( oper )
{
#region Equality
case "=":
case "==":
case "is":
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.Equal, val );
break;
case "!=":
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.NotEqual, val );
break;
#endregion
#region Relational
case ">":
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.Greater, val );
break;
case "<":
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.Lesser, val );
break;
case ">=":
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.GreaterEqual, val );
break;
case "<=":
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.LesserEqual, val );
break;
#endregion
#region Strings
case "==~":
case "~==":
case "=~":
case "~=":
case "is~":
case "~is":
condition = new StringCondition( prop, inverse, StringOperator.Equal, val, true );
break;
case "!=~":
case "~!=":
condition = new StringCondition( prop, inverse, StringOperator.NotEqual, val, true );
break;
case "starts":
condition = new StringCondition( prop, inverse, StringOperator.StartsWith, val, false );
break;
case "starts~":
case "~starts":
condition = new StringCondition( prop, inverse, StringOperator.StartsWith, val, true );
break;
case "ends":
condition = new StringCondition( prop, inverse, StringOperator.EndsWith, val, false );
break;
case "ends~":
case "~ends":
condition = new StringCondition( prop, inverse, StringOperator.EndsWith, val, true );
break;
case "contains":
condition = new StringCondition( prop, inverse, StringOperator.Contains, val, false );
break;
case "contains~":
case "~contains":
condition = new StringCondition( prop, inverse, StringOperator.Contains, val, true );
break;
#endregion
}
if ( condition == null )
throw new InvalidOperationException( String.Format( "Unrecognized operator (\"{0}\").", oper ) );
current.Add( condition );
}
conditions.Add( current.ToArray() );
return new ObjectConditional( objectType, conditions.ToArray() );
}
public ObjectConditional( Type objectType, ICondition[][] conditions )
{
m_ObjectType = objectType;
m_Conditions = conditions;
}
}
}

View file

@ -0,0 +1,67 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Network;
namespace Server.Commands.Generic
{
public class OnlineCommandImplementor : BaseCommandImplementor
{
public OnlineCommandImplementor()
{
Accessors = new string[]{ "Online" };
SupportRequirement = CommandSupport.Online;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Online <command> [condition]";
Description = "Invokes the command on all mobiles that are currently logged in. Optional condition arguments can further restrict the set of objects.";
}
public override void Compile( Mobile from, BaseCommand command, ref string[] args, ref object obj )
{
try
{
Extensions ext = Extensions.Parse( from, ref args );
bool items, mobiles;
if ( !CheckObjectTypes( command, ext, out items, out mobiles ) )
return;
if ( !mobiles ) // sanity check
{
command.LogFailure( "This command does not support mobiles." );
return;
}
ArrayList list = new ArrayList();
List<NetState> states = NetState.Instances;
for ( int i = 0; i < states.Count; ++i )
{
NetState ns = states[i];
Mobile mob = ns.Mobile;
if ( mob == null )
continue;
if( !BaseCommand.IsAccessible( from, mob ) )
continue;
if ( ext.IsValid( mob ) )
list.Add( mob );
}
ext.Filter( list );
obj = list;
}
catch ( Exception ex )
{
from.SendMessage( ex.Message );
}
}
}
}

View file

@ -0,0 +1,61 @@
using System;
using System.Collections;
using Server;
namespace Server.Commands.Generic
{
public class RegionCommandImplementor : BaseCommandImplementor
{
public RegionCommandImplementor()
{
Accessors = new string[]{ "Region" };
SupportRequirement = CommandSupport.Region;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Region <command> [condition]";
Description = "Invokes the command on all appropriate mobiles in your current region. Optional condition arguments can further restrict the set of objects.";
}
public override void Compile( Mobile from, BaseCommand command, ref string[] args, ref object obj )
{
try
{
Extensions ext = Extensions.Parse( from, ref args );
bool items, mobiles;
if ( !CheckObjectTypes( command, ext, out items, out mobiles ) )
return;
Region reg = from.Region;
ArrayList list = new ArrayList();
if ( mobiles )
{
foreach ( Mobile mob in reg.GetMobiles() )
{
if( !BaseCommand.IsAccessible( from, mob ) )
continue;
if ( ext.IsValid( mob ) )
list.Add( mob );
}
}
else
{
command.LogFailure( "This command does not support items." );
return;
}
ext.Filter( list );
obj = list;
}
catch ( Exception ex )
{
from.SendMessage( ex.Message );
}
}
}
}

View file

@ -0,0 +1,27 @@
using System;
using System.Collections;
using Server;
using Server.Targeting;
namespace Server.Commands.Generic
{
public class SelfCommandImplementor : BaseCommandImplementor
{
public SelfCommandImplementor()
{
Accessors = new string[]{ "Self" };
SupportRequirement = CommandSupport.Self;
AccessLevel = AccessLevel.Counselor;
Usage = "Self <command>";
Description = "Invokes the command on the commanding player.";
}
public override void Compile( Mobile from, BaseCommand command, ref string[] args, ref object obj )
{
if ( command.ObjectTypes == ObjectTypes.Items )
return; // sanity check
obj = from;
}
}
}

View file

@ -0,0 +1,67 @@
using System;
using System.Collections;
using Server;
using Server.Targeting;
namespace Server.Commands.Generic
{
public class SerialCommandImplementor : BaseCommandImplementor
{
public SerialCommandImplementor()
{
Accessors = new string[]{ "Serial" };
SupportRequirement = CommandSupport.Single;
AccessLevel = AccessLevel.Counselor;
Usage = "Serial <serial> <command>";
Description = "Invokes the command on a single object by serial.";
}
public override void Execute( CommandEventArgs e )
{
if ( e.Length >= 2 )
{
Serial serial = e.GetInt32( 0 );
object obj = null;
if ( serial.IsItem )
obj = World.FindItem( serial );
else if ( serial.IsMobile )
obj = World.FindMobile( serial );
if ( obj == null )
{
e.Mobile.SendMessage( "That is not a valid serial." );
}
else
{
BaseCommand command = null;
Commands.TryGetValue( e.GetString( 1 ), out command );
if ( command == null )
{
e.Mobile.SendMessage( "That is either an invalid command name or one that does not support this modifier." );
}
else if ( e.Mobile.AccessLevel < command.AccessLevel )
{
e.Mobile.SendMessage( "You do not have access to that command." );
}
else
{
string[] oldArgs = e.Arguments;
string[] args = new string[oldArgs.Length - 2];
for ( int i = 0; i < args.Length; ++i )
args[i] = oldArgs[i + 2];
RunCommand( e.Mobile, obj, command, args );
}
}
}
else
{
e.Mobile.SendMessage( "You must supply an object serial and a command name." );
}
}
}
}

View file

@ -0,0 +1,96 @@
using System;
using System.Collections;
using Server;
using Server.Targeting;
namespace Server.Commands.Generic
{
public class SingleCommandImplementor : BaseCommandImplementor
{
public SingleCommandImplementor()
{
Accessors = new string[]{ "Single" };
SupportRequirement = CommandSupport.Single;
AccessLevel = AccessLevel.Counselor;
Usage = "Single <command>";
Description = "Invokes the command on a single targeted object. This is the same as just invoking the command directly.";
}
public override void Register( BaseCommand command )
{
base.Register( command );
for ( int i = 0; i < command.Commands.Length; ++i )
CommandSystem.Register( command.Commands[i], command.AccessLevel, new CommandEventHandler( Redirect ) );
}
public void Redirect( CommandEventArgs e )
{
BaseCommand command = null;
Commands.TryGetValue( e.Command, out command );
if ( command == null )
e.Mobile.SendMessage( "That is either an invalid command name or one that does not support this modifier." );
else if ( e.Mobile.AccessLevel < command.AccessLevel )
e.Mobile.SendMessage( "You do not have access to that command." );
else if ( command.ValidateArgs( this, e ) )
Process( e.Mobile, command, e.Arguments );
}
public override void Process( Mobile from, BaseCommand command, string[] args )
{
if ( command.ValidateArgs( this, new CommandEventArgs( from, command.Commands[0], GenerateArgString( args ), args ) ) )
from.BeginTarget( -1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback( OnTarget ), new object[]{ command, args } );
}
public void OnTarget( Mobile from, object targeted, object state )
{
if ( !BaseCommand.IsAccessible( from, targeted ) )
{
from.SendMessage( "That is not accessible." );
return;
}
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
switch ( command.ObjectTypes )
{
case ObjectTypes.Both:
{
if ( !(targeted is Item) && !(targeted is Mobile) )
{
from.SendMessage( "This command does not work on that." );
return;
}
break;
}
case ObjectTypes.Items:
{
if ( !(targeted is Item) )
{
from.SendMessage( "This command only works on items." );
return;
}
break;
}
case ObjectTypes.Mobiles:
{
if ( !(targeted is Mobile) )
{
from.SendMessage( "This command only works on mobiles." );
return;
}
break;
}
}
RunCommand( from, targeted, command, args );
}
}
}

1018
Scripts/Commands/Handlers.cs Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,422 @@
using System;
using Server;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using Server.Gumps;
using Server.Network;
using Server.Commands;
using Server.Commands.Generic;
using CommandInfo=Server.Commands.Docs.DocCommandEntry;
using CommandInfoSorter=Server.Commands.Docs.CommandEntrySorter;
namespace Server.Commands
{
public class HelpInfo
{
private static Dictionary<string, CommandInfo> m_HelpInfos = new Dictionary<string, CommandInfo>();
private static List<CommandInfo> m_SortedHelpInfo = new List<CommandInfo>(); //No need for SortedList cause it's only sorted once at creation...
public static Dictionary<string, CommandInfo> HelpInfos{ get { return m_HelpInfos; } }
public static List<CommandInfo> SortedHelpInfo { get { return m_SortedHelpInfo; } }
[CallPriority( 100 )]
public static void Initialize()
{
CommandSystem.Register( "HelpInfo", AccessLevel.Player, new CommandEventHandler( HelpInfo_OnCommand ) );
FillTable();
}
[Usage( "HelpInfo [<command>]" )]
[Description( "Gives information on a specified command, or when no argument specified, displays a gump containing all commands" )]
private static void HelpInfo_OnCommand( CommandEventArgs e )
{
if( e.Length > 0 )
{
string arg = e.GetString( 0 ).ToLower();
CommandInfo c;
if( m_HelpInfos.TryGetValue( arg, out c ) )
{
Mobile m = e.Mobile;
if( m.AccessLevel >= c.AccessLevel )
m.SendGump( new CommandInfoGump( c ) );
else
m.SendMessage( "You don't have access to that command." );
return;
}
else
e.Mobile.SendMessage( String.Format( "Command '{0}' not found!", arg ) );
}
e.Mobile.SendGump( new CommandListGump( 0, e.Mobile, null ) );
}
public static void FillTable()
{
List<CommandEntry> commands = new List<CommandEntry>( CommandSystem.Entries.Values );
List<CommandInfo> list = new List<CommandInfo>();
commands.Sort();
commands.Reverse();
Docs.Clean( commands );
for( int i = 0; i < commands.Count; ++i )
{
CommandEntry e =commands[i];
MethodInfo mi = e.Handler.Method;
object[] attrs = mi.GetCustomAttributes( typeof( UsageAttribute ), false );
if( attrs.Length == 0 )
continue;
UsageAttribute usage = attrs[0] as UsageAttribute;
attrs = mi.GetCustomAttributes( typeof( DescriptionAttribute ), false );
if( attrs.Length == 0 )
continue;
DescriptionAttribute desc = attrs[0] as DescriptionAttribute;
if( usage == null || desc == null )
continue;
attrs = mi.GetCustomAttributes( typeof( AliasesAttribute ), false );
AliasesAttribute aliases = (attrs.Length == 0 ? null : attrs[0] as AliasesAttribute);
string descString = desc.Description.Replace( "<", "(" ).Replace( ">", ")" );
if( aliases == null )
list.Add( new CommandInfo( e.AccessLevel, e.Command, null, usage.Usage, descString ) );
else
{
list.Add( new CommandInfo( e.AccessLevel, e.Command, aliases.Aliases, usage.Usage, descString ) );
for( int j = 0; j < aliases.Aliases.Length; j++ )
{
string[] newAliases = new string[aliases.Aliases.Length];
aliases.Aliases.CopyTo( newAliases, 0 );
newAliases[j] = e.Command;
list.Add( new CommandInfo( e.AccessLevel, aliases.Aliases[j], newAliases, usage.Usage, descString ) );
}
}
}
for( int i = 0; i < TargetCommands.AllCommands.Count; ++i )
{
BaseCommand command = TargetCommands.AllCommands[i];
string usage = command.Usage;
string desc = command.Description;
if( usage == null || desc == null )
continue;
string[] cmds = command.Commands;
string cmd = cmds[0];
string[] aliases = new string[cmds.Length - 1];
for( int j = 0; j < aliases.Length; ++j )
aliases[j] = cmds[j + 1];
desc = desc.Replace( "<", "(" ).Replace( ">", ")" );
if( command.Supports != CommandSupport.Single )
{
StringBuilder sb = new StringBuilder( 50 + desc.Length );
sb.Append( "Modifiers: " );
if( (command.Supports & CommandSupport.Global) != 0 )
sb.Append( "<i><Global</i>, " );
if( (command.Supports & CommandSupport.Online) != 0 )
sb.Append( "<i>Online</i>, " );
if( (command.Supports & CommandSupport.Region) != 0 )
sb.Append( "<i>Region</i>, " );
if( (command.Supports & CommandSupport.Contained) != 0 )
sb.Append( "<i>Contained</i>, " );
if( (command.Supports & CommandSupport.Multi) != 0 )
sb.Append( "<i>Multi</i>, " );
if( (command.Supports & CommandSupport.Area) != 0 )
sb.Append( "<i>Area</i>, " );
if( (command.Supports & CommandSupport.Self) != 0 )
sb.Append( "<i>Self</i>, " );
sb.Remove( sb.Length - 2, 2 );
sb.Append( "<br>" );
sb.Append( desc );
desc = sb.ToString();
}
list.Add( new CommandInfo( command.AccessLevel, cmd, aliases, usage, desc ) );
for( int j = 0; j < aliases.Length; j++ )
{
string[] newAliases = new string[aliases.Length];
aliases.CopyTo( newAliases, 0 );
newAliases[j] = cmd;
list.Add( new CommandInfo( command.AccessLevel, aliases[j], newAliases, usage, desc ) );
}
}
List<BaseCommandImplementor> commandImpls = BaseCommandImplementor.Implementors;
for( int i = 0; i < commandImpls.Count; ++i )
{
BaseCommandImplementor command = commandImpls[i];
string usage = command.Usage;
string desc = command.Description;
if( usage == null || desc == null )
continue;
string[] cmds = command.Accessors;
string cmd = cmds[0];
string[] aliases = new string[cmds.Length - 1];
for( int j = 0; j < aliases.Length; ++j )
aliases[j] = cmds[j + 1];
desc = desc.Replace( "<", ")" ).Replace( ">", ")" );
list.Add( new CommandInfo( command.AccessLevel, cmd, aliases, usage, desc ) );
for( int j = 0; j < aliases.Length; j++ )
{
string[] newAliases = new string[aliases.Length];
aliases.CopyTo( newAliases, 0 );
newAliases[j] = cmd;
list.Add( new CommandInfo( command.AccessLevel, aliases[j], newAliases, usage, desc ) );
}
}
list.Sort( new CommandInfoSorter() );
m_SortedHelpInfo = list;
foreach( CommandInfo c in m_SortedHelpInfo )
{
if( !m_HelpInfos.ContainsKey( c.Name.ToLower() ) )
m_HelpInfos.Add( c.Name.ToLower(), c );
}
}
public class CommandListGump : BaseGridGump
{
private const int EntriesPerPage = 15;
int m_Page;
List<CommandInfo> m_List;
public CommandListGump( int page, Mobile from, List<CommandInfo> list )
: base( 30, 30 )
{
m_Page = page;
if( list == null )
{
m_List = new List<CommandInfo>();
foreach( CommandInfo c in m_SortedHelpInfo )
{
if( from.AccessLevel >= c.AccessLevel )
m_List.Add( c );
}
}
else
m_List = list;
AddNewPage();
if( m_Page > 0 )
AddEntryButton( 20, ArrowLeftID1, ArrowLeftID2, 1, ArrowLeftWidth, ArrowLeftHeight );
else
AddEntryHeader( 20 );
AddEntryHtml( 160, Center( String.Format( "Page {0} of {1}", m_Page+1, (m_List.Count + EntriesPerPage - 1) / EntriesPerPage ) ) );
if( (m_Page + 1) * EntriesPerPage < m_List.Count )
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 2, ArrowRightWidth, ArrowRightHeight );
else
AddEntryHeader( 20 );
int last = (int)AccessLevel.Player - 1;
for( int i = m_Page * EntriesPerPage, line = 0; line < EntriesPerPage && i < m_List.Count; ++i, ++line )
{
CommandInfo c = m_List[i];
if( from.AccessLevel >= c.AccessLevel )
{
if( (int)c.AccessLevel != last )
{
AddNewLine();
AddEntryHtml( 20 + OffsetSize + 160, Color( c.AccessLevel.ToString(), 0xFF0000 ) );
AddEntryHeader( 20 );
line++;
}
last = (int)c.AccessLevel;
AddNewLine();
AddEntryHtml( 20 + OffsetSize + 160, c.Name );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 3 + i, ArrowRightWidth, ArrowRightHeight );
}
}
FinishPage();
}
public override void OnResponse( NetState sender, RelayInfo info )
{
Mobile m = sender.Mobile;
switch( info.ButtonID )
{
case 0:
{
m.CloseGump( typeof( CommandInfoGump ) );
break;
}
case 1:
{
if( m_Page > 0 )
m.SendGump( new CommandListGump( m_Page - 1, m, m_List ) );
break;
}
case 2:
{
if( (m_Page + 1) * EntriesPerPage < m_SortedHelpInfo.Count )
m.SendGump( new CommandListGump( m_Page + 1, m, m_List ) );
break;
}
default:
{
int v = info.ButtonID - 3;
if( v >= 0 && v < m_List.Count )
{
CommandInfo c = m_List[v];
if( m.AccessLevel >= c.AccessLevel )
{
m.SendGump( new CommandInfoGump( c ) );
m.SendGump( new CommandListGump( m_Page, m, m_List ) );
}
else
{
m.SendMessage( "You no longer have access to that command." );
m.SendGump( new CommandListGump( m_Page, m, null ) );
}
}
break;
}
}
}
}
public class CommandInfoGump : Gump
{
public string Color( string text, int color )
{
return String.Format( "<BASEFONT COLOR=#{0:X6}>{1}</BASEFONT>", color, text );
}
public string Center( string text )
{
return String.Format( "<CENTER>{0}</CENTER>", text );
}
public CommandInfoGump( CommandInfo info )
: this( info, 320, 200 )
{
}
public CommandInfoGump( CommandInfo info, int width, int height )
: base( 300, 50 )
{
AddPage( 0 );
AddBackground( 0, 0, width, height, 5054 );
//AddImageTiled( 10, 10, width - 20, 20, 2624 );
//AddAlphaRegion( 10, 10, width - 20, 20 );
//AddHtmlLocalized( 10, 10, width - 20, 20, header, headerColor, false, false );
AddHtml( 10, 10, width - 20, 20, Color( Center( info.Name ), 0xFF0000 ), false, false );
//AddImageTiled( 10, 40, width - 20, height - 80, 2624 );
//AddAlphaRegion( 10, 40, width - 20, height - 80 );
StringBuilder sb = new StringBuilder();
sb.Append( "Usage: " );
sb.Append( info.Usage.Replace( "<", "(" ).Replace( ">", ")" ) );
sb.Append( "<BR>" );
string[] aliases = info.Aliases;
if( aliases != null && aliases.Length != 0 )
{
sb.Append( String.Format( "Alias{0}: ", aliases.Length == 1 ? "" : "es" ) );
for( int i = 0; i < aliases.Length; ++i )
{
if( i != 0 )
sb.Append( ", " );
sb.Append( aliases[i] );
}
sb.Append( "<BR>" );
}
sb.Append( "AccessLevel: " );
sb.Append( info.AccessLevel.ToString() );
sb.Append( "<BR>" );
sb.Append( "<BR>" );
sb.Append( info.Description );
AddHtml( 10, 40, width - 20, height - 80, sb.ToString(), false, true );
//AddImageTiled( 10, height - 30, width - 20, 20, 2624 );
//AddAlphaRegion( 10, height - 30, width - 20, 20 );
}
}
}
}

147
Scripts/Commands/Logging.cs Normal file
View file

@ -0,0 +1,147 @@
using System;
using System.IO;
using Server;
using Server.Accounting;
namespace Server.Commands
{
public class CommandLogging
{
private static StreamWriter m_Output;
private static bool m_Enabled = true;
public static bool Enabled{ get{ return m_Enabled; } set{ m_Enabled = value; } }
public static StreamWriter Output{ get{ return m_Output; } }
public static void Initialize()
{
EventSink.Command += new CommandEventHandler( EventSink_Command );
if ( !Directory.Exists( "Data/Logs" ) )
Directory.CreateDirectory( "Data/Logs" );
string directory = "Data/Logs/Commands";
if ( !Directory.Exists( directory ) )
Directory.CreateDirectory( directory );
try
{
m_Output = new StreamWriter( Path.Combine( directory, String.Format( "{0}.log", DateTime.Now.ToLongDateString() ) ), true );
m_Output.AutoFlush = true;
m_Output.WriteLine( "##############################" );
m_Output.WriteLine( "Log started on {0}", DateTime.Now );
m_Output.WriteLine();
}
catch
{
}
}
public static object Format( object o )
{
if ( o is Mobile )
{
Mobile m = (Mobile)o;
if ( m.Account == null )
return String.Format( "{0} (no account)", m );
else
return String.Format( "{0} ('{1}')", m, m.Account.Username );
}
else if ( o is Item )
{
Item item = (Item)o;
return String.Format( "0x{0:X} ({1})", item.Serial.Value, item.GetType().Name );
}
return o;
}
public static void WriteLine( Mobile from, string format, params object[] args )
{
if ( !m_Enabled )
return;
WriteLine( from, String.Format( format, args ) );
}
public static void WriteLine( Mobile from, string text )
{
if ( !m_Enabled )
return;
try
{
m_Output.WriteLine( "{0}: {1}: {2}", DateTime.Now, from.NetState, text );
string path = Core.BaseDirectory;
Account acct = from.Account as Account;
string name = ( acct == null ? from.Name : acct.Username );
AppendPath( ref path, "Data/Logs" );
AppendPath( ref path, "Commands" );
AppendPath( ref path, from.AccessLevel.ToString() );
path = Path.Combine( path, String.Format( "{0}.log", name ) );
using ( StreamWriter sw = new StreamWriter( path, true ) )
sw.WriteLine( "{0}: {1}: {2}", DateTime.Now, from.NetState, text );
}
catch
{
}
}
private static char[] m_NotSafe = new char[]{ '\\', '/', ':', '*', '?', '"', '<', '>', '|' };
public static void AppendPath( ref string path, string toAppend )
{
path = Path.Combine( path, toAppend );
if ( !Directory.Exists( path ) )
Directory.CreateDirectory( path );
}
public static string Safe( string ip )
{
if ( ip == null )
return "null";
ip = ip.Trim();
if ( ip.Length == 0 )
return "empty";
bool isSafe = true;
for ( int i = 0; isSafe && i < m_NotSafe.Length; ++i )
isSafe = ( ip.IndexOf( m_NotSafe[i] ) == -1 );
if ( isSafe )
return ip;
System.Text.StringBuilder sb = new System.Text.StringBuilder( ip );
for ( int i = 0; i < m_NotSafe.Length; ++i )
sb.Replace( m_NotSafe[i], '_' );
return sb.ToString();
}
public static void EventSink_Command( CommandEventArgs e )
{
WriteLine( e.Mobile, "{0} {1} used command '{2} {3}'", e.Mobile.AccessLevel, Format( e.Mobile ), e.Command, e.ArgString );
}
public static void LogChangeProperty( Mobile from, object o, string name, string value )
{
WriteLine( from, "{0} {1} set property '{2}' of {3} to '{4}'", from.AccessLevel, Format( from ), name, Format( o ), value );
}
}
}

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

@ -0,0 +1,837 @@
using System;
using System.Reflection;
using System.Collections;
using Server;
using Server.Targeting;
using Server.Items;
using Server.Gumps;
using CPA = Server.CommandPropertyAttribute;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Commands
{
public enum PropertyAccess
{
Read = 0x01,
Write = 0x02,
ReadWrite = Read | Write
}
public class Properties
{
public static void Initialize()
{
CommandSystem.Register( "Props", AccessLevel.Counselor, new CommandEventHandler( Props_OnCommand ) );
}
private class PropsTarget : Target
{
public PropsTarget() : base( -1, true, TargetFlags.None )
{
}
protected override void OnTarget( Mobile from, object o )
{
if ( !BaseCommand.IsAccessible( from, o ) )
from.SendMessage( "That is not accessible." );
else
from.SendGump( new PropertiesGump( from, o ) );
}
}
[Usage( "Props [serial]" )]
[Description( "Opens a menu where you can view and edit all properties of a targeted (or specified) object." )]
private static void Props_OnCommand( CommandEventArgs e )
{
if ( e.Length == 1 )
{
IEntity ent = World.FindEntity( e.GetInt32( 0 ) );
if ( ent == null )
e.Mobile.SendMessage( "No object with that serial was found." );
else if ( !BaseCommand.IsAccessible( e.Mobile, ent ) )
e.Mobile.SendMessage( "That is not accessible." );
else
e.Mobile.SendGump( new PropertiesGump( e.Mobile, ent ) );
}
else
{
e.Mobile.Target = new PropsTarget();
}
}
private static bool CIEqual( string l, string r )
{
return Insensitive.Equals( l, r );
}
private static Type typeofCPA = typeof( CPA );
public static CPA GetCPA( PropertyInfo p )
{
object[] attrs = p.GetCustomAttributes( typeofCPA, false );
if ( attrs.Length == 0 )
return null;
return attrs[0] as CPA;
}
public static PropertyInfo[] GetPropertyInfoChain( Mobile from, Type type, string propertyString, PropertyAccess endAccess, ref string failReason )
{
string[] split = propertyString.Split( '.' );
if ( split.Length == 0 )
return null;
PropertyInfo[] info = new PropertyInfo[split.Length];
for ( int i = 0; i < info.Length; ++i )
{
string propertyName = split[i];
if ( CIEqual( propertyName, "current" ) )
continue;
PropertyInfo[] props = type.GetProperties( BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public );
bool isFinal = ( i == (info.Length - 1) );
PropertyAccess access = endAccess;
if ( !isFinal )
access |= PropertyAccess.Read;
for ( int j = 0; j < props.Length; ++j )
{
PropertyInfo p = props[j];
if ( CIEqual( p.Name, propertyName ) )
{
CPA attr = GetCPA( p );
if ( attr == null )
{
failReason = String.Format( "Property '{0}' not found.", propertyName );
return null;
}
else if ( (access & PropertyAccess.Read) != 0 && from.AccessLevel < attr.ReadLevel )
{
failReason = String.Format( "You must be at least {0} to get the property '{1}'.",
Mobile.GetAccessLevelName( attr.ReadLevel ), propertyName );
return null;
}
else if ( (access & PropertyAccess.Write) != 0 && from.AccessLevel < attr.WriteLevel )
{
failReason = String.Format( "You must be at least {0} to set the property '{1}'.",
Mobile.GetAccessLevelName( attr.WriteLevel ), propertyName );
return null;
}
else if ( (access & PropertyAccess.Read) != 0 && !p.CanRead )
{
failReason = String.Format( "Property '{0}' is write only.", propertyName );
return null;
}
else if ( (access & PropertyAccess.Write) != 0 && (!p.CanWrite || attr.ReadOnly) && isFinal )
{
failReason = String.Format( "Property '{0}' is read only.", propertyName );
return null;
}
info[i] = p;
type = p.PropertyType;
break;
}
}
if ( info[i] == null )
{
failReason = String.Format( "Property '{0}' not found.", propertyName );
return null;
}
}
return info;
}
public static PropertyInfo GetPropertyInfo( Mobile from, ref object obj, string propertyName, PropertyAccess access, ref string failReason )
{
PropertyInfo[] chain = GetPropertyInfoChain( from, obj.GetType(), propertyName, access, ref failReason );
if ( chain == null )
return null;
return GetPropertyInfo( ref obj, chain, ref failReason );
}
public static PropertyInfo GetPropertyInfo( ref object obj, PropertyInfo[] chain, ref string failReason )
{
if ( chain == null || chain.Length == 0 )
{
failReason = "Property chain is empty.";
return null;
}
for ( int i = 0; i < chain.Length - 1; ++i )
{
if ( chain[i] == null )
continue;
obj = chain[i].GetValue( obj, null );
if ( obj == null )
{
failReason = String.Format( "Property '{0}' is null.", chain[i] );
return null;
}
}
return chain[chain.Length-1];
}
public static string GetValue( Mobile from, object o, string name )
{
string failReason = "";
PropertyInfo[] chain = GetPropertyInfoChain( from, o.GetType(), name, PropertyAccess.Read, ref failReason );
if ( chain == null || chain.Length == 0 )
return failReason;
PropertyInfo p = GetPropertyInfo( ref o, chain, ref failReason );
if ( p == null )
return failReason;
return InternalGetValue( o, p, chain );
}
public static string IncreaseValue( Mobile from, object o, string[] args )
{
Type type = o.GetType();
object[] realObjs = new object[args.Length/2];
PropertyInfo[] realProps = new PropertyInfo[args.Length/2];
int[] realValues = new int[args.Length/2];
bool positive = false, negative = false;
for ( int i = 0; i < realProps.Length; ++i )
{
string name = args[i*2];
try
{
string valueString = args[1 + (i*2)];
if ( valueString.StartsWith( "0x" ) )
{
realValues[i] = Convert.ToInt32( valueString.Substring( 2 ), 16 );
}
else
{
realValues[i] = Convert.ToInt32( valueString );
}
}
catch
{
return "Offset value could not be parsed.";
}
if ( realValues[i] > 0 )
positive = true;
else if ( realValues[i] < 0 )
negative = true;
else
return "Zero is not a valid value to offset.";
string failReason = null;
realObjs[i] = o;
realProps[i] = GetPropertyInfo( from, ref realObjs[i], name, PropertyAccess.ReadWrite, ref failReason );
if ( failReason != null )
return failReason;
if ( realProps[i] == null )
return "Property not found.";
}
for ( int i = 0; i < realProps.Length; ++i )
{
object obj = realProps[i].GetValue( realObjs[i], null );
if( !( obj is IConvertible ) )
return "Property is not IConvertable.";
try
{
long v = (long)Convert.ChangeType( obj, TypeCode.Int64 );
v += realValues[i];
realProps[i].SetValue( realObjs[i], Convert.ChangeType( v, realProps[i].PropertyType ), null );
}
catch
{
return "Value could not be converted";
}
}
if ( realProps.Length == 1 )
{
if ( positive )
return "The property has been increased.";
return "The property has been decreased.";
}
if ( positive && negative )
return "The properties have been changed.";
if ( positive )
return "The properties have been increased.";
return "The properties have been decreased.";
}
private static string InternalGetValue( object o, PropertyInfo p )
{
return InternalGetValue( o, p, null );
}
private static string InternalGetValue( object o, PropertyInfo p, PropertyInfo[] chain )
{
Type type = p.PropertyType;
object value = p.GetValue( o, null );
string toString;
if ( value == null )
toString = "null";
else if ( IsNumeric( type ) )
toString = String.Format( "{0} (0x{0:X})", value );
else if ( IsChar( type ) )
toString = String.Format( "'{0}' ({1} [0x{1:X}])", value, (int) value );
else if ( IsString( type ) )
toString = ( (string) value == "null" ? @"@""null""" : String.Format( "\"{0}\"", value ) );
else
toString = value.ToString();
if ( chain == null )
return String.Format( "{0} = {1}", p.Name, toString );
string[] concat = new string[chain.Length*2+1];
for ( int i = 0; i < chain.Length; ++i )
{
concat[(i*2)+0] = chain[i].Name;
concat[(i*2)+1] = ( i < (chain.Length - 1) ) ? "." : " = ";
}
concat[concat.Length-1] = toString;
return String.Concat( concat );
}
public static string SetValue( Mobile from, object o, string name, string value )
{
object logObject = o;
string failReason = "";
PropertyInfo p = GetPropertyInfo( from, ref o, name, PropertyAccess.Write, ref failReason );
if ( p == null )
return failReason;
return InternalSetValue( from, logObject, o, p, name, value, true );
}
private static Type typeofSerial = typeof( Serial );
private static bool IsSerial( Type t )
{
return ( t == typeofSerial );
}
private static Type typeofType = typeof( Type );
private static bool IsType( Type t )
{
return ( t == typeofType );
}
private static Type typeofChar = typeof( Char );
private static bool IsChar( Type t )
{
return ( t == typeofChar );
}
private static Type typeofString = typeof( String );
private static bool IsString( Type t )
{
return ( t == typeofString );
}
private static bool IsEnum( Type t )
{
return t.IsEnum;
}
private static Type typeofTimeSpan = typeof( TimeSpan );
private static Type typeofParsable = typeof( ParsableAttribute );
private static bool IsParsable( Type t )
{
return ( t == typeofTimeSpan || t.IsDefined( typeofParsable, false ) );
}
private static Type[] m_ParseTypes = new Type[]{ typeof( string ) };
private static object[] m_ParseParams = new object[1];
private static object Parse( object o, Type t, string value )
{
MethodInfo method = t.GetMethod( "Parse", m_ParseTypes );
m_ParseParams[0] = value;
return method.Invoke( o, m_ParseParams );
}
private static Type[] m_NumericTypes = new Type[]
{
typeof( Byte ), typeof( SByte ),
typeof( Int16 ), typeof( UInt16 ),
typeof( Int32 ), typeof( UInt32 ),
typeof( Int64 ), typeof( UInt64 )
};
private static bool IsNumeric( Type t )
{
return ( Array.IndexOf( m_NumericTypes, t ) >= 0 );
}
public static string ConstructFromString( Type type, object obj, string value, ref object constructed )
{
object toSet;
bool isSerial = IsSerial( type );
if ( isSerial ) // mutate into int32
type = m_NumericTypes[4];
if ( value == "(-null-)" && !type.IsValueType )
value = null;
if ( IsEnum( type ) )
{
try
{
toSet = Enum.Parse( type, value, true );
}
catch
{
return "That is not a valid enumeration member.";
}
}
else if ( IsType( type ) )
{
try
{
toSet = ScriptCompiler.FindTypeByName( value );
if ( toSet == null )
return "No type with that name was found.";
}
catch
{
return "No type with that name was found.";
}
}
else if ( IsParsable( type ) )
{
try
{
toSet = Parse( obj, type, value );
}
catch
{
return "That is not properly formatted.";
}
}
else if ( value == null )
{
toSet = null;
}
else if ( value.StartsWith( "0x" ) && IsNumeric( type ) )
{
try
{
toSet = Convert.ChangeType( Convert.ToUInt64( value.Substring( 2 ), 16 ), type );
}
catch
{
return "That is not properly formatted.";
}
}
else
{
try
{
toSet = Convert.ChangeType( value, type );
}
catch
{
return "That is not properly formatted.";
}
}
if ( isSerial ) // mutate back
toSet = (Serial)((Int32)toSet);
constructed = toSet;
return null;
}
public static string SetDirect( Mobile from, object logObject, object obj, PropertyInfo prop, string givenName, object toSet, bool shouldLog )
{
try
{
if ( toSet is AccessLevel )
{
AccessLevel newLevel = (AccessLevel) toSet;
AccessLevel reqLevel = AccessLevel.Administrator;
if ( newLevel == AccessLevel.Administrator )
reqLevel = AccessLevel.Developer;
else if ( newLevel >= AccessLevel.Developer )
reqLevel = AccessLevel.Owner;
if ( from.AccessLevel < reqLevel )
return "You do not have access to that level.";
}
if ( shouldLog )
CommandLogging.LogChangeProperty( from, logObject, givenName, toSet == null ? "(-null-)" : toSet.ToString() );
prop.SetValue( obj, toSet, null );
return "Property has been set.";
}
catch
{
return "An exception was caught, the property may not be set.";
}
}
public static string SetDirect( object obj, PropertyInfo prop, object toSet )
{
try
{
if ( toSet is AccessLevel )
{
return "You do not have access to that level.";
}
prop.SetValue( obj, toSet, null );
return "Property has been set.";
}
catch
{
return "An exception was caught, the property may not be set.";
}
}
public static string InternalSetValue( Mobile from, object logobj, object o, PropertyInfo p, string pname, string value, bool shouldLog )
{
object toSet = null;
string result = ConstructFromString( p.PropertyType, o, value, ref toSet );
if ( result != null )
return result;
return SetDirect( from, logobj, o, p, pname, toSet, shouldLog );
}
public static string InternalSetValue( object o, PropertyInfo p, string value )
{
object toSet = null;
string result = ConstructFromString( p.PropertyType, o, value, ref toSet );
if ( result != null )
return result;
return SetDirect( o, p, toSet );
}
}
}
namespace Server
{
public abstract class PropertyException : ApplicationException
{
protected Property m_Property;
public Property Property
{
get { return m_Property; }
}
public PropertyException( Property property, string message )
: base( message )
{
m_Property = property;
}
}
public abstract class BindingException : PropertyException
{
public BindingException( Property property, string message )
: base( property, message )
{
}
}
public sealed class NotYetBoundException : BindingException
{
public NotYetBoundException( Property property )
: base( property, String.Format( "Property has not yet been bound." ) )
{
}
}
public sealed class AlreadyBoundException : BindingException
{
public AlreadyBoundException( Property property )
: base( property, String.Format( "Property has already been bound." ) )
{
}
}
public sealed class UnknownPropertyException : BindingException
{
public UnknownPropertyException( Property property, string current )
: base( property, String.Format( "Property '{0}' not found.", current ) )
{
}
}
public sealed class ReadOnlyException : BindingException
{
public ReadOnlyException( Property property )
: base( property, "Property is read-only." )
{
}
}
public sealed class WriteOnlyException : BindingException
{
public WriteOnlyException( Property property )
: base( property, "Property is write-only." )
{
}
}
public abstract class AccessException : PropertyException
{
public AccessException( Property property, string message )
: base( property, message )
{
}
}
public sealed class InternalAccessException : AccessException
{
public InternalAccessException( Property property )
: base( property, "Property is internal." )
{
}
}
public abstract class ClearanceException : AccessException
{
protected AccessLevel m_PlayerAccess;
protected AccessLevel m_NeededAccess;
public AccessLevel PlayerAccess
{
get { return m_PlayerAccess; }
}
public AccessLevel NeededAccess
{
get { return m_NeededAccess; }
}
public ClearanceException( Property property, AccessLevel playerAccess, AccessLevel neededAccess, string accessType )
: base( property, string.Format(
"You must be at least {0} to {1} this property.",
Mobile.GetAccessLevelName( neededAccess ),
accessType
) )
{
}
}
public sealed class ReadAccessException : ClearanceException
{
public ReadAccessException( Property property, AccessLevel playerAccess, AccessLevel neededAccess )
: base( property, playerAccess, neededAccess, "read" )
{
}
}
public sealed class WriteAccessException : ClearanceException
{
public WriteAccessException( Property property, AccessLevel playerAccess, AccessLevel neededAccess )
: base( property, playerAccess, neededAccess, "write" )
{
}
}
public sealed class Property
{
private string m_Binding;
private PropertyInfo[] m_Chain;
private PropertyAccess m_Access;
public string Binding
{
get { return m_Binding; }
}
public bool IsBound
{
get { return ( m_Chain != null ); }
}
public PropertyAccess Access
{
get { return m_Access; }
}
public PropertyInfo[] Chain
{
get
{
if ( !IsBound )
throw new NotYetBoundException( this );
return m_Chain;
}
}
public Type Type
{
get
{
if ( !IsBound )
throw new NotYetBoundException( this );
return m_Chain[m_Chain.Length - 1].PropertyType;
}
}
public bool CheckAccess( Mobile from )
{
if ( !IsBound )
throw new NotYetBoundException( this );
for ( int i = 0; i < m_Chain.Length; ++i )
{
PropertyInfo prop = m_Chain[i];
bool isFinal = ( i == ( m_Chain.Length - 1 ) );
PropertyAccess access = m_Access;
if ( !isFinal )
access |= PropertyAccess.Read;
CPA security = Properties.GetCPA( prop );
if ( security == null )
throw new InternalAccessException( this );
if ( ( access & PropertyAccess.Read ) != 0 && from.AccessLevel < security.ReadLevel )
throw new ReadAccessException( this, from.AccessLevel, security.ReadLevel );
if ( ( access & PropertyAccess.Write ) != 0 && (from.AccessLevel < security.WriteLevel || security.ReadOnly) )
throw new WriteAccessException( this, from.AccessLevel, security.ReadLevel );
}
return true;
}
public void BindTo( Type objectType, PropertyAccess desiredAccess )
{
if ( IsBound )
throw new AlreadyBoundException( this );
string[] split = m_Binding.Split( '.' );
PropertyInfo[] chain = new PropertyInfo[split.Length];
for ( int i = 0; i < split.Length; ++i )
{
bool isFinal = ( i == ( chain.Length - 1 ) );
chain[i] = objectType.GetProperty( split[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase );
if ( chain[i] == null )
throw new UnknownPropertyException( this, split[i] );
objectType = chain[i].PropertyType;
PropertyAccess access = desiredAccess;
if ( !isFinal )
access |= PropertyAccess.Read;
if ( ( access & PropertyAccess.Read ) != 0 && !chain[i].CanRead )
throw new WriteOnlyException( this );
if ( ( access & PropertyAccess.Write ) != 0 && !chain[i].CanWrite )
throw new ReadOnlyException( this );
}
m_Access = desiredAccess;
m_Chain = chain;
}
public Property( string binding )
{
m_Binding = binding;
}
public Property( PropertyInfo[] chain )
{
m_Chain = chain;
}
public override string ToString()
{
if ( !IsBound )
return m_Binding;
string[] toJoin = new string[m_Chain.Length];
for ( int i = 0; i < toJoin.Length; ++i )
toJoin[i] = m_Chain[i].Name;
return string.Join( ".", toJoin );
}
public static Property Parse( Type type, string binding, PropertyAccess access )
{
Property prop = new Property( binding );
prop.BindTo( type, access );
return prop;
}
}
}

152
Scripts/Commands/Skills.cs Normal file
View file

@ -0,0 +1,152 @@
using System;
using System.Collections;
using Server;
using Server.Targeting;
namespace Server.Commands
{
public class SkillsCommand
{
public static void Initialize()
{
CommandSystem.Register( "SetSkill", AccessLevel.GameMaster, new CommandEventHandler( SetSkill_OnCommand ) );
CommandSystem.Register( "GetSkill", AccessLevel.GameMaster, new CommandEventHandler( GetSkill_OnCommand ) );
CommandSystem.Register( "SetAllSkills", AccessLevel.GameMaster, new CommandEventHandler( SetAllSkills_OnCommand ) );
}
[Usage( "SetSkill <name> <value>" )]
[Description( "Sets a skill value by name of a targeted mobile." )]
public static void SetSkill_OnCommand( CommandEventArgs arg )
{
if ( arg.Length != 2 )
{
arg.Mobile.SendMessage( "SetSkill <skill name> <value>" );
}
else
{
SkillName skill;
try
{
skill = (SkillName)Enum.Parse( typeof( SkillName ), arg.GetString( 0 ), true );
}
catch
{
arg.Mobile.SendLocalizedMessage( 1005631 ); // You have specified an invalid skill to set.
return;
}
arg.Mobile.Target = new SkillTarget( skill, arg.GetDouble( 1 ) );
}
}
[Usage( "SetAllSkills <name> <value>" )]
[Description( "Sets all skill values of a targeted mobile." )]
public static void SetAllSkills_OnCommand( CommandEventArgs arg )
{
if ( arg.Length != 1 )
{
arg.Mobile.SendMessage( "SetAllSkills <value>" );
}
else
{
arg.Mobile.Target = new AllSkillsTarget( arg.GetDouble( 0 ) );
}
}
[Usage( "GetSkill <name>" )]
[Description( "Gets a skill value by name of a targeted mobile." )]
public static void GetSkill_OnCommand( CommandEventArgs arg )
{
if ( arg.Length != 1 )
{
arg.Mobile.SendMessage( "GetSkill <skill name>" );
}
else
{
SkillName skill;
try
{
skill = (SkillName)Enum.Parse( typeof( SkillName ), arg.GetString( 0 ), true );
}
catch
{
arg.Mobile.SendLocalizedMessage( 1005631 ); // You have specified an invalid skill to set.
return;
}
arg.Mobile.Target = new SkillTarget( skill );
}
}
public class AllSkillsTarget : Target
{
private double m_Value;
public AllSkillsTarget( double value ) : base( -1, false, TargetFlags.None )
{
m_Value = value;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( targeted is Mobile )
{
Mobile targ = (Mobile)targeted;
Server.Skills skills = targ.Skills;
for ( int i = 0; i < skills.Length; ++i )
skills[i].Base = m_Value;
CommandLogging.LogChangeProperty( from, targ, "EverySkill.Base", m_Value.ToString() );
}
else
{
from.SendMessage( "That does not have skills!" );
}
}
}
public class SkillTarget : Target
{
private bool m_Set;
private SkillName m_Skill;
private double m_Value;
public SkillTarget( SkillName skill, double value ) : base( -1, false, TargetFlags.None )
{
m_Set = true;
m_Skill = skill;
m_Value = value;
}
public SkillTarget( SkillName skill ) : base( -1, false, TargetFlags.None )
{
m_Set = false;
m_Skill = skill;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( targeted is Mobile )
{
Mobile targ = (Mobile)targeted;
Skill skill = targ.Skills[m_Skill];
if ( skill == null )
return;
if ( m_Set )
{
skill.Base = m_Value;
CommandLogging.LogChangeProperty( from, targ, String.Format( "{0}.Base", m_Skill ), m_Value.ToString() );
}
from.SendMessage( "{0} : {1} (Base: {2})", m_Skill, skill.Value, skill.Base );
}
else
{
from.SendMessage( "That does not have skills!" );
}
}
}
}
}

View file

@ -0,0 +1,40 @@
using System;
using Server;
using Server.Targeting;
using Server.Gumps;
namespace Server.Commands
{
public class Skills
{
public static void Initialize()
{
Register();
}
public static void Register()
{
CommandSystem.Register( "Skills", AccessLevel.Counselor, new CommandEventHandler( Skills_OnCommand ) );
}
private class SkillsTarget : Target
{
public SkillsTarget( ) : base( -1, true, TargetFlags.None )
{
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is Mobile )
from.SendGump( new SkillsGump( from, (Mobile)o ) );
}
}
[Usage( "Skills" )]
[Description( "Opens a menu where you can view or edit skills of a targeted mobile." )]
private static void Skills_OnCommand( CommandEventArgs e )
{
e.Mobile.Target = new SkillsTarget();
}
}
}

570
Scripts/Commands/Statics.cs Normal file
View file

@ -0,0 +1,570 @@
using System;
using System.IO;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Commands;
using Server.Targeting;
using System.Collections.Generic;
namespace Server
{
public class Statics
{
public static void Initialize()
{
CommandSystem.Register( "Freeze", AccessLevel.Administrator, new CommandEventHandler( Freeze_OnCommand ) );
CommandSystem.Register( "FreezeMap", AccessLevel.Administrator, new CommandEventHandler( FreezeMap_OnCommand ) );
CommandSystem.Register( "FreezeWorld", AccessLevel.Administrator, new CommandEventHandler( FreezeWorld_OnCommand ) );
CommandSystem.Register( "Unfreeze", AccessLevel.Administrator, new CommandEventHandler( Unfreeze_OnCommand ) );
CommandSystem.Register( "UnfreezeMap", AccessLevel.Administrator, new CommandEventHandler( UnfreezeMap_OnCommand ) );
CommandSystem.Register( "UnfreezeWorld", AccessLevel.Administrator, new CommandEventHandler( UnfreezeWorld_OnCommand ) );
}
private static Point3D NullP3D = new Point3D( int.MinValue, int.MinValue, int.MinValue );
[Usage( "Freeze" )]
[Description( "Makes a targeted area of dynamic items static." )]
public static void Freeze_OnCommand( CommandEventArgs e )
{
BoundingBoxPicker.Begin( e.Mobile, new BoundingBoxCallback( FreezeBox_Callback ), null );
}
[Usage( "FreezeMap" )]
[Description( "Makes every dynamic item in your map static." )]
public static void FreezeMap_OnCommand( CommandEventArgs e )
{
Map map = e.Mobile.Map;
if ( map != null && map != Map.Internal )
SendWarning( e.Mobile, "You are about to freeze <u>all items in {0}</u>.", BaseFreezeWarning, map, NullP3D, NullP3D, new WarningGumpCallback( FreezeWarning_Callback ) );
}
[Usage( "FreezeWorld" )]
[Description( "Makes every dynamic item on all maps static." )]
public static void FreezeWorld_OnCommand( CommandEventArgs e )
{
SendWarning( e.Mobile, "You are about to freeze <u>every item on every map</u>.", BaseFreezeWarning, null, NullP3D, NullP3D, new WarningGumpCallback( FreezeWarning_Callback ) );
}
public static void SendWarning( Mobile m, string header, string baseWarning, Map map, Point3D start, Point3D end, WarningGumpCallback callback )
{
m.SendGump( new WarningGump( 1060635, 30720, String.Format( baseWarning, String.Format( header, map ) ), 0xFFC000, 420, 400, callback, new StateInfo( map, start, end ) ) );
}
private const string BaseFreezeWarning = "{0} " +
"Those items <u>will be removed from the world</u> and placed into the server data files. " +
"Other players <u>will not see the changes</u> unless you distribute your data files to them.<br><br>" +
"This operation may not complete unless the server and client are using different data files. " +
"If you receive a message stating 'output data files could not be opened,' then you are probably sharing data files. " +
"Create a new directory for the world data files (statics*.mul and staidx*.mul) and add that to Scritps/Misc/DataPath.cs.<br><br>" +
"The change will be in effect immediately on the server, however, you must restart your client and update it's data files for the changes to become visible. " +
"It is strongly recommended that you make backup of the data files mentioned above. " +
"Do you wish to proceed?";
private static void FreezeBox_Callback( Mobile from, Map map, Point3D start, Point3D end, object state )
{
SendWarning( from, "You are about to freeze a section of items.", BaseFreezeWarning, map, start, end, new WarningGumpCallback( FreezeWarning_Callback ) );
}
private static void FreezeWarning_Callback( Mobile from, bool okay, object state )
{
if ( !okay )
return;
StateInfo si = (StateInfo)state;
Freeze( from, si.m_Map, si.m_Start, si.m_End );
}
public static void Freeze( Mobile from, Map targetMap, Point3D start3d, Point3D end3d )
{
Hashtable mapTable = new Hashtable();
if ( start3d == NullP3D && end3d == NullP3D )
{
if ( targetMap == null )
CommandLogging.WriteLine( from, "{0} {1} invoking freeze for every item in every map", from.AccessLevel, CommandLogging.Format( from ) );
else
CommandLogging.WriteLine( from, "{0} {1} invoking freeze for every item in {0}", from.AccessLevel, CommandLogging.Format( from ), targetMap );
foreach ( Item item in World.Items.Values )
{
if ( targetMap != null && item.Map != targetMap )
continue;
if ( item.Parent != null )
continue;
if ( item is Static || item is BaseFloor || item is BaseWall )
{
Map itemMap = item.Map;
if ( itemMap == null || itemMap == Map.Internal )
continue;
Hashtable table = (Hashtable)mapTable[itemMap];
if ( table == null )
mapTable[itemMap] = table = new Hashtable();
Point2D p = new Point2D( item.X >> 3, item.Y >> 3 );
DeltaState state = (DeltaState)table[p];
if ( state == null )
table[p] = state = new DeltaState( p );
state.m_List.Add( item );
}
}
}
else if ( targetMap != null )
{
Point2D start = targetMap.Bound( new Point2D( start3d ) ), end = targetMap.Bound( new Point2D( end3d ) );
CommandLogging.WriteLine( from, "{0} {1} invoking freeze from {2} to {3} in {4}", from.AccessLevel, CommandLogging.Format( from ), start, end, targetMap );
IPooledEnumerable eable = targetMap.GetItemsInBounds( new Rectangle2D( start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1 ) );
foreach ( Item item in eable )
{
if ( item is Static || item is BaseFloor || item is BaseWall )
{
Map itemMap = item.Map;
if ( itemMap == null || itemMap == Map.Internal )
continue;
Hashtable table = (Hashtable)mapTable[itemMap];
if ( table == null )
mapTable[itemMap] = table = new Hashtable();
Point2D p = new Point2D( item.X >> 3, item.Y >> 3 );
DeltaState state = (DeltaState)table[p];
if ( state == null )
table[p] = state = new DeltaState( p );
state.m_List.Add( item );
}
}
eable.Free();
}
if ( mapTable.Count == 0 )
{
from.SendGump( new NoticeGump( 1060637, 30720, "No freezable items were found. Only the following item types are frozen:<br> - Static<br> - BaseFloor<br> - BaseWall", 0xFFC000, 320, 240, null, null ) );
return;
}
bool badDataFile = false;
int totalFrozen = 0;
foreach ( DictionaryEntry de in mapTable )
{
Map map = (Map)de.Key;
Hashtable table = (Hashtable)de.Value;
TileMatrix matrix = map.Tiles;
using ( FileStream idxStream = OpenWrite( matrix.IndexStream ) )
{
using ( FileStream mulStream = OpenWrite( matrix.DataStream ) )
{
if ( idxStream == null || mulStream == null )
{
badDataFile = true;
continue;
}
BinaryReader idxReader = new BinaryReader( idxStream );
BinaryWriter idxWriter = new BinaryWriter( idxStream );
BinaryWriter mulWriter = new BinaryWriter( mulStream );
foreach ( DeltaState state in table.Values )
{
int oldTileCount;
StaticTile[] oldTiles = ReadStaticBlock( idxReader, mulStream, state.m_X, state.m_Y, matrix.BlockWidth, matrix.BlockHeight, out oldTileCount );
if ( oldTileCount < 0 )
continue;
int newTileCount = 0;
StaticTile[] newTiles = new StaticTile[state.m_List.Count];
for ( int i = 0; i < state.m_List.Count; ++i )
{
Item item = state.m_List[i];
int xOffset = item.X - (state.m_X * 8);
int yOffset = item.Y - (state.m_Y * 8);
if ( xOffset < 0 || xOffset >= 8 || yOffset < 0 || yOffset >= 8 )
continue;
StaticTile newTile = new StaticTile( (ushort)item.ItemID, (byte)xOffset, (byte)yOffset, (sbyte)item.Z, (short)item.Hue );
newTiles[newTileCount++] = newTile;
item.Delete();
++totalFrozen;
}
int mulPos = -1;
int length = -1;
int extra = 0;
if ( (oldTileCount + newTileCount) > 0 )
{
mulWriter.Seek( 0, SeekOrigin.End );
mulPos = (int)mulWriter.BaseStream.Position;
length = (oldTileCount + newTileCount) * 7;
extra = 1;
for ( int i = 0; i < oldTileCount; ++i )
{
StaticTile toWrite = oldTiles[i];
mulWriter.Write( (ushort) toWrite.ID );
mulWriter.Write( (byte) toWrite.X );
mulWriter.Write( (byte) toWrite.Y );
mulWriter.Write( (sbyte) toWrite.Z );
mulWriter.Write( (short) toWrite.Hue );
}
for ( int i = 0; i < newTileCount; ++i )
{
StaticTile toWrite = newTiles[i];
mulWriter.Write( (ushort) toWrite.ID );
mulWriter.Write( (byte) toWrite.X );
mulWriter.Write( (byte) toWrite.Y );
mulWriter.Write( (sbyte) toWrite.Z );
mulWriter.Write( (short) toWrite.Hue );
}
mulWriter.Flush();
}
int idxPos = ((state.m_X * matrix.BlockHeight) + state.m_Y) * 12;
idxWriter.Seek( idxPos, SeekOrigin.Begin );
idxWriter.Write( mulPos );
idxWriter.Write( length );
idxWriter.Write( extra );
idxWriter.Flush();
matrix.SetStaticBlock( state.m_X, state.m_Y, null );
}
}
}
}
if ( totalFrozen == 0 && badDataFile )
from.SendGump( new NoticeGump( 1060637, 30720, "Output data files could not be opened and the freeze operation has been aborted.<br><br>This probably means your server and client are using the same data files. Instructions on how to resolve this can be found in the first warning window.", 0xFFC000, 320, 240, null, null ) );
else
from.SendGump( new NoticeGump( 1060637, 30720, String.Format( "Freeze operation completed successfully.<br><br>{0} item{1} frozen.<br><br>You must restart your client and update it's data files to see the changes.", totalFrozen, totalFrozen != 1 ? "s were" : " was" ), 0xFFC000, 320, 240, null, null ) );
}
private const string BaseUnfreezeWarning = "{0} " +
"Those items <u>will be removed from the static files</u> and exchanged with unmovable dynamic items. " +
"Other players <u>will not see the changes</u> unless you distribute your data files to them.<br><br>" +
"This operation may not complete unless the server and client are using different data files. " +
"If you receive a message stating 'output data files could not be opened,' then you are probably sharing data files. " +
"Create a new directory for the world data files (statics*.mul and staidx*.mul) and add that to Scritps/Misc/DataPath.cs.<br><br>" +
"The change will be in effect immediately on the server, however, you must restart your client and update it's data files for the changes to become visible. " +
"It is strongly recommended that you make backup of the data files mentioned above. " +
"Do you wish to proceed?";
[Usage( "Unfreeze" )]
[Description( "Makes a targeted area of static items dynamic." )]
public static void Unfreeze_OnCommand( CommandEventArgs e )
{
BoundingBoxPicker.Begin( e.Mobile, new BoundingBoxCallback( UnfreezeBox_Callback ), null );
}
[Usage( "UnfreezeMap" )]
[Description( "Makes every static item in your map dynamic." )]
public static void UnfreezeMap_OnCommand( CommandEventArgs e )
{
Map map = e.Mobile.Map;
if ( map != null && map != Map.Internal )
SendWarning( e.Mobile, "You are about to unfreeze <u>all items in {0}</u>.", BaseUnfreezeWarning, map, NullP3D, NullP3D, new WarningGumpCallback( UnfreezeWarning_Callback ) );
}
[Usage( "UnfreezeWorld" )]
[Description( "Makes every static item on all maps dynamic." )]
public static void UnfreezeWorld_OnCommand( CommandEventArgs e )
{
SendWarning( e.Mobile, "You are about to unfreeze <u>every item on every map</u>.", BaseUnfreezeWarning, null, NullP3D, NullP3D, new WarningGumpCallback( UnfreezeWarning_Callback ) );
}
private static void UnfreezeBox_Callback( Mobile from, Map map, Point3D start, Point3D end, object state )
{
SendWarning( from, "You are about to unfreeze a section of items.", BaseUnfreezeWarning, map, start, end, new WarningGumpCallback( UnfreezeWarning_Callback ) );
}
private static void UnfreezeWarning_Callback( Mobile from, bool okay, object state )
{
if ( !okay )
return;
StateInfo si = (StateInfo)state;
Unfreeze( from, si.m_Map, si.m_Start, si.m_End );
}
private static void DoUnfreeze( Map map, Point2D start, Point2D end, ref bool badDataFile, ref int totalUnfrozen )
{
start = map.Bound( start );
end = map.Bound( end );
int xStartBlock = start.X >> 3;
int yStartBlock = start.Y >> 3;
int xEndBlock = end.X >> 3;
int yEndBlock = end.Y >> 3;
int xTileStart = start.X, yTileStart = start.Y;
int xTileWidth = end.X - start.X + 1, yTileHeight = end.Y - start.Y + 1;
TileMatrix matrix = map.Tiles;
using ( FileStream idxStream = OpenWrite( matrix.IndexStream ) )
{
using ( FileStream mulStream = OpenWrite( matrix.DataStream ) )
{
if ( idxStream == null || mulStream == null )
{
badDataFile = true;
return;
}
BinaryReader idxReader = new BinaryReader( idxStream );
BinaryWriter idxWriter = new BinaryWriter( idxStream );
BinaryWriter mulWriter = new BinaryWriter( mulStream );
for ( int x = xStartBlock; x <= xEndBlock; ++x )
{
for ( int y = yStartBlock; y <= yEndBlock; ++y )
{
int oldTileCount;
StaticTile[] oldTiles = ReadStaticBlock( idxReader, mulStream, x, y, matrix.BlockWidth, matrix.BlockHeight, out oldTileCount );
if ( oldTileCount < 0 )
continue;
int newTileCount = 0;
StaticTile[] newTiles = new StaticTile[oldTileCount];
int baseX = (x << 3) - xTileStart, baseY = (y << 3) - yTileStart;
for ( int i = 0; i < oldTileCount; ++i )
{
StaticTile oldTile = oldTiles[i];
int px = baseX + oldTile.X;
int py = baseY + oldTile.Y;
if ( px < 0 || px >= xTileWidth || py < 0 || py >= yTileHeight )
{
newTiles[newTileCount++] = oldTile;
}
else
{
++totalUnfrozen;
Item item = new Static( oldTile.ID );
item.Hue = oldTile.Hue;
item.MoveToWorld( new Point3D( px + xTileStart, py + yTileStart, oldTile.Z ), map );
}
}
int mulPos = -1;
int length = -1;
int extra = 0;
if ( newTileCount > 0 )
{
mulWriter.Seek( 0, SeekOrigin.End );
mulPos = (int)mulWriter.BaseStream.Position;
length = newTileCount * 7;
extra = 1;
for ( int i = 0; i < newTileCount; ++i )
{
StaticTile toWrite = newTiles[i];
mulWriter.Write( (ushort) toWrite.ID );
mulWriter.Write( (byte) toWrite.X );
mulWriter.Write( (byte) toWrite.Y );
mulWriter.Write( (sbyte) toWrite.Z );
mulWriter.Write( (short) toWrite.Hue );
}
mulWriter.Flush();
}
int idxPos = ((x * matrix.BlockHeight) + y) * 12;
idxWriter.Seek( idxPos, SeekOrigin.Begin );
idxWriter.Write( mulPos );
idxWriter.Write( length );
idxWriter.Write( extra );
idxWriter.Flush();
matrix.SetStaticBlock( x, y, null );
}
}
}
}
}
public static void DoUnfreeze( Map map, ref bool badDataFile, ref int totalUnfrozen )
{
DoUnfreeze( map, Point2D.Zero, new Point2D( map.Width - 1, map.Height - 1 ), ref badDataFile, ref totalUnfrozen );
}
public static void Unfreeze( Mobile from, Map map, Point3D start, Point3D end )
{
int totalUnfrozen = 0;
bool badDataFile = false;
if ( map == null )
{
CommandLogging.WriteLine( from, "{0} {1} invoking unfreeze for every item in every map", from.AccessLevel, CommandLogging.Format( from ) );
DoUnfreeze( Map.Britannia, ref badDataFile, ref totalUnfrozen );
DoUnfreeze( Map.Underworld, ref badDataFile, ref totalUnfrozen );
DoUnfreeze( Map.Darkness, ref badDataFile, ref totalUnfrozen );
DoUnfreeze( Map.Ocean, ref badDataFile, ref totalUnfrozen );
DoUnfreeze( Map.Grassland, ref badDataFile, ref totalUnfrozen );
}
else if ( start == NullP3D && end == NullP3D )
{
CommandLogging.WriteLine( from, "{0} {1} invoking unfreeze for every item in {2}", from.AccessLevel, CommandLogging.Format( from ), map );
DoUnfreeze( map, ref badDataFile, ref totalUnfrozen );
}
else
{
CommandLogging.WriteLine( from, "{0} {1} invoking unfreeze from {2} to {3} in {4}", from.AccessLevel, CommandLogging.Format( from ), new Point2D( start ), new Point2D( end ), map );
DoUnfreeze( map, new Point2D( start ), new Point2D( end ), ref badDataFile, ref totalUnfrozen );
}
if ( totalUnfrozen == 0 && badDataFile )
from.SendGump( new NoticeGump( 1060637, 30720, "Output data files could not be opened and the unfreeze operation has been aborted.<br><br>This probably means your server and client are using the same data files. Instructions on how to resolve this can be found in the first warning window.", 0xFFC000, 320, 240, null, null ) );
else
from.SendGump( new NoticeGump( 1060637, 30720, String.Format( "Unfreeze operation completed successfully.<br><br>{0} item{1} unfrozen.<br><br>You must restart your client and update it's data files to see the changes.", totalUnfrozen, totalUnfrozen != 1 ? "s were" : " was" ), 0xFFC000, 320, 240, null, null ) );
}
private static FileStream OpenWrite( FileStream orig )
{
if ( orig == null )
return null;
try{ return new FileStream( orig.Name, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite ); }
catch{ return null; }
}
private static byte[] m_Buffer;
private static StaticTile[] m_TileBuffer = new StaticTile[128];
private static StaticTile[] ReadStaticBlock( BinaryReader idxReader, FileStream mulStream, int x, int y, int width, int height, out int count )
{
try
{
if ( x < 0 || x >= width || y < 0 || y >= height )
{
count = -1;
return m_TileBuffer;
}
idxReader.BaseStream.Seek( ((x * height) + y) * 12, SeekOrigin.Begin );
int lookup = idxReader.ReadInt32();
int length = idxReader.ReadInt32();
if ( lookup < 0 || length <= 0 )
{
count = 0;
}
else
{
count = length / 7;
mulStream.Seek( lookup, SeekOrigin.Begin );
if ( m_TileBuffer.Length < count )
m_TileBuffer = new StaticTile[count];
StaticTile[] staTiles = m_TileBuffer;
if ( m_Buffer == null || length > m_Buffer.Length )
m_Buffer = new byte[length];
mulStream.Read( m_Buffer, 0, length );
int index = 0;
for ( int i = 0; i < count; ++i )
{
staTiles[i].Set((ushort)(m_Buffer[index++] | (m_Buffer[index++] << 8)),
(byte)m_Buffer[index++], (byte)m_Buffer[index++], (sbyte)m_Buffer[index++],
(short)(m_Buffer[index++] | (m_Buffer[index++] << 8)));
}
}
}
catch
{
count = -1;
}
return m_TileBuffer;
}
private class DeltaState
{
public int m_X, m_Y;
public List<Item> m_List;
public DeltaState( Point2D p )
{
m_X = p.X;
m_Y = p.Y;
m_List = new List<Item>();
}
}
private class StateInfo
{
public Map m_Map;
public Point3D m_Start, m_End;
public StateInfo( Map map, Point3D start, Point3D end )
{
m_Map = map;
m_Start = start;
m_End = end;
}
}
}
}

View file

@ -0,0 +1,155 @@
using System;
using System.Collections;
using Server;
using Server.Mobiles;
using Server.Targeting;
using Server.Network;
using System.Collections.Generic;
namespace Server.Commands
{
public class VisibilityList
{
public static void Initialize()
{
EventSink.Login += new LoginEventHandler( OnLogin );
CommandSystem.Register( "Vis", AccessLevel.Counselor, new CommandEventHandler( Vis_OnCommand ) );
CommandSystem.Register( "VisList", AccessLevel.Counselor, new CommandEventHandler( VisList_OnCommand ) );
CommandSystem.Register( "VisClear", AccessLevel.Counselor, new CommandEventHandler( VisClear_OnCommand ) );
}
public static void OnLogin( LoginEventArgs e )
{
if ( e.Mobile is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile)e.Mobile;
pm.VisibilityList.Clear();
}
}
[Usage( "Vis" )]
[Description( "Adds or removes a targeted player from your visibility list. Anyone on your visibility list will be able to see you at all times, even when you're hidden." )]
public static void Vis_OnCommand( CommandEventArgs e )
{
if ( e.Mobile is PlayerMobile )
{
e.Mobile.Target = new VisTarget();
e.Mobile.SendMessage( "Select person to add or remove from your visibility list." );
}
}
[Usage( "VisList" )]
[Description( "Shows the names of everyone in your visibility list." )]
public static void VisList_OnCommand( CommandEventArgs e )
{
if ( e.Mobile is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile)e.Mobile;
List<Mobile> list = pm.VisibilityList;
if ( list.Count > 0 )
{
pm.SendMessage( "You are visible to {0} mobile{1}:", list.Count, list.Count == 1 ? "" : "s" );
for ( int i = 0; i < list.Count; ++i )
pm.SendMessage( "#{0}: {1}", i+1, list[i].Name );
}
else
{
pm.SendMessage( "Your visibility list is empty." );
}
}
}
[Usage( "VisClear" )]
[Description( "Removes everyone from your visibility list." )]
public static void VisClear_OnCommand( CommandEventArgs e )
{
if ( e.Mobile is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile)e.Mobile;
List<Mobile> list = new List<Mobile>( pm.VisibilityList );
pm.VisibilityList.Clear();
pm.SendMessage( "Your visibility list has been cleared." );
for ( int i = 0; i < list.Count; ++i )
{
Mobile m = list[i];
if ( !m.CanSee( pm ) && Utility.InUpdateRange( m, pm ) )
m.Send( pm.RemovePacket );
}
}
}
private class VisTarget : Target
{
public VisTarget() : base( -1, false, TargetFlags.None )
{
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( from is PlayerMobile && targeted is Mobile )
{
PlayerMobile pm = (PlayerMobile)from;
Mobile targ = (Mobile)targeted;
if ( targ.AccessLevel <= from.AccessLevel )
{
List<Mobile> list = pm.VisibilityList;
if ( list.Contains( targ ) )
{
list.Remove( targ );
from.SendMessage( "{0} has been removed from your visibility list.", targ.Name );
}
else
{
list.Add( targ );
from.SendMessage( "{0} has been added to your visibility list.", targ.Name );
}
if ( Utility.InUpdateRange( targ, from ) )
{
NetState ns = targ.NetState;
if ( ns != null ) {
if ( targ.CanSee( from ) )
{
if ( ns.StygianAbyss )
ns.Send( new MobileIncoming( targ, from ) );
else
ns.Send( new MobileIncomingOld( targ, from ) );
if ( ObjectPropertyList.Enabled )
{
ns.Send( from.OPLPacket );
foreach ( Item item in from.Items )
ns.Send( item.OPLPacket );
}
}
else
{
ns.Send( from.RemovePacket );
}
}
}
}
else
{
from.SendMessage( "They can already see you!" );
}
}
else
{
from.SendMessage( "Add only mobiles to your visibility list." );
}
}
}
}
}

106
Scripts/Commands/Wipe.cs Normal file
View file

@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Multis;
using Server.Targeting;
namespace Server.Commands
{
public class Wipe
{
[Flags]
public enum WipeType
{
Items = 0x01,
Mobiles = 0x02,
Multis = 0x04,
All = Items | Mobiles | Multis
}
public static void Initialize()
{
CommandSystem.Register( "Wipe", AccessLevel.GameMaster, new CommandEventHandler( WipeAll_OnCommand ) );
CommandSystem.Register( "WipeItems", AccessLevel.GameMaster, new CommandEventHandler( WipeItems_OnCommand ) );
CommandSystem.Register( "WipeNPCs", AccessLevel.GameMaster, new CommandEventHandler( WipeNPCs_OnCommand ) );
CommandSystem.Register( "WipeMultis", AccessLevel.GameMaster, new CommandEventHandler( WipeMultis_OnCommand ) );
}
[Usage( "Wipe" )]
[Description( "Wipes all items and npcs in a targeted bounding box." )]
private static void WipeAll_OnCommand( CommandEventArgs e )
{
BeginWipe( e.Mobile, WipeType.Items | WipeType.Mobiles );
}
[Usage( "WipeItems" )]
[Description( "Wipes all items in a targeted bounding box." )]
private static void WipeItems_OnCommand( CommandEventArgs e )
{
BeginWipe( e.Mobile, WipeType.Items );
}
[Usage( "WipeNPCs" )]
[Description( "Wipes all npcs in a targeted bounding box." )]
private static void WipeNPCs_OnCommand( CommandEventArgs e )
{
BeginWipe( e.Mobile, WipeType.Mobiles );
}
[Usage( "WipeMultis" )]
[Description( "Wipes all multis in a targeted bounding box." )]
private static void WipeMultis_OnCommand( CommandEventArgs e )
{
BeginWipe( e.Mobile, WipeType.Multis );
}
public static void BeginWipe( Mobile from, WipeType type )
{
BoundingBoxPicker.Begin( from, new BoundingBoxCallback( WipeBox_Callback ), type );
}
private static void WipeBox_Callback( Mobile from, Map map, Point3D start, Point3D end, object state )
{
DoWipe( from, map, start, end, (WipeType)state );
}
public static void DoWipe( Mobile from, Map map, Point3D start, Point3D end, WipeType type )
{
CommandLogging.WriteLine( from, "{0} {1} wiping from {2} to {3} in {5} ({4})", from.AccessLevel, CommandLogging.Format( from ), start, end, type, map );
bool mobiles = ( (type & WipeType.Mobiles) != 0 );
bool multis = ( (type & WipeType.Multis) != 0 );
bool items = ( (type & WipeType.Items) != 0 );
List<IEntity> toDelete = new List<IEntity>();
Rectangle2D rect = new Rectangle2D( start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1 );
IPooledEnumerable eable;
if ( (items || multis) && mobiles )
eable = map.GetObjectsInBounds( rect );
else if ( items || multis )
eable = map.GetItemsInBounds( rect );
else if ( mobiles )
eable = map.GetMobilesInBounds( rect );
else
return;
foreach ( IEntity obj in eable )
{
if ( items && (obj is Item) && !((obj is BaseMulti) || (obj is HouseSign)) )
toDelete.Add( obj );
else if ( multis && (obj is BaseMulti) )
toDelete.Add( obj );
else if ( mobiles && (obj is Mobile) && !((Mobile)obj).Player )
toDelete.Add( obj );
}
eable.Free();
for ( int i = 0; i < toDelete.Count; ++i )
toDelete[i].Delete();
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Server.Mobiles;
using Server.Engines.PartySystem;
namespace Server.ContextMenus
{
public class AddToPartyEntry : ContextMenuEntry
{
private Mobile m_From;
private Mobile m_Target;
public AddToPartyEntry( Mobile from, Mobile target ) : base( 0197, 12 )
{
m_From = from;
m_Target = target;
}
public override void OnClick()
{
Party p = Party.Get( m_From );
Party mp = Party.Get( m_Target );
if ( m_From == m_Target )
m_From.SendLocalizedMessage( 1005439 ); // You cannot add yourself to a party.
else if ( p != null && p.Leader != m_From )
m_From.SendLocalizedMessage( 1005453 ); // You may only add members to the party if you are the leader.
else if ( p != null && (p.Members.Count + p.Candidates.Count) >= Party.Capacity )
m_From.SendLocalizedMessage( 1008095 ); // You may only have 10 in your party (this includes candidates).
else if ( !m_Target.Player )
m_From.SendLocalizedMessage( 1005444 ); // The creature ignores your offer.
else if ( mp != null && mp == p )
m_From.SendLocalizedMessage( 1005440 ); // This person is already in your party!
else if ( mp != null )
m_From.SendLocalizedMessage( 1005441 ); // This person is already in a party!
else
Party.Invite( m_From, m_Target );
}
}
}

View file

@ -0,0 +1,64 @@
using System;
using Server.Items;
using Server.Network;
using Server.Targeting;
namespace Server.ContextMenus
{
public class AddToSpellbookEntry : ContextMenuEntry
{
public AddToSpellbookEntry() : base( 6144, 3 )
{
}
public override void OnClick()
{
if ( Owner.From.CheckAlive() && Owner.Target is SpellScroll )
Owner.From.Target = new InternalTarget( (SpellScroll)Owner.Target );
}
private class InternalTarget : Target
{
private SpellScroll m_Scroll;
public InternalTarget( SpellScroll scroll ) : base( 3, false, TargetFlags.None )
{
m_Scroll = scroll;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( targeted is Spellbook )
{
if ( from.CheckAlive() && !m_Scroll.Deleted && m_Scroll.Movable && m_Scroll.Amount >= 1 && m_Scroll.CheckItemUse( from ) )
{
Spellbook book = (Spellbook)targeted;
SpellbookType type = Spellbook.GetTypeForSpell( m_Scroll.SpellID );
if ( type != book.SpellbookType )
{
}
else if ( book.HasSpell( m_Scroll.SpellID ) )
{
from.SendLocalizedMessage( 500179 ); // That spell is already present in that spellbook.
}
else
{
int val = m_Scroll.SpellID - book.BookOffset;
if ( val >= 0 && val < book.BookCount )
{
book.Content |= (ulong)1 << val;
m_Scroll.Consume();
from.Send( new Network.PlaySound( 0x249, book.GetWorldLocation() ) );
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,25 @@
using System;
using Server.Items;
namespace Server.ContextMenus
{
public class EatEntry : ContextMenuEntry
{
private Mobile m_From;
private Food m_Food;
public EatEntry( Mobile from, Food food ) : base( 6135, 1 )
{
m_From = from;
m_Food = food;
}
public override void OnClick()
{
if ( m_Food.Deleted || !m_Food.Movable || !m_From.CheckAlive() || !m_Food.CheckItemUse( m_From ) )
return;
m_Food.Eat( m_From );
}
}
}

View file

@ -0,0 +1,31 @@
using System;
using Server.Mobiles;
using Server.Multis;
namespace Server.ContextMenus
{
public class EjectPlayerEntry : ContextMenuEntry
{
private Mobile m_From;
private Mobile m_Target;
private BaseHouse m_TargetHouse;
public EjectPlayerEntry( Mobile from, Mobile target ) : base( 6206, 12 )
{
m_From = from;
m_Target = target;
m_TargetHouse = BaseHouse.FindHouseAt( m_Target );
}
public override void OnClick()
{
if ( !m_From.Alive || m_TargetHouse.Deleted || !m_TargetHouse.IsFriend( m_From ) )
return;
if ( m_Target is Mobile )
{
m_TargetHouse.Kick( m_From, (Mobile)m_Target );
}
}
}
}

View file

@ -0,0 +1,30 @@
using System;
using Server.Items;
namespace Server.ContextMenus
{
public class OpenInnEntry : ContextMenuEntry
{
private Mobile m_Innkeeper;
public OpenInnEntry( Mobile from, Mobile inn ) : base( 6105, 12 )
{
m_Innkeeper = inn;
}
public override void OnClick()
{
if ( !Owner.From.CheckAlive() )
return;
if ( Owner.From.Criminal )
{
m_Innkeeper.Say( 500378 ); // Thou art a criminal and cannot access thy inn chest.
}
else
{
this.Owner.From.InnBox.Open();
}
}
}
}

View file

@ -0,0 +1,30 @@
using System;
using Server.Mobiles;
namespace Server.ContextMenus
{
public class TeachEntry : ContextMenuEntry
{
private SkillName m_Skill;
private BaseCreature m_Mobile;
private Mobile m_From;
public TeachEntry( SkillName skill, BaseCreature m, Mobile from, bool enabled ) : base( 6000 + (int)skill )
{
m_Skill = skill;
m_Mobile = m;
m_From = from;
if ( !enabled )
Flags |= Network.CMEFlags.Disabled;
}
public override void OnClick()
{
if ( !m_From.CheckAlive() )
return;
m_Mobile.Teach( m_Skill, m_From, 0, false );
}
}
}

View file

@ -0,0 +1,548 @@
using System;
using System.Collections.Generic;
using Server;
namespace Server.Engines.Chat
{
public class Channel
{
private string m_Name;
private string m_Password;
private List<ChatUser> m_Users, m_Banned, m_Moderators, m_Voices;
private bool m_VoiceRestricted;
private bool m_AlwaysAvailable;
public Channel( string name )
{
m_Name = name;
m_Users = new List<ChatUser>();
m_Banned = new List<ChatUser>();
m_Moderators = new List<ChatUser>();
m_Voices = new List<ChatUser>();
}
public Channel( string name, string password ) : this( name )
{
m_Password = password;
}
public string Name
{
get
{
return m_Name;
}
set
{
SendCommand( ChatCommand.RemoveChannel, m_Name );
m_Name = value;
SendCommand( ChatCommand.AddChannel, m_Name );
SendCommand( ChatCommand.JoinedChannel, m_Name );
}
}
public string Password
{
get
{
return m_Password;
}
set
{
string newValue = null;
if ( value != null )
{
newValue = value.Trim();
if ( String.IsNullOrEmpty( newValue ) )
newValue = null;
}
m_Password = newValue;
}
}
public bool Contains( ChatUser user )
{
return m_Users.Contains( user );
}
public bool IsBanned( ChatUser user )
{
return m_Banned.Contains( user );
}
public bool CanTalk( ChatUser user )
{
return ( !m_VoiceRestricted || m_Voices.Contains( user ) || m_Moderators.Contains( user ) );
}
public bool IsModerator( ChatUser user )
{
return m_Moderators.Contains( user );
}
public bool IsVoiced( ChatUser user )
{
return m_Voices.Contains( user );
}
public bool ValidatePassword( string password )
{
return ( m_Password == null || Insensitive.Equals( m_Password, password ) );
}
public bool ValidateModerator( ChatUser user )
{
if ( user != null && !IsModerator( user ) )
{
user.SendMessage( 29 ); // You must have operator status to do this.
return false;
}
return true;
}
public bool ValidateAccess( ChatUser from, ChatUser target )
{
if ( from != null && target != null && from.Mobile.AccessLevel < target.Mobile.AccessLevel )
{
from.Mobile.SendMessage( "Your access level is too low to do this." );
return false;
}
return true;
}
public bool AddUser( ChatUser user )
{
return AddUser( user, null );
}
public bool AddUser( ChatUser user, string password )
{
if ( Contains( user ) )
{
user.SendMessage( 46, m_Name ); // You are already in the conference '%1'.
return true;
}
else if ( IsBanned( user ) )
{
user.SendMessage( 64 ); // You have been banned from this conference.
return false;
}
else if ( !ValidatePassword( password ) )
{
user.SendMessage( 34 ); // That is not the correct password.
return false;
}
else
{
if ( user.CurrentChannel != null )
user.CurrentChannel.RemoveUser( user ); // Remove them from their current channel first
ChatSystem.SendCommandTo( user.Mobile, ChatCommand.JoinedChannel, m_Name );
SendCommand( ChatCommand.AddUserToChannel, user.GetColorCharacter() + user.Username );
m_Users.Add( user );
user.CurrentChannel = this;
if ( user.Mobile.AccessLevel >= AccessLevel.GameMaster || (!m_AlwaysAvailable && m_Users.Count == 1) )
AddModerator( user );
SendUsersTo( user );
return true;
}
}
public void RemoveUser( ChatUser user )
{
if ( Contains( user ) )
{
m_Users.Remove( user );
user.CurrentChannel = null;
if ( m_Moderators.Contains( user ) )
m_Moderators.Remove( user );
if ( m_Voices.Contains( user ) )
m_Voices.Remove( user );
SendCommand( ChatCommand.RemoveUserFromChannel, user, user.Username );
ChatSystem.SendCommandTo( user.Mobile, ChatCommand.LeaveChannel );
if ( m_Users.Count == 0 && !m_AlwaysAvailable )
RemoveChannel( this );
}
}
public void AdBan( ChatUser user )
{
AddBan( user, null );
}
public void AddBan( ChatUser user, ChatUser moderator )
{
if ( !ValidateModerator( moderator ) || !ValidateAccess( moderator, user ) )
return;
if ( !m_Banned.Contains( user ) )
m_Banned.Add( user );
Kick( user, moderator, true );
}
public void RemoveBan( ChatUser user )
{
if ( m_Banned.Contains( user ) )
m_Banned.Remove( user );
}
public void Kick( ChatUser user )
{
Kick( user, null );
}
public void Kick( ChatUser user, ChatUser moderator )
{
Kick( user, moderator, false );
}
public void Kick( ChatUser user, ChatUser moderator, bool wasBanned )
{
if ( !ValidateModerator( moderator ) || !ValidateAccess( moderator, user ) )
return;
if ( Contains( user ) )
{
if ( moderator != null )
{
if ( wasBanned )
user.SendMessage( 63, moderator.Username ); // %1, a conference moderator, has banned you from the conference.
else
user.SendMessage( 45, moderator.Username ); // %1, a conference moderator, has kicked you out of the conference.
}
RemoveUser( user );
ChatSystem.SendCommandTo( user.Mobile, ChatCommand.AddUserToChannel, user.GetColorCharacter() + user.Username );
SendMessage( 44, user.Username ) ; // %1 has been kicked out of the conference.
}
if ( wasBanned && moderator != null )
moderator.SendMessage( 62, user.Username ); // You are banning %1 from this conference.
}
public bool VoiceRestricted
{
get
{
return m_VoiceRestricted;
}
set
{
m_VoiceRestricted = value;
if ( value )
SendMessage( 56 ); // From now on, only moderators will have speaking privileges in this conference by default.
else
SendMessage( 55 ); // From now on, everyone in the conference will have speaking privileges by default.
}
}
public bool AlwaysAvailable
{
get
{
return m_AlwaysAvailable;
}
set
{
m_AlwaysAvailable = value;
}
}
public void AddVoiced( ChatUser user )
{
AddVoiced( user, null );
}
public void AddVoiced( ChatUser user, ChatUser moderator )
{
if ( !ValidateModerator( moderator ) )
return;
if ( !IsBanned( user ) && !IsModerator( user ) && !IsVoiced( user ) )
{
m_Voices.Add( user );
if ( moderator != null )
user.SendMessage( 54, moderator.Username ); // %1, a conference moderator, has granted you speaking priviledges in this conference.
SendMessage( 52, user, user.Username ); // %1 now has speaking privileges in this conference.
SendCommand( ChatCommand.AddUserToChannel, user, user.GetColorCharacter() + user.Username );
}
}
public void RemoveVoiced( ChatUser user, ChatUser moderator )
{
if ( !ValidateModerator( moderator ) || !ValidateAccess( moderator, user ) )
return;
if ( !IsModerator( user ) && IsVoiced( user ) )
{
m_Voices.Remove( user );
if ( moderator != null )
user.SendMessage( 53, moderator.Username ); // %1, a conference moderator, has removed your speaking priviledges for this conference.
SendMessage( 51, user, user.Username ); // %1 no longer has speaking privileges in this conference.
SendCommand( ChatCommand.AddUserToChannel, user, user.GetColorCharacter() + user.Username );
}
}
public void AddModerator( ChatUser user )
{
AddModerator( user, null );
}
public void AddModerator( ChatUser user, ChatUser moderator )
{
if ( !ValidateModerator( moderator ) )
return;
if ( IsBanned( user ) || IsModerator( user ) )
return;
if ( IsVoiced( user ) )
m_Voices.Remove( user );
m_Moderators.Add( user );
if ( moderator != null )
user.SendMessage( 50, moderator.Username ); // %1 has made you a conference moderator.
SendMessage( 48, user, user.Username ); // %1 is now a conference moderator.
SendCommand( ChatCommand.AddUserToChannel, user.GetColorCharacter() + user.Username );
}
public void RemoveModerator( ChatUser user )
{
RemoveModerator( user, null );
}
public void RemoveModerator( ChatUser user, ChatUser moderator )
{
if ( !ValidateModerator( moderator ) || !ValidateAccess( moderator, user ) )
return;
if ( IsModerator( user ) )
{
m_Moderators.Remove( user );
if ( moderator != null )
user.SendMessage( 49, moderator.Username ); // %1 has removed you from the list of conference moderators.
SendMessage( 47, user, user.Username ); // %1 is no longer a conference moderator.
SendCommand( ChatCommand.AddUserToChannel, user.GetColorCharacter() + user.Username );
}
}
public void SendMessage( int number )
{
SendMessage( number, null, null, null );
}
public void SendMessage( int number, string param1 )
{
SendMessage( number, null, param1, null );
}
public void SendMessage( int number, string param1, string param2 )
{
SendMessage( number, null, param1, param2 );
}
public void SendMessage( int number, ChatUser initiator )
{
SendMessage( number, initiator, null, null );
}
public void SendMessage( int number, ChatUser initiator, string param1 )
{
SendMessage( number, initiator, param1, null );
}
public void SendMessage( int number, ChatUser initiator, string param1, string param2 )
{
for ( int i = 0; i < m_Users.Count; ++i )
{
ChatUser user = m_Users[i];
if ( user == initiator )
continue;
if ( user.CheckOnline() )
user.SendMessage( number, param1, param2 );
else if ( !Contains( user ) )
--i;
}
}
public void SendIgnorableMessage( int number, ChatUser from, string param1, string param2 )
{
for ( int i = 0; i < m_Users.Count; ++i )
{
ChatUser user = m_Users[i];
if ( user.IsIgnored( from ) )
continue;
if ( user.CheckOnline() )
user.SendMessage( number, from.Mobile, param1, param2 );
else if ( !Contains( user ) )
--i;
}
}
public void SendCommand( ChatCommand command )
{
SendCommand( command, null, null, null );
}
public void SendCommand( ChatCommand command, string param1 )
{
SendCommand( command, null, param1, null );
}
public void SendCommand( ChatCommand command, string param1, string param2 )
{
SendCommand( command, null, param1, param2 );
}
public void SendCommand( ChatCommand command, ChatUser initiator )
{
SendCommand( command, initiator, null, null );
}
public void SendCommand( ChatCommand command, ChatUser initiator, string param1 )
{
SendCommand( command, initiator, param1, null );
}
public void SendCommand( ChatCommand command, ChatUser initiator, string param1, string param2 )
{
for ( int i = 0; i < m_Users.Count; ++i )
{
ChatUser user = m_Users[i];
if ( user == initiator )
continue;
if ( user.CheckOnline() )
ChatSystem.SendCommandTo( user.Mobile, command, param1, param2 );
else if ( !Contains( user ) )
--i;
}
}
public void SendUsersTo( ChatUser to )
{
for ( int i = 0; i < m_Users.Count; ++i )
{
ChatUser user = m_Users[i];
ChatSystem.SendCommandTo( to.Mobile, ChatCommand.AddUserToChannel, user.GetColorCharacter() + user.Username );
}
}
private static List<Channel> m_Channels = new List<Channel>();
public static List<Channel> Channels
{
get
{
return m_Channels;
}
}
public static void SendChannelsTo( ChatUser user )
{
for ( int i = 0; i < m_Channels.Count; ++i )
{
Channel channel = m_Channels[i];
if ( !channel.IsBanned( user ) )
ChatSystem.SendCommandTo( user.Mobile, ChatCommand.AddChannel, channel.Name, "0" );
}
}
public static Channel AddChannel( string name )
{
return AddChannel( name, null );
}
public static Channel AddChannel( string name, string password )
{
Channel channel = FindChannelByName( name );
if ( channel == null )
{
channel = new Channel( name, password );
m_Channels.Add( channel );
}
ChatUser.GlobalSendCommand( ChatCommand.AddChannel, name, "0" ) ;
return channel;
}
public static void RemoveChannel( string name )
{
RemoveChannel( FindChannelByName( name ) );
}
public static void RemoveChannel( Channel channel )
{
if ( channel == null )
return;
if ( m_Channels.Contains( channel ) && channel.m_Users.Count == 0 )
{
ChatUser.GlobalSendCommand( ChatCommand.RemoveChannel, channel.Name ) ;
channel.m_Moderators.Clear();
channel.m_Voices.Clear();
m_Channels.Remove( channel );
}
}
public static Channel FindChannelByName( string name )
{
for ( int i = 0; i < m_Channels.Count; ++i )
{
Channel channel = m_Channels[i];
if ( channel.m_Name == name )
return channel;
}
return null;
}
public static void Initialize()
{
AddStaticChannel( "Newbie Help" );
}
public static void AddStaticChannel( string name )
{
AddChannel( name ).AlwaysAvailable = true;
}
}
}

View file

@ -0,0 +1,174 @@
using System;
using Server;
using Server.Misc;
using Server.Network;
using Server.Accounting;
namespace Server.Engines.Chat
{
public class ChatSystem
{
private static bool m_Enabled = true;
public static bool Enabled
{
get{ return m_Enabled; }
set{ m_Enabled = value; }
}
public static void Initialize()
{
PacketHandlers.Register( 0xB5, 0x40, true, new OnPacketReceive( OpenChatWindowRequest ) );
PacketHandlers.Register( 0xB3, 0, true, new OnPacketReceive( ChatAction ) );
}
public static void SendCommandTo( Mobile to, ChatCommand type )
{
SendCommandTo( to, type, null, null );
}
public static void SendCommandTo( Mobile to, ChatCommand type, string param1 )
{
SendCommandTo( to, type, param1, null );
}
public static void SendCommandTo( Mobile to, ChatCommand type, string param1, string param2 )
{
if ( to != null )
to.Send( new ChatMessagePacket( null, (int)type + 20, param1, param2 ) );
}
public static void OpenChatWindowRequest( NetState state, PacketReader pvSrc )
{
Mobile from = state.Mobile;
if ( !m_Enabled )
{
from.SendMessage( "The chat system has been disabled." );
return;
}
pvSrc.Seek( 2, System.IO.SeekOrigin.Begin );
string chatName = pvSrc.ReadUnicodeStringSafe( ( 0x40 - 2 ) >> 1 ).Trim();
Account acct = state.Account as Account;
string accountChatName = null;
if ( acct != null )
accountChatName = acct.GetTag( "ChatName" );
if ( accountChatName != null )
accountChatName = accountChatName.Trim();
if ( accountChatName != null && accountChatName.Length > 0 )
{
if ( chatName.Length > 0 && chatName != accountChatName )
from.SendMessage( "You cannot change chat nickname once it has been set." );
}
else
{
if ( chatName == null || chatName.Length == 0 )
{
SendCommandTo( from, ChatCommand.AskNewNickname );
return;
}
if ( NameVerification.Validate( chatName, 2, 31, true, true, true, 0, NameVerification.SpaceDashPeriodQuote ) && chatName.ToLower().IndexOf( "system" ) == -1 )
{
// TODO: Optimize this search
foreach ( Account checkAccount in Accounts.GetAccounts() )
{
string existingName = checkAccount.GetTag( "ChatName" );
if ( existingName != null )
{
existingName = existingName.Trim();
if ( Insensitive.Equals( existingName, chatName ) )
{
from.SendMessage( "Nickname already in use." );
SendCommandTo( from, ChatCommand.AskNewNickname );
return;
}
}
}
accountChatName = chatName;
if ( acct != null )
acct.AddTag( "ChatName", chatName );
}
else
{
from.SendLocalizedMessage( 501173 ); // That name is disallowed.
SendCommandTo( from, ChatCommand.AskNewNickname );
return;
}
}
SendCommandTo( from, ChatCommand.OpenChatWindow, accountChatName );
ChatUser.AddChatUser( from );
}
public static ChatUser SearchForUser( ChatUser from, string name )
{
ChatUser user = ChatUser.GetChatUser( name );
if ( user == null )
from.SendMessage( 32, name ); // There is no player named '%1'.
return user;
}
public static void ChatAction( NetState state, PacketReader pvSrc )
{
if ( !m_Enabled )
return;
try
{
Mobile from = state.Mobile;
ChatUser user = ChatUser.GetChatUser( from );
if ( user == null )
return;
string lang = pvSrc.ReadStringSafe( 4 );
int actionID = pvSrc.ReadInt16();
string param = pvSrc.ReadUnicodeString();
ChatActionHandler handler = ChatActionHandlers.GetHandler( actionID );
if ( handler != null )
{
Channel channel = user.CurrentChannel;
if ( handler.RequireConference && channel == null )
{
user.SendMessage( 31 ); /* You must be in a conference to do this.
* To join a conference, select one from the Conference menu.
*/
}
else if ( handler.RequireModerator && !user.IsModerator )
{
user.SendMessage( 29 ); // You must have operator status to do this.
}
else
{
handler.Callback( user, channel, param );
}
}
else
{
Console.WriteLine( "Client: {0}: Unknown chat action 0x{1:X}: {2}", state, actionID, param );
}
}
catch ( Exception e )
{
Console.WriteLine( e );
}
}
}
}

View file

@ -0,0 +1,24 @@
using System;
namespace Server.Engines.Chat
{
public delegate void OnChatAction( ChatUser from, Channel channel, string param );
public class ChatActionHandler
{
private bool m_RequireModerator;
private bool m_RequireConference;
private OnChatAction m_Callback;
public bool RequireModerator{ get{ return m_RequireModerator; } }
public bool RequireConference{ get{ return m_RequireConference; } }
public OnChatAction Callback{ get{ return m_Callback; } }
public ChatActionHandler( bool requireModerator, bool requireConference, OnChatAction callback )
{
m_RequireModerator = requireModerator;
m_RequireConference = requireConference;
m_Callback = callback;
}
}
}

View file

@ -0,0 +1,359 @@
using System;
namespace Server.Engines.Chat
{
public class ChatActionHandlers
{
private static ChatActionHandler[] m_Handlers;
static ChatActionHandlers()
{
m_Handlers = new ChatActionHandler[0x100];
Register( 0x41, true, true, new OnChatAction( ChangeChannelPassword ) );
Register( 0x58, false, false, new OnChatAction( LeaveChat ) );
Register( 0x61, false, true, new OnChatAction( ChannelMessage ) );
Register( 0x62, false, false, new OnChatAction( JoinChannel ) );
Register( 0x63, false, false, new OnChatAction( JoinNewChannel ) );
Register( 0x64, true, true, new OnChatAction( RenameChannel ) );
Register( 0x65, false, false, new OnChatAction( PrivateMessage ) );
Register( 0x66, false, false, new OnChatAction( AddIgnore ) );
Register( 0x67, false, false, new OnChatAction( RemoveIgnore ) );
Register( 0x68, false, false, new OnChatAction( ToggleIgnore ) );
Register( 0x69, true, true, new OnChatAction( AddVoice ) );
Register( 0x6A, true, true, new OnChatAction( RemoveVoice ) );
Register( 0x6B, true, true, new OnChatAction( ToggleVoice ) );
Register( 0x6C, true, true, new OnChatAction( AddModerator ) );
Register( 0x6D, true, true, new OnChatAction( RemoveModerator ) );
Register( 0x6E, true, true, new OnChatAction( ToggleModerator ) );
Register( 0x6F, false, false, new OnChatAction( AllowPrivateMessages ) );
Register( 0x70, false, false, new OnChatAction( DisallowPrivateMessages ) );
Register( 0x71, false, false, new OnChatAction( TogglePrivateMessages ) );
Register( 0x72, false, false, new OnChatAction( ShowCharacterName ) );
Register( 0x73, false, false, new OnChatAction( HideCharacterName ) );
Register( 0x74, false, false, new OnChatAction( ToggleCharacterName ) );
Register( 0x75, false, false, new OnChatAction( QueryWhoIs ) );
Register( 0x76, true, true, new OnChatAction( Kick ) );
Register( 0x77, true, true, new OnChatAction( EnableDefaultVoice ) );
Register( 0x78, true, true, new OnChatAction( DisableDefaultVoice ) );
Register( 0x79, true, true, new OnChatAction( ToggleDefaultVoice ) );
Register( 0x7A, false, true, new OnChatAction( EmoteMessage ) );
}
public static void Register( int actionID, bool requireModerator, bool requireConference, OnChatAction callback )
{
if ( actionID >= 0 && actionID < m_Handlers.Length )
m_Handlers[actionID] = new ChatActionHandler( requireModerator, requireConference, callback );
}
public static ChatActionHandler GetHandler( int actionID )
{
if ( actionID >= 0 && actionID < m_Handlers.Length )
return m_Handlers[actionID];
return null;
}
public static void ChannelMessage( ChatUser from, Channel channel, string param )
{
if ( channel.CanTalk( from ) )
channel.SendIgnorableMessage( 57, from, from.GetColorCharacter() + from.Username, param ); // %1: %2
else
from.SendMessage( 36 ); // The moderator of this conference has not given you speaking priviledges.
}
public static void EmoteMessage( ChatUser from, Channel channel, string param )
{
if ( channel.CanTalk( from ) )
channel.SendIgnorableMessage( 58, from, from.GetColorCharacter() + from.Username, param ); // %1 %2
else
from.SendMessage( 36 ); // The moderator of this conference has not given you speaking priviledges.
}
public static void PrivateMessage( ChatUser from, Channel channel, string param )
{
int indexOf = param.IndexOf( ' ' );
string name = param.Substring( 0, indexOf );
string text = param.Substring( indexOf + 1 );
ChatUser target = ChatSystem.SearchForUser( from, name );
if ( target == null )
return;
if ( target.IsIgnored( from ) )
from.SendMessage( 35, target.Username ); // %1 has chosen to ignore you. None of your messages to them will get through.
else if ( target.IgnorePrivateMessage )
from.SendMessage( 42, target.Username ); // %1 has chosen to not receive private messages at the moment.
else
target.SendMessage( 59, from.Mobile, from.GetColorCharacter() + from.Username, text ); // [%1]: %2
}
public static void LeaveChat( ChatUser from, Channel channel, string param )
{
ChatUser.RemoveChatUser( from );
}
public static void ChangeChannelPassword( ChatUser from, Channel channel, string param )
{
channel.Password = param;
from.SendMessage( 60 ); // The password to the conference has been changed.
}
public static void AllowPrivateMessages( ChatUser from, Channel channel, string param )
{
from.IgnorePrivateMessage = false;
from.SendMessage( 37 ); // You can now receive private messages.
}
public static void DisallowPrivateMessages( ChatUser from, Channel channel, string param )
{
from.IgnorePrivateMessage = true;
from.SendMessage( 38 ); /* You will no longer receive private messages.
* Those who send you a message will be notified that you are blocking incoming messages.
*/
}
public static void TogglePrivateMessages( ChatUser from, Channel channel, string param )
{
from.IgnorePrivateMessage = !from.IgnorePrivateMessage;
from.SendMessage( from.IgnorePrivateMessage ? 38 : 37 ); // See above for messages
}
public static void ShowCharacterName( ChatUser from, Channel channel, string param )
{
from.Anonymous = false;
from.SendMessage( 39 ); // You are now showing your character name to any players who inquire with the whois command.
}
public static void HideCharacterName( ChatUser from, Channel channel, string param )
{
from.Anonymous = true;
from.SendMessage( 40 ); // You are no longer showing your character name to any players who inquire with the whois command.
}
public static void ToggleCharacterName( ChatUser from, Channel channel, string param )
{
from.Anonymous = !from.Anonymous;
from.SendMessage( from.Anonymous ? 40 : 39 ); // See above for messages
}
public static void JoinChannel( ChatUser from, Channel channel, string param )
{
string name;
string password = null;
int start = param.IndexOf( '\"' );
if ( start >= 0 )
{
int end = param.IndexOf( '\"', ++start );
if ( end >= 0 )
{
name = param.Substring( start, end - start );
password = param.Substring( ++end );
}
else
{
name = param.Substring( start );
}
}
else
{
int indexOf = param.IndexOf( ' ' );
if ( indexOf >= 0 )
{
name = param.Substring( 0, indexOf++ );
password = param.Substring( indexOf );
}
else
{
name = param;
}
}
if ( password != null )
password = password.Trim();
if ( password != null && password.Length == 0 )
password = null;
Channel joined = Channel.FindChannelByName( name );
if ( joined == null )
from.SendMessage( 33, name ); // There is no conference named '%1'.
else
joined.AddUser( from, password );
}
public static void JoinNewChannel( ChatUser from, Channel channel, string param )
{
if ( (param = param.Trim()).Length == 0 )
return;
string name;
string password = null;
int start = param.IndexOf( '{' );
if ( start >= 0 )
{
name = param.Substring( 0, start++ );
int end = param.IndexOf( '}', start );
if ( end >= start )
password = param.Substring( start, end - start );
}
else
{
name = param;
}
if ( password != null )
password = password.Trim();
if ( password != null && password.Length == 0 )
password = null;
Channel.AddChannel( name, password ).AddUser( from, password );
}
public static void AddIgnore( ChatUser from, Channel channel, string param )
{
ChatUser target = ChatSystem.SearchForUser( from, param );
if ( target == null )
return;
from.AddIgnored( target );
}
public static void RemoveIgnore( ChatUser from, Channel channel, string param )
{
ChatUser target = ChatSystem.SearchForUser( from, param );
if ( target == null )
return;
from.RemoveIgnored( target );
}
public static void ToggleIgnore( ChatUser from, Channel channel, string param )
{
ChatUser target = ChatSystem.SearchForUser( from, param );
if ( target == null )
return;
if ( from.IsIgnored( target ) )
from.RemoveIgnored( target );
else
from.AddIgnored( target );
}
public static void AddVoice( ChatUser from, Channel channel, string param )
{
ChatUser target = ChatSystem.SearchForUser( from, param );
if ( target != null )
channel.AddVoiced( target, from );
}
public static void RemoveVoice( ChatUser from, Channel channel, string param )
{
ChatUser target = ChatSystem.SearchForUser( from, param );
if ( target != null )
channel.RemoveVoiced( target, from );
}
public static void ToggleVoice( ChatUser from, Channel channel, string param )
{
ChatUser target = ChatSystem.SearchForUser( from, param );
if ( target == null )
return;
if ( channel.IsVoiced( target ) )
channel.RemoveVoiced( target, from );
else
channel.AddVoiced( target, from );
}
public static void AddModerator( ChatUser from, Channel channel, string param )
{
ChatUser target = ChatSystem.SearchForUser( from, param );
if ( target != null )
channel.AddModerator( target, from );
}
public static void RemoveModerator( ChatUser from, Channel channel, string param )
{
ChatUser target = ChatSystem.SearchForUser( from, param );
if ( target != null )
channel.RemoveModerator( target, from );
}
public static void ToggleModerator( ChatUser from, Channel channel, string param )
{
ChatUser target = ChatSystem.SearchForUser( from, param );
if ( target == null )
return;
if ( channel.IsModerator( target ) )
channel.RemoveModerator( target, from );
else
channel.AddModerator( target, from );
}
public static void RenameChannel( ChatUser from, Channel channel, string param )
{
channel.Name = param;
}
public static void QueryWhoIs( ChatUser from, Channel channel, string param )
{
ChatUser target = ChatSystem.SearchForUser( from, param );
if ( target == null )
return;
if ( target.Anonymous )
from.SendMessage( 41, target.Username ); // %1 is remaining anonymous.
else
from.SendMessage( 43, target.Username, target.Mobile.Name ); // %2 is known in the lands of Britannia as %2.
}
public static void Kick( ChatUser from, Channel channel, string param )
{
ChatUser target = ChatSystem.SearchForUser( from, param );
if ( target != null )
channel.Kick( target, from );
}
public static void EnableDefaultVoice( ChatUser from, Channel channel, string param )
{
channel.VoiceRestricted = false;
}
public static void DisableDefaultVoice( ChatUser from, Channel channel, string param )
{
channel.VoiceRestricted = true;
}
public static void ToggleDefaultVoice( ChatUser from, Channel channel, string param )
{
channel.VoiceRestricted = !channel.VoiceRestricted;
}
}
}

View file

@ -0,0 +1,44 @@
using System;
namespace Server.Engines.Chat
{
public enum ChatCommand
{
/// <summary>
/// Add a channel to top list.
/// </summary>
AddChannel = 0x3E8,
/// <summary>
/// Remove channel from top list.
/// </summary>
RemoveChannel = 0x3E9,
/// <summary>
/// Queries for a new chat nickname.
/// </summary>
AskNewNickname = 0x3EB,
/// <summary>
/// Closes the chat window.
/// </summary>
CloseChatWindow = 0x3EC,
/// <summary>
/// Opens the chat window.
/// </summary>
OpenChatWindow = 0x3ED,
/// <summary>
/// Add a user to current channel.
/// </summary>
AddUserToChannel = 0x3EE,
/// <summary>
/// Remove a user from current channel.
/// </summary>
RemoveUserFromChannel = 0x3EF,
/// <summary>
/// Send a message putting generic conference name at top when player leaves a channel.
/// </summary>
LeaveChannel = 0x3F0,
/// <summary>
/// Send a message putting Channel name at top and telling player he joined the channel.
/// </summary>
JoinedChannel = 0x3F1
}
}

View file

@ -0,0 +1,321 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Accounting;
namespace Server.Engines.Chat
{
public class ChatUser
{
private Mobile m_Mobile;
private Channel m_Channel;
private bool m_Anonymous;
private bool m_IgnorePrivateMessage;
private List<ChatUser> m_Ignored, m_Ignoring;
public ChatUser( Mobile m )
{
m_Mobile = m;
m_Ignored = new List<ChatUser>();
m_Ignoring = new List<ChatUser>();
}
public Mobile Mobile
{
get
{
return m_Mobile;
}
}
public List<ChatUser> Ignored
{
get
{
return m_Ignored;
}
}
public List<ChatUser> Ignoring
{
get
{
return m_Ignoring;
}
}
public string Username
{
get
{
Account acct = m_Mobile.Account as Account;
if ( acct != null )
return acct.GetTag( "ChatName" );
return null;
}
set
{
Account acct = m_Mobile.Account as Account;
if ( acct != null )
acct.SetTag( "ChatName", value );
}
}
public Channel CurrentChannel
{
get
{
return m_Channel;
}
set
{
m_Channel = value;
}
}
public bool IsOnline
{
get
{
return ( m_Mobile.NetState != null );
}
}
public bool Anonymous
{
get
{
return m_Anonymous;
}
set
{
m_Anonymous = value;
}
}
public bool IgnorePrivateMessage
{
get
{
return m_IgnorePrivateMessage;
}
set
{
m_IgnorePrivateMessage = value;
}
}
public const char NormalColorCharacter = '0';
public const char ModeratorColorCharacter = '1';
public const char VoicedColorCharacter = '2';
public char GetColorCharacter()
{
if ( m_Channel != null && m_Channel.IsModerator( this ) )
return ModeratorColorCharacter;
if ( m_Channel != null && m_Channel.IsVoiced( this ) )
return VoicedColorCharacter;
return NormalColorCharacter;
}
public bool CheckOnline()
{
if ( IsOnline )
return true;
RemoveChatUser( this );
return false;
}
public void SendMessage( int number )
{
SendMessage( number, null, null );
}
public void SendMessage( int number, string param1 )
{
SendMessage( number, param1, null );
}
public void SendMessage( int number, string param1, string param2 )
{
if ( m_Mobile.NetState != null )
m_Mobile.Send( new ChatMessagePacket( m_Mobile, number, param1, param2 ) );
}
public void SendMessage( int number, Mobile from, string param1, string param2 )
{
if ( m_Mobile.NetState != null )
m_Mobile.Send( new ChatMessagePacket( from, number, param1, param2 ) );
}
public bool IsIgnored( ChatUser check )
{
return m_Ignored.Contains( check );
}
public bool IsModerator
{
get
{
return ( m_Channel != null && m_Channel.IsModerator( this ) );
}
}
public void AddIgnored( ChatUser user )
{
if ( IsIgnored( user ) )
{
SendMessage( 22, user.Username ); // You are already ignoring %1.
}
else
{
m_Ignored.Add( user );
user.m_Ignoring.Add( this );
SendMessage( 23, user.Username ); // You are now ignoring %1.
}
}
public void RemoveIgnored( ChatUser user )
{
if ( IsIgnored( user ) )
{
m_Ignored.Remove( user );
user.m_Ignoring.Remove( this );
SendMessage( 24, user.Username ); // You are no longer ignoring %1.
if ( m_Ignored.Count == 0 )
SendMessage( 26 ); // You are no longer ignoring anyone.
}
else
{
SendMessage( 25, user.Username ); // You are not ignoring %1.
}
}
private static List<ChatUser> m_Users = new List<ChatUser>();
private static Dictionary<Mobile, ChatUser> m_Table = new Dictionary<Mobile, ChatUser>();
public static ChatUser AddChatUser( Mobile from )
{
ChatUser user = GetChatUser( from );
if ( user == null )
{
user = new ChatUser( from );
m_Users.Add( user );
m_Table[from] = user;
Channel.SendChannelsTo( user );
List<Channel> list = Channel.Channels;
for ( int i = 0; i < list.Count; ++i )
{
Channel c = list[i];
if ( c.AddUser( user ) )
break;
}
//ChatSystem.SendCommandTo( user.m_Mobile, ChatCommand.AddUserToChannel, user.GetColorCharacter() + user.Username );
}
return user;
}
public static void RemoveChatUser( ChatUser user )
{
if ( user == null )
return;
for ( int i = 0; i < user.m_Ignoring.Count; ++i )
user.m_Ignoring[i].RemoveIgnored( user );
if ( m_Users.Contains( user ) )
{
ChatSystem.SendCommandTo( user.Mobile, ChatCommand.CloseChatWindow );
if ( user.m_Channel != null )
user.m_Channel.RemoveUser( user );
m_Users.Remove( user );
m_Table.Remove( user.m_Mobile );
}
}
public static void RemoveChatUser( Mobile from )
{
ChatUser user = GetChatUser( from );
RemoveChatUser( user );
}
public static ChatUser GetChatUser( Mobile from )
{
ChatUser c;
m_Table.TryGetValue( from, out c );
return c;
}
public static ChatUser GetChatUser( string username )
{
for ( int i = 0; i < m_Users.Count; ++i )
{
ChatUser user = m_Users[i];
if ( user.Username == username )
return user;
}
return null;
}
public static void GlobalSendCommand( ChatCommand command )
{
GlobalSendCommand( command, null, null, null );
}
public static void GlobalSendCommand( ChatCommand command, string param1 )
{
GlobalSendCommand( command, null, param1, null );
}
public static void GlobalSendCommand( ChatCommand command, string param1, string param2 )
{
GlobalSendCommand( command, null, param1, param2 );
}
public static void GlobalSendCommand( ChatCommand command, ChatUser initiator )
{
GlobalSendCommand( command, initiator, null, null );
}
public static void GlobalSendCommand( ChatCommand command, ChatUser initiator, string param1 )
{
GlobalSendCommand( command, initiator, param1, null );
}
public static void GlobalSendCommand( ChatCommand command, ChatUser initiator, string param1, string param2 )
{
for ( int i = 0; i < m_Users.Count; ++i )
{
ChatUser user = m_Users[i];
if ( user == initiator )
continue;
if ( user.CheckOnline() )
ChatSystem.SendCommandTo( user.m_Mobile, command, param1, param2 );
}
}
}
}

View file

@ -0,0 +1,20 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
namespace Server.Chat
{
public class ChatSystem
{
public static void Initialize()
{
EventSink.ChatRequest += new ChatRequestEventHandler( EventSink_ChatRequest );
}
private static void EventSink_ChatRequest( ChatRequestEventArgs e )
{
e.Mobile.SendMessage( "Chat is not currently supported." );
}
}
}

View file

@ -0,0 +1,30 @@
using System;
using Server;
using Server.Network;
namespace Server.Engines.Chat
{
public sealed class ChatMessagePacket : Packet
{
public ChatMessagePacket( Mobile who, int number, string param1, string param2 ) : base( 0xB2 )
{
if ( param1 == null )
param1 = String.Empty;
if ( param2 == null )
param2 = String.Empty;
EnsureCapacity( 13 + ((param1.Length + param2.Length) * 2) );
m_Stream.Write( (ushort) (number - 20) );
if ( who != null )
m_Stream.WriteAsciiFixed( who.Language, 4 );
else
m_Stream.Write( (int) 0 );
m_Stream.WriteBigUniNull( param1 );
m_Stream.WriteBigUniNull( param2 );
}
}
}

View file

@ -0,0 +1,56 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Engines.Craft
{
public enum CraftMarkOption
{
MarkItem,
DoNotMark,
PromptForMark
}
public class CraftContext
{
private List<CraftItem> m_Items;
private int m_LastResourceIndex;
private int m_LastGroupIndex;
private bool m_DoNotColor;
private CraftMarkOption m_MarkOption;
public List<CraftItem> Items { get { return m_Items; } }
public int LastResourceIndex{ get{ return m_LastResourceIndex; } set{ m_LastResourceIndex = value; } }
public int LastGroupIndex{ get{ return m_LastGroupIndex; } set{ m_LastGroupIndex = value; } }
public bool DoNotColor{ get{ return m_DoNotColor; } set{ m_DoNotColor = value; } }
public CraftMarkOption MarkOption{ get{ return m_MarkOption; } set{ m_MarkOption = value; } }
public CraftContext()
{
m_Items = new List<CraftItem>();
m_LastResourceIndex = -1;
m_LastGroupIndex = -1;
}
public CraftItem LastMade
{
get
{
if ( m_Items.Count > 0 )
return m_Items[0];
return null;
}
}
public void OnMade( CraftItem item )
{
m_Items.Remove( item );
if ( m_Items.Count == 10 )
m_Items.RemoveAt( 9 );
m_Items.Insert( 0, item );
}
}
}

View file

@ -0,0 +1,39 @@
using System;
namespace Server.Engines.Craft
{
public class CraftGroup
{
private CraftItemCol m_arCraftItem;
private string m_NameString;
private int m_NameNumber;
public CraftGroup( TextDefinition groupName )
{
m_NameNumber = groupName;
m_NameString = groupName;
m_arCraftItem = new CraftItemCol();
}
public void AddCraftItem( CraftItem craftItem )
{
m_arCraftItem.Add( craftItem );
}
public CraftItemCol CraftItems
{
get { return m_arCraftItem; }
}
public string NameString
{
get { return m_NameString; }
}
public int NameNumber
{
get { return m_NameNumber; }
}
}
}

View file

@ -0,0 +1,48 @@
using System;
namespace Server.Engines.Craft
{
public class CraftGroupCol : System.Collections.CollectionBase
{
public CraftGroupCol()
{
}
public int Add( CraftGroup craftGroup )
{
return List.Add( craftGroup );
}
public void Remove( int index )
{
if ( index > Count - 1 || index < 0 )
{
}
else
{
List.RemoveAt( index );
}
}
public CraftGroup GetAt( int index )
{
return ( CraftGroup ) List[index];
}
public int SearchFor( TextDefinition groupName )
{
for ( int i = 0; i < List.Count; i++ )
{
CraftGroup craftGroup = (CraftGroup)List[i];
int nameNumber = craftGroup.NameNumber;
string nameString = craftGroup.NameString;
if ( ( nameNumber != 0 && nameNumber == groupName.Number ) || ( nameString != null && nameString == groupName.String ) )
return i;
}
return -1;
}
}
}

View file

@ -0,0 +1,539 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Gumps;
using Server.Network;
using Server.Items;
using Server.Misc;
namespace Server.Engines.Craft
{
public class CraftGump : Gump
{
private Mobile m_From;
private CraftSystem m_CraftSystem;
private BaseTool m_Tool;
private CraftPage m_Page;
private const int LabelHue = 0x480;
private const int LabelColor = 0x7FFF;
private const int FontColor = 0xFFFFFF;
private enum CraftPage
{
None,
PickResource
}
/*public CraftGump( Mobile from, CraftSystem craftSystem, BaseTool tool ): this( from, craftSystem, -1, -1, tool, null )
{
}*/
public CraftGump( Mobile from, CraftSystem craftSystem, BaseTool tool, object notice ) : this( from, craftSystem, tool, notice, CraftPage.None )
{
}
private CraftGump( Mobile from, CraftSystem craftSystem, BaseTool tool, object notice, CraftPage page ) : base( 40, 40 )
{
m_From = from;
m_CraftSystem = craftSystem;
m_Tool = tool;
m_Page = page;
CraftContext context = craftSystem.GetContext( from );
from.CloseGump( typeof( CraftGump ) );
from.CloseGump( typeof( CraftGumpItem ) );
AddPage( 0 );
AddBackground( 0, 0, 530, 437, 5054 );
AddImageTiled( 10, 10, 510, 22, 2624 );
AddImageTiled( 10, 292, 150, 45, 2624 );
AddImageTiled( 165, 292, 355, 45, 2624 );
AddImageTiled( 10, 342, 510, 85, 2624 );
AddImageTiled( 10, 37, 200, 250, 2624 );
AddImageTiled( 215, 37, 305, 250, 2624 );
AddAlphaRegion( 10, 10, 510, 417 );
if ( craftSystem.GumpTitleNumber > 0 )
AddHtmlLocalized( 10, 12, 510, 20, craftSystem.GumpTitleNumber, LabelColor, false, false );
else
AddHtml( 10, 12, 510, 20, craftSystem.GumpTitleString, false, false );
AddHtmlLocalized( 10, 37, 200, 22, 1044010, LabelColor, false, false ); // <CENTER>CATEGORIES</CENTER>
AddHtmlLocalized( 215, 37, 305, 22, 1044011, LabelColor, false, false ); // <CENTER>SELECTIONS</CENTER>
AddHtmlLocalized( 10, 302, 150, 25, 1044012, LabelColor, false, false ); // <CENTER>NOTICES</CENTER>
AddButton( 15, 402, 4017, 4019, 0, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 50, 405, 150, 18, 1011441, LabelColor, false, false ); // EXIT
AddButton( 270, 402, 4005, 4007, GetButtonID( 6, 2 ), GumpButtonType.Reply, 0 );
AddHtmlLocalized( 305, 405, 150, 18, 1044013, LabelColor, false, false ); // MAKE LAST
// Mark option
if ( craftSystem.MarkOption )
{
AddButton( 270, 362, 4005, 4007, GetButtonID( 6, 6 ), GumpButtonType.Reply, 0 );
AddHtmlLocalized( 305, 365, 150, 18, 1044017 + (context == null ? 0 : (int)context.MarkOption), LabelColor, false, false ); // MARK ITEM
}
// ****************************************
// Resmelt option
if ( craftSystem.Resmelt )
{
AddButton( 15, 342, 4005, 4007, GetButtonID( 6, 1 ), GumpButtonType.Reply, 0 );
AddHtmlLocalized( 50, 345, 150, 18, 1044259, LabelColor, false, false ); // SMELT ITEM
}
// ****************************************
// Repair option
if ( craftSystem.Repair )
{
AddButton( 270, 342, 4005, 4007, GetButtonID( 6, 5 ), GumpButtonType.Reply, 0 );
AddHtmlLocalized( 305, 345, 150, 18, 1044260, LabelColor, false, false ); // REPAIR ITEM
}
// ****************************************
if ( notice is int && (int)notice > 0 )
AddHtmlLocalized( 170, 295, 350, 40, (int)notice, LabelColor, false, false );
else if ( notice is string )
AddHtml( 170, 295, 350, 40, String.Format( "<BASEFONT COLOR=#{0:X6}>{1}</BASEFONT>", FontColor, notice ), false, false );
// If the system has more than one resource
if ( craftSystem.CraftSubRes.Init )
{
string nameString = craftSystem.CraftSubRes.NameString;
int nameNumber = craftSystem.CraftSubRes.NameNumber;
int resIndex = ( context == null ? -1 : context.LastResourceIndex );
Type resourceType = craftSystem.CraftSubRes.ResType;
if ( resIndex > -1 )
{
CraftSubRes subResource = craftSystem.CraftSubRes.GetAt( resIndex );
nameString = subResource.NameString;
nameNumber = subResource.NameNumber;
resourceType = subResource.ItemType;
}
int resourceCount = 0;
if ( from.Backpack != null )
{
Item[] items = from.Backpack.FindItemsByType( resourceType, true );
for ( int i = 0; i < items.Length; ++i )
resourceCount += items[i].Amount;
}
AddButton( 15, 362, 4005, 4007, GetButtonID( 6, 0 ), GumpButtonType.Reply, 0 );
if ( nameNumber > 0 )
AddHtmlLocalized( 50, 365, 250, 18, nameNumber, resourceCount.ToString(), LabelColor, false, false );
else
AddLabel( 50, 362, LabelHue, String.Format( "{0} ({1} Available)", nameString, resourceCount ) );
}
// ****************************************
CreateGroupList();
if ( page == CraftPage.PickResource )
CreateResList( false, from );
else if ( context != null && context.LastGroupIndex > -1 )
CreateItemList( context.LastGroupIndex );
}
public void CreateResList( bool opt, Mobile from )
{
CraftSubResCol res = ( m_CraftSystem.CraftSubRes );
for ( int i = 0; i < res.Count; ++i )
{
int index = i % 10;
CraftSubRes subResource = res.GetAt( i );
if ( index == 0 )
{
if ( i > 0 )
AddButton( 485, 260, 4005, 4007, 0, GumpButtonType.Page, (i / 10) + 1 );
AddPage( (i / 10) + 1 );
if ( i > 0 )
AddButton( 455, 260, 4014, 4015, 0, GumpButtonType.Page, i / 10 );
CraftContext context = m_CraftSystem.GetContext( m_From );
AddButton( 220, 260, 4005, 4007, GetButtonID( 6, 4 ), GumpButtonType.Reply, 0 );
AddHtmlLocalized( 255, 263, 200, 18, (context == null || !context.DoNotColor) ? 1061591 : 1061590, LabelColor, false, false );
}
int resourceCount = 0;
if ( from.Backpack != null )
{
Item[] items = from.Backpack.FindItemsByType( subResource.ItemType, true );
for ( int j = 0; j < items.Length; ++j )
resourceCount += items[j].Amount;
}
AddButton( 220, 60 + (index * 20), 4005, 4007, GetButtonID( 5, i ), GumpButtonType.Reply, 0 );
if ( subResource.NameNumber > 0 )
AddHtmlLocalized( 255, 63 + (index * 20), 250, 18, subResource.NameNumber, resourceCount.ToString(), LabelColor, false, false );
else
AddLabel( 255, 60 + ( index * 20 ), LabelHue, String.Format( "{0} ({1})", subResource.NameString, resourceCount ) );
}
}
public void CreateMakeLastList()
{
CraftContext context = m_CraftSystem.GetContext( m_From );
if ( context == null )
return;
List<CraftItem> items = context.Items;
if ( items.Count > 0 )
{
for ( int i = 0; i < items.Count; ++i )
{
int index = i % 10;
CraftItem craftItem = items[i];
if ( index == 0 )
{
if ( i > 0 )
{
AddButton( 370, 260, 4005, 4007, 0, GumpButtonType.Page, (i / 10) + 1 );
AddHtmlLocalized( 405, 263, 100, 18, 1044045, LabelColor, false, false ); // NEXT PAGE
}
AddPage( (i / 10) + 1 );
if ( i > 0 )
{
AddButton( 220, 260, 4014, 4015, 0, GumpButtonType.Page, i / 10 );
AddHtmlLocalized( 255, 263, 100, 18, 1044044, LabelColor, false, false ); // PREV PAGE
}
}
AddButton( 220, 60 + (index * 20), 4005, 4007, GetButtonID( 3, i ), GumpButtonType.Reply, 0 );
if ( craftItem.NameNumber > 0 )
AddHtmlLocalized( 255, 63 + (index * 20), 220, 18, craftItem.NameNumber, LabelColor, false, false );
else
AddLabel( 255, 60 + (index * 20), LabelHue, craftItem.NameString );
AddButton( 480, 60 + (index * 20), 4011, 4012, GetButtonID( 4, i ), GumpButtonType.Reply, 0 );
}
}
else
{
// NOTE: This is not as OSI; it is an intentional difference
AddHtmlLocalized( 230, 62, 200, 22, 1044165, LabelColor, false, false ); // You haven't made anything yet.
}
}
public void CreateItemList( int selectedGroup )
{
if ( selectedGroup == 501 ) // 501 : Last 10
{
CreateMakeLastList();
return;
}
CraftGroupCol craftGroupCol = m_CraftSystem.CraftGroups;
CraftGroup craftGroup = craftGroupCol.GetAt( selectedGroup );
CraftItemCol craftItemCol = craftGroup.CraftItems;
for ( int i = 0; i < craftItemCol.Count; ++i )
{
int index = i % 10;
CraftItem craftItem = craftItemCol.GetAt( i );
if ( index == 0 )
{
if ( i > 0 )
{
AddButton( 370, 260, 4005, 4007, 0, GumpButtonType.Page, (i / 10) + 1 );
AddHtmlLocalized( 405, 263, 100, 18, 1044045, LabelColor, false, false ); // NEXT PAGE
}
AddPage( (i / 10) + 1 );
if ( i > 0 )
{
AddButton( 220, 260, 4014, 4015, 0, GumpButtonType.Page, i / 10 );
AddHtmlLocalized( 255, 263, 100, 18, 1044044, LabelColor, false, false ); // PREV PAGE
}
}
AddButton( 220, 60 + (index * 20), 4005, 4007, GetButtonID( 1, i ), GumpButtonType.Reply, 0 );
if ( craftItem.NameNumber > 0 )
AddHtmlLocalized( 255, 63 + (index * 20), 220, 18, craftItem.NameNumber, LabelColor, false, false );
else
AddLabel( 255, 60 + (index * 20), LabelHue, craftItem.NameString );
AddButton( 480, 60 + (index * 20), 4011, 4012, GetButtonID( 2, i ), GumpButtonType.Reply, 0 );
}
}
public int CreateGroupList()
{
CraftGroupCol craftGroupCol = m_CraftSystem.CraftGroups;
AddButton( 15, 60, 4005, 4007, GetButtonID( 6, 3 ), GumpButtonType.Reply, 0 );
AddHtmlLocalized( 50, 63, 150, 18, 1044014, LabelColor, false, false ); // LAST TEN
for ( int i = 0; i < craftGroupCol.Count; i++ )
{
CraftGroup craftGroup = craftGroupCol.GetAt( i );
AddButton( 15, 80 + (i * 20), 4005, 4007, GetButtonID( 0, i ), GumpButtonType.Reply, 0 );
if ( craftGroup.NameNumber > 0 )
AddHtmlLocalized( 50, 83 + (i * 20), 150, 18, craftGroup.NameNumber, LabelColor, false, false );
else
AddLabel( 50, 80 + (i * 20), LabelHue, craftGroup.NameString );
}
return craftGroupCol.Count;
}
public static int GetButtonID( int type, int index )
{
return 1 + type + (index * 7);
}
public void CraftItem( CraftItem item )
{
int num = m_CraftSystem.CanCraft( m_From, m_Tool, item.ItemType );
if ( num > 0 )
{
m_From.SendGump( new CraftGump( m_From, m_CraftSystem, m_Tool, num ) );
}
else
{
Type type = null;
CraftContext context = m_CraftSystem.GetContext( m_From );
if ( context != null )
{
CraftSubResCol res = ( m_CraftSystem.CraftSubRes );
int resIndex = ( context.LastResourceIndex );
if ( resIndex >= 0 && resIndex < res.Count )
type = res.GetAt( resIndex ).ItemType;
}
m_CraftSystem.CreateItem( m_From, item.ItemType, type, m_Tool, item );
}
}
public override void OnResponse( NetState sender, RelayInfo info )
{
if ( info.ButtonID <= 0 )
return; // Canceled
int buttonID = info.ButtonID - 1;
int type = buttonID % 7;
int index = buttonID / 7;
CraftSystem system = m_CraftSystem;
CraftGroupCol groups = system.CraftGroups;
CraftContext context = system.GetContext( m_From );
switch ( type )
{
case 0: // Show group
{
if ( context == null )
break;
if ( index >= 0 && index < groups.Count )
{
context.LastGroupIndex = index;
m_From.SendGump( new CraftGump( m_From, system, m_Tool, null ) );
}
break;
}
case 1: // Create item
{
if ( context == null )
break;
int groupIndex = context.LastGroupIndex;
if ( groupIndex >= 0 && groupIndex < groups.Count )
{
CraftGroup group = groups.GetAt( groupIndex );
if ( index >= 0 && index < group.CraftItems.Count )
CraftItem( group.CraftItems.GetAt( index ) );
}
break;
}
case 2: // Item details
{
if ( context == null )
break;
int groupIndex = context.LastGroupIndex;
if ( groupIndex >= 0 && groupIndex < groups.Count )
{
CraftGroup group = groups.GetAt( groupIndex );
if ( index >= 0 && index < group.CraftItems.Count )
m_From.SendGump( new CraftGumpItem( m_From, system, group.CraftItems.GetAt( index ), m_Tool ) );
}
break;
}
case 3: // Create item (last 10)
{
if ( context == null )
break;
List<CraftItem> lastTen = context.Items;
if ( index >= 0 && index < lastTen.Count )
CraftItem( lastTen[index] );
break;
}
case 4: // Item details (last 10)
{
if ( context == null )
break;
List<CraftItem> lastTen = context.Items;
if ( index >= 0 && index < lastTen.Count )
m_From.SendGump( new CraftGumpItem( m_From, system, lastTen[index], m_Tool ) );
break;
}
case 5: // Resource selected
{
if ( m_Page == CraftPage.PickResource && index >= 0 && index < system.CraftSubRes.Count )
{
int groupIndex = ( context == null ? -1 : context.LastGroupIndex );
CraftSubRes res = system.CraftSubRes.GetAt( index );
if ( SkillCheck.TradeSkill( m_From, system.MainSkill, false ) < res.RequiredSkill )
{
m_From.SendGump( new CraftGump( m_From, system, m_Tool, res.Message ) );
}
else
{
if ( context != null )
context.LastResourceIndex = index;
m_From.SendGump( new CraftGump( m_From, system, m_Tool, null ) );
}
}
break;
}
case 6: // Misc. buttons
{
switch ( index )
{
case 0: // Resource selection
{
if ( system.CraftSubRes.Init )
m_From.SendGump( new CraftGump( m_From, system, m_Tool, null, CraftPage.PickResource ) );
break;
}
case 1: // Smelt item
{
if ( system.Resmelt )
Resmelt.Do( m_From, system, m_Tool );
break;
}
case 2: // Make last
{
if ( context == null )
break;
CraftItem item = context.LastMade;
if ( item != null )
CraftItem( item );
else
m_From.SendGump( new CraftGump( m_From, m_CraftSystem, m_Tool, 1044165, m_Page ) ); // You haven't made anything yet.
break;
}
case 3: // Last 10
{
if ( context == null )
break;
context.LastGroupIndex = 501;
m_From.SendGump( new CraftGump( m_From, system, m_Tool, null ) );
break;
}
case 4: // Toggle use resource hue
{
if ( context == null )
break;
context.DoNotColor = !context.DoNotColor;
m_From.SendGump( new CraftGump( m_From, m_CraftSystem, m_Tool, null, m_Page ) );
break;
}
case 5: // Repair item
{
if ( system.Repair )
Repair.Do( m_From, system, m_Tool );
break;
}
case 6: // Toggle mark option
{
if ( context == null || !system.MarkOption )
break;
switch ( context.MarkOption )
{
case CraftMarkOption.MarkItem: context.MarkOption = CraftMarkOption.DoNotMark; break;
case CraftMarkOption.DoNotMark: context.MarkOption = CraftMarkOption.PromptForMark; break;
case CraftMarkOption.PromptForMark: context.MarkOption = CraftMarkOption.MarkItem; break;
}
m_From.SendGump( new CraftGump( m_From, m_CraftSystem, m_Tool, null, m_Page ) );
break;
}
}
break;
}
}
}
}
}

View file

@ -0,0 +1,244 @@
using System;
using Server.Gumps;
using Server.Network;
using Server.Items;
using Server.Misc;
using Server.Mobiles;
namespace Server.Engines.Craft
{
public class CraftGumpItem : Gump
{
private Mobile m_From;
private CraftSystem m_CraftSystem;
private CraftItem m_CraftItem;
private BaseTool m_Tool;
private const int LabelHue = 0x480; // 0x384
private const int RedLabelHue = 0x20;
private const int LabelColor = 0x7FFF;
private const int RedLabelColor = 0x6400;
private const int GreyLabelColor = 0x3DEF;
private int m_OtherCount;
public CraftGumpItem( Mobile from, CraftSystem craftSystem, CraftItem craftItem, BaseTool tool ) : base( 40, 40 )
{
m_From = from;
m_CraftSystem = craftSystem;
m_CraftItem = craftItem;
m_Tool = tool;
from.CloseGump( typeof( CraftGump ) );
from.CloseGump( typeof( CraftGumpItem ) );
AddPage( 0 );
AddBackground( 0, 0, 530, 417, 5054 );
AddImageTiled( 10, 10, 510, 22, 2624 );
AddImageTiled( 10, 37, 150, 148, 2624 );
AddImageTiled( 165, 37, 355, 90, 2624 );
AddImageTiled( 10, 190, 155, 22, 2624 );
AddImageTiled( 10, 217, 150, 53, 2624 );
AddImageTiled( 165, 132, 355, 80, 2624 );
AddImageTiled( 10, 275, 155, 22, 2624 );
AddImageTiled( 10, 302, 150, 53, 2624 );
AddImageTiled( 165, 217, 355, 80, 2624 );
AddImageTiled( 10, 360, 155, 22, 2624 );
AddImageTiled( 165, 302, 355, 80, 2624 );
AddImageTiled( 10, 387, 510, 22, 2624 );
AddAlphaRegion( 10, 10, 510, 399 );
AddHtmlLocalized( 170, 40, 150, 20, 1044053, LabelColor, false, false ); // ITEM
AddHtmlLocalized( 10, 192, 150, 22, 1044054, LabelColor, false, false ); // <CENTER>SKILLS</CENTER>
AddHtmlLocalized( 10, 277, 150, 22, 1044055, LabelColor, false, false ); // <CENTER>MATERIALS</CENTER>
AddHtmlLocalized( 10, 362, 150, 22, 1044056, LabelColor, false, false ); // <CENTER>OTHER</CENTER>
if ( craftSystem.GumpTitleNumber > 0 )
AddHtmlLocalized( 10, 12, 510, 20, craftSystem.GumpTitleNumber, LabelColor, false, false );
else
AddHtml( 10, 12, 510, 20, craftSystem.GumpTitleString, false, false );
AddButton( 15, 387, 4014, 4016, 0, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 50, 390, 150, 18, 1044150, LabelColor, false, false ); // BACK
AddButton( 270, 387, 4005, 4007, 1, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 305, 390, 150, 18, 1044151, LabelColor, false, false ); // MAKE NOW
if ( craftItem.NameNumber > 0 )
AddHtmlLocalized( 330, 40, 180, 18, craftItem.NameNumber, LabelColor, false, false );
else
AddLabel( 330, 40, LabelHue, craftItem.NameString );
if ( craftItem.UseAllRes )
AddHtmlLocalized( 170, 302 + (m_OtherCount++ * 20), 310, 18, 1048176, LabelColor, false, false ); // Makes as many as possible at once
DrawItem();
DrawSkill();
DrawResource();
}
private bool m_ShowExceptionalChance;
public void DrawItem()
{
Type type = m_CraftItem.ItemType;
AddItem( 20, 50, CraftItem.ItemIDOf( type ) );
if ( m_CraftItem.IsMarkable( type ) )
{
AddHtmlLocalized( 170, 302 + (m_OtherCount++ * 20), 310, 18, 1044059, LabelColor, false, false ); // This item may hold its maker's mark
m_ShowExceptionalChance = true;
}
}
public void DrawSkill()
{
for ( int i = 0; i < m_CraftItem.Skills.Count; i++ )
{
CraftSkill skill = m_CraftItem.Skills.GetAt( i );
double minSkill = skill.MinSkill, maxSkill = skill.MaxSkill;
if ( minSkill < 0 )
minSkill = 0;
AddLabel( 170, 132 + (i * 20), LabelHue, SkillCheck.TradeName( skill.SkillToMake ) );
AddLabel( 430, 132 + (i * 20), LabelHue, String.Format( "{0:F1}", minSkill ) );
}
CraftSubResCol res = ( m_CraftSystem.CraftSubRes );
int resIndex = -1;
CraftContext context = m_CraftSystem.GetContext( m_From );
if ( context != null )
resIndex = ( context.LastResourceIndex );
bool allRequiredSkills = true;
double chance = m_CraftItem.GetSuccessChance( m_From, resIndex > -1 ? res.GetAt( resIndex ).ItemType : null, m_CraftSystem, ref allRequiredSkills );
double excepChance = m_CraftItem.GetExceptionalChance( m_CraftSystem, chance, m_From );
if ( chance < 0.0 )
chance = 0.0;
else if ( chance > 1.0 )
chance = 1.0;
AddHtmlLocalized( 170, 80, 250, 18, 1044057, LabelColor, false, false ); // Success Chance:
AddLabel( 430, 80, LabelHue, String.Format( "{0:F1}%", chance * 100 ) );
if ( m_ShowExceptionalChance )
{
if( excepChance < 0.0 )
excepChance = 0.0;
else if( excepChance > 1.0 )
excepChance = 1.0;
AddHtmlLocalized( 170, 100, 250, 18, 1044058, 32767, false, false ); // Exceptional Chance:
AddLabel( 430, 100, LabelHue, String.Format( "{0:F1}%", excepChance * 100 ) );
}
}
private static Type typeofBlankScroll = typeof( BlankScroll );
private static Type typeofSpellScroll = typeof( SpellScroll );
public void DrawResource()
{
bool retainedColor = false;
CraftContext context = m_CraftSystem.GetContext( m_From );
CraftSubResCol res = ( m_CraftSystem.CraftSubRes );
int resIndex = -1;
if ( context != null )
resIndex = ( context.LastResourceIndex );
bool cropScroll = ( m_CraftItem.Resources.Count > 1 )
&& m_CraftItem.Resources.GetAt( m_CraftItem.Resources.Count - 1 ).ItemType == typeofBlankScroll
&& typeofSpellScroll.IsAssignableFrom( m_CraftItem.ItemType );
for ( int i = 0; i < m_CraftItem.Resources.Count - (cropScroll ? 1 : 0) && i < 4; i++ )
{
Type type;
string nameString;
int nameNumber;
CraftRes craftResource = m_CraftItem.Resources.GetAt( i );
type = craftResource.ItemType;
nameString = craftResource.NameString;
nameNumber = craftResource.NameNumber;
// Resource Mutation
if ( type == res.ResType && resIndex > -1 )
{
CraftSubRes subResource = res.GetAt( resIndex );
type = subResource.ItemType;
nameString = subResource.NameString;
nameNumber = subResource.GenericNameNumber;
if ( nameNumber <= 0 )
nameNumber = subResource.NameNumber;
}
// ******************
if ( !retainedColor && m_CraftItem.RetainsColorFrom( m_CraftSystem, type ) )
{
retainedColor = true;
AddHtmlLocalized( 170, 302 + (m_OtherCount++ * 20), 310, 18, 1044152, LabelColor, false, false ); // * The item retains the color of this material
AddLabel( 500, 219 + (i * 20), LabelHue, "*" );
}
if ( nameNumber > 0 )
AddHtmlLocalized( 170, 219 + (i * 20), 310, 18, nameNumber, LabelColor, false, false );
else
AddLabel( 170, 219 + (i * 20), LabelHue, nameString );
AddLabel( 430, 219 + (i * 20), LabelHue, craftResource.Amount.ToString() );
}
if ( cropScroll )
AddHtmlLocalized( 170, 302 + (m_OtherCount++ * 20), 360, 18, 1044379, LabelColor, false, false ); // Inscribing scrolls also requires a blank scroll and mana.
}
public override void OnResponse( NetState sender, RelayInfo info )
{
// Back Button
if ( info.ButtonID == 0 )
{
CraftGump craftGump = new CraftGump( m_From, m_CraftSystem, m_Tool, null );
m_From.SendGump( craftGump );
}
else // Make Button
{
int num = m_CraftSystem.CanCraft( m_From, m_Tool, m_CraftItem.ItemType );
if ( num > 0 )
{
m_From.SendGump( new CraftGump( m_From, m_CraftSystem, m_Tool, num ) );
}
else
{
Type type = null;
CraftContext context = m_CraftSystem.GetContext( m_From );
if ( context != null )
{
CraftSubResCol res = ( m_CraftSystem.CraftSubRes );
int resIndex = ( context.LastResourceIndex );
if ( resIndex > -1 )
type = res.GetAt( resIndex ).ItemType;
}
m_CraftSystem.CreateItem( m_From, m_CraftItem.ItemType, type, m_Tool, m_CraftItem );
}
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,58 @@
using System;
namespace Server.Engines.Craft
{
public class CraftItemCol : System.Collections.CollectionBase
{
public CraftItemCol()
{
}
public int Add( CraftItem craftItem )
{
return List.Add( craftItem );
}
public void Remove( int index )
{
if ( index > Count - 1 || index < 0 )
{
}
else
{
List.RemoveAt( index );
}
}
public CraftItem GetAt( int index )
{
return ( CraftItem ) List[index];
}
public CraftItem SearchForSubclass( Type type )
{
for ( int i = 0; i < List.Count; i++ )
{
CraftItem craftItem = ( CraftItem )List[i];
if ( craftItem.ItemType == type || type.IsSubclassOf( craftItem.ItemType ) )
return craftItem;
}
return null;
}
public CraftItem SearchFor( Type type )
{
for ( int i = 0; i < List.Count; i++ )
{
CraftItem craftItem = ( CraftItem )List[i];
if ( craftItem.ItemType == type )
{
return craftItem;
}
}
return null;
}
}
}

View file

@ -0,0 +1,18 @@
using System;
using Server;
namespace Server.Engines.Craft
{
[AttributeUsage( AttributeTargets.Class )]
public class CraftItemIDAttribute : Attribute
{
private int m_ItemID;
public int ItemID{ get{ return m_ItemID; } }
public CraftItemIDAttribute( int itemID )
{
m_ItemID = itemID;
}
}
}

View file

@ -0,0 +1,71 @@
using System;
namespace Server.Engines.Craft
{
public class CraftRes
{
private Type m_Type;
private int m_Amount;
private string m_MessageString;
private int m_MessageNumber;
private string m_NameString;
private int m_NameNumber;
public CraftRes( Type type, int amount )
{
m_Type = type;
m_Amount = amount;
}
public CraftRes( Type type, TextDefinition name, int amount, TextDefinition message ): this ( type, amount )
{
m_NameNumber = name;
m_MessageNumber = message;
m_NameString = name;
m_MessageString = message;
}
public void SendMessage( Mobile from )
{
if ( m_MessageNumber > 0 )
from.SendLocalizedMessage( m_MessageNumber );
else if ( !String.IsNullOrEmpty( m_MessageString ) )
from.SendMessage( m_MessageString );
else
from.SendLocalizedMessage( 502925 ); // You don't have the resources required to make that item.
}
public Type ItemType
{
get { return m_Type; }
}
public string MessageString
{
get { return m_MessageString; }
}
public int MessageNumber
{
get { return m_MessageNumber; }
}
public string NameString
{
get { return m_NameString; }
}
public int NameNumber
{
get { return m_NameNumber; }
}
public int Amount
{
get { return m_Amount; }
}
}
}

View file

@ -0,0 +1,32 @@
using System;
namespace Server.Engines.Craft
{
public class CraftResCol : System.Collections.CollectionBase
{
public CraftResCol()
{
}
public void Add( CraftRes craftRes )
{
List.Add( craftRes );
}
public void Remove( int index )
{
if ( index > Count - 1 || index < 0 )
{
}
else
{
List.RemoveAt( index );
}
}
public CraftRes GetAt( int index )
{
return ( CraftRes ) List[index];
}
}
}

View file

@ -0,0 +1,34 @@
using System;
using Server.Misc;
namespace Server.Engines.Craft
{
public class CraftSkill
{
private Trades m_SkillToMake;
private double m_MinSkill;
private double m_MaxSkill;
public CraftSkill( Trades skillToMake, double minSkill, double maxSkill )
{
m_SkillToMake = skillToMake;
m_MinSkill = minSkill;
m_MaxSkill = maxSkill;
}
public Trades SkillToMake
{
get { return m_SkillToMake; }
}
public double MinSkill
{
get { return m_MinSkill; }
}
public double MaxSkill
{
get { return m_MaxSkill; }
}
}
}

View file

@ -0,0 +1,32 @@
using System;
namespace Server.Engines.Craft
{
public class CraftSkillCol : System.Collections.CollectionBase
{
public CraftSkillCol()
{
}
public void Add( CraftSkill craftSkill )
{
List.Add( craftSkill );
}
public void Remove( int index )
{
if ( index > Count - 1 || index < 0 )
{
}
else
{
List.RemoveAt( index );
}
}
public CraftSkill GetAt( int index )
{
return ( CraftSkill ) List[index];
}
}
}

View file

@ -0,0 +1,58 @@
using System;
namespace Server.Engines.Craft
{
public class CraftSubRes
{
private Type m_Type;
private double m_ReqSkill;
private string m_NameString;
private int m_NameNumber;
private int m_GenericNameNumber;
private object m_Message;
public CraftSubRes( Type type, TextDefinition name, double reqSkill, object message ) : this( type, name, reqSkill, 0, message )
{
}
public CraftSubRes( Type type, TextDefinition name, double reqSkill, int genericNameNumber, object message )
{
m_Type = type;
m_NameNumber = name;
m_NameString = name;
m_ReqSkill = reqSkill;
m_GenericNameNumber = genericNameNumber;
m_Message = message;
}
public Type ItemType
{
get { return m_Type; }
}
public string NameString
{
get { return m_NameString; }
}
public int NameNumber
{
get { return m_NameNumber; }
}
public int GenericNameNumber
{
get { return m_GenericNameNumber; }
}
public object Message
{
get { return m_Message; }
}
public double RequiredSkill
{
get { return m_ReqSkill; }
}
}
}

View file

@ -0,0 +1,75 @@
using System;
namespace Server.Engines.Craft
{
public class CraftSubResCol : System.Collections.CollectionBase
{
private Type m_Type;
private string m_NameString;
private int m_NameNumber;
private bool m_Init;
public bool Init
{
get { return m_Init; }
set { m_Init = value; }
}
public Type ResType
{
get { return m_Type; }
set { m_Type = value; }
}
public string NameString
{
get { return m_NameString; }
set { m_NameString = value; }
}
public int NameNumber
{
get { return m_NameNumber; }
set { m_NameNumber = value; }
}
public CraftSubResCol()
{
m_Init = false;
}
public void Add( CraftSubRes craftSubRes )
{
List.Add( craftSubRes );
}
public void Remove( int index )
{
if ( index > Count - 1 || index < 0 )
{
}
else
{
List.RemoveAt( index );
}
}
public CraftSubRes GetAt( int index )
{
return ( CraftSubRes ) List[index];
}
public CraftSubRes SearchFor( Type type )
{
for ( int i = 0; i < List.Count; i++ )
{
CraftSubRes craftSubRes = ( CraftSubRes )List[i];
if ( craftSubRes.ItemType == type )
{
return craftSubRes;
}
}
return null;
}
}
}

View file

@ -0,0 +1,283 @@
using System;
using System.Collections.Generic;
using Server.Items;
using Server.Misc;
namespace Server.Engines.Craft
{
public enum CraftECA
{
ChanceMinusSixty,
FiftyPercentChanceMinusTenPercent,
ChanceMinusSixtyToFourtyFive
}
public abstract class CraftSystem
{
private int m_MinCraftEffect;
private int m_MaxCraftEffect;
private double m_Delay;
private bool m_Resmelt;
private bool m_Repair;
private bool m_MarkOption;
private CraftItemCol m_CraftItems;
private CraftGroupCol m_CraftGroups;
private CraftSubResCol m_CraftSubRes;
public int MinCraftEffect { get { return m_MinCraftEffect; } }
public int MaxCraftEffect { get { return m_MaxCraftEffect; } }
public double Delay { get { return m_Delay; } }
public CraftItemCol CraftItems{ get { return m_CraftItems; } }
public CraftGroupCol CraftGroups{ get { return m_CraftGroups; } }
public CraftSubResCol CraftSubRes{ get { return m_CraftSubRes; } }
public abstract Trades MainSkill{ get; }
public virtual int GumpTitleNumber{ get{ return 0; } }
public virtual string GumpTitleString{ get{ return ""; } }
public virtual CraftECA ECA{ get{ return CraftECA.ChanceMinusSixty; } }
private Dictionary<Mobile, CraftContext> m_ContextTable = new Dictionary<Mobile, CraftContext>();
public abstract double GetChanceAtMin( CraftItem item );
public virtual bool RetainsColorFrom( CraftItem item, Type type )
{
return false;
}
public CraftContext GetContext( Mobile m )
{
if ( m == null )
return null;
if ( m.Deleted )
{
m_ContextTable.Remove( m );
return null;
}
CraftContext c = null;
m_ContextTable.TryGetValue( m, out c );
if ( c == null )
m_ContextTable[m] = c = new CraftContext();
return c;
}
public void OnMade( Mobile m, CraftItem item )
{
CraftContext c = GetContext( m );
if ( c != null )
c.OnMade( item );
}
public bool Resmelt
{
get { return m_Resmelt; }
set { m_Resmelt = value; }
}
public bool Repair
{
get{ return m_Repair; }
set{ m_Repair = value; }
}
public bool MarkOption
{
get{ return m_MarkOption; }
set{ m_MarkOption = value; }
}
public CraftSystem( int minCraftEffect, int maxCraftEffect, double delay )
{
m_MinCraftEffect = minCraftEffect;
m_MaxCraftEffect = maxCraftEffect;
m_Delay = delay;
m_CraftItems = new CraftItemCol();
m_CraftGroups = new CraftGroupCol();
m_CraftSubRes = new CraftSubResCol();
InitCraftList();
}
public virtual bool ConsumeOnFailure( Mobile from, Type resourceType, CraftItem craftItem )
{
return true;
}
public void CreateItem( Mobile from, Type type, Type typeRes, BaseTool tool, CraftItem realCraftItem )
{
// Verify if the type is in the list of the craftable item
CraftItem craftItem = m_CraftItems.SearchFor( type );
if ( craftItem != null )
{
// The item is in the list, try to create it
// Test code: items like sextant parts can be crafted either directly from ingots, or from different parts
realCraftItem.Craft( from, this, typeRes, tool );
//craftItem.Craft( from, this, typeRes, tool );
}
}
public int AddCraft( Type typeItem, TextDefinition group, TextDefinition name, double minSkill, double maxSkill, Type typeRes, TextDefinition nameRes, int amount )
{
return AddCraft( typeItem, group, name, MainSkill, minSkill, maxSkill, typeRes, nameRes, amount, "" );
}
public int AddCraft( Type typeItem, TextDefinition group, TextDefinition name, double minSkill, double maxSkill, Type typeRes, TextDefinition nameRes, int amount, TextDefinition message )
{
return AddCraft( typeItem, group, name, MainSkill, minSkill, maxSkill, typeRes, nameRes, amount, message );
}
public int AddCraft( Type typeItem, TextDefinition group, TextDefinition name, Trades skillToMake, double minSkill, double maxSkill, Type typeRes, TextDefinition nameRes, int amount )
{
return AddCraft( typeItem, group, name, skillToMake, minSkill, maxSkill, typeRes, nameRes, amount, "" );
}
public int AddCraft( Type typeItem, TextDefinition group, TextDefinition name, Trades skillToMake, double minSkill, double maxSkill, Type typeRes, TextDefinition nameRes, int amount, TextDefinition message )
{
CraftItem craftItem = new CraftItem( typeItem, group, name );
craftItem.AddRes( typeRes, nameRes, amount, message );
craftItem.AddSkill( skillToMake, minSkill, maxSkill );
DoGroup( group, craftItem );
return m_CraftItems.Add( craftItem );
}
private void DoGroup( TextDefinition groupName, CraftItem craftItem )
{
int index = m_CraftGroups.SearchFor( groupName );
if ( index == -1)
{
CraftGroup craftGroup = new CraftGroup( groupName );
craftGroup.AddCraftItem( craftItem );
m_CraftGroups.Add( craftGroup );
}
else
{
m_CraftGroups.GetAt( index ).AddCraftItem( craftItem );
}
}
public void SetManaReq( int index, int mana )
{
CraftItem craftItem = m_CraftItems.GetAt( index );
craftItem.Mana = mana;
}
public void SetStamReq( int index, int stam )
{
CraftItem craftItem = m_CraftItems.GetAt( index );
craftItem.Stam = stam;
}
public void SetHitsReq( int index, int hits )
{
CraftItem craftItem = m_CraftItems.GetAt( index );
craftItem.Hits = hits;
}
public void SetUseAllRes( int index, bool useAll )
{
CraftItem craftItem = m_CraftItems.GetAt( index );
craftItem.UseAllRes = useAll;
}
public void SetNeedHeat( int index, bool needHeat )
{
CraftItem craftItem = m_CraftItems.GetAt( index );
craftItem.NeedHeat = needHeat;
}
public void SetNeedOven( int index, bool needOven )
{
CraftItem craftItem = m_CraftItems.GetAt( index );
craftItem.NeedOven = needOven;
}
public void SetNeedMill( int index, bool needMill )
{
CraftItem craftItem = m_CraftItems.GetAt( index );
craftItem.NeedMill = needMill;
}
public void SetNeededExpansion( int index, Expansion expansion )
{
CraftItem craftItem = m_CraftItems.GetAt( index );
craftItem.RequiredExpansion = expansion;
}
public void AddRes( int index, Type type, TextDefinition name, int amount )
{
AddRes( index, type, name, amount, "" );
}
public void AddRes( int index, Type type, TextDefinition name, int amount, TextDefinition message )
{
CraftItem craftItem = m_CraftItems.GetAt( index );
craftItem.AddRes( type, name, amount, message );
}
public void AddSkill( int index, Trades skillToMake, double minSkill, double maxSkill )
{
CraftItem craftItem = m_CraftItems.GetAt(index);
craftItem.AddSkill(skillToMake, minSkill, maxSkill);
}
public void ForceNonExceptional( int index )
{
CraftItem craftItem = m_CraftItems.GetAt( index );
craftItem.ForceNonExceptional = true;
}
public void SetSubRes( Type type, string name )
{
m_CraftSubRes.ResType = type;
m_CraftSubRes.NameString = name;
m_CraftSubRes.Init = true;
}
public void SetSubRes( Type type, int name )
{
m_CraftSubRes.ResType = type;
m_CraftSubRes.NameNumber = name;
m_CraftSubRes.Init = true;
}
public void AddSubRes( Type type, int name, double reqSkill, object message )
{
CraftSubRes craftSubRes = new CraftSubRes( type, name, reqSkill, message );
m_CraftSubRes.Add( craftSubRes );
}
public void AddSubRes( Type type, int name, double reqSkill, int genericName, object message )
{
CraftSubRes craftSubRes = new CraftSubRes( type, name, reqSkill, genericName, message );
m_CraftSubRes.Add( craftSubRes );
}
public void AddSubRes( Type type, string name, double reqSkill, object message )
{
CraftSubRes craftSubRes = new CraftSubRes( type, name, reqSkill, message );
m_CraftSubRes.Add( craftSubRes );
}
public abstract void InitCraftList();
public abstract void PlayCraftEffect( Mobile from );
public abstract int PlayEndingEffect( Mobile from, bool failed, bool lostMaterial, bool toolBroken, int quality, bool makersMark, CraftItem item );
public abstract int CanCraft( Mobile from, BaseTool tool, Type itemType );
}
}

View file

@ -0,0 +1,36 @@
using System;
using Server;
using Server.Items;
namespace Server.Engines.Craft
{
public abstract class CustomCraft
{
private Mobile m_From;
private CraftItem m_CraftItem;
private CraftSystem m_CraftSystem;
private Type m_TypeRes;
private BaseTool m_Tool;
private int m_Quality;
public Mobile From{ get{ return m_From; } }
public CraftItem CraftItem{ get{ return m_CraftItem; } }
public CraftSystem CraftSystem{ get{ return m_CraftSystem; } }
public Type TypeRes{ get{ return m_TypeRes; } }
public BaseTool Tool{ get{ return m_Tool; } }
public int Quality{ get{ return m_Quality; } }
public CustomCraft( Mobile from, CraftItem craftItem, CraftSystem craftSystem, Type typeRes, BaseTool tool, int quality )
{
m_From = from;
m_CraftItem = craftItem;
m_CraftSystem = craftSystem;
m_TypeRes = typeRes;
m_Tool = tool;
m_Quality = quality;
}
public abstract void EndCraftAction();
public abstract Item CompleteCraft( out int message );
}
}

View file

@ -0,0 +1,54 @@
using System;
using Server;
using Server.Gumps;
using Server.Items;
namespace Server.Engines.Craft
{
public class QueryMakersMarkGump : Gump
{
private int m_Quality;
private Mobile m_From;
private CraftItem m_CraftItem;
private CraftSystem m_CraftSystem;
private Type m_TypeRes;
private BaseTool m_Tool;
public QueryMakersMarkGump( int quality, Mobile from, CraftItem craftItem, CraftSystem craftSystem, Type typeRes, BaseTool tool ) : base( 100, 200 )
{
from.CloseGump( typeof( QueryMakersMarkGump ) );
m_Quality = quality;
m_From = from;
m_CraftItem = craftItem;
m_CraftSystem = craftSystem;
m_TypeRes = typeRes;
m_Tool = tool;
AddPage( 0 );
AddBackground( 0, 0, 220, 170, 5054 );
AddBackground( 10, 10, 200, 150, 3000 );
AddHtmlLocalized( 20, 20, 180, 80, 1018317, false, false ); // Do you wish to place your maker's mark on this item?
AddHtmlLocalized( 55, 100, 140, 25, 1011011, false, false ); // CONTINUE
AddButton( 20, 100, 4005, 4007, 1, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 55, 125, 140, 25, 1011012, false, false ); // CANCEL
AddButton( 20, 125, 4005, 4007, 0, GumpButtonType.Reply, 0 );
}
public override void OnResponse( Server.Network.NetState sender, RelayInfo info )
{
bool makersMark = ( info.ButtonID == 1 );
if ( makersMark )
m_From.SendLocalizedMessage( 501808 ); // You mark the item.
else
m_From.SendLocalizedMessage( 501809 ); // Cancelled mark.
m_CraftItem.CompleteCraft( m_Quality, makersMark, m_From, m_CraftSystem, m_TypeRes, m_Tool, null );
}
}
}

View file

@ -0,0 +1,230 @@
using System;
using Server;
using Server.Mobiles;
using Server.Targeting;
using Server.Items;
using Server.Misc;
namespace Server.Engines.Craft
{
public class Repair
{
public Repair()
{
}
public static void Do( Mobile from, CraftSystem craftSystem, BaseTool tool )
{
from.Target = new InternalTarget( craftSystem, tool );
from.SendLocalizedMessage( 1044276 ); // Target an item to repair.
}
private class InternalTarget : Target
{
private CraftSystem m_CraftSystem;
private BaseTool m_Tool;
public InternalTarget( CraftSystem craftSystem, BaseTool tool ) : base ( 2, false, TargetFlags.None )
{
m_CraftSystem = craftSystem;
m_Tool = tool;
}
private static void EndGolemRepair( object state )
{
((Mobile)state).EndAction( typeof( Golem ) );
}
private int GetWeakenChance( Mobile mob, Trades trade, int curHits, int maxHits )
{
// 40% - (1% per hp lost) - (1% per 10 craft skill)
return (40 + (maxHits - curHits)) - (int)((SkillCheck.TradeSkill( mob, trade, false ) ) / 10);
}
private bool CheckWeaken( Mobile mob, Trades trade, int curHits, int maxHits )
{
return ( GetWeakenChance( mob, trade, curHits, maxHits ) > Utility.Random( 100 ) );
}
private int GetRepairDifficulty( int curHits, int maxHits )
{
return (((maxHits - curHits) * 1250) / Math.Max( maxHits, 1 )) - 250;
}
private bool CheckRepairDifficulty( Mobile mob, Trades trade, int curHits, int maxHits )
{
double difficulty = GetRepairDifficulty( curHits, maxHits ) * 0.1;
return SkillCheck.TestTrade( mob, trade, difficulty - 25.0, difficulty + 25.0 );
}
private bool IsSpecialClothing( BaseClothing clothing )
{
// Armor repairable but not craftable
if( m_CraftSystem is DefTailoring )
{
return (clothing is BearMask)
|| (clothing is DeerMask);
}
return false;
}
private bool IsSpecialWeapon( BaseWeapon weapon )
{
// Weapons repairable but not craftable
if ( m_CraftSystem is DefTinkering )
{
return ( weapon is Cleaver )
|| ( weapon is Hatchet )
|| ( weapon is Pickaxe )
|| ( weapon is ButcherKnife )
|| ( weapon is SkinningKnife );
}
else if ( m_CraftSystem is DefCarpentry )
{
return ( weapon is Club )
|| ( weapon is BlackStaff );
}
else if ( m_CraftSystem is DefTailoring )
{
return ( weapon is Whip );
}
else if ( m_CraftSystem is DefBlacksmithy )
{
return ( weapon is Pitchfork );
}
return false;
}
protected override void OnTarget( Mobile from, object targeted )
{
int number;
if ( m_CraftSystem.CanCraft( from, m_Tool, targeted.GetType() ) == 1044267 )
{
number = 1044282; // You must be near a forge and and anvil to repair items. * Yes, there are two and's *
}
else if ( targeted is BaseWeapon )
{
BaseWeapon weapon = (BaseWeapon)targeted;
Trades trade = m_CraftSystem.MainSkill;
int toWeaken = 0;
double skillLevel = SkillCheck.TradeSkill( from, trade, false );
if ( skillLevel >= 90.0 )
toWeaken = 1;
else if ( skillLevel >= 70.0 )
toWeaken = 2;
else
toWeaken = 3;
if ( m_CraftSystem.CraftItems.SearchForSubclass( weapon.GetType() ) == null && !IsSpecialWeapon( weapon ) )
{
number = 1044277; // That item cannot be repaired.
}
else if ( !weapon.IsChildOf( from.Backpack ) )
{
number = 1044275; // The item must be in your backpack to repair it.
}
else if ( weapon.MaxHitPoints <= 0 || weapon.HitPoints == weapon.MaxHitPoints )
{
number = 1044281; // That item is in full repair
}
else if ( weapon.MaxHitPoints <= toWeaken )
{
number = 1044278; // That item has been repaired many times, and will break if repairs are attempted again.
}
else
{
if ( CheckWeaken( from, trade, weapon.HitPoints, weapon.MaxHitPoints ) )
{
weapon.MaxHitPoints -= toWeaken;
weapon.HitPoints = Math.Max( 0, weapon.HitPoints - toWeaken );
}
if ( CheckRepairDifficulty( from, trade, weapon.HitPoints, weapon.MaxHitPoints ) )
{
number = 1044279; // You repair the item.
m_CraftSystem.PlayCraftEffect( from );
weapon.HitPoints = weapon.MaxHitPoints;
}
else
{
number = 1044280; // You fail to repair the item.
m_CraftSystem.PlayCraftEffect( from );
}
}
}
else if ( targeted is BaseArmor )
{
BaseArmor armor = (BaseArmor)targeted;
Trades trade = m_CraftSystem.MainSkill;
int toWeaken = 0;
double skillLevel = SkillCheck.TradeSkill( from, trade, false );
if ( skillLevel >= 90.0 )
toWeaken = 1;
else if ( skillLevel >= 70.0 )
toWeaken = 2;
else
toWeaken = 3;
if ( m_CraftSystem.CraftItems.SearchForSubclass( armor.GetType() ) == null )
{
number = 1044277; // That item cannot be repaired.
}
else if ( !armor.IsChildOf( from.Backpack ) )
{
number = 1044275; // The item must be in your backpack to repair it.
}
else if ( armor.MaxHitPoints <= 0 || armor.HitPoints == armor.MaxHitPoints )
{
number = 1044281; // That item is in full repair
}
else if ( armor.MaxHitPoints <= toWeaken )
{
number = 1044278; // That item has been repaired many times, and will break if repairs are attempted again.
}
else
{
if ( CheckWeaken( from, trade, armor.HitPoints, armor.MaxHitPoints ) )
{
armor.MaxHitPoints -= toWeaken;
armor.HitPoints = Math.Max( 0, armor.HitPoints - toWeaken );
}
if ( CheckRepairDifficulty( from, trade, armor.HitPoints, armor.MaxHitPoints ) )
{
number = 1044279; // You repair the item.
m_CraftSystem.PlayCraftEffect( from );
armor.HitPoints = armor.MaxHitPoints;
}
else
{
number = 1044280; // You fail to repair the item.
m_CraftSystem.PlayCraftEffect( from );
}
}
}
else if ( targeted is Item )
{
number = 1044277;
}
else
{
number = 500426; // You can't repair that.
}
CraftContext context = m_CraftSystem.GetContext( from );
from.SendGump( new CraftGump( from, m_CraftSystem, m_Tool, number ) );
}
}
}
}

View file

@ -0,0 +1,147 @@
using System;
using Server;
using Server.Targeting;
using Server.Items;
using Server.Misc;
namespace Server.Engines.Craft
{
public enum SmeltResult
{
Success,
Invalid,
NoSkill
}
public class Resmelt
{
public Resmelt()
{
}
public static void Do( Mobile from, CraftSystem craftSystem, BaseTool tool )
{
int num = craftSystem.CanCraft( from, tool, null );
if ( num > 0 && num != 1044267 )
{
from.SendGump( new CraftGump( from, craftSystem, tool, num ) );
}
else
{
from.Target = new InternalTarget( craftSystem, tool );
from.SendLocalizedMessage( 1044273 ); // Target an item to recycle.
}
}
private class InternalTarget : Target
{
private CraftSystem m_CraftSystem;
private BaseTool m_Tool;
public InternalTarget( CraftSystem craftSystem, BaseTool tool ) : base ( 2, false, TargetFlags.None )
{
m_CraftSystem = craftSystem;
m_Tool = tool;
}
private SmeltResult Resmelt( Mobile from, Item item, CraftResource resource )
{
try
{
if ( CraftResources.GetType( resource ) != CraftResourceType.Metal )
return SmeltResult.Invalid;
CraftResourceInfo info = CraftResources.GetInfo( resource );
if ( info == null || info.ResourceTypes.Length == 0 )
return SmeltResult.Invalid;
CraftItem craftItem = m_CraftSystem.CraftItems.SearchFor( item.GetType() );
if ( craftItem == null || craftItem.Resources.Count == 0 )
return SmeltResult.Invalid;
CraftRes craftResource = craftItem.Resources.GetAt( 0 );
if ( craftResource.Amount < 2 )
return SmeltResult.Invalid; // Not enough metal to resmelt
double difficulty = 0.0;
if ( difficulty > SkillCheck.TradeSkill( from, Trades.Mining, false ) )
return SmeltResult.NoSkill;
Type resourceType = info.ResourceTypes[0];
Item ingot = (Item)Activator.CreateInstance( resourceType );
if ( (item is BaseArmor && ((BaseArmor)item).PlayerConstructed) || (item is BaseWeapon && ((BaseWeapon)item).PlayerConstructed) || (item is BaseClothing && ((BaseClothing)item).PlayerConstructed) )
ingot.Amount = craftResource.Amount / 2;
else
ingot.Amount = 1;
item.Delete();
from.AddToBackpack( ingot );
from.PlaySound( 0x2A );
from.PlaySound( 0x240 );
return SmeltResult.Success;
}
catch
{
}
return SmeltResult.Invalid;
}
protected override void OnTarget( Mobile from, object targeted )
{
int num = m_CraftSystem.CanCraft( from, m_Tool, null );
if ( num > 0 )
{
if ( num == 1044267 )
{
bool anvil, forge;
DefBlacksmithy.CheckAnvilAndForge( from, 2, out anvil, out forge );
if ( !anvil )
num = 1044266; // You must be near an anvil
else if ( !forge )
num = 1044265; // You must be near a forge.
}
from.SendGump( new CraftGump( from, m_CraftSystem, m_Tool, num ) );
}
else
{
SmeltResult result = SmeltResult.Invalid;
bool isStoreBought = false;
int message;
if ( targeted is BaseArmor )
{
result = Resmelt( from, (BaseArmor)targeted, ((BaseArmor)targeted).Resource );
isStoreBought = !((BaseArmor)targeted).PlayerConstructed;
}
else if ( targeted is BaseWeapon )
{
result = Resmelt( from, (BaseWeapon)targeted, ((BaseWeapon)targeted).Resource );
isStoreBought = !((BaseWeapon)targeted).PlayerConstructed;
}
switch ( result )
{
default:
case SmeltResult.Invalid: message = 1044272; break; // You can't melt that down into ingots.
case SmeltResult.NoSkill: message = 1044269; break; // You have no idea how to work this metal.
case SmeltResult.Success: message = isStoreBought ? 500418 : 1044270; break; // You melt the item down into ingots.
}
from.SendGump( new CraftGump( from, m_CraftSystem, m_Tool, message ) );
}
}
}
}
}

View file

@ -0,0 +1,159 @@
using System;
using Server.Items;
using Server.Misc;
namespace Server.Engines.Craft
{
public class DefAlchemy : CraftSystem
{
public override Trades MainSkill
{
get { return Trades.Alchemy; }
}
public override int GumpTitleNumber
{
get { return 1044001; } // <CENTER>ALCHEMY MENU</CENTER>
}
private static CraftSystem m_CraftSystem;
public static CraftSystem CraftSystem
{
get
{
if ( m_CraftSystem == null )
m_CraftSystem = new DefAlchemy();
return m_CraftSystem;
}
}
public override double GetChanceAtMin( CraftItem item )
{
return 0.0; // 0%
}
private DefAlchemy() : base( 1, 1, 1.25 )// base( 1, 1, 3.1 )
{
}
public override int CanCraft( Mobile from, BaseTool tool, Type itemType )
{
if( tool == null || tool.Deleted || tool.UsesRemaining < 0 )
return 1044038; // You have worn out your tool!
else if ( !BaseTool.CheckAccessible( tool, from ) )
return 1044263; // The tool must be on your person to use.
return 0;
}
public override void PlayCraftEffect( Mobile from )
{
from.PlaySound( 0x242 );
}
private static Type typeofPotion = typeof( BasePotion );
public static bool IsPotion( Type type )
{
return typeofPotion.IsAssignableFrom( type );
}
public override int PlayEndingEffect( Mobile from, bool failed, bool lostMaterial, bool toolBroken, int quality, bool makersMark, CraftItem item )
{
if ( toolBroken )
from.SendLocalizedMessage( 1044038 ); // You have worn out your tool
if ( failed )
{
if ( IsPotion( item.ItemType ) )
{
from.AddToBackpack( new Bottle() );
return 500287; // You fail to create a useful potion.
}
else
{
return 1044043; // You failed to create the item, and some of your materials are lost.
}
}
else
{
from.PlaySound( 0x240 ); // Sound of a filling bottle
if ( IsPotion( item.ItemType ) )
{
if ( quality == -1 )
return 1048136; // You create the potion and pour it into a keg.
else
return 500279; // You pour the potion into a bottle...
}
else
{
return 1044154; // You create the item.
}
}
}
public override void InitCraftList()
{
int index = -1;
// Refresh Potion
index = AddCraft( typeof( RefreshPotion ), 1044530, 1044538, -25, 25.0, typeof( BlackPearl ), 1044353, 1, 1044361 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
index = AddCraft( typeof( TotalRefreshPotion ), 1044530, 1044539, 25.0, 75.0, typeof( BlackPearl ), 1044353, 5, 1044361 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
// Agility Potion
index = AddCraft( typeof( AgilityPotion ), 1044531, 1044540, 15.0, 65.0, typeof( Bloodmoss ), 1044354, 1, 1044362 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
index = AddCraft( typeof( GreaterAgilityPotion ), 1044531, 1044541, 35.0, 85.0, typeof( Bloodmoss ), 1044354, 3, 1044362 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
// Nightsight Potion
index = AddCraft( typeof( NightSightPotion ), 1044532, 1044542, -25.0, 25.0, typeof( SpidersSilk ), 1044360, 1, 1044368 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
// Heal Potion
index = AddCraft( typeof( LesserHealPotion ), 1044533, 1044543, -25.0, 25.0, typeof( Ginseng ), 1044356, 1, 1044364 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
index = AddCraft( typeof( HealPotion ), 1044533, 1044544, 15.0, 65.0, typeof( Ginseng ), 1044356, 3, 1044364 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
index = AddCraft( typeof( GreaterHealPotion ), 1044533, 1044545, 55.0, 105.0, typeof( Ginseng ), 1044356, 7, 1044364 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
// Strength Potion
index = AddCraft( typeof( StrengthPotion ), 1044534, 1044546, 25.0, 75.0, typeof( MandrakeRoot ), 1044357, 2, 1044365 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
index = AddCraft( typeof( GreaterStrengthPotion ), 1044534, 1044547, 45.0, 95.0, typeof( MandrakeRoot ), 1044357, 5, 1044365 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
// Poison Potion
index = AddCraft( typeof( LesserPoisonPotion ), 1044535, 1044548, -5.0, 45.0, typeof( Nightshade ), 1044358, 1, 1044366 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
index = AddCraft( typeof( PoisonPotion ), 1044535, 1044549, 15.0, 65.0, typeof( Nightshade ), 1044358, 2, 1044366 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
index = AddCraft( typeof( GreaterPoisonPotion ), 1044535, 1044550, 55.0, 105.0, typeof( Nightshade ), 1044358, 4, 1044366 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
index = AddCraft( typeof( DeadlyPoisonPotion ), 1044535, 1044551, 90.0, 140.0, typeof( Nightshade ), 1044358, 8, 1044366 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
// Cure Potion
index = AddCraft( typeof( LesserCurePotion ), 1044536, 1044552, -10.0, 40.0, typeof( Garlic ), 1044355, 1, 1044363 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
index = AddCraft( typeof( CurePotion ), 1044536, 1044553, 25.0, 75.0, typeof( Garlic ), 1044355, 3, 1044363 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
index = AddCraft( typeof( GreaterCurePotion ), 1044536, 1044554, 65.0, 115.0, typeof( Garlic ), 1044355, 6, 1044363 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
// Explosion Potion
index = AddCraft( typeof( LesserExplosionPotion ), 1044537, 1044555, 5.0, 55.0, typeof( SulfurousAsh ), 1044359, 3, 1044367 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
index = AddCraft( typeof( ExplosionPotion ), 1044537, 1044556, 35.0, 85.0, typeof( SulfurousAsh ), 1044359, 5, 1044367 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
index = AddCraft( typeof( GreaterExplosionPotion ), 1044537, 1044557, 65.0, 115.0, typeof( SulfurousAsh ), 1044359, 10, 1044367 );
AddRes( index, typeof ( Bottle ), 1044529, 1, 500315 );
}
}
}

View file

@ -0,0 +1,307 @@
using System;
using Server.Items;
using Server.Misc;
namespace Server.Engines.Craft
{
public class DefBlacksmithy : CraftSystem
{
public override Trades MainSkill
{
get { return Trades.Blacksmith; }
}
public override int GumpTitleNumber
{
get { return 1044002; } // <CENTER>BLACKSMITHY MENU</CENTER>
}
private static CraftSystem m_CraftSystem;
public static CraftSystem CraftSystem
{
get
{
if ( m_CraftSystem == null )
m_CraftSystem = new DefBlacksmithy();
return m_CraftSystem;
}
}
public override CraftECA ECA{ get{ return CraftECA.ChanceMinusSixtyToFourtyFive; } }
public override double GetChanceAtMin( CraftItem item )
{
return 0.0; // 0%
}
private DefBlacksmithy() : base( 1, 1, 1.25 )// base( 1, 2, 1.7 )
{
/*
base( MinCraftEffect, MaxCraftEffect, Delay )
MinCraftEffect : The minimum number of time the mobile will play the craft effect
MaxCraftEffect : The maximum number of time the mobile will play the craft effect
Delay : The delay between each craft effect
Example: (3, 6, 1.7) would make the mobile do the PlayCraftEffect override
function between 3 and 6 time, with a 1.7 second delay each time.
*/
}
private static Type typeofAnvil = typeof( AnvilAttribute );
private static Type typeofForge = typeof( ForgeAttribute );
public static void CheckAnvilAndForge( Mobile from, int range, out bool anvil, out bool forge )
{
anvil = false;
forge = false;
Map map = from.Map;
if ( map == null )
return;
IPooledEnumerable eable = map.GetItemsInRange( from.Location, range );
foreach ( Item item in eable )
{
Type type = item.GetType();
bool isAnvil = ( type.IsDefined( typeofAnvil, false ) || item.ItemID == 4015 || item.ItemID == 4016 || item.ItemID == 0x2DD5 || item.ItemID == 0x2DD6 );
bool isForge = ( type.IsDefined( typeofForge, false ) || item.ItemID == 4017 || (item.ItemID >= 6522 && item.ItemID <= 6569) || item.ItemID == 0x2DD8 );
if ( isAnvil || isForge )
{
if ( (from.Z + 16) < item.Z || (item.Z + 16) < from.Z || !from.InLOS( item ) )
continue;
anvil = anvil || isAnvil;
forge = forge || isForge;
if ( anvil && forge )
break;
}
}
eable.Free();
for ( int x = -range; (!anvil || !forge) && x <= range; ++x )
{
for ( int y = -range; (!anvil || !forge) && y <= range; ++y )
{
StaticTile[] tiles = map.Tiles.GetStaticTiles( from.X+x, from.Y+y, true );
for ( int i = 0; (!anvil || !forge) && i < tiles.Length; ++i )
{
int id = tiles[i].ID;
bool isAnvil = ( id == 4015 || id == 4016 || id == 0x2DD5 || id == 0x2DD6 );
bool isForge = ( id == 4017 || (id >= 6522 && id <= 6569) || id == 0x2DD8 );
if ( isAnvil || isForge )
{
if ( (from.Z + 16) < tiles[i].Z || (tiles[i].Z + 16) < from.Z || !from.InLOS( new Point3D( from.X+x, from.Y+y, tiles[i].Z + (tiles[i].Height/2) + 1 ) ) )
continue;
anvil = anvil || isAnvil;
forge = forge || isForge;
}
}
}
}
}
public override int CanCraft( Mobile from, BaseTool tool, Type itemType )
{
if ( tool == null || tool.Deleted || tool.UsesRemaining < 0 )
return 1044038; // You have worn out your tool!
else if ( !BaseTool.CheckTool( tool, from ) )
return 1048146; // If you have a tool equipped, you must use that tool.
else if ( !BaseTool.CheckAccessible( tool, from ) )
return 1044263; // The tool must be on your person to use.
bool anvil, forge;
CheckAnvilAndForge( from, 2, out anvil, out forge );
if ( anvil && forge )
return 0;
return 1044267; // You must be near an anvil and a forge to smith items.
}
public override void PlayCraftEffect( Mobile from )
{
// no animation, instant sound
//if ( from.Body.Type == BodyType.Human && !from.Mounted )
// from.Animate( 9, 5, 1, true, false, 0 );
//new InternalTimer( from ).Start();
from.PlaySound( 0x2A );
}
// Delay to synchronize the sound with the hit on the anvil
private class InternalTimer : Timer
{
private Mobile m_From;
public InternalTimer( Mobile from ) : base( TimeSpan.FromSeconds( 0.7 ) )
{
m_From = from;
}
protected override void OnTick()
{
m_From.PlaySound( 0x2A );
}
}
public override int PlayEndingEffect( Mobile from, bool failed, bool lostMaterial, bool toolBroken, int quality, bool makersMark, CraftItem item )
{
if ( toolBroken )
from.SendLocalizedMessage( 1044038 ); // You have worn out your tool
if ( failed )
{
if ( lostMaterial )
return 1044043; // You failed to create the item, and some of your materials are lost.
else
return 1044157; // You failed to create the item, but no materials were lost.
}
else
{
if ( quality == 0 )
return 502785; // You were barely able to make this item. It's quality is below average.
else if ( makersMark && quality == 2 )
return 1044156; // You create an exceptional quality item and affix your maker's mark.
else if ( quality == 2 )
return 1044155; // You create an exceptional quality item.
else
return 1044154; // You create the item.
}
}
public override void InitCraftList()
{
/*
Synthax for a SIMPLE craft item
AddCraft( ObjectType, Group, MinSkill, MaxSkill, ResourceType, Amount, Message )
ObjectType : The type of the object you want to add to the build list.
Group : The group in wich the object will be showed in the craft menu.
MinSkill : The minimum of skill value
MaxSkill : The maximum of skill value
ResourceType : The type of the resource the mobile need to create the item
Amount : The amount of the ResourceType it need to create the item
Message : String or Int for Localized. The message that will be sent to the mobile, if the specified resource is missing.
Synthax for a COMPLEXE craft item. A complexe item is an item that need either more than
only one skill, or more than only one resource.
Coming soon....
*/
#region Ringmail
AddCraft( typeof( RingmailGloves ), 1011076, 1025099, 12.0, 62.0, typeof( IronIngot ), 1044036, 10, 1044037 );
AddCraft( typeof( RingmailLegs ), 1011076, 1025104, 19.4, 69.4, typeof( IronIngot ), 1044036, 16, 1044037 );
AddCraft( typeof( RingmailArms ), 1011076, 1025103, 16.9, 66.9, typeof( IronIngot ), 1044036, 14, 1044037 );
AddCraft( typeof( RingmailChest ), 1011076, 1025100, 21.9, 71.9, typeof( IronIngot ), 1044036, 18, 1044037 );
#endregion
#region Chainmail
AddCraft( typeof( ChainCoif ), 1011077, 1025051, 14.5, 64.5, typeof( IronIngot ), 1044036, 10, 1044037 );
AddCraft( typeof( ChainLegs ), 1011077, 1025054, 36.7, 86.7, typeof( IronIngot ), 1044036, 18, 1044037 );
AddCraft( typeof( ChainChest ), 1011077, 1025055, 39.1, 89.1, typeof( IronIngot ), 1044036, 20, 1044037 );
#endregion
#region Platemail
AddCraft( typeof( PlateArms ), 1011078, 1025136, 66.3, 116.3, typeof( IronIngot ), 1044036, 18, 1044037 );
AddCraft( typeof( PlateGloves ), 1011078, 1025140, 58.9, 108.9, typeof( IronIngot ), 1044036, 12, 1044037 );
AddCraft( typeof( PlateGorget ), 1011078, 1025139, 56.4, 106.4, typeof( IronIngot ), 1044036, 10, 1044037 );
AddCraft( typeof( PlateLegs ), 1011078, 1025137, 68.8, 118.8, typeof( IronIngot ), 1044036, 20, 1044037 );
AddCraft( typeof( PlateChest ), 1011078, 1046431, 75.0, 125.0, typeof( IronIngot ), 1044036, 25, 1044037 );
AddCraft( typeof( FemalePlateChest ), 1011078, 1046430, 44.1, 94.1, typeof( IronIngot ), 1044036, 20, 1044037 );
#endregion
#region Helmets
AddCraft( typeof( Bascinet ), 1011079, 1025132, 8.3, 58.3, typeof( IronIngot ), 1044036, 15, 1044037 );
AddCraft( typeof( CloseHelm ), 1011079, 1025128, 37.9, 87.9, typeof( IronIngot ), 1044036, 15, 1044037 );
AddCraft( typeof( Helmet ), 1011079, 1025130, 37.9, 87.9, typeof( IronIngot ), 1044036, 15, 1044037 );
AddCraft( typeof( NorseHelm ), 1011079, 1025134, 37.9, 87.9, typeof( IronIngot ), 1044036, 15, 1044037 );
AddCraft( typeof( PlateHelm ), 1011079, 1025138, 62.6, 112.6, typeof( IronIngot ), 1044036, 15, 1044037 );
#endregion
#region Shields
AddCraft( typeof( Buckler ), 1011080, 1027027, -25.0, 25.0, typeof( IronIngot ), 1044036, 10, 1044037 );
AddCraft( typeof( BronzeShield ), 1011080, 1027026, -15.2, 34.8, typeof( IronIngot ), 1044036, 12, 1044037 );
AddCraft( typeof( HeaterShield ), 1011080, 1027030, 24.3, 74.3, typeof( IronIngot ), 1044036, 18, 1044037 );
AddCraft( typeof( MetalShield ), 1011080, 1027035, -10.2, 39.8, typeof( IronIngot ), 1044036, 14, 1044037 );
AddCraft( typeof( MetalKiteShield ), 1011080, 1027028, 4.6, 54.6, typeof( IronIngot ), 1044036, 16, 1044037 );
AddCraft( typeof( ChaosShield ), 1011080, 1027107, 85.0, 135.0, typeof( IronIngot ), 1044036, 25, 1044037 );
AddCraft( typeof( OrderShield ), 1011080, 1027108, 85.0, 135.0, typeof( IronIngot ), 1044036, 25, 1044037 );
#endregion
#region Bladed
AddCraft( typeof( Broadsword ), 1011081, 1023934, 35.4, 85.4, typeof( IronIngot ), 1044036, 10, 1044037 );
AddCraft( typeof( Cutlass ), 1011081, 1025185, 24.3, 74.3, typeof( IronIngot ), 1044036, 8, 1044037 );
AddCraft( typeof( Dagger ), 1011081, 1023921, -0.4, 49.6, typeof( IronIngot ), 1044036, 3, 1044037 );
AddCraft( typeof( Katana ),1011081, 1025119, 44.1, 94.1, typeof( IronIngot ), 1044036, 8, 1044037 );
AddCraft( typeof( Kryss ), 1011081, 1025121, 36.7, 86.7, typeof( IronIngot ), 1044036, 8, 1044037 );
AddCraft( typeof( Longsword ), 1011081, 1023937, 28.0, 78.0, typeof( IronIngot ), 1044036, 12, 1044037 );
AddCraft( typeof( Rapier ), 1011081, 1025123, 45.3, 95.3, typeof( IronIngot ), 1044036, 6, 1044037 );
AddCraft( typeof( Scimitar ), 1011081, 1025046, 31.7, 81.7, typeof( IronIngot ), 1044036, 10, 1044037 );
AddCraft( typeof( VikingSword ), 1011081, 1025049, 24.3, 74.3, typeof( IronIngot ), 1044036, 14, 1044037 );
#endregion
#region Axes
AddCraft( typeof( Axe ), 1011082, 1023913, 34.2, 84.2, typeof( IronIngot ), 1044036, 14, 1044037 );
AddCraft( typeof( BattleAxe ), 1011082, 1023911, 30.5, 80.5, typeof( IronIngot ), 1044036, 14, 1044037 );
AddCraft( typeof( DoubleAxe ), 1011082, 1023915, 29.3, 79.3, typeof( IronIngot ), 1044036, 12, 1044037 );
AddCraft( typeof( GreatAxe ), 1011082, 1023909, 34.2, 84.2, typeof( IronIngot ), 1044036, 14, 1044037 );
AddCraft( typeof( LargeBattleAxe ), 1011082, 1025115, 28.0, 78.0, typeof( IronIngot ), 1044036, 12, 1044037 );
AddCraft( typeof( TwoHandedAxe ), 1011082, 1025187, 33.0, 83.0, typeof( IronIngot ), 1044036, 16, 1044037 );
AddCraft( typeof( WarAxe ), 1011082, 1025040, 39.1, 89.1, typeof( IronIngot ), 1044036, 16, 1044037 );
#endregion
#region Pole Arms
AddCraft( typeof( Bardiche ), 1011083, 1023917, 31.7, 81.7, typeof( IronIngot ), 1044036, 18, 1044037 );
AddCraft( typeof( Halberd ), 1011083, 1025183, 39.1, 89.1, typeof( IronIngot ), 1044036, 20, 1044037 );
AddCraft( typeof( Pike ), 1011083, 1029918, 47.0, 97.0, typeof( IronIngot ), 1044036, 12, 1044037 );
AddCraft( typeof( Scythe ), 1011083, 1029914, 39.0, 89.0, typeof( IronIngot ), 1044036, 14, 1044037 );
AddCraft( typeof( Spear ), 1011083, 1023938, 49.0, 99.0, typeof( IronIngot ), 1044036, 12, 1044037 );
AddCraft( typeof( WarFork ), 1011083, 1025125, 42.9, 92.9, typeof( IronIngot ), 1044036, 12, 1044037 );
AddCraft( typeof( Pitchfork ), 1011083, 1023720, 36.1, 86.1, typeof( IronIngot ), 1044036, 12, 1044037 );
#endregion
#region Bashing
AddCraft( typeof( HammerPick ), 1011084, 1025181, 34.2, 84.2, typeof( IronIngot ), 1044036, 16, 1044037 );
AddCraft( typeof( Mace ), 1011084, 1023932, 14.5, 64.5, typeof( IronIngot ), 1044036, 6, 1044037 );
AddCraft( typeof( Maul ), 1011084, 1025179, 19.4, 69.4, typeof( IronIngot ), 1044036, 10, 1044037 );
AddCraft( typeof( WarMace ), 1011084, 1025127, 28.0, 78.0, typeof( IronIngot ), 1044036, 14, 1044037 );
AddCraft( typeof( WarHammer ), 1011084, 1025177, 34.2, 84.2, typeof( IronIngot ), 1044036, 16, 1044037 );
#endregion
Resmelt = true;
Repair = true;
MarkOption = true;
}
}
public class ForgeAttribute : Attribute
{
public ForgeAttribute()
{
}
}
public class AnvilAttribute : Attribute
{
public AnvilAttribute()
{
}
}
}

View file

@ -0,0 +1,111 @@
using System;
using Server.Items;
using Server.Misc;
namespace Server.Engines.Craft
{
public class DefBowFletching : CraftSystem
{
public override Trades MainSkill
{
get { return Trades.Fletching; }
}
public override int GumpTitleNumber
{
get { return 1044006; } // <CENTER>BOWCRAFT AND FLETCHING MENU</CENTER>
}
private static CraftSystem m_CraftSystem;
public static CraftSystem CraftSystem
{
get
{
if ( m_CraftSystem == null )
m_CraftSystem = new DefBowFletching();
return m_CraftSystem;
}
}
public override double GetChanceAtMin( CraftItem item )
{
return 0.5; // 50%
}
private DefBowFletching() : base( 1, 1, 1.25 )// base( 1, 2, 1.7 )
{
}
public override int CanCraft( Mobile from, BaseTool tool, Type itemType )
{
if( tool == null || tool.Deleted || tool.UsesRemaining < 0 )
return 1044038; // You have worn out your tool!
else if ( !BaseTool.CheckAccessible( tool, from ) )
return 1044263; // The tool must be on your person to use.
return 0;
}
public override void PlayCraftEffect( Mobile from )
{
from.PlaySound( 0x55 );
}
public override int PlayEndingEffect( Mobile from, bool failed, bool lostMaterial, bool toolBroken, int quality, bool makersMark, CraftItem item )
{
if ( toolBroken )
from.SendLocalizedMessage( 1044038 ); // You have worn out your tool
if ( failed )
{
if ( lostMaterial )
return 1044043; // You failed to create the item, and some of your materials are lost.
else
return 1044157; // You failed to create the item, but no materials were lost.
}
else
{
if ( quality == 0 )
return 502785; // You were barely able to make this item. It's quality is below average.
else if ( makersMark && quality == 2 )
return 1044156; // You create an exceptional quality item and affix your maker's mark.
else if ( quality == 2 )
return 1044155; // You create an exceptional quality item.
else
return 1044154; // You create the item.
}
}
public override CraftECA ECA{ get{ return CraftECA.FiftyPercentChanceMinusTenPercent; } }
public override void InitCraftList()
{
int index = -1;
// Materials
AddCraft( typeof( Kindling ), 1044457, 1023553, 0.0, 00.0, typeof( WoodBoard ), 1044041, 1, 1044351 );
index = AddCraft( typeof( Shaft ), 1044457, 1027124, 0.0, 40.0, typeof( WoodBoard ), 1044041, 1, 1044351 );
SetUseAllRes( index, true );
// Ammunition
index = AddCraft( typeof( Arrow ), 1044565, 1023903, 0.0, 40.0, typeof( Shaft ), 1044560, 1, 1044561 );
AddRes( index, typeof( Feather ), 1044562, 1, 1044563 );
SetUseAllRes( index, true );
index = AddCraft( typeof( Bolt ), 1044565, 1027163, 0.0, 40.0, typeof( Shaft ), 1044560, 1, 1044561 );
AddRes( index, typeof( Feather ), 1044562, 1, 1044563 );
SetUseAllRes( index, true );
// Weapons
AddCraft( typeof( Bow ), 1044566, 1025042, 30.0, 70.0, typeof( WoodBoard ), 1044041, 7, 1044351 );
AddCraft( typeof( Crossbow ), 1044566, 1023919, 60.0, 100.0, typeof( WoodBoard ), 1044041, 7, 1044351 );
AddCraft( typeof( HeavyCrossbow ), 1044566, 1025117, 80.0, 120.0, typeof( WoodBoard ), 1044041, 10, 1044351 );
MarkOption = true;
Repair = true;
}
}
}

View file

@ -0,0 +1,289 @@
using System;
using Server.Items;
using Server.Misc;
namespace Server.Engines.Craft
{
public class DefCarpentry : CraftSystem
{
public override Trades MainSkill
{
get { return Trades.Carpentry; }
}
public override int GumpTitleNumber
{
get { return 1044004; } // <CENTER>CARPENTRY MENU</CENTER>
}
private static CraftSystem m_CraftSystem;
public static CraftSystem CraftSystem
{
get
{
if ( m_CraftSystem == null )
m_CraftSystem = new DefCarpentry();
return m_CraftSystem;
}
}
public override double GetChanceAtMin( CraftItem item )
{
return 0.5; // 50%
}
private DefCarpentry() : base( 1, 1, 1.25 )// base( 1, 1, 3.0 )
{
}
public override int CanCraft( Mobile from, BaseTool tool, Type itemType )
{
if( tool == null || tool.Deleted || tool.UsesRemaining < 0 )
return 1044038; // You have worn out your tool!
else if ( !BaseTool.CheckAccessible( tool, from ) )
return 1044263; // The tool must be on your person to use.
return 0;
}
public override void PlayCraftEffect( Mobile from )
{
from.PlaySound( 0x23D );
}
public override int PlayEndingEffect( Mobile from, bool failed, bool lostMaterial, bool toolBroken, int quality, bool makersMark, CraftItem item )
{
if ( toolBroken )
from.SendLocalizedMessage( 1044038 ); // You have worn out your tool
if ( failed )
{
if ( lostMaterial )
return 1044043; // You failed to create the item, and some of your materials are lost.
else
return 1044157; // You failed to create the item, but no materials were lost.
}
else
{
if ( quality == 0 )
return 502785; // You were barely able to make this item. It's quality is below average.
else if ( makersMark && quality == 2 )
return 1044156; // You create an exceptional quality item and affix your maker's mark.
else if ( quality == 2 )
return 1044155; // You create an exceptional quality item.
else
return 1044154; // You create the item.
}
}
public override void InitCraftList()
{
int index = -1;
AddCraft( typeof( BarrelStaves ), 1044294, 1027857, 00.0, 25.0, typeof( WoodBoard ), 1044041, 5, 1044351 );
AddCraft( typeof( BarrelLid ), 1044294, 1027608, 11.0, 36.0, typeof( WoodBoard ), 1044041, 4, 1044351 );
AddCraft( typeof( ShortMusicStand ), 1044294, 1044313, 78.9, 103.9, typeof( WoodBoard ), 1044041, 15, 1044351 );
AddCraft( typeof( TallMusicStand ), 1044294, 1044315, 81.5, 106.5, typeof( WoodBoard ), 1044041, 20, 1044351 );
AddCraft( typeof( Easle ), 1044294, 1044317, 86.8, 111.8, typeof( WoodBoard ), 1044041, 20, 1044351 );
index = AddCraft( typeof( FishingPole ), 1044294, 1023519, 68.4, 93.4, typeof( WoodBoard ), 1044041, 5, 1044351 );
AddSkill( index, Trades.Tailoring, 40.0, 45.0 );
AddRes( index, typeof( Cloth ), 1044286, 5, 1044287 );
// Furniture
AddCraft( typeof( FootStool ), 1044291, 1022910, 11.0, 36.0, typeof( WoodBoard ), 1044041, 9, 1044351 );
AddCraft( typeof( Stool ), 1044291, 1022602, 11.0, 36.0, typeof( WoodBoard ), 1044041, 9, 1044351 );
AddCraft( typeof( BambooChair ), 1044291, 1044300, 21.0, 46.0, typeof( WoodBoard ), 1044041, 13, 1044351 );
AddCraft( typeof( WoodenChair ), 1044291, 1044301, 21.0, 46.0, typeof( WoodBoard ), 1044041, 13, 1044351 );
AddCraft( typeof( FancyWoodenChairCushion ), 1044291, 1044302, 42.1, 67.1, typeof( WoodBoard ), 1044041, 15, 1044351 );
AddCraft( typeof( WoodenChairCushion ), 1044291, 1044303, 42.1, 67.1, typeof( WoodBoard ), 1044041, 13, 1044351 );
AddCraft( typeof( WoodenBench ), 1044291, 1022860, 52.6, 77.6, typeof( WoodBoard ), 1044041, 17, 1044351 );
AddCraft( typeof( WoodenThrone ), 1044291, 1044304, 52.6, 77.6, typeof( WoodBoard ), 1044041, 17, 1044351 );
AddCraft( typeof( Throne ), 1044291, 1044305, 73.6, 98.6, typeof( WoodBoard ), 1044041, 19, 1044351 );
AddCraft( typeof( Nightstand ), 1044291, 1044306, 42.1, 67.1, typeof( WoodBoard ), 1044041, 17, 1044351 );
AddCraft( typeof( WritingTable ), 1044291, 1022890, 63.1, 88.1, typeof( WoodBoard ), 1044041, 17, 1044351 );
AddCraft( typeof( YewWoodTable ), 1044291, 1044307, 63.1, 88.1, typeof( WoodBoard ), 1044041, 23, 1044351 );
AddCraft( typeof( LargeTable ), 1044291, 1044308, 84.2, 109.2, typeof( WoodBoard ), 1044041, 27, 1044351 );
AddCraft( typeof( StoneChair ), 1044291, 1024635, 55.0, 105.0, typeof( IronOre ), 1072392, 4, 1044513 );
AddCraft( typeof( MediumStoneTableEastDeed ), 1044291, 1044508, 65.0, 115.0, typeof( IronOre ), 1072392, 6, 1044513 );
AddCraft( typeof( MediumStoneTableSouthDeed ), 1044291, 1044509, 65.0, 115.0, typeof( IronOre ), 1072392, 6, 1044513 );
AddCraft( typeof( LargeStoneTableEastDeed ), 1044291, 1044511, 75.0, 125.0, typeof( IronOre ), 1072392, 9, 1044513 );
AddCraft( typeof( LargeStoneTableSouthDeed ), 1044291, 1044512, 75.0, 125.0, typeof( IronOre ), 1072392, 9, 1044513 );
// Containers
AddCraft( typeof( WoodenBox ), 1044292, 1023709, 21.0, 46.0, typeof( WoodBoard ), 1044041, 10, 1044351 );
AddCraft( typeof( SmallCrate ), 1044292, 1044309, 10.0, 35.0, typeof( WoodBoard ), 1044041, 8 , 1044351 );
AddCraft( typeof( MediumCrate ), 1044292, 1044310, 31.0, 56.0, typeof( WoodBoard ), 1044041, 15, 1044351 );
AddCraft( typeof( LargeCrate ), 1044292, 1044311, 47.3, 72.3, typeof( WoodBoard ), 1044041, 18, 1044351 );
AddCraft( typeof( WoodenChest ), 1044292, 1023650, 73.6, 98.6, typeof( WoodBoard ), 1044041, 20, 1044351 );
AddCraft( typeof( EmptyBookcase ), 1044292, 1022718, 31.5, 56.5, typeof( WoodBoard ), 1044041, 25, 1044351 );
AddCraft( typeof( FancyArmoire ), 1044292, 1044312, 84.2, 109.2, typeof( WoodBoard ), 1044041, 35, 1044351 );
AddCraft( typeof( Armoire ), 1044292, 1022643, 84.2, 109.2, typeof( WoodBoard ), 1044041, 35, 1044351 );
AddCraft( typeof( CratePlain ), 1044292, 1045025, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateCarpenter ), 1044292, 1045026, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateJewels ), 1044292, 1045027, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateWizard ), 1044292, 1045028, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateSmithing ), 1044292, 1045029, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateProvisions ), 1044292, 1045030, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateTailor ), 1044292, 1045031, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateMaps ), 1044292, 1045032, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateSailing ), 1044292, 1045033, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateInn ), 1044292, 1045034, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateArms ), 1044292, 1045035, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateStable ), 1044292, 1045036, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateFletcher ), 1044292, 1045037, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateMeat ), 1044292, 1045038, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateTinker ), 1044292, 1045039, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CratePotions ), 1044292, 1045040, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateFood ), 1044292, 1045041, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateGold ), 1044292, 1045042, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateBard ), 1044292, 1045043, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateWax ), 1044292, 1045044, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateBooks ), 1044292, 1045045, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateBows ), 1044292, 1045046, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateHealer ), 1044292, 1045047, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
AddCraft( typeof( CrateTavern ), 1044292, 1045048, 57.3, 82.3, typeof( WoodBoard ), 1044041, 22, 1044351 );
index = AddCraft( typeof( Keg ), 1044292, 1023711, 57.8, 82.8, typeof( BarrelStaves ), 1044288, 3, 1044253 );
AddRes( index, typeof( BarrelHoops ), 1044289, 1, 1044253 );
AddRes( index, typeof( BarrelLid ), 1044251, 1, 1044253 );
// Staves and Shields
AddCraft( typeof( ShepherdsCrook ), 1044295, 1023713, 78.9, 103.9, typeof( WoodBoard ), 1044041, 7, 1044351 );
AddCraft( typeof( QuarterStaff ), 1044295, 1023721, 73.6, 98.6, typeof( WoodBoard ), 1044041, 6, 1044351 );
AddCraft( typeof( GnarledStaff ), 1044295, 1025112, 78.9, 103.9, typeof( WoodBoard ), 1044041, 7, 1044351 );
AddCraft( typeof( WoodenShield ), 1044295, 1027034, 52.6, 77.6, typeof( WoodBoard ), 1044041, 9, 1044351 );
AddCraft( typeof( WoodenKiteShield ), 1044295, 1027032, 82.6, 97.6, typeof( WoodBoard ), 1044041, 12, 1044351 );
AddCraft( typeof( Club ), 1044295, 1025043, 53.9, 78.9, typeof( WoodBoard ), 1044041, 4, 1044351 );
// Instruments
index = AddCraft( typeof( LapHarp ), 1044293, 1023762, 63.1, 88.1, typeof( WoodBoard ), 1044041, 20, 1044351 );
AddSkill( index, Trades.Musicianship, 45.0, 50.0 );
AddRes( index, typeof( Cloth ), 1044286, 10, 1044287 );
index = AddCraft( typeof( Harp ), 1044293, 1023761, 78.9, 103.9, typeof( WoodBoard ), 1044041, 35, 1044351 );
AddSkill( index, Trades.Musicianship, 45.0, 50.0 );
AddRes( index, typeof( Cloth ), 1044286, 15, 1044287 );
index = AddCraft( typeof( Drums ), 1044293, 1023740, 57.8, 82.8, typeof( WoodBoard ), 1044041, 20, 1044351 );
AddSkill( index, Trades.Musicianship, 45.0, 50.0 );
AddRes( index, typeof( Cloth ), 1044286, 10, 1044287 );
index = AddCraft( typeof( Flute ), 1044293, 1023738, 68.4, 93.4, typeof( WoodBoard ), 1044041, 25, 1044351 );
AddSkill( index, Trades.Musicianship, 45.0, 50.0 );
index = AddCraft( typeof( Lute ), 1044293, 1023763, 68.4, 93.4, typeof( WoodBoard ), 1044041, 25, 1044351 );
AddSkill( index, Trades.Musicianship, 45.0, 50.0 );
AddRes( index, typeof( Cloth ), 1044286, 10, 1044287 );
index = AddCraft( typeof( Pipes ), 1044293, 1023737, 68.4, 93.4, typeof( WoodBoard ), 1044041, 25, 1044351 );
AddSkill( index, Trades.Musicianship, 45.0, 50.0 );
index = AddCraft( typeof( Tambourine ), 1044293, 1023741, 57.8, 82.8, typeof( WoodBoard ), 1044041, 15, 1044351 );
AddSkill( index, Trades.Musicianship, 45.0, 50.0 );
AddRes( index, typeof( Cloth ), 1044286, 10, 1044287 );
index = AddCraft( typeof( TambourineTassel ), 1044293, 1044320, 57.8, 82.8, typeof( WoodBoard ), 1044041, 15, 1044351 );
AddSkill( index, Trades.Musicianship, 45.0, 50.0 );
AddRes( index, typeof( Cloth ), 1044286, 15, 1044287 );
// Misc
index = AddCraft( typeof( SmallBedSouthDeed ), 1044290, 1044321, 94.7, 119.8, typeof( WoodBoard ), 1044041, 100, 1044351 );
AddSkill( index, Trades.Tailoring, 75.0, 80.0 );
AddRes( index, typeof( Cloth ), 1044286, 100, 1044287 );
index = AddCraft(typeof(SmallBedEastDeed), 1044290, 1044322, 94.7, 119.8, typeof(WoodBoard), 1044041, 100, 1044351);
AddSkill( index, Trades.Tailoring, 75.0, 80.0 );
AddRes( index, typeof( Cloth ), 1044286, 100, 1044287 );
index = AddCraft(typeof(LargeBedSouthDeed), 1044290, 1044323, 94.7, 119.8, typeof(WoodBoard), 1044041, 150, 1044351);
AddSkill( index, Trades.Tailoring, 75.0, 80.0 );
AddRes( index, typeof( Cloth ), 1044286, 150, 1044287 );
index = AddCraft(typeof(LargeBedEastDeed), 1044290, 1044324, 94.7, 119.8, typeof(WoodBoard), 1044041, 150, 1044351);
AddSkill( index, Trades.Tailoring, 75.0, 80.0 );
AddRes( index, typeof( Cloth ), 1044286, 150, 1044287 );
AddCraft( typeof( DartBoardSouthDeed ), 1044290, 1044325, 15.7, 40.7, typeof( WoodBoard ), 1044041, 5, 1044351 );
AddCraft( typeof( DartBoardEastDeed ), 1044290, 1044326, 15.7, 40.7, typeof( WoodBoard ), 1044041, 5, 1044351 );
index = AddCraft( typeof( PentagramDeed ), 1044290, 1044328, 100.0, 125.0, typeof( WoodBoard ), 1044041, 100, 1044351 );
AddSkill( index, Trades.Magery, 75.0, 80.0 );
AddRes( index, typeof( IronIngot ), 1044036, 40, 1044037 );
index = AddCraft( typeof( AbbatoirDeed ), 1044290, 1044329, 100.0, 125.0, typeof( IronOre ), 1072392, 100, 1044513 );
AddSkill( index, Trades.Magery, 50.0, 55.0 );
AddRes( index, typeof( IronIngot ), 1044036, 40, 1044037 );
AddCraft( typeof( Vase ), 1044290, 1022888, 52.5, 102.5, typeof( IronOre ), 1072392, 1, 1044513 );
AddCraft( typeof( LargeVase ), 1044290, 1022887, 52.5, 102.5, typeof( IronOre ), 1072392, 3, 1044513 );
AddCraft( typeof( StatueSouth ), 1044290, 1044505, 60.0, 120.0, typeof( IronOre ), 1072392, 3, 1044513 );
AddCraft( typeof( StatueNorth ), 1044290, 1044506, 60.0, 120.0, typeof( IronOre ), 1072392, 3, 1044513 );
AddCraft( typeof( StatueEast ), 1044290, 1044507, 60.0, 120.0, typeof( IronOre ), 1072392, 3, 1044513 );
AddCraft( typeof( StatuePegasus ), 1044290, 1044510, 70.0, 130.0, typeof( IronOre ), 1072392, 4, 1044513 );
// Blacksmithy
index = AddCraft( typeof( SmallForgeDeed ), 1044296, 1044330, 73.6, 98.6, typeof( WoodBoard ), 1044041, 5, 1044351 );
AddSkill( index, Trades.Blacksmith, 75.0, 80.0 );
AddRes( index, typeof( IronIngot ), 1044036, 75, 1044037 );
index = AddCraft( typeof( LargeForgeEastDeed ), 1044296, 1044331, 78.9, 103.9, typeof( WoodBoard ), 1044041, 5, 1044351 );
AddSkill( index, Trades.Blacksmith, 80.0, 85.0 );
AddRes( index, typeof( IronIngot ), 1044036, 100, 1044037 );
index = AddCraft( typeof( LargeForgeSouthDeed ), 1044296, 1044332, 78.9, 103.9, typeof( WoodBoard ), 1044041, 5, 1044351 );
AddSkill( index, Trades.Blacksmith, 80.0, 85.0 );
AddRes( index, typeof( IronIngot ), 1044036, 100, 1044037 );
index = AddCraft( typeof( AnvilEastDeed ), 1044296, 1044333, 73.6, 98.6, typeof( WoodBoard ), 1044041, 5, 1044351 );
AddSkill( index, Trades.Blacksmith, 75.0, 80.0 );
AddRes( index, typeof( IronIngot ), 1044036, 150, 1044037 );
index = AddCraft( typeof( AnvilSouthDeed ), 1044296, 1044334, 73.6, 98.6, typeof( WoodBoard ), 1044041, 5, 1044351 );
AddSkill( index, Trades.Blacksmith, 75.0, 80.0 );
AddRes( index, typeof( IronIngot ), 1044036, 150, 1044037 );
// Training
index = AddCraft( typeof( TrainingDummyEastDeed ), 1044297, 1044335, 68.4, 93.4, typeof( WoodBoard ), 1044041, 55, 1044351 );
AddSkill( index, Trades.Tailoring, 50.0, 55.0 );
AddRes( index, typeof( Cloth ), 1044286, 60, 1044287 );
index = AddCraft( typeof( TrainingDummySouthDeed ), 1044297, 1044336, 68.4, 93.4, typeof( WoodBoard ), 1044041, 55, 1044351 );
AddSkill( index, Trades.Tailoring, 50.0, 55.0 );
AddRes( index, typeof( Cloth ), 1044286, 60, 1044287 );
index = AddCraft( typeof( PickpocketDipEastDeed ), 1044297, 1044337, 73.6, 98.6, typeof( WoodBoard ), 1044041, 65, 1044351 );
AddSkill( index, Trades.Tailoring, 50.0, 55.0 );
AddRes( index, typeof( Cloth ), 1044286, 60, 1044287 );
index = AddCraft( typeof( PickpocketDipSouthDeed ), 1044297, 1044338, 73.6, 98.6, typeof( WoodBoard ), 1044041, 65, 1044351 );
AddSkill( index, Trades.Tailoring, 50.0, 55.0 );
AddRes( index, typeof( Cloth ), 1044286, 60, 1044287 );
// Tailoring
index = AddCraft( typeof( Dressform ), 1044298, 1044339, 63.1, 88.1, typeof( WoodBoard ), 1044041, 25, 1044351 );
AddSkill( index, Trades.Tailoring, 65.0, 70.0 );
AddRes( index, typeof( Cloth ), 1044286, 10, 1044287 );
index = AddCraft( typeof( SpinningwheelEastDeed ), 1044298, 1044341, 73.6, 98.6, typeof( WoodBoard ), 1044041, 75, 1044351 );
AddSkill( index, Trades.Tailoring, 65.0, 70.0 );
AddRes( index, typeof( Cloth ), 1044286, 25, 1044287 );
index = AddCraft( typeof( SpinningwheelSouthDeed ), 1044298, 1044342, 73.6, 98.6, typeof( WoodBoard ), 1044041, 75, 1044351 );
AddSkill( index, Trades.Tailoring, 65.0, 70.0 );
AddRes( index, typeof( Cloth ), 1044286, 25, 1044287 );
index = AddCraft( typeof( LoomEastDeed ), 1044298, 1044343, 84.2, 109.2, typeof( WoodBoard ), 1044041, 85, 1044351 );
AddSkill( index, Trades.Tailoring, 65.0, 70.0 );
AddRes( index, typeof( Cloth ), 1044286, 25, 1044287 );
index = AddCraft( typeof( LoomSouthDeed ), 1044298, 1044344, 84.2, 109.2, typeof( WoodBoard ), 1044041, 85, 1044351 );
AddSkill( index, Trades.Tailoring, 65.0, 70.0 );
AddRes( index, typeof( Cloth ), 1044286, 25, 1044287 );
// Cooking
index = AddCraft( typeof( Bonfire ), 1044299, 1044230, 84.7, 109.7, typeof( WoodBoard ), 1044041, 100, 1044351 );
AddRes( index, typeof( IronOre ), 1072392, 10, 1044513 );
index = AddCraft( typeof( StoneOvenEastDeed ), 1044299, 1044345, 68.4, 93.4, typeof( WoodBoard ), 1044041, 85, 1044351 );
AddSkill( index, Trades.Tinkering, 50.0, 55.0 );
AddRes( index, typeof( IronIngot ), 1044036, 125, 1044037 );
index = AddCraft( typeof( StoneOvenSouthDeed ), 1044299, 1044346, 68.4, 93.4, typeof( WoodBoard ), 1044041, 85, 1044351 );
AddSkill( index, Trades.Tinkering, 50.0, 55.0 );
AddRes( index, typeof( IronIngot ), 1044036, 125, 1044037 );
index = AddCraft( typeof( FlourMillEastDeed ), 1044299, 1044347, 94.7, 119.7, typeof( WoodBoard ), 1044041, 100, 1044351 );
AddSkill( index, Trades.Tinkering, 50.0, 55.0 );
AddRes( index, typeof( IronIngot ), 1044036, 50, 1044037 );
index = AddCraft( typeof( FlourMillSouthDeed ), 1044299, 1044348, 94.7, 119.7, typeof( WoodBoard ), 1044041, 100, 1044351 );
AddSkill( index, Trades.Tinkering, 50.0, 55.0 );
AddRes( index, typeof( IronIngot ), 1044036, 50, 1044037 );
AddCraft( typeof( WaterTroughEastDeed ), 1044299, 1044349, 94.7, 119.7, typeof( WoodBoard ), 1044041, 150, 1044351 );
AddCraft( typeof( WaterTroughSouthDeed ), 1044299, 1044350, 94.7, 119.7, typeof( WoodBoard ), 1044041, 150, 1044351 );
MarkOption = true;
Repair = true;
}
}
}

View file

@ -0,0 +1,89 @@
using System;
using Server.Items;
using Server.Misc;
namespace Server.Engines.Craft
{
public class DefCartography : CraftSystem
{
public override Trades MainSkill
{
get { return Trades.Cartography; }
}
public override int GumpTitleNumber
{
get { return 1044008; } // <CENTER>CARTOGRAPHY MENU</CENTER>
}
public override double GetChanceAtMin( CraftItem item )
{
return 0.0; // 0%
}
private static CraftSystem m_CraftSystem;
public static CraftSystem CraftSystem
{
get
{
if ( m_CraftSystem == null )
m_CraftSystem = new DefCartography();
return m_CraftSystem;
}
}
private DefCartography() : base( 1, 1, 1.25 )// base( 1, 1, 3.0 )
{
}
public override int CanCraft( Mobile from, BaseTool tool, Type itemType )
{
if( tool == null || tool.Deleted || tool.UsesRemaining < 0 )
return 1044038; // You have worn out your tool!
else if ( !BaseTool.CheckAccessible( tool, from ) )
return 1044263; // The tool must be on your person to use.
return 0;
}
public override void PlayCraftEffect( Mobile from )
{
from.PlaySound( 0x249 );
}
public override int PlayEndingEffect( Mobile from, bool failed, bool lostMaterial, bool toolBroken, int quality, bool makersMark, CraftItem item )
{
if ( toolBroken )
from.SendLocalizedMessage( 1044038 ); // You have worn out your tool
if ( failed )
{
if ( lostMaterial )
return 1044043; // You failed to create the item, and some of your materials are lost.
else
return 1044157; // You failed to create the item, but no materials were lost.
}
else
{
if ( quality == 0 )
return 502785; // You were barely able to make this item. It's quality is below average.
else if ( makersMark && quality == 2 )
return 1044156; // You create an exceptional quality item and affix your maker's mark.
else if ( quality == 2 )
return 1044155; // You create an exceptional quality item.
else
return 1044154; // You create the item.
}
}
public override void InitCraftList()
{
AddCraft( typeof( LocalMap ), 1044448, 1015230, 10.0, 70.0, typeof( BlankMap ), 1044449, 1, 1044450 );
AddCraft( typeof( CityMap ), 1044448, 1015231, 25.0, 85.0, typeof( BlankMap ), 1044449, 1, 1044450 );
AddCraft( typeof( SeaChart ), 1044448, 1015232, 35.0, 95.0, typeof( BlankMap ), 1044449, 1, 1044450 );
AddCraft( typeof( WorldMap ), 1044448, 1015233, 39.5, 99.5, typeof( BlankMap ), 1044449, 1, 1044450 );
}
}
}

View file

@ -0,0 +1,203 @@
using System;
using Server.Items;
using Server.Misc;
namespace Server.Engines.Craft
{
public class DefCooking : CraftSystem
{
public override Trades MainSkill
{
get { return Trades.Cooking; }
}
public override int GumpTitleNumber
{
get { return 1044003; } // <CENTER>COOKING MENU</CENTER>
}
private static CraftSystem m_CraftSystem;
public static CraftSystem CraftSystem
{
get
{
if ( m_CraftSystem == null )
m_CraftSystem = new DefCooking();
return m_CraftSystem;
}
}
public override CraftECA ECA{ get{ return CraftECA.ChanceMinusSixtyToFourtyFive; } }
public override double GetChanceAtMin( CraftItem item )
{
return 0.0; // 0%
}
private DefCooking() : base( 1, 1, 1.25 )
{
}
public override int CanCraft( Mobile from, BaseTool tool, Type itemType )
{
if( tool == null || tool.Deleted || tool.UsesRemaining < 0 )
return 1044038; // You have worn out your tool!
else if ( !BaseTool.CheckAccessible( tool, from ) )
return 1044263; // The tool must be on your person to use.
return 0;
}
public override void PlayCraftEffect( Mobile from )
{
}
public override int PlayEndingEffect( Mobile from, bool failed, bool lostMaterial, bool toolBroken, int quality, bool makersMark, CraftItem item )
{
if ( toolBroken )
from.SendLocalizedMessage( 1044038 ); // You have worn out your tool
if ( failed )
{
if ( lostMaterial )
return 1044043; // You failed to create the item, and some of your materials are lost.
else
return 1044157; // You failed to create the item, but no materials were lost.
}
else
{
if ( quality == 0 )
return 502785; // You were barely able to make this item. It's quality is below average.
else if ( makersMark && quality == 2 )
return 1044156; // You create an exceptional quality item and affix your maker's mark.
else if ( quality == 2 )
return 1044155; // You create an exceptional quality item.
else
return 1044154; // You create the item.
}
}
public override void InitCraftList()
{
int index = -1;
/* Begin Ingredients */
index = AddCraft( typeof( SackFlour ), 1044495, 1024153, 0.0, 100.0, typeof( WheatSheaf ), 1044489, 2, 1044490 );
SetNeedMill( index, true );
index = AddCraft( typeof( Dough ), 1044495, 1024157, 0.0, 100.0, typeof( SackFlour ), 1044468, 1, 1044253 );
AddRes( index, typeof( BaseBeverage ), 1046458, 1, 1044253 );
index = AddCraft( typeof( SweetDough ), 1044495, 1041340, 0.0, 100.0, typeof( Dough ), 1044469, 1, 1044253 );
AddRes( index, typeof( JarHoney ), 1044472, 1, 1044253 );
index = AddCraft( typeof( CakeMix ), 1044495, 1041002, 0.0, 100.0, typeof( SackFlour ), 1044468, 1, 1044253 );
AddRes( index, typeof( SweetDough ), 1044475, 1, 1044253 );
index = AddCraft( typeof( CookieMix ), 1044495, 1024159, 0.0, 100.0, typeof( JarHoney ), 1044472, 1, 1044253 );
AddRes( index, typeof( SweetDough ), 1044475, 1, 1044253 );
/* End Ingredients */
/* Begin Preparations */
index = AddCraft( typeof( UnbakedQuiche ), 1044496, 1041339, 0.0, 100.0, typeof( Dough ), 1044469, 1, 1044253 );
AddRes( index, typeof( Eggs ), 1044477, 1, 1044253 );
// TODO: This must also support chicken and lamb legs
index = AddCraft( typeof( UnbakedMeatPie ), 1044496, 1041338, 0.0, 100.0, typeof( Dough ), 1044469, 1, 1044253 );
AddRes( index, typeof( RawRibs ), 1044482, 1, 1044253 );
index = AddCraft( typeof( UncookedSausagePizza ), 1044496, 1041337, 0.0, 100.0, typeof( Dough ), 1044469, 1, 1044253 );
AddRes( index, typeof( Sausage ), 1044483, 1, 1044253 );
index = AddCraft( typeof( UncookedCheesePizza ), 1044496, 1041341, 0.0, 100.0, typeof( Dough ), 1044469, 1, 1044253 );
AddRes( index, typeof( CheeseWheel ), 1044486, 1, 1044253 );
index = AddCraft( typeof( UnbakedFruitPie ), 1044496, 1041334, 0.0, 100.0, typeof( Dough ), 1044469, 1, 1044253 );
AddRes( index, typeof( Pear ), 1044481, 1, 1044253 );
index = AddCraft( typeof( UnbakedPeachCobbler ), 1044496, 1041335, 0.0, 100.0, typeof( Dough ), 1044469, 1, 1044253 );
AddRes( index, typeof( Peach ), 1044480, 1, 1044253 );
index = AddCraft( typeof( UnbakedApplePie ), 1044496, 1041336, 0.0, 100.0, typeof( Dough ), 1044469, 1, 1044253 );
AddRes( index, typeof( Apple ), 1044479, 1, 1044253 );
index = AddCraft( typeof( UnbakedPumpkinPie ), 1044496, 1041342, 0.0, 100.0, typeof( Dough ), 1044469, 1, 1044253 );
AddRes( index, typeof( Pumpkin ), 1044484, 1, 1044253 );
/* End Preparations */
/* Begin Baking */
index = AddCraft( typeof( BreadLoaf ), 1044497, 1024156, 0.0, 100.0, typeof( Dough ), 1044469, 1, 1044253 );
SetNeedOven( index, true );
index = AddCraft( typeof( Cookies ), 1044497, 1025643, 0.0, 100.0, typeof( CookieMix ), 1044474, 1, 1044253 );
SetNeedOven( index, true );
index = AddCraft( typeof( Cake ), 1044497, 1022537, 0.0, 100.0, typeof( CakeMix ), 1044471, 1, 1044253 );
SetNeedOven( index, true );
index = AddCraft( typeof( Muffins ), 1044497, 1022539, 0.0, 100.0, typeof( SweetDough ), 1044475, 1, 1044253 );
SetNeedOven( index, true );
index = AddCraft( typeof( Quiche ), 1044497, 1041345, 0.0, 100.0, typeof( UnbakedQuiche ), 1044518, 1, 1044253 );
SetNeedOven( index, true );
index = AddCraft( typeof( MeatPie ), 1044497, 1041347, 0.0, 100.0, typeof( UnbakedMeatPie ), 1044519, 1, 1044253 );
SetNeedOven( index, true );
index = AddCraft( typeof( SausagePizza ), 1044497, 1044517, 0.0, 100.0, typeof( UncookedSausagePizza ), 1044520, 1, 1044253 );
SetNeedOven( index, true );
index = AddCraft( typeof( CheesePizza ), 1044497, 1044516, 0.0, 100.0, typeof( UncookedCheesePizza ), 1044521, 1, 1044253 );
SetNeedOven( index, true );
index = AddCraft( typeof( FruitPie ), 1044497, 1041346, 0.0, 100.0, typeof( UnbakedFruitPie ), 1044522, 1, 1044253 );
SetNeedOven( index, true );
index = AddCraft( typeof( PeachCobbler ), 1044497, 1041344, 0.0, 100.0, typeof( UnbakedPeachCobbler ), 1044523, 1, 1044253 );
SetNeedOven( index, true );
index = AddCraft( typeof( ApplePie ), 1044497, 1041343, 0.0, 100.0, typeof( UnbakedApplePie ), 1044524, 1, 1044253 );
SetNeedOven( index, true );
index = AddCraft( typeof( PumpkinPie ), 1044497, 1041348, 0.0, 100.0, typeof( UnbakedPumpkinPie ), 1046461, 1, 1044253 );
SetNeedOven( index, true );
/* End Baking */
/* Begin Barbecue */
index = AddCraft( typeof( CookedBird ), 1044498, 1022487, 0.0, 100.0, typeof( RawBird ), 1044470, 1, 1044253 );
SetNeedHeat( index, true );
SetUseAllRes( index, true );
index = AddCraft( typeof( ChickenLeg ), 1044498, 1025640, 0.0, 100.0, typeof( RawChickenLeg ), 1044473, 1, 1044253 );
SetNeedHeat( index, true );
SetUseAllRes( index, true );
index = AddCraft( typeof( Ham ), 1044498, 1022505, 0.0, 100.0, typeof( RawHam ), 1044499, 1, 1044253 );
SetNeedHeat( index, true );
SetUseAllRes( index, true );
index = AddCraft( typeof( FishSteak ), 1044498, 1022427, 0.0, 100.0, typeof( RawFishSteak ), 1044476, 1, 1044253 );
SetNeedHeat( index, true );
SetUseAllRes( index, true );
index = AddCraft( typeof( FriedEggs ), 1044498, 1022486, 0.0, 100.0, typeof( Eggs ), 1044477, 1, 1044253 );
SetNeedHeat( index, true );
SetUseAllRes( index, true );
index = AddCraft( typeof( LambLeg ), 1044498, 1025642, 0.0, 100.0, typeof( RawLambLeg ), 1044478, 1, 1044253 );
SetNeedHeat( index, true );
SetUseAllRes( index, true );
index = AddCraft( typeof( Ribs ), 1044498, 1022546, 0.0, 100.0, typeof( RawRibs ), 1044485, 1, 1044253 );
SetNeedHeat( index, true );
SetUseAllRes( index, true );
index = AddCraft( typeof( SlabOfBacon ), 1044498, 1022422, 0.0, 100.0, typeof( RawSlabOfBacon ), 1044574, 1, 1044253 );
SetNeedHeat( index, true );
SetUseAllRes( index, true );
/* End Barbecue */
}
}
}

Some files were not shown because too many files have changed in this diff Show more