Fixes code according to modern code style. Fixes a few expression bugs.
This commit is contained in:
parent
89eea25e5f
commit
970fd563b2
3324 changed files with 441118 additions and 433755 deletions
|
|
@ -1,10 +0,0 @@
|
|||
# http://editorconfig.org
|
||||
root=true
|
||||
|
||||
[*]
|
||||
indent_style = tab
|
||||
tab_width = 4
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
|
|
@ -5,40 +5,42 @@ using Server.Misc;
|
|||
|
||||
namespace Server
|
||||
{
|
||||
public class AccessRestrictions
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.SocketConnect += EventSink_SocketConnect;
|
||||
}
|
||||
|
||||
private static void EventSink_SocketConnect( SocketConnectEventArgs e )
|
||||
{
|
||||
try
|
||||
{
|
||||
IPAddress ip = ((IPEndPoint)e.Socket.RemoteEndPoint).Address;
|
||||
public class AccessRestrictions
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.SocketConnect += EventSink_SocketConnect;
|
||||
}
|
||||
|
||||
if ( Firewall.IsBlocked( ip ) )
|
||||
{
|
||||
Console.WriteLine( "Client: {0}: Firewall blocked connection attempt.", ip );
|
||||
e.AllowConnection = false;
|
||||
return;
|
||||
}
|
||||
private static void EventSink_SocketConnect(SocketConnectEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
IPAddress ip = ((IPEndPoint)e.Socket.RemoteEndPoint).Address;
|
||||
|
||||
if ( IPLimiter.SocketBlock && !IPLimiter.Verify( ip ) )
|
||||
{
|
||||
Console.WriteLine( "Client: {0}: Past IP limit threshold", ip );
|
||||
if (Firewall.IsBlocked(ip))
|
||||
{
|
||||
Console.WriteLine("Client: {0}: Firewall blocked connection attempt.", ip);
|
||||
e.AllowConnection = false;
|
||||
return;
|
||||
}
|
||||
|
||||
using ( StreamWriter op = new StreamWriter( "ipLimits.log", true ) )
|
||||
op.WriteLine( "{0}\tPast IP limit threshold\t{1}", ip, DateTime.UtcNow );
|
||||
|
||||
e.AllowConnection = false;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
e.AllowConnection = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
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.UtcNow);
|
||||
}
|
||||
|
||||
e.AllowConnection = false;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
e.AllowConnection = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,121 +6,123 @@ using Server.Network;
|
|||
|
||||
namespace Server.Accounting
|
||||
{
|
||||
public class AccountAttackLimiter
|
||||
{
|
||||
public static bool Enabled = true;
|
||||
public class AccountAttackLimiter
|
||||
{
|
||||
public static bool Enabled = true;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if ( !Enabled )
|
||||
return;
|
||||
private static List<InvalidAccountAccessLog> m_List = new List<InvalidAccountAccessLog>();
|
||||
|
||||
PacketHandlers.RegisterThrottler( 0x80, Throttle_Callback );
|
||||
PacketHandlers.RegisterThrottler( 0x91, Throttle_Callback );
|
||||
PacketHandlers.RegisterThrottler( 0xCF, Throttle_Callback );
|
||||
}
|
||||
public static void Initialize()
|
||||
{
|
||||
if (!Enabled)
|
||||
return;
|
||||
|
||||
public static bool Throttle_Callback( NetState ns )
|
||||
{
|
||||
InvalidAccountAccessLog accessLog = FindAccessLog( ns );
|
||||
PacketHandlers.RegisterThrottler(0x80, Throttle_Callback);
|
||||
PacketHandlers.RegisterThrottler(0x91, Throttle_Callback);
|
||||
PacketHandlers.RegisterThrottler(0xCF, Throttle_Callback);
|
||||
}
|
||||
|
||||
if ( accessLog == null )
|
||||
return true;
|
||||
public static bool Throttle_Callback(NetState ns)
|
||||
{
|
||||
InvalidAccountAccessLog accessLog = FindAccessLog(ns);
|
||||
|
||||
return ( DateTime.UtcNow >= (accessLog.LastAccessTime + ComputeThrottle( accessLog.Counts )) );
|
||||
}
|
||||
if (accessLog == null)
|
||||
return true;
|
||||
|
||||
private static List<InvalidAccountAccessLog> m_List = new List<InvalidAccountAccessLog>();
|
||||
return DateTime.UtcNow >= accessLog.LastAccessTime + ComputeThrottle(accessLog.Counts);
|
||||
}
|
||||
|
||||
public static InvalidAccountAccessLog FindAccessLog( NetState ns )
|
||||
{
|
||||
if ( ns == null )
|
||||
return null;
|
||||
public static InvalidAccountAccessLog FindAccessLog(NetState ns)
|
||||
{
|
||||
if (ns == null)
|
||||
return null;
|
||||
|
||||
IPAddress ipAddress = ns.Address;
|
||||
IPAddress ipAddress = ns.Address;
|
||||
|
||||
for ( int i = 0; i < m_List.Count; ++i )
|
||||
{
|
||||
InvalidAccountAccessLog accessLog = m_List[i];
|
||||
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;
|
||||
}
|
||||
if (accessLog.HasExpired)
|
||||
m_List.RemoveAt(i--);
|
||||
else if (accessLog.Address.Equals(ipAddress))
|
||||
return accessLog;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void RegisterInvalidAccess( NetState ns )
|
||||
{
|
||||
if ( ns == null || !Enabled )
|
||||
return;
|
||||
public static void RegisterInvalidAccess(NetState ns)
|
||||
{
|
||||
if (ns == null || !Enabled)
|
||||
return;
|
||||
|
||||
InvalidAccountAccessLog accessLog = FindAccessLog( ns );
|
||||
InvalidAccountAccessLog accessLog = FindAccessLog(ns);
|
||||
|
||||
if ( accessLog == null )
|
||||
m_List.Add( accessLog = new InvalidAccountAccessLog( ns.Address ) );
|
||||
if (accessLog == null)
|
||||
m_List.Add(accessLog = new InvalidAccountAccessLog(ns.Address));
|
||||
|
||||
accessLog.Counts += 1;
|
||||
accessLog.RefreshAccessTime();
|
||||
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.UtcNow,
|
||||
ns,
|
||||
accessLog.Counts
|
||||
);
|
||||
}
|
||||
}
|
||||
catch {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (accessLog.Counts >= 3)
|
||||
try
|
||||
{
|
||||
using (StreamWriter op = new StreamWriter("throttle.log", true))
|
||||
{
|
||||
op.WriteLine(
|
||||
"{0}\t{1}\t{2}",
|
||||
DateTime.UtcNow,
|
||||
ns,
|
||||
accessLog.Counts
|
||||
);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static TimeSpan ComputeThrottle( int counts )
|
||||
{
|
||||
if ( counts >= 15 )
|
||||
return TimeSpan.FromMinutes( 5.0 );
|
||||
public static TimeSpan ComputeThrottle(int counts)
|
||||
{
|
||||
if (counts >= 15)
|
||||
return TimeSpan.FromMinutes(5.0);
|
||||
|
||||
if ( counts >= 10 )
|
||||
return TimeSpan.FromMinutes( 1.0 );
|
||||
if (counts >= 10)
|
||||
return TimeSpan.FromMinutes(1.0);
|
||||
|
||||
if ( counts >= 5 )
|
||||
return TimeSpan.FromSeconds( 20.0 );
|
||||
if (counts >= 5)
|
||||
return TimeSpan.FromSeconds(20.0);
|
||||
|
||||
if ( counts >= 3 )
|
||||
return TimeSpan.FromSeconds( 10.0 );
|
||||
if (counts >= 3)
|
||||
return TimeSpan.FromSeconds(10.0);
|
||||
|
||||
if ( counts >= 1 )
|
||||
return TimeSpan.FromSeconds( 2.0 );
|
||||
if (counts >= 1)
|
||||
return TimeSpan.FromSeconds(2.0);
|
||||
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public class InvalidAccountAccessLog
|
||||
{
|
||||
public IPAddress Address { get; set; }
|
||||
public class InvalidAccountAccessLog
|
||||
{
|
||||
public InvalidAccountAccessLog(IPAddress address)
|
||||
{
|
||||
Address = address;
|
||||
RefreshAccessTime();
|
||||
}
|
||||
|
||||
public DateTime LastAccessTime { get; set; }
|
||||
public IPAddress Address{ get; set; }
|
||||
|
||||
public bool HasExpired => ( DateTime.UtcNow >= ( LastAccessTime + TimeSpan.FromHours( 1.0 ) ) );
|
||||
public DateTime LastAccessTime{ get; set; }
|
||||
|
||||
public int Counts { get; set; }
|
||||
public bool HasExpired => DateTime.UtcNow >= LastAccessTime + TimeSpan.FromHours(1.0);
|
||||
|
||||
public void RefreshAccessTime()
|
||||
{
|
||||
LastAccessTime = DateTime.UtcNow;
|
||||
}
|
||||
public int Counts{ get; set; }
|
||||
|
||||
public InvalidAccountAccessLog( IPAddress address )
|
||||
{
|
||||
Address = address;
|
||||
RefreshAccessTime();
|
||||
}
|
||||
}
|
||||
public void RefreshAccessTime()
|
||||
{
|
||||
LastAccessTime = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,67 +3,71 @@ using System.Xml;
|
|||
|
||||
namespace Server.Accounting
|
||||
{
|
||||
public class AccountComment
|
||||
{
|
||||
private string m_Content;
|
||||
public class AccountComment
|
||||
{
|
||||
private string m_Content;
|
||||
|
||||
/// <summary>
|
||||
/// A string representing who added this comment.
|
||||
/// </summary>
|
||||
public string AddedBy { get; }
|
||||
/// <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)
|
||||
{
|
||||
AddedBy = addedBy;
|
||||
m_Content = content;
|
||||
LastModified = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the body of this comment. Setting this value will reset LastModified.
|
||||
/// </summary>
|
||||
public string Content
|
||||
{
|
||||
get => m_Content;
|
||||
set{ m_Content = value; LastModified = DateTime.UtcNow; }
|
||||
}
|
||||
/// <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)
|
||||
{
|
||||
AddedBy = Utility.GetAttribute(node, "addedBy", "empty");
|
||||
LastModified = Utility.GetXMLDateTime(Utility.GetAttribute(node, "lastModified"), DateTime.UtcNow);
|
||||
m_Content = Utility.GetText(node, "");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The date and time when this account was last modified -or- the comment creation time, if never modified.
|
||||
/// </summary>
|
||||
public DateTime LastModified { get; private set; }
|
||||
/// <summary>
|
||||
/// A string representing who added this comment.
|
||||
/// </summary>
|
||||
public string AddedBy{ get; }
|
||||
|
||||
/// <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 )
|
||||
{
|
||||
AddedBy = addedBy;
|
||||
m_Content = content;
|
||||
LastModified = DateTime.UtcNow;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the body of this comment. Setting this value will reset LastModified.
|
||||
/// </summary>
|
||||
public string Content
|
||||
{
|
||||
get => m_Content;
|
||||
set
|
||||
{
|
||||
m_Content = value;
|
||||
LastModified = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
|
||||
/// <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 )
|
||||
{
|
||||
AddedBy = Utility.GetAttribute( node, "addedBy", "empty" );
|
||||
LastModified = Utility.GetXMLDateTime( Utility.GetAttribute( node, "lastModified" ), DateTime.UtcNow );
|
||||
m_Content = Utility.GetText( node, "" );
|
||||
}
|
||||
/// <summary>
|
||||
/// The date and time when this account was last modified -or- the comment creation time, if never modified.
|
||||
/// </summary>
|
||||
public DateTime LastModified{ get; private set; }
|
||||
|
||||
/// <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" );
|
||||
/// <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", AddedBy );
|
||||
xml.WriteAttributeString("addedBy", AddedBy);
|
||||
|
||||
xml.WriteAttributeString( "lastModified", XmlConvert.ToString( LastModified, XmlDateTimeSerializationMode.Utc ) );
|
||||
xml.WriteAttributeString("lastModified", XmlConvert.ToString(LastModified, XmlDateTimeSerializationMode.Utc));
|
||||
|
||||
xml.WriteString( m_Content );
|
||||
xml.WriteString(m_Content);
|
||||
|
||||
xml.WriteEndElement();
|
||||
}
|
||||
}
|
||||
xml.WriteEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,407 +10,417 @@ using Server.Regions;
|
|||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public enum PasswordProtection
|
||||
{
|
||||
None,
|
||||
Crypt,
|
||||
NewCrypt
|
||||
}
|
||||
public enum PasswordProtection
|
||||
{
|
||||
None,
|
||||
Crypt,
|
||||
NewCrypt
|
||||
}
|
||||
|
||||
public class AccountHandler
|
||||
{
|
||||
private static int MaxAccountsPerIP = 1;
|
||||
private static bool AutoAccountCreation = true;
|
||||
private static bool RestrictDeletion = !TestCenter.Enabled;
|
||||
private static TimeSpan DeleteDelay = TimeSpan.FromDays( 7.0 );
|
||||
public class AccountHandler
|
||||
{
|
||||
private static int MaxAccountsPerIP = 1;
|
||||
private static bool AutoAccountCreation = true;
|
||||
private static bool RestrictDeletion = !TestCenter.Enabled;
|
||||
private static TimeSpan DeleteDelay = TimeSpan.FromDays(7.0);
|
||||
|
||||
public static PasswordProtection ProtectPasswords = PasswordProtection.NewCrypt;
|
||||
public static PasswordProtection ProtectPasswords = PasswordProtection.NewCrypt;
|
||||
|
||||
public static AccessLevel LockdownLevel { get; set; }
|
||||
private static CityInfo[] StartingCities =
|
||||
{
|
||||
new CityInfo("New Haven", "New Haven Bank", 1150168, 3667, 2625, 0),
|
||||
new CityInfo("Yew", "The Empath Abbey", 1075072, 633, 858, 0),
|
||||
new CityInfo("Minoc", "The Barnacle", 1075073, 2476, 413, 15),
|
||||
new CityInfo("Britain", "The Wayfarer's Inn", 1075074, 1602, 1591, 20),
|
||||
new CityInfo("Moonglow", "The Scholars Inn", 1075075, 4408, 1168, 0),
|
||||
new CityInfo("Trinsic", "The Traveler's Inn", 1075076, 1845, 2745, 0),
|
||||
new CityInfo("Jhelom", "The Mercenary Inn", 1075078, 1374, 3826, 0),
|
||||
new CityInfo("Skara Brae", "The Falconer's Inn", 1075079, 618, 2234, 0),
|
||||
new CityInfo("Vesper", "The Ironwood Inn", 1075080, 2771, 976, 0)
|
||||
};
|
||||
|
||||
private static CityInfo[] StartingCities = {
|
||||
new CityInfo( "New Haven", "New Haven Bank", 1150168, 3667, 2625, 0 ),
|
||||
new CityInfo( "Yew", "The Empath Abbey", 1075072, 633, 858, 0 ),
|
||||
new CityInfo( "Minoc", "The Barnacle", 1075073, 2476, 413, 15 ),
|
||||
new CityInfo( "Britain", "The Wayfarer's Inn", 1075074, 1602, 1591, 20 ),
|
||||
new CityInfo( "Moonglow", "The Scholars Inn", 1075075, 4408, 1168, 0 ),
|
||||
new CityInfo( "Trinsic", "The Traveler's Inn", 1075076, 1845, 2745, 0 ),
|
||||
new CityInfo( "Jhelom", "The Mercenary Inn", 1075078, 1374, 3826, 0 ),
|
||||
new CityInfo( "Skara Brae", "The Falconer's Inn", 1075079, 618, 2234, 0 ),
|
||||
new CityInfo( "Vesper", "The Ironwood Inn", 1075080, 2771, 976, 0 )
|
||||
};
|
||||
/* Old Haven/Magincia Locations
|
||||
new CityInfo( "Britain", "Sweet Dreams Inn", 1496, 1628, 10 );
|
||||
// ..
|
||||
// Trinsic
|
||||
new CityInfo( "Magincia", "The Great Horns Tavern", 3734, 2222, 20 ),
|
||||
// Jhelom
|
||||
// ..
|
||||
new CityInfo( "Haven", "Buckler's Hideaway", 3667, 2625, 0 )
|
||||
|
||||
/* Old Haven/Magincia Locations
|
||||
new CityInfo( "Britain", "Sweet Dreams Inn", 1496, 1628, 10 );
|
||||
// ..
|
||||
// Trinsic
|
||||
new CityInfo( "Magincia", "The Great Horns Tavern", 3734, 2222, 20 ),
|
||||
// Jhelom
|
||||
// ..
|
||||
new CityInfo( "Haven", "Buckler's Hideaway", 3667, 2625, 0 )
|
||||
if ( Core.AOS )
|
||||
{
|
||||
//CityInfo haven = new CityInfo( "Haven", "Uzeraan's Mansion", 3618, 2591, 0 );
|
||||
CityInfo haven = new CityInfo( "Haven", "Uzeraan's Mansion", 3503, 2574, 14 );
|
||||
StartingCities[StartingCities.Length - 1] = haven;
|
||||
}
|
||||
*/
|
||||
|
||||
if ( Core.AOS )
|
||||
{
|
||||
//CityInfo haven = new CityInfo( "Haven", "Uzeraan's Mansion", 3618, 2591, 0 );
|
||||
CityInfo haven = new CityInfo( "Haven", "Uzeraan's Mansion", 3503, 2574, 14 );
|
||||
StartingCities[StartingCities.Length - 1] = haven;
|
||||
}
|
||||
*/
|
||||
private static bool PasswordCommandEnabled = false;
|
||||
|
||||
private static bool PasswordCommandEnabled = false;
|
||||
private static Dictionary<IPAddress, int> m_IPTable;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.DeleteRequest += EventSink_DeleteRequest;
|
||||
EventSink.AccountLogin += EventSink_AccountLogin;
|
||||
EventSink.GameLogin += EventSink_GameLogin;
|
||||
private static readonly char[] m_ForbiddenChars =
|
||||
{
|
||||
'<', '>', ':', '"', '/', '\\', '|', '?', '*'
|
||||
};
|
||||
|
||||
if ( PasswordCommandEnabled )
|
||||
CommandSystem.Register( "Password", AccessLevel.Player, Password_OnCommand );
|
||||
}
|
||||
public static AccessLevel LockdownLevel{ get; set; }
|
||||
|
||||
[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;
|
||||
public static Dictionary<IPAddress, int> IPTable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_IPTable == null)
|
||||
{
|
||||
m_IPTable = new Dictionary<IPAddress, int>();
|
||||
|
||||
if ( !(from.Account is Account acct) )
|
||||
return;
|
||||
foreach (Account a in Accounts.GetAccounts())
|
||||
if (a.LoginIPs.Length > 0)
|
||||
{
|
||||
IPAddress ip = a.LoginIPs[0];
|
||||
|
||||
IPAddress[] accessList = acct.LoginIPs;
|
||||
if (m_IPTable.ContainsKey(ip))
|
||||
m_IPTable[ip]++;
|
||||
else
|
||||
m_IPTable[ip] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( accessList.Length == 0 )
|
||||
return;
|
||||
return m_IPTable;
|
||||
}
|
||||
}
|
||||
|
||||
NetState ns = from.NetState;
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.DeleteRequest += EventSink_DeleteRequest;
|
||||
EventSink.AccountLogin += EventSink_AccountLogin;
|
||||
EventSink.GameLogin += EventSink_GameLogin;
|
||||
|
||||
if ( ns == null )
|
||||
return;
|
||||
if (PasswordCommandEnabled)
|
||||
CommandSystem.Register("Password", AccessLevel.Player, Password_OnCommand);
|
||||
}
|
||||
|
||||
if ( e.Length == 0 )
|
||||
{
|
||||
from.SendMessage( "You must specify the new password." );
|
||||
return;
|
||||
}
|
||||
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;
|
||||
}
|
||||
[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;
|
||||
|
||||
string pass = e.GetString( 0 );
|
||||
string pass2 = e.GetString( 1 );
|
||||
if (!(from.Account is Account acct))
|
||||
return;
|
||||
|
||||
if ( pass != pass2 )
|
||||
{
|
||||
from.SendMessage( "The passwords do not match." );
|
||||
return;
|
||||
}
|
||||
IPAddress[] accessList = acct.LoginIPs;
|
||||
|
||||
bool isSafe = true;
|
||||
if (accessList.Length == 0)
|
||||
return;
|
||||
|
||||
for ( int i = 0; isSafe && i < pass.Length; ++i )
|
||||
isSafe = ( pass[i] >= 0x20 && pass[i] < 0x7F );
|
||||
NetState ns = from.NetState;
|
||||
|
||||
if ( !isSafe )
|
||||
{
|
||||
from.SendMessage( "That is not a valid password." );
|
||||
return;
|
||||
}
|
||||
if (ns == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
IPAddress ipAddress = ns.Address;
|
||||
if (e.Length == 0)
|
||||
{
|
||||
from.SendMessage("You must specify the new password.");
|
||||
return;
|
||||
}
|
||||
|
||||
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 (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;
|
||||
}
|
||||
|
||||
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." );
|
||||
string pass = e.GetString(0);
|
||||
string pass2 = e.GetString(1);
|
||||
|
||||
from.SendLocalizedMessage( 501234, "", 0x35 ); /* The next available Counselor/Game Master will respond as soon as possible.
|
||||
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] < 0x7F;
|
||||
|
||||
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,
|
||||
$"[Automated: Change Password]<br>Desired password: {pass}<br>Current IP address: {ipAddress}<br>Account IP address: {accessList[0]}", PageType.Account ) );
|
||||
}
|
||||
PageQueue.Enqueue(new PageEntry(from,
|
||||
$"[Automated: Change Password]<br>Desired password: {pass}<br>Current IP address: {ipAddress}<br>Account IP address: {accessList[0]}",
|
||||
PageType.Account));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
private static void EventSink_DeleteRequest(DeleteRequestEventArgs e)
|
||||
{
|
||||
NetState state = e.State;
|
||||
int index = e.Index;
|
||||
|
||||
private static void EventSink_DeleteRequest( DeleteRequestEventArgs e )
|
||||
{
|
||||
NetState state = e.State;
|
||||
int index = e.Index;
|
||||
if (!(state.Account is Account acct))
|
||||
{
|
||||
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 ( !(state.Account is Account acct) )
|
||||
{
|
||||
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.UtcNow < m.CreationTime + DeleteDelay)
|
||||
{
|
||||
state.Send(new DeleteResult(DeleteResultType.CharTooYoung));
|
||||
state.Send(new CharacterListUpdate(acct));
|
||||
}
|
||||
else if (m.AccessLevel == AccessLevel.Player &&
|
||||
Region.Find(m.LogoutLocation, m.LogoutMap).GetRegion(typeof(Jail)) != null
|
||||
) //Don't need to check current location, if netstate is null, they're logged out
|
||||
{
|
||||
state.Send(new DeleteResult(DeleteResultType.BadRequest));
|
||||
state.Send(new CharacterListUpdate(acct));
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Client: {0}: Deleting character {1} (0x{2:X})", state, index, m.Serial.Value);
|
||||
|
||||
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.UtcNow < (m.CreationTime + DeleteDelay) )
|
||||
{
|
||||
state.Send( new DeleteResult( DeleteResultType.CharTooYoung ) );
|
||||
state.Send( new CharacterListUpdate( acct ) );
|
||||
}
|
||||
else if ( m.AccessLevel == AccessLevel.Player && Region.Find( m.LogoutLocation, m.LogoutMap ).GetRegion( typeof( Jail ) ) != null ) //Don't need to check current location, if netstate is null, they're logged out
|
||||
{
|
||||
state.Send( new DeleteResult( DeleteResultType.BadRequest ) );
|
||||
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", $"Character #{index + 1} {m} deleted by {state}"));
|
||||
|
||||
acct.Comments.Add( new AccountComment( "System", $"Character #{index + 1} {m} deleted by {state}") );
|
||||
m.Delete();
|
||||
state.Send(new CharacterListUpdate(acct));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m.Delete();
|
||||
state.Send( new CharacterListUpdate( acct ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
public static bool CanCreate(IPAddress ip)
|
||||
{
|
||||
if (!IPTable.ContainsKey(ip))
|
||||
return true;
|
||||
|
||||
public static bool CanCreate( IPAddress ip )
|
||||
{
|
||||
if ( !IPTable.ContainsKey( ip ) )
|
||||
return true;
|
||||
return IPTable[ip] < MaxAccountsPerIP;
|
||||
}
|
||||
|
||||
return ( IPTable[ip] < MaxAccountsPerIP );
|
||||
}
|
||||
private static bool IsForbiddenChar(char c)
|
||||
{
|
||||
for (int i = 0; i < m_ForbiddenChars.Length; ++i)
|
||||
if (c == m_ForbiddenChars[i])
|
||||
return true;
|
||||
|
||||
private static Dictionary<IPAddress, int> m_IPTable;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Dictionary<IPAddress, int> IPTable
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( m_IPTable == null )
|
||||
{
|
||||
m_IPTable = new Dictionary<IPAddress, int>();
|
||||
private static Account CreateAccount(NetState state, string un, string pw)
|
||||
{
|
||||
if (un.Length == 0 || pw.Length == 0)
|
||||
return null;
|
||||
|
||||
foreach ( Account a in Accounts.GetAccounts() )
|
||||
if ( a.LoginIPs.Length > 0 )
|
||||
{
|
||||
IPAddress ip = a.LoginIPs[0];
|
||||
bool isSafe = !(un.StartsWith(" ") || un.EndsWith(" ") || un.EndsWith("."));
|
||||
|
||||
if ( m_IPTable.ContainsKey( ip ) )
|
||||
m_IPTable[ip]++;
|
||||
else
|
||||
m_IPTable[ip] = 1;
|
||||
}
|
||||
}
|
||||
for (int i = 0; isSafe && i < un.Length; ++i)
|
||||
isSafe = un[i] >= 0x20 && un[i] < 0x7F && !IsForbiddenChar(un[i]);
|
||||
|
||||
return m_IPTable;
|
||||
}
|
||||
}
|
||||
for (int i = 0; isSafe && i < pw.Length; ++i)
|
||||
isSafe = pw[i] >= 0x20 && pw[i] < 0x7F;
|
||||
|
||||
private static readonly char[] m_ForbiddenChars = {
|
||||
'<', '>', ':', '"', '/', '\\', '|', '?', '*'
|
||||
};
|
||||
if (!isSafe)
|
||||
return null;
|
||||
|
||||
private static bool IsForbiddenChar( char c )
|
||||
{
|
||||
for ( int i = 0; i < m_ForbiddenChars.Length; ++i )
|
||||
if ( c == m_ForbiddenChars[i] )
|
||||
return true;
|
||||
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;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
Console.WriteLine("Login: {0}: Creating new account '{1}'", state, un);
|
||||
|
||||
private static Account CreateAccount( NetState state, string un, string pw )
|
||||
{
|
||||
if ( un.Length == 0 || pw.Length == 0 )
|
||||
return null;
|
||||
Account a = new Account(un, pw);
|
||||
|
||||
bool isSafe = !( un.StartsWith( " " ) || un.EndsWith( " " ) || un.EndsWith( "." ) );
|
||||
return a;
|
||||
}
|
||||
|
||||
for ( int i = 0; isSafe && i < un.Length; ++i )
|
||||
isSafe = ( un[i] >= 0x20 && un[i] < 0x7F && !IsForbiddenChar( un[i] ) );
|
||||
public static void EventSink_AccountLogin(AccountLoginEventArgs e)
|
||||
{
|
||||
if (!IPLimiter.SocketBlock && !IPLimiter.Verify(e.State.Address))
|
||||
{
|
||||
e.Accepted = false;
|
||||
e.RejectReason = ALRReason.InUse;
|
||||
|
||||
for ( int i = 0; isSafe && i < pw.Length; ++i )
|
||||
isSafe = ( pw[i] >= 0x20 && pw[i] < 0x7F );
|
||||
Console.WriteLine("Login: {0}: Past IP limit threshold", e.State);
|
||||
|
||||
if ( !isSafe )
|
||||
return null;
|
||||
using (StreamWriter op = new StreamWriter("ipLimits.log", true))
|
||||
{
|
||||
op.WriteLine("{0}\tPast IP limit threshold\t{1}", e.State, DateTime.UtcNow);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine( "Login: {0}: Creating new account '{1}'", state, un );
|
||||
string un = e.Username;
|
||||
string pw = e.Password;
|
||||
|
||||
Account a = new Account( un, pw );
|
||||
e.Accepted = false;
|
||||
|
||||
return a;
|
||||
}
|
||||
if (!(Accounts.GetAccount(un) is Account acct))
|
||||
{
|
||||
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?.CheckAccess(e.State) ?? false;
|
||||
|
||||
public static void EventSink_AccountLogin( AccountLoginEventArgs e )
|
||||
{
|
||||
if ( !IPLimiter.SocketBlock && !IPLimiter.Verify( e.State.Address ) )
|
||||
{
|
||||
e.Accepted = false;
|
||||
e.RejectReason = ALRReason.InUse;
|
||||
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 = 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;
|
||||
|
||||
Console.WriteLine( "Login: {0}: Past IP limit threshold", e.State );
|
||||
acct.LogAccess(e.State);
|
||||
}
|
||||
|
||||
using ( StreamWriter op = new StreamWriter( "ipLimits.log", true ) )
|
||||
op.WriteLine( "{0}\tPast IP limit threshold\t{1}", e.State, DateTime.UtcNow );
|
||||
if (!e.Accepted)
|
||||
AccountAttackLimiter.RegisterInvalidAccess(e.State);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
public static void EventSink_GameLogin(GameLoginEventArgs e)
|
||||
{
|
||||
if (!IPLimiter.SocketBlock && !IPLimiter.Verify(e.State.Address))
|
||||
{
|
||||
e.Accepted = false;
|
||||
|
||||
string un = e.Username;
|
||||
string pw = e.Password;
|
||||
Console.WriteLine("Login: {0}: Past IP limit threshold", e.State);
|
||||
|
||||
e.Accepted = false;
|
||||
using (StreamWriter op = new StreamWriter("ipLimits.log", true))
|
||||
{
|
||||
op.WriteLine("{0}\tPast IP limit threshold\t{1}", e.State, DateTime.UtcNow);
|
||||
}
|
||||
|
||||
if ( !(Accounts.GetAccount( un ) is Account acct) )
|
||||
{
|
||||
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?.CheckAccess( e.State ) ?? false;
|
||||
return;
|
||||
}
|
||||
|
||||
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 = ( 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;
|
||||
string un = e.Username;
|
||||
string pw = e.Password;
|
||||
|
||||
acct.LogAccess( e.State );
|
||||
}
|
||||
if (!(Accounts.GetAccount(un) is Account acct))
|
||||
{
|
||||
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);
|
||||
|
||||
if ( !e.Accepted )
|
||||
AccountAttackLimiter.RegisterInvalidAccess( e.State );
|
||||
}
|
||||
Console.WriteLine("Login: {0}: Account '{1}' at character list", e.State, un);
|
||||
e.State.Account = acct;
|
||||
e.Accepted = true;
|
||||
e.CityInfo = StartingCities;
|
||||
}
|
||||
|
||||
public static void EventSink_GameLogin( GameLoginEventArgs e )
|
||||
{
|
||||
if ( !IPLimiter.SocketBlock && !IPLimiter.Verify( e.State.Address ) )
|
||||
{
|
||||
e.Accepted = false;
|
||||
if (!e.Accepted)
|
||||
AccountAttackLimiter.RegisterInvalidAccess(e.State);
|
||||
}
|
||||
|
||||
Console.WriteLine( "Login: {0}: Past IP limit threshold", e.State );
|
||||
public static bool CheckAccount(Mobile mobCheck, Mobile accCheck)
|
||||
{
|
||||
if (accCheck?.Account is Account a)
|
||||
for (int i = 0; i < a.Length; ++i)
|
||||
if (a[i] == mobCheck)
|
||||
return true;
|
||||
|
||||
using ( StreamWriter op = new StreamWriter( "ipLimits.log", true ) )
|
||||
op.WriteLine( "{0}\tPast IP limit threshold\t{1}", e.State, DateTime.UtcNow );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
string un = e.Username;
|
||||
string pw = e.Password;
|
||||
|
||||
if ( !(Accounts.GetAccount( un ) is Account acct) )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
|
||||
public static bool CheckAccount( Mobile mobCheck, Mobile accCheck )
|
||||
{
|
||||
if ( accCheck?.Account is Account a )
|
||||
{
|
||||
for ( int i = 0; i < a.Length; ++i )
|
||||
{
|
||||
if ( a[i] == mobCheck )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,49 +2,49 @@ using System.Xml;
|
|||
|
||||
namespace Server.Accounting
|
||||
{
|
||||
public class AccountTag
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name of this tag.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
public class AccountTag
|
||||
{
|
||||
/// <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)
|
||||
{
|
||||
Name = name;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value of this tag.
|
||||
/// </summary>
|
||||
public string Value { get; set; }
|
||||
/// <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)
|
||||
{
|
||||
Name = Utility.GetAttribute(node, "name", "empty");
|
||||
Value = Utility.GetText(node, "");
|
||||
}
|
||||
|
||||
/// <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 )
|
||||
{
|
||||
Name = name;
|
||||
Value = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the name of this tag.
|
||||
/// </summary>
|
||||
public string Name{ get; set; }
|
||||
|
||||
/// <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 )
|
||||
{
|
||||
Name = Utility.GetAttribute( node, "name", "empty" );
|
||||
Value = Utility.GetText( node, "" );
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the value of this tag.
|
||||
/// </summary>
|
||||
public string Value{ get; set; }
|
||||
|
||||
/// <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", Name );
|
||||
xml.WriteString( Value );
|
||||
xml.WriteEndElement();
|
||||
}
|
||||
}
|
||||
/// <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", Name);
|
||||
xml.WriteString(Value);
|
||||
xml.WriteEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,99 +5,97 @@ using System.Xml;
|
|||
|
||||
namespace Server.Accounting
|
||||
{
|
||||
public class Accounts
|
||||
{
|
||||
private static Dictionary<string, IAccount> m_Accounts = new Dictionary<string, IAccount>();
|
||||
public class Accounts
|
||||
{
|
||||
private static Dictionary<string, IAccount> m_Accounts = new Dictionary<string, IAccount>();
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
EventSink.WorldLoad += Load;
|
||||
EventSink.WorldSave += Save;
|
||||
}
|
||||
static Accounts()
|
||||
{
|
||||
}
|
||||
|
||||
static Accounts()
|
||||
{
|
||||
}
|
||||
public static int Count => m_Accounts.Count;
|
||||
|
||||
public static int Count => m_Accounts.Count;
|
||||
public static void Configure()
|
||||
{
|
||||
EventSink.WorldLoad += Load;
|
||||
EventSink.WorldSave += Save;
|
||||
}
|
||||
|
||||
public static ICollection<IAccount> GetAccounts()
|
||||
{
|
||||
return m_Accounts.Values;
|
||||
}
|
||||
public static ICollection<IAccount> GetAccounts()
|
||||
{
|
||||
return m_Accounts.Values;
|
||||
}
|
||||
|
||||
public static IAccount GetAccount( string username )
|
||||
{
|
||||
m_Accounts.TryGetValue( username, out IAccount a );
|
||||
public static IAccount GetAccount(string username)
|
||||
{
|
||||
m_Accounts.TryGetValue(username, out IAccount a);
|
||||
|
||||
return a;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
public static void Add( IAccount a )
|
||||
{
|
||||
m_Accounts[a.Username] = 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 Remove(string username)
|
||||
{
|
||||
m_Accounts.Remove(username);
|
||||
}
|
||||
|
||||
public static void Load()
|
||||
{
|
||||
m_Accounts = new Dictionary<string, IAccount>( 32, StringComparer.OrdinalIgnoreCase );
|
||||
public static void Load()
|
||||
{
|
||||
m_Accounts = new Dictionary<string, IAccount>(32, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
string filePath = Path.Combine( "Saves/Accounts", "accounts.xml" );
|
||||
string filePath = Path.Combine("Saves/Accounts", "accounts.xml");
|
||||
|
||||
if ( !File.Exists( filePath ) )
|
||||
return;
|
||||
if (!File.Exists(filePath))
|
||||
return;
|
||||
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load( filePath );
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(filePath);
|
||||
|
||||
XmlElement root = doc["accounts"];
|
||||
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" );
|
||||
}
|
||||
}
|
||||
}
|
||||
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" );
|
||||
public static void Save(WorldSaveEventArgs e)
|
||||
{
|
||||
if (!Directory.Exists("Saves/Accounts"))
|
||||
Directory.CreateDirectory("Saves/Accounts");
|
||||
|
||||
string filePath = Path.Combine( "Saves/Accounts", "accounts.xml" );
|
||||
string filePath = Path.Combine("Saves/Accounts", "accounts.xml");
|
||||
|
||||
using ( StreamWriter op = new StreamWriter( filePath ) )
|
||||
{
|
||||
XmlTextWriter xml = new XmlTextWriter( op );
|
||||
using (StreamWriter op = new StreamWriter(filePath))
|
||||
{
|
||||
XmlTextWriter xml = new XmlTextWriter(op);
|
||||
|
||||
xml.Formatting = Formatting.Indented;
|
||||
xml.IndentChar = '\t';
|
||||
xml.Indentation = 1;
|
||||
xml.Formatting = Formatting.Indented;
|
||||
xml.IndentChar = '\t';
|
||||
xml.Indentation = 1;
|
||||
|
||||
xml.WriteStartDocument( true );
|
||||
xml.WriteStartDocument(true);
|
||||
|
||||
xml.WriteStartElement( "accounts" );
|
||||
xml.WriteStartElement("accounts");
|
||||
|
||||
xml.WriteAttributeString( "count", m_Accounts.Count.ToString() );
|
||||
xml.WriteAttributeString("count", m_Accounts.Count.ToString());
|
||||
|
||||
foreach ( Account a in GetAccounts() )
|
||||
a.Save( xml );
|
||||
foreach (Account a in GetAccounts())
|
||||
a.Save(xml);
|
||||
|
||||
xml.WriteEndElement();
|
||||
xml.WriteEndElement();
|
||||
|
||||
xml.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
xml.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,303 +1,156 @@
|
|||
using System;
|
||||
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 Firewall
|
||||
{
|
||||
static Firewall()
|
||||
{
|
||||
List = new List<IFirewallEntry>();
|
||||
|
||||
public class IPFirewallEntry : IFirewallEntry
|
||||
{
|
||||
IPAddress m_Address;
|
||||
public IPFirewallEntry( IPAddress address )
|
||||
{
|
||||
m_Address = address;
|
||||
}
|
||||
string path = "firewall.cfg";
|
||||
|
||||
public bool IsBlocked( IPAddress address )
|
||||
{
|
||||
return m_Address.Equals( address );
|
||||
}
|
||||
if (File.Exists(path))
|
||||
using (StreamReader ip = new StreamReader(path))
|
||||
{
|
||||
string line;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return m_Address.ToString();
|
||||
}
|
||||
while ((line = ip.ReadLine()) != null)
|
||||
{
|
||||
line = line.Trim();
|
||||
|
||||
public override bool Equals( object obj )
|
||||
{
|
||||
if ( obj is IPAddress )
|
||||
{
|
||||
return obj.Equals( m_Address );
|
||||
}
|
||||
if ( obj is string s )
|
||||
{
|
||||
if ( IPAddress.TryParse( s, out IPAddress otherAddress ) )
|
||||
return otherAddress.Equals( m_Address );
|
||||
}
|
||||
else if ( obj is IPFirewallEntry entry )
|
||||
{
|
||||
return m_Address.Equals( entry.m_Address );
|
||||
}
|
||||
if (line.Length == 0)
|
||||
continue;
|
||||
|
||||
return false;
|
||||
}
|
||||
List.Add(ToFirewallEntry(line));
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return m_Address.GetHashCode();
|
||||
}
|
||||
}
|
||||
/*
|
||||
object toAdd;
|
||||
|
||||
public class CIDRFirewallEntry : IFirewallEntry
|
||||
{
|
||||
IPAddress m_CIDRPrefix;
|
||||
int m_CIDRLength;
|
||||
IPAddress addr;
|
||||
if ( IPAddress.TryParse( line, out addr ) )
|
||||
toAdd = addr;
|
||||
else
|
||||
toAdd = line;
|
||||
|
||||
public CIDRFirewallEntry( IPAddress cidrPrefix, int cidrLength )
|
||||
{
|
||||
m_CIDRPrefix = cidrPrefix;
|
||||
m_CIDRLength = cidrLength;
|
||||
}
|
||||
m_Blocked.Add( toAdd.ToString() );
|
||||
* */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsBlocked( IPAddress address )
|
||||
{
|
||||
return Utility.IPMatchCIDR( m_CIDRPrefix, address, m_CIDRLength );
|
||||
}
|
||||
public static List<IFirewallEntry> List{ get; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{m_CIDRPrefix}/{m_CIDRLength}";
|
||||
}
|
||||
public static IFirewallEntry ToFirewallEntry(object entry)
|
||||
{
|
||||
if (entry is IFirewallEntry firewallEntry)
|
||||
return firewallEntry;
|
||||
if (entry is IPAddress address)
|
||||
return new IPFirewallEntry(address);
|
||||
if (entry is string s)
|
||||
return ToFirewallEntry(s);
|
||||
|
||||
public override bool Equals( object obj )
|
||||
{
|
||||
if ( obj is string entry )
|
||||
{
|
||||
string[] str = entry.Split( '/' );
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( str.Length == 2 )
|
||||
{
|
||||
if ( IPAddress.TryParse( str[0], out IPAddress cidrPrefix ) )
|
||||
{
|
||||
if ( int.TryParse( str[1], out int cidrLength ) )
|
||||
return m_CIDRPrefix.Equals( cidrPrefix ) && m_CIDRLength.Equals( cidrLength );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( obj is CIDRFirewallEntry cidrEntry )
|
||||
{
|
||||
return m_CIDRPrefix.Equals( cidrEntry.m_CIDRPrefix ) && m_CIDRLength.Equals( cidrEntry.m_CIDRLength );
|
||||
}
|
||||
public static IFirewallEntry ToFirewallEntry(string entry)
|
||||
{
|
||||
if (IPAddress.TryParse(entry, out IPAddress addr))
|
||||
return new IPFirewallEntry(addr);
|
||||
|
||||
return false;
|
||||
}
|
||||
//Try CIDR parse
|
||||
string[] str = entry.Split('/');
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return m_CIDRPrefix.GetHashCode() ^ m_CIDRLength.GetHashCode();
|
||||
}
|
||||
}
|
||||
if (str.Length == 2)
|
||||
if (IPAddress.TryParse(str[0], out IPAddress cidrPrefix))
|
||||
if (int.TryParse(str[1], out int cidrLength))
|
||||
return new CIDRFirewallEntry(cidrPrefix, cidrLength);
|
||||
|
||||
public class WildcardIPFirewallEntry : IFirewallEntry
|
||||
{
|
||||
string m_Entry;
|
||||
return new WildcardIPFirewallEntry(entry);
|
||||
}
|
||||
|
||||
bool m_Valid = true;
|
||||
public static void RemoveAt(int index)
|
||||
{
|
||||
List.RemoveAt(index);
|
||||
Save();
|
||||
}
|
||||
|
||||
public WildcardIPFirewallEntry( string entry )
|
||||
{
|
||||
m_Entry = entry;
|
||||
}
|
||||
public static void Remove(object obj)
|
||||
{
|
||||
IFirewallEntry entry = ToFirewallEntry(obj);
|
||||
|
||||
public bool IsBlocked( IPAddress address )
|
||||
{
|
||||
if ( !m_Valid )
|
||||
return false; //Why process if it's invalid? it'll return false anyway after processing it.
|
||||
if (entry != null)
|
||||
{
|
||||
List.Remove(entry);
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
return Utility.IPMatch( m_Entry, address, ref m_Valid );
|
||||
}
|
||||
public static void Add(object obj)
|
||||
{
|
||||
if (obj is IPAddress address)
|
||||
Add(address);
|
||||
else if (obj is string s)
|
||||
Add(s);
|
||||
else if (obj is IFirewallEntry entry)
|
||||
Add(entry);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return m_Entry;
|
||||
}
|
||||
public static void Add(IFirewallEntry entry)
|
||||
{
|
||||
if (!List.Contains(entry))
|
||||
List.Add(entry);
|
||||
|
||||
public override bool Equals( object obj )
|
||||
{
|
||||
if ( obj is string )
|
||||
return obj.Equals( m_Entry );
|
||||
Save();
|
||||
}
|
||||
|
||||
return obj is WildcardIPFirewallEntry entry && m_Entry.Equals( entry.m_Entry );
|
||||
}
|
||||
public static void Add(string pattern)
|
||||
{
|
||||
IFirewallEntry entry = ToFirewallEntry(pattern);
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return m_Entry.GetHashCode();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
if (!List.Contains(entry))
|
||||
List.Add(entry);
|
||||
|
||||
static Firewall()
|
||||
{
|
||||
List = new List<IFirewallEntry>();
|
||||
Save();
|
||||
}
|
||||
|
||||
string path = "firewall.cfg";
|
||||
public static void Add(IPAddress ip)
|
||||
{
|
||||
IFirewallEntry entry = new IPFirewallEntry(ip);
|
||||
|
||||
if ( File.Exists( path ) )
|
||||
{
|
||||
using ( StreamReader ip = new StreamReader( path ) )
|
||||
{
|
||||
string line;
|
||||
if (!List.Contains(entry))
|
||||
List.Add(entry);
|
||||
|
||||
while ( (line = ip.ReadLine()) != null )
|
||||
{
|
||||
line = line.Trim();
|
||||
Save();
|
||||
}
|
||||
|
||||
if ( line.Length == 0 )
|
||||
continue;
|
||||
public static void Save()
|
||||
{
|
||||
string path = "firewall.cfg";
|
||||
|
||||
List.Add( ToFirewallEntry( line ) );
|
||||
using (StreamWriter op = new StreamWriter(path))
|
||||
{
|
||||
for (int i = 0; i < List.Count; ++i)
|
||||
op.WriteLine(List[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
object toAdd;
|
||||
public static bool IsBlocked(IPAddress ip)
|
||||
{
|
||||
for (int i = 0; i < List.Count; i++)
|
||||
if (List[i].IsBlocked(ip))
|
||||
return true;
|
||||
|
||||
IPAddress addr;
|
||||
if ( IPAddress.TryParse( line, out addr ) )
|
||||
toAdd = addr;
|
||||
else
|
||||
toAdd = line;
|
||||
return false;
|
||||
/*
|
||||
bool contains = false;
|
||||
|
||||
m_Blocked.Add( toAdd.ToString() );
|
||||
* */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<IFirewallEntry> List { get; }
|
||||
|
||||
public static IFirewallEntry ToFirewallEntry( object entry )
|
||||
{
|
||||
if ( entry is IFirewallEntry firewallEntry )
|
||||
return firewallEntry;
|
||||
if ( entry is IPAddress address )
|
||||
return new IPFirewallEntry( address );
|
||||
if ( entry is string s )
|
||||
return ToFirewallEntry( s );
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IFirewallEntry ToFirewallEntry( string entry )
|
||||
{
|
||||
if ( IPAddress.TryParse( entry, out IPAddress addr ) )
|
||||
return new IPFirewallEntry( addr );
|
||||
|
||||
//Try CIDR parse
|
||||
string[] str = entry.Split( '/' );
|
||||
|
||||
if ( str.Length == 2 )
|
||||
{
|
||||
if ( IPAddress.TryParse( str[0], out IPAddress cidrPrefix ) )
|
||||
{
|
||||
if ( int.TryParse( str[1], out int cidrLength ) )
|
||||
return new CIDRFirewallEntry( cidrPrefix, cidrLength );
|
||||
}
|
||||
}
|
||||
|
||||
return new WildcardIPFirewallEntry( entry );
|
||||
}
|
||||
|
||||
public static void RemoveAt( int index )
|
||||
{
|
||||
List.RemoveAt( index );
|
||||
Save();
|
||||
}
|
||||
|
||||
public static void Remove( object obj )
|
||||
{
|
||||
IFirewallEntry entry = ToFirewallEntry( obj );
|
||||
|
||||
if ( entry != null )
|
||||
{
|
||||
List.Remove( entry );
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Add( object obj )
|
||||
{
|
||||
if ( obj is IPAddress address )
|
||||
Add( address );
|
||||
else if ( obj is string s )
|
||||
Add( s );
|
||||
else if ( obj is IFirewallEntry entry )
|
||||
Add( entry );
|
||||
}
|
||||
|
||||
public static void Add( IFirewallEntry entry )
|
||||
{
|
||||
if ( !List.Contains( entry ) )
|
||||
List.Add( entry );
|
||||
|
||||
Save();
|
||||
}
|
||||
|
||||
public static void Add( string pattern )
|
||||
{
|
||||
IFirewallEntry entry = ToFirewallEntry( pattern );
|
||||
|
||||
if ( !List.Contains( entry ) )
|
||||
List.Add( entry );
|
||||
|
||||
Save();
|
||||
}
|
||||
|
||||
public static void Add( IPAddress ip )
|
||||
{
|
||||
IFirewallEntry entry = new IPFirewallEntry( ip );
|
||||
|
||||
if ( !List.Contains( entry ) )
|
||||
List.Add( entry );
|
||||
|
||||
Save();
|
||||
}
|
||||
|
||||
public static void Save()
|
||||
{
|
||||
string path = "firewall.cfg";
|
||||
|
||||
using ( StreamWriter op = new StreamWriter( path ) )
|
||||
{
|
||||
for ( int i = 0; i < List.Count; ++i )
|
||||
op.WriteLine( List[i] );
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsBlocked( IPAddress ip )
|
||||
{
|
||||
for( int i = 0; i < List.Count; i++ )
|
||||
{
|
||||
if ( List[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] );
|
||||
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];
|
||||
|
|
@ -307,10 +160,144 @@ namespace Server
|
|||
if ( !contains )
|
||||
contains = Utility.IPMatch( s, ip );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return contains;
|
||||
* */
|
||||
}
|
||||
}
|
||||
}
|
||||
return contains;
|
||||
* */
|
||||
}
|
||||
|
||||
#region Firewall Entries
|
||||
|
||||
public interface IFirewallEntry
|
||||
{
|
||||
bool IsBlocked(IPAddress address);
|
||||
}
|
||||
|
||||
public class IPFirewallEntry : IFirewallEntry
|
||||
{
|
||||
private 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);
|
||||
if (obj is string s)
|
||||
{
|
||||
if (IPAddress.TryParse(s, out IPAddress otherAddress))
|
||||
return otherAddress.Equals(m_Address);
|
||||
}
|
||||
else if (obj is IPFirewallEntry entry)
|
||||
{
|
||||
return m_Address.Equals(entry.m_Address);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return m_Address.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public class CIDRFirewallEntry : IFirewallEntry
|
||||
{
|
||||
private int m_CIDRLength;
|
||||
private IPAddress m_CIDRPrefix;
|
||||
|
||||
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 $"{m_CIDRPrefix}/{m_CIDRLength}";
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is string entry)
|
||||
{
|
||||
string[] str = entry.Split('/');
|
||||
|
||||
if (str.Length == 2)
|
||||
if (IPAddress.TryParse(str[0], out IPAddress cidrPrefix))
|
||||
if (int.TryParse(str[1], out int cidrLength))
|
||||
return m_CIDRPrefix.Equals(cidrPrefix) && m_CIDRLength.Equals(cidrLength);
|
||||
}
|
||||
else if (obj is CIDRFirewallEntry cidrEntry)
|
||||
{
|
||||
return m_CIDRPrefix.Equals(cidrEntry.m_CIDRPrefix) && m_CIDRLength.Equals(cidrEntry.m_CIDRLength);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return m_CIDRPrefix.GetHashCode() ^ m_CIDRLength.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public class WildcardIPFirewallEntry : IFirewallEntry
|
||||
{
|
||||
private string m_Entry;
|
||||
|
||||
private 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;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is string)
|
||||
return obj.Equals(m_Entry);
|
||||
|
||||
return obj is WildcardIPFirewallEntry entry && m_Entry.Equals(entry.m_Entry);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return m_Entry.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -4,51 +4,50 @@ 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 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 = {
|
||||
//IPAddress.Parse( "127.0.0.1" ),
|
||||
};
|
||||
public static int MaxAddresses = 10;
|
||||
|
||||
public static bool IsExempt( IPAddress ip )
|
||||
{
|
||||
for ( int i = 0; i < Exemptions.Length; i++ )
|
||||
{
|
||||
if ( ip.Equals( Exemptions[i] ) )
|
||||
return true;
|
||||
}
|
||||
public static IPAddress[] Exemptions =
|
||||
{
|
||||
//IPAddress.Parse( "127.0.0.1" ),
|
||||
};
|
||||
|
||||
return false;
|
||||
}
|
||||
public static bool IsExempt(IPAddress ip)
|
||||
{
|
||||
for (int i = 0; i < Exemptions.Length; i++)
|
||||
if (ip.Equals(Exemptions[i]))
|
||||
return true;
|
||||
|
||||
public static bool Verify( IPAddress ourAddress )
|
||||
{
|
||||
if ( !Enabled || IsExempt( ourAddress ) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
List<NetState> netStates = NetState.Instances;
|
||||
public static bool Verify(IPAddress ourAddress)
|
||||
{
|
||||
if (!Enabled || IsExempt(ourAddress))
|
||||
return true;
|
||||
|
||||
int count = 0;
|
||||
List<NetState> netStates = NetState.Instances;
|
||||
|
||||
for ( int i = 0; i < netStates.Count; ++i )
|
||||
{
|
||||
NetState compState = netStates[i];
|
||||
int count = 0;
|
||||
|
||||
if ( ourAddress.Equals( compState.Address ) )
|
||||
{
|
||||
++count;
|
||||
for (int i = 0; i < netStates.Count; ++i)
|
||||
{
|
||||
NetState compState = netStates[i];
|
||||
|
||||
if ( count >= MaxAddresses )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (ourAddress.Equals(compState.Address))
|
||||
{
|
||||
++count;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (count >= MaxAddresses)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -2,33 +2,33 @@ using System;
|
|||
|
||||
namespace Server
|
||||
{
|
||||
public class UsageAttribute : Attribute
|
||||
{
|
||||
public string Usage { get; }
|
||||
public class UsageAttribute : Attribute
|
||||
{
|
||||
public UsageAttribute(string usage)
|
||||
{
|
||||
Usage = usage;
|
||||
}
|
||||
|
||||
public UsageAttribute( string usage )
|
||||
{
|
||||
Usage = usage;
|
||||
}
|
||||
}
|
||||
public string Usage{ get; }
|
||||
}
|
||||
|
||||
public class DescriptionAttribute : Attribute
|
||||
{
|
||||
public string Description { get; }
|
||||
public class DescriptionAttribute : Attribute
|
||||
{
|
||||
public DescriptionAttribute(string description)
|
||||
{
|
||||
Description = description;
|
||||
}
|
||||
|
||||
public DescriptionAttribute( string description )
|
||||
{
|
||||
Description = description;
|
||||
}
|
||||
}
|
||||
public string Description{ get; }
|
||||
}
|
||||
|
||||
public class AliasesAttribute : Attribute
|
||||
{
|
||||
public string[] Aliases { get; }
|
||||
public class AliasesAttribute : Attribute
|
||||
{
|
||||
public AliasesAttribute(params string[] aliases)
|
||||
{
|
||||
Aliases = aliases;
|
||||
}
|
||||
|
||||
public AliasesAttribute( params string[] aliases )
|
||||
{
|
||||
Aliases = aliases;
|
||||
}
|
||||
}
|
||||
public string[] Aliases{ get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,423 +1,423 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using Server.Commands.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
using Server.Commands.Generic;
|
||||
|
||||
namespace Server.Commands
|
||||
{
|
||||
public class Batch : BaseCommand
|
||||
{
|
||||
public BaseCommandImplementor Scope { get; set; }
|
||||
public class Batch : BaseCommand
|
||||
{
|
||||
public Batch()
|
||||
{
|
||||
Commands = new[] { "Batch" };
|
||||
ListOptimized = true;
|
||||
|
||||
public string Condition { get; set; }
|
||||
BatchCommands = new ArrayList();
|
||||
Condition = "";
|
||||
}
|
||||
|
||||
public ArrayList BatchCommands { get; }
|
||||
public BaseCommandImplementor Scope{ get; set; }
|
||||
|
||||
public Batch()
|
||||
{
|
||||
Commands = new[]{ "Batch" };
|
||||
ListOptimized = true;
|
||||
public string Condition{ get; set; }
|
||||
|
||||
BatchCommands = new ArrayList();
|
||||
Condition = "";
|
||||
}
|
||||
public ArrayList BatchCommands{ get; }
|
||||
|
||||
public override void ExecuteList( CommandEventArgs e, ArrayList list )
|
||||
{
|
||||
if ( list.Count == 0 )
|
||||
{
|
||||
LogFailure( "Nothing was found to use this command on." );
|
||||
return;
|
||||
}
|
||||
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[BatchCommands.Count];
|
||||
CommandEventArgs[] eventArgs = new CommandEventArgs[BatchCommands.Count];
|
||||
try
|
||||
{
|
||||
BaseCommand[] commands = new BaseCommand[BatchCommands.Count];
|
||||
CommandEventArgs[] eventArgs = new CommandEventArgs[BatchCommands.Count];
|
||||
|
||||
for ( int i = 0; i < BatchCommands.Count; ++i )
|
||||
{
|
||||
BatchCommand bc = (BatchCommand)BatchCommands[i];
|
||||
|
||||
bc.GetDetails( out string commandString, out string argString, out string[] args );
|
||||
|
||||
BaseCommand command = 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;
|
||||
}
|
||||
|
||||
if ( e.Mobile.AccessLevel < command.AccessLevel )
|
||||
{
|
||||
e.Mobile.SendMessage( "You do not have access to that command: {0}.", commandString );
|
||||
return;
|
||||
}
|
||||
if ( !command.ValidateArgs( Scope, eventArgs[i] ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0; i < commands.Length; ++i )
|
||||
{
|
||||
BaseCommand command = commands[i];
|
||||
BatchCommand bc = (BatchCommand)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 ( Scope == null )
|
||||
{
|
||||
from.SendMessage( "You must select the batch command scope." );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( Condition.Length > 0 && !Scope.SupportsConditionals )
|
||||
{
|
||||
from.SendMessage( "This command scope does not support conditionals." );
|
||||
return false;
|
||||
}
|
||||
if ( Condition.Length > 0 && !Utility.InsensitiveStartsWith( Condition, "where" ) )
|
||||
{
|
||||
from.SendMessage( "The condition field must start with \"where\"." );
|
||||
return false;
|
||||
}
|
||||
|
||||
string[] args = CommandSystem.Split( Condition );
|
||||
|
||||
Scope.Process( from, this, args );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "Batch", AccessLevel.Counselor, Batch_OnCommand );
|
||||
}
|
||||
|
||||
[Usage( "Batch" )]
|
||||
[Description( "Allows multiple commands to be run at the same time." )]
|
||||
public static void Batch_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
e.Mobile.SendGump( new BatchGump( e.Mobile, new Batch() ) );
|
||||
}
|
||||
}
|
||||
|
||||
public class BatchCommand
|
||||
{
|
||||
public string Command { get; set; }
|
||||
|
||||
public string Object { get; set; }
|
||||
|
||||
public void GetDetails( out string command, out string argString, out string[] args )
|
||||
{
|
||||
int indexOf = Command.IndexOf( ' ' );
|
||||
|
||||
if ( indexOf >= 0 )
|
||||
{
|
||||
argString = Command.Substring( indexOf + 1 );
|
||||
|
||||
command = Command.Substring( 0, indexOf );
|
||||
args = CommandSystem.Split( argString );
|
||||
}
|
||||
else
|
||||
{
|
||||
argString = "";
|
||||
command = Command.ToLower();
|
||||
args = new string[0];
|
||||
}
|
||||
}
|
||||
|
||||
public BatchCommand( string command, string obj )
|
||||
{
|
||||
Command = command;
|
||||
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 )
|
||||
{
|
||||
if ( !SplitButtonID( info.ButtonID, 1, out int type, out int 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 )
|
||||
{
|
||||
if ( SplitButtonID( info.ButtonID, 1, out int type, out int 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 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < BatchCommands.Count; ++i)
|
||||
{
|
||||
BatchCommand bc = (BatchCommand)BatchCommands[i];
|
||||
|
||||
bc.GetDetails(out string commandString, out string argString, out string[] args);
|
||||
|
||||
BaseCommand command = 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;
|
||||
}
|
||||
|
||||
if (e.Mobile.AccessLevel < command.AccessLevel)
|
||||
{
|
||||
e.Mobile.SendMessage("You do not have access to that command: {0}.", commandString);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!command.ValidateArgs(Scope, eventArgs[i])) return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < commands.Length; ++i)
|
||||
{
|
||||
BaseCommand command = commands[i];
|
||||
BatchCommand bc = (BatchCommand)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 (Scope == null)
|
||||
{
|
||||
from.SendMessage("You must select the batch command scope.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Condition.Length > 0 && !Scope.SupportsConditionals)
|
||||
{
|
||||
from.SendMessage("This command scope does not support conditionals.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Condition.Length > 0 && !Utility.InsensitiveStartsWith(Condition, "where"))
|
||||
{
|
||||
from.SendMessage("The condition field must start with \"where\".");
|
||||
return false;
|
||||
}
|
||||
|
||||
string[] args = CommandSystem.Split(Condition);
|
||||
|
||||
Scope.Process(from, this, args);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("Batch", AccessLevel.Counselor, Batch_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("Batch")]
|
||||
[Description("Allows multiple commands to be run at the same time.")]
|
||||
public static void Batch_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.SendGump(new BatchGump(e.Mobile, new Batch()));
|
||||
}
|
||||
}
|
||||
|
||||
public class BatchCommand
|
||||
{
|
||||
public BatchCommand(string command, string obj)
|
||||
{
|
||||
Command = command;
|
||||
Object = obj;
|
||||
}
|
||||
|
||||
public string Command{ get; set; }
|
||||
|
||||
public string Object{ get; set; }
|
||||
|
||||
public void GetDetails(out string command, out string argString, out string[] args)
|
||||
{
|
||||
int indexOf = Command.IndexOf(' ');
|
||||
|
||||
if (indexOf >= 0)
|
||||
{
|
||||
argString = Command.Substring(indexOf + 1);
|
||||
|
||||
command = Command.Substring(0, indexOf);
|
||||
args = CommandSystem.Split(argString);
|
||||
}
|
||||
else
|
||||
{
|
||||
argString = "";
|
||||
command = Command.ToLower();
|
||||
args = new string[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class BatchGump : BaseGridGump
|
||||
{
|
||||
private Batch m_Batch;
|
||||
private Mobile m_From;
|
||||
|
||||
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)
|
||||
{
|
||||
if (!SplitButtonID(info.ButtonID, 1, out int type, out int 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 Batch m_Batch;
|
||||
private Mobile m_From;
|
||||
|
||||
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)
|
||||
{
|
||||
if (SplitButtonID(info.ButtonID, 1, out int type, out int 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,64 +2,65 @@ using Server.Targeting;
|
|||
|
||||
namespace Server
|
||||
{
|
||||
public delegate void BoundingBoxCallback( Mobile from, Map map, Point3D start, Point3D end, object state );
|
||||
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 );
|
||||
}
|
||||
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;
|
||||
private class PickTarget : Target
|
||||
{
|
||||
private BoundingBoxCallback m_Callback;
|
||||
private bool m_First;
|
||||
private Map m_Map;
|
||||
private object m_State;
|
||||
private Point3D m_Store;
|
||||
|
||||
public PickTarget( BoundingBoxCallback callback, object state ) : this( Point3D.Zero, true, null, callback, 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;
|
||||
}
|
||||
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 )
|
||||
{
|
||||
if ( !(targeted is IPoint3D p) )
|
||||
return;
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (!(targeted is IPoint3D p))
|
||||
return;
|
||||
|
||||
if ( p is Item item )
|
||||
p = item.GetWorldTop();
|
||||
if (p is Item item)
|
||||
p = item.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 );
|
||||
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 );
|
||||
Utility.FixPoints(ref start, ref end);
|
||||
|
||||
m_Callback( from, m_Map, start, end, m_State );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_Callback(from, m_Map, start, end, m_State);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,84 +6,82 @@ using Server.Network;
|
|||
|
||||
namespace Server.Commands
|
||||
{
|
||||
public class ConvertPlayers
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "ConvertPlayers", AccessLevel.Administrator, 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++;
|
||||
m.NetState?.Dispose();
|
||||
public class ConvertPlayers
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("ConvertPlayers", AccessLevel.Administrator, Convert_OnCommand);
|
||||
}
|
||||
|
||||
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 );
|
||||
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;
|
||||
|
||||
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
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (Mobile m in mobs)
|
||||
if (m.Player && !(m is PlayerMobile))
|
||||
{
|
||||
count++;
|
||||
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
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,26 +1,26 @@
|
|||
namespace Server.Commands
|
||||
{
|
||||
public static class DragEffects
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "DragEffects", AccessLevel.Developer, DragEffects_OnCommand );
|
||||
}
|
||||
public static class DragEffects
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("DragEffects", AccessLevel.Developer, DragEffects_OnCommand);
|
||||
}
|
||||
|
||||
[Usage( "DragEffects [enable=false]" )]
|
||||
[Description( "Enables or disables the item drag and drop effects." )]
|
||||
public static void DragEffects_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
if ( e.Length == 0 )
|
||||
{
|
||||
e.Mobile.SendMessage( "Drag effects are currently {0}.", Mobile.DragEffects ? "enabled" : "disabled" );
|
||||
}
|
||||
else
|
||||
{
|
||||
Mobile.DragEffects = e.GetBoolean( 0 );
|
||||
[Usage("DragEffects [enable=false]")]
|
||||
[Description("Enables or disables the item drag and drop effects.")]
|
||||
public static void DragEffects_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if (e.Length == 0)
|
||||
{
|
||||
e.Mobile.SendMessage("Drag effects are currently {0}.", Mobile.DragEffects ? "enabled" : "disabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
Mobile.DragEffects = e.GetBoolean(0);
|
||||
|
||||
e.Mobile.SendMessage( "Drag effects have been {0}.", Mobile.DragEffects ? "enabled" : "disabled" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
e.Mobile.SendMessage("Drag effects have been {0}.", Mobile.DragEffects ? "enabled" : "disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,138 +5,131 @@ using Server.Targeting;
|
|||
|
||||
namespace Server.Commands
|
||||
{
|
||||
public class Dupe
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "Dupe", AccessLevel.GameMaster, Dupe_OnCommand );
|
||||
CommandSystem.Register( "DupeInBag", AccessLevel.GameMaster, DupeInBag_OnCommand );
|
||||
}
|
||||
public class Dupe
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("Dupe", AccessLevel.GameMaster, Dupe_OnCommand);
|
||||
CommandSystem.Register("DupeInBag", AccessLevel.GameMaster, 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("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 );
|
||||
[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?" );
|
||||
}
|
||||
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 static void CopyProperties(Item dest, Item src)
|
||||
{
|
||||
PropertyInfo[] props = src.GetType().GetProperties();
|
||||
|
||||
public DupeTarget( bool inbag, int amount )
|
||||
: base( 15, false, TargetFlags.None )
|
||||
{
|
||||
m_InBag = inbag;
|
||||
m_Amount = amount;
|
||||
}
|
||||
for (int i = 0; i < props.Length; i++)
|
||||
try
|
||||
{
|
||||
if (props[i].CanRead && props[i].CanWrite) props[i].SetValue(dest, props[i].GetValue(src, null), null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Console.WriteLine( "Denied" );
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object targ )
|
||||
{
|
||||
bool done = false;
|
||||
if ( !( targ is Item ) )
|
||||
{
|
||||
from.SendMessage( "You can only dupe items." );
|
||||
return;
|
||||
}
|
||||
private class DupeTarget : Target
|
||||
{
|
||||
private int m_Amount;
|
||||
private bool m_InBag;
|
||||
|
||||
CommandLogging.WriteLine( from, "{0} {1} duping {2} (inBag={3}; amount={4})", from.AccessLevel, CommandLogging.Format( from ), CommandLogging.Format( targ ), m_InBag, m_Amount );
|
||||
public DupeTarget(bool inbag, int amount)
|
||||
: base(15, false, TargetFlags.None)
|
||||
{
|
||||
m_InBag = inbag;
|
||||
m_Amount = amount;
|
||||
}
|
||||
|
||||
Item copy = (Item)targ;
|
||||
Container pack = null;
|
||||
protected override void OnTarget(Mobile from, object targ)
|
||||
{
|
||||
bool done = false;
|
||||
if (!(targ is Item))
|
||||
{
|
||||
from.SendMessage("You can only dupe items.");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_InBag )
|
||||
{
|
||||
if ( copy.Parent is Container cont )
|
||||
pack = cont;
|
||||
else if ( copy.Parent is Mobile m )
|
||||
pack = m.Backpack;
|
||||
}
|
||||
else
|
||||
pack = from.Backpack;
|
||||
CommandLogging.WriteLine(from, "{0} {1} duping {2} (inBag={3}; amount={4})", from.AccessLevel,
|
||||
CommandLogging.Format(from), CommandLogging.Format(targ), m_InBag, m_Amount);
|
||||
|
||||
Type t = copy.GetType();
|
||||
Item copy = (Item)targ;
|
||||
Container pack = null;
|
||||
|
||||
//ConstructorInfo[] info = t.GetConstructors();
|
||||
if (m_InBag)
|
||||
{
|
||||
if (copy.Parent is Container cont)
|
||||
pack = cont;
|
||||
else if (copy.Parent is Mobile m)
|
||||
pack = m.Backpack;
|
||||
}
|
||||
else
|
||||
{
|
||||
pack = from.Backpack;
|
||||
}
|
||||
|
||||
ConstructorInfo c = t.GetConstructor( Type.EmptyTypes );
|
||||
Type t = copy.GetType();
|
||||
|
||||
if ( c != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
from.SendMessage( "Duping {0}...", m_Amount );
|
||||
for ( int i = 0; i < m_Amount; i++ )
|
||||
{
|
||||
if ( c.Invoke( null ) is Item newItem )
|
||||
{
|
||||
CopyProperties( newItem, copy );//copy.Dupe( item, copy.Amount );
|
||||
copy.OnAfterDuped( newItem );
|
||||
newItem.Parent = null;
|
||||
//ConstructorInfo[] info = t.GetConstructors();
|
||||
|
||||
if ( pack != null )
|
||||
pack.DropItem( newItem );
|
||||
else
|
||||
newItem.MoveToWorld( from.Location, from.Map );
|
||||
ConstructorInfo c = t.GetConstructor(Type.EmptyTypes);
|
||||
|
||||
newItem.InvalidateProperties();
|
||||
if (c != null)
|
||||
try
|
||||
{
|
||||
from.SendMessage("Duping {0}...", m_Amount);
|
||||
for (int i = 0; i < m_Amount; i++)
|
||||
if (c.Invoke(null) is Item newItem)
|
||||
{
|
||||
CopyProperties(newItem, copy); //copy.Dupe( item, copy.Amount );
|
||||
copy.OnAfterDuped(newItem);
|
||||
newItem.Parent = null;
|
||||
|
||||
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 (pack != null)
|
||||
pack.DropItem(newItem);
|
||||
else
|
||||
newItem.MoveToWorld(from.Location, from.Map);
|
||||
|
||||
if ( !done )
|
||||
{
|
||||
from.SendMessage( "Unable to dupe. Item must have a 0 parameter constructor." );
|
||||
}
|
||||
}
|
||||
}
|
||||
newItem.InvalidateProperties();
|
||||
|
||||
public static void CopyProperties( Item dest, Item src )
|
||||
{
|
||||
PropertyInfo[] props = src.GetType().GetProperties();
|
||||
CommandLogging.WriteLine(from, "{0} {1} duped {2} creating {3}", from.AccessLevel,
|
||||
CommandLogging.Format(from), CommandLogging.Format(targ),
|
||||
CommandLogging.Format(newItem));
|
||||
}
|
||||
|
||||
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" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
from.SendMessage("Done");
|
||||
done = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
from.SendMessage("Error!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!done) from.SendMessage("Unable to dupe. Item must have a 0 parameter constructor.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,63 +4,61 @@ using Server.Items;
|
|||
|
||||
namespace Server.Commands
|
||||
{
|
||||
public class ExportCommand
|
||||
{
|
||||
private const string ExportFile = @"C:\Uo\WorldForge\items.wsc";
|
||||
public class ExportCommand
|
||||
{
|
||||
private const string ExportFile = @"C:\Uo\WorldForge\items.wsc";
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "ExportWSC", AccessLevel.Administrator, Export_OnCommand );
|
||||
}
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("ExportWSC", AccessLevel.Administrator, Export_OnCommand);
|
||||
}
|
||||
|
||||
public static void Export_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
StreamWriter w = new StreamWriter( ExportFile );
|
||||
ArrayList remove = new ArrayList();
|
||||
int count = 0;
|
||||
public static void Export_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
StreamWriter w = new StreamWriter(ExportFile);
|
||||
ArrayList remove = new ArrayList();
|
||||
int count = 0;
|
||||
|
||||
e.Mobile.SendMessage( "Exporting all static items to \"{0}\"...", ExportFile );
|
||||
e.Mobile.SendMessage( "This will delete all static items in the world. Please make a backup." );
|
||||
e.Mobile.SendMessage("Exporting all static items to \"{0}\"...", ExportFile);
|
||||
e.Mobile.SendMessage("This will delete all static items in the world. Please make a backup.");
|
||||
|
||||
foreach ( Item item in World.Items.Values )
|
||||
{
|
||||
if ( ( item is Static || item is BaseFloor || item is BaseWall )
|
||||
&& item.RootParent == null )
|
||||
{
|
||||
w.WriteLine( "SECTION WORLDITEM {0}", count );
|
||||
w.WriteLine( "{" );
|
||||
w.WriteLine( "SERIAL {0}", item.Serial );
|
||||
w.WriteLine( "NAME #" );
|
||||
w.WriteLine( "NAME2 #" );
|
||||
w.WriteLine( "ID {0}", item.ItemID );
|
||||
w.WriteLine( "X {0}", item.X );
|
||||
w.WriteLine( "Y {0}", item.Y );
|
||||
w.WriteLine( "Z {0}", item.Z );
|
||||
w.WriteLine( "COLOR {0}", item.Hue );
|
||||
w.WriteLine( "CONT -1" );
|
||||
w.WriteLine( "TYPE 0" );
|
||||
w.WriteLine( "AMOUNT 1" );
|
||||
w.WriteLine( "WEIGHT 255" );
|
||||
w.WriteLine( "OWNER -1" );
|
||||
w.WriteLine( "SPAWN -1" );
|
||||
w.WriteLine( "VALUE 1" );
|
||||
w.WriteLine( "}" );
|
||||
w.WriteLine( "" );
|
||||
foreach (Item item in World.Items.Values)
|
||||
if ((item is Static || item is BaseFloor || item is BaseWall)
|
||||
&& item.RootParent == null)
|
||||
{
|
||||
w.WriteLine("SECTION WORLDITEM {0}", count);
|
||||
w.WriteLine("{");
|
||||
w.WriteLine("SERIAL {0}", item.Serial);
|
||||
w.WriteLine("NAME #");
|
||||
w.WriteLine("NAME2 #");
|
||||
w.WriteLine("ID {0}", item.ItemID);
|
||||
w.WriteLine("X {0}", item.X);
|
||||
w.WriteLine("Y {0}", item.Y);
|
||||
w.WriteLine("Z {0}", item.Z);
|
||||
w.WriteLine("COLOR {0}", item.Hue);
|
||||
w.WriteLine("CONT -1");
|
||||
w.WriteLine("TYPE 0");
|
||||
w.WriteLine("AMOUNT 1");
|
||||
w.WriteLine("WEIGHT 255");
|
||||
w.WriteLine("OWNER -1");
|
||||
w.WriteLine("SPAWN -1");
|
||||
w.WriteLine("VALUE 1");
|
||||
w.WriteLine("}");
|
||||
w.WriteLine("");
|
||||
|
||||
count++;
|
||||
remove.Add( item );
|
||||
w.Flush();
|
||||
}
|
||||
}
|
||||
count++;
|
||||
remove.Add(item);
|
||||
w.Flush();
|
||||
}
|
||||
|
||||
w.Close();
|
||||
w.Close();
|
||||
|
||||
foreach( Item item in remove )
|
||||
item.Delete();
|
||||
foreach (Item item in remove)
|
||||
item.Delete();
|
||||
|
||||
e.Mobile.SendMessage( "Export complete. Exported {0} statics.", count );
|
||||
}
|
||||
}
|
||||
e.Mobile.SendMessage("Export complete. Exported {0} statics.", count);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*SECTION WORLDITEM 1
|
||||
{
|
||||
|
|
@ -78,4 +76,4 @@ WEIGHT 25500
|
|||
OWNER -1
|
||||
SPAWN -1
|
||||
VALUE 1
|
||||
}*/
|
||||
}*/
|
||||
|
|
@ -1,413 +1,410 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Commands
|
||||
{
|
||||
public class Categorization
|
||||
{
|
||||
private static CategoryEntry m_RootItems, m_RootMobiles;
|
||||
public class Categorization
|
||||
{
|
||||
private static CategoryEntry m_RootItems, m_RootMobiles;
|
||||
|
||||
public static CategoryEntry Items
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( m_RootItems == null )
|
||||
Load();
|
||||
private static Type typeofItem = typeof(Item);
|
||||
private static Type typeofMobile = typeof(Mobile);
|
||||
private static Type typeofConstructible = typeof(ConstructibleAttribute);
|
||||
|
||||
return m_RootItems;
|
||||
}
|
||||
}
|
||||
public static CategoryEntry Items
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_RootItems == null)
|
||||
Load();
|
||||
|
||||
public static CategoryEntry Mobiles
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( m_RootMobiles == null )
|
||||
Load();
|
||||
return m_RootItems;
|
||||
}
|
||||
}
|
||||
|
||||
return m_RootMobiles;
|
||||
}
|
||||
}
|
||||
public static CategoryEntry Mobiles
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_RootMobiles == null)
|
||||
Load();
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "RebuildCategorization", AccessLevel.Administrator, RebuildCategorization_OnCommand );
|
||||
}
|
||||
return m_RootMobiles;
|
||||
}
|
||||
}
|
||||
|
||||
[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[]{ Items, Mobiles } );
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("RebuildCategorization", AccessLevel.Administrator, RebuildCategorization_OnCommand);
|
||||
}
|
||||
|
||||
Export( root, "Data/objects.xml", "Objects" );
|
||||
[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[] { Items, Mobiles });
|
||||
|
||||
e.Mobile.SendMessage( "Categorization menu rebuilt." );
|
||||
}
|
||||
Export(root, "Data/objects.xml", "Objects");
|
||||
|
||||
public static void RecurseFindCategories( CategoryEntry ce, ArrayList list )
|
||||
{
|
||||
list.Add( ce );
|
||||
e.Mobile.SendMessage("Categorization menu rebuilt.");
|
||||
}
|
||||
|
||||
for ( int i = 0; i < ce.SubCategories.Length; ++i )
|
||||
RecurseFindCategories( ce.SubCategories[i], list );
|
||||
}
|
||||
public static void RecurseFindCategories(CategoryEntry ce, ArrayList list)
|
||||
{
|
||||
list.Add(ce);
|
||||
|
||||
public static void Export( CategoryEntry ce, string fileName, string title )
|
||||
{
|
||||
XmlTextWriter xml = new XmlTextWriter( fileName, System.Text.Encoding.UTF8 );
|
||||
for (int i = 0; i < ce.SubCategories.Length; ++i)
|
||||
RecurseFindCategories(ce.SubCategories[i], list);
|
||||
}
|
||||
|
||||
xml.Indentation = 1;
|
||||
xml.IndentChar = '\t';
|
||||
xml.Formatting = Formatting.Indented;
|
||||
public static void Export(CategoryEntry ce, string fileName, string title)
|
||||
{
|
||||
XmlTextWriter xml = new XmlTextWriter(fileName, Encoding.UTF8);
|
||||
|
||||
xml.WriteStartDocument( true );
|
||||
xml.Indentation = 1;
|
||||
xml.IndentChar = '\t';
|
||||
xml.Formatting = Formatting.Indented;
|
||||
|
||||
RecurseExport( xml, ce );
|
||||
xml.WriteStartDocument(true);
|
||||
|
||||
xml.Flush();
|
||||
xml.Close();
|
||||
}
|
||||
RecurseExport(xml, ce);
|
||||
|
||||
public static void RecurseExport( XmlTextWriter xml, CategoryEntry ce )
|
||||
{
|
||||
xml.WriteStartElement( "category" );
|
||||
xml.Flush();
|
||||
xml.Close();
|
||||
}
|
||||
|
||||
xml.WriteAttributeString( "title", ce.Title );
|
||||
public static void RecurseExport(XmlTextWriter xml, CategoryEntry ce)
|
||||
{
|
||||
xml.WriteStartElement("category");
|
||||
|
||||
ArrayList subCats = new ArrayList( ce.SubCategories );
|
||||
xml.WriteAttributeString("title", ce.Title);
|
||||
|
||||
subCats.Sort( new CategorySorter() );
|
||||
ArrayList subCats = new ArrayList(ce.SubCategories);
|
||||
|
||||
for ( int i = 0; i < subCats.Count; ++i )
|
||||
RecurseExport( xml, (CategoryEntry)subCats[i] );
|
||||
subCats.Sort(new CategorySorter());
|
||||
|
||||
ce.Matched.Sort( new CategorySorter() );
|
||||
for (int i = 0; i < subCats.Count; ++i)
|
||||
RecurseExport(xml, (CategoryEntry)subCats[i]);
|
||||
|
||||
for ( int i = 0; i < ce.Matched.Count; ++i )
|
||||
{
|
||||
CategoryTypeEntry cte = (CategoryTypeEntry)ce.Matched[i];
|
||||
ce.Matched.Sort(new CategorySorter());
|
||||
|
||||
xml.WriteStartElement( "object" );
|
||||
for (int i = 0; i < ce.Matched.Count; ++i)
|
||||
{
|
||||
CategoryTypeEntry cte = (CategoryTypeEntry)ce.Matched[i];
|
||||
|
||||
xml.WriteAttributeString( "type", cte.Type.ToString() );
|
||||
xml.WriteStartElement("object");
|
||||
|
||||
if ( cte.Object is Item item )
|
||||
{
|
||||
int itemID = item.ItemID;
|
||||
xml.WriteAttributeString("type", cte.Type.ToString());
|
||||
|
||||
if ( item is BaseAddon addon && addon.Components.Count == 1 )
|
||||
itemID = addon.Components[0].ItemID;
|
||||
if (cte.Object is Item item)
|
||||
{
|
||||
int itemID = item.ItemID;
|
||||
|
||||
if ( itemID > TileData.MaxItemValue )
|
||||
itemID = 1;
|
||||
if (item is BaseAddon addon && addon.Components.Count == 1)
|
||||
itemID = addon.Components[0].ItemID;
|
||||
|
||||
xml.WriteAttributeString( "gfx", XmlConvert.ToString( itemID ) );
|
||||
if (itemID > TileData.MaxItemValue)
|
||||
itemID = 1;
|
||||
|
||||
int hue = item.Hue & 0x7FFF;
|
||||
xml.WriteAttributeString("gfx", XmlConvert.ToString(itemID));
|
||||
|
||||
if ( (hue & 0x4000) != 0 )
|
||||
hue = 0;
|
||||
int hue = item.Hue & 0x7FFF;
|
||||
|
||||
if ( hue != 0 )
|
||||
xml.WriteAttributeString( "hue", XmlConvert.ToString( hue ) );
|
||||
if ((hue & 0x4000) != 0)
|
||||
hue = 0;
|
||||
|
||||
item.Delete();
|
||||
}
|
||||
else if ( cte.Object is Mobile mob )
|
||||
{
|
||||
int itemID = ShrinkTable.Lookup( mob, 1 );
|
||||
if (hue != 0)
|
||||
xml.WriteAttributeString("hue", XmlConvert.ToString(hue));
|
||||
|
||||
xml.WriteAttributeString( "gfx", XmlConvert.ToString( itemID ) );
|
||||
item.Delete();
|
||||
}
|
||||
else if (cte.Object is Mobile mob)
|
||||
{
|
||||
int itemID = ShrinkTable.Lookup(mob, 1);
|
||||
|
||||
int hue = mob.Hue & 0x7FFF;
|
||||
xml.WriteAttributeString("gfx", XmlConvert.ToString(itemID));
|
||||
|
||||
if ( (hue & 0x4000) != 0 )
|
||||
hue = 0;
|
||||
int hue = mob.Hue & 0x7FFF;
|
||||
|
||||
if ( hue != 0 )
|
||||
xml.WriteAttributeString( "hue", XmlConvert.ToString( hue ) );
|
||||
if ((hue & 0x4000) != 0)
|
||||
hue = 0;
|
||||
|
||||
mob.Delete();
|
||||
}
|
||||
if (hue != 0)
|
||||
xml.WriteAttributeString("hue", XmlConvert.ToString(hue));
|
||||
|
||||
xml.WriteEndElement();
|
||||
}
|
||||
mob.Delete();
|
||||
}
|
||||
|
||||
xml.WriteEndElement();
|
||||
}
|
||||
xml.WriteEndElement();
|
||||
}
|
||||
|
||||
public static void Load()
|
||||
{
|
||||
ArrayList types = new ArrayList();
|
||||
xml.WriteEndElement();
|
||||
}
|
||||
|
||||
AddTypes( Core.Assembly, types );
|
||||
public static void Load()
|
||||
{
|
||||
ArrayList types = new ArrayList();
|
||||
|
||||
for ( int i = 0; i < ScriptCompiler.Assemblies.Length; ++i )
|
||||
AddTypes( ScriptCompiler.Assemblies[i], types );
|
||||
AddTypes(Core.Assembly, types);
|
||||
|
||||
m_RootItems = Load( types, "Data/items.cfg" );
|
||||
m_RootMobiles = Load( types, "Data/mobiles.cfg" );
|
||||
}
|
||||
for (int i = 0; i < ScriptCompiler.Assemblies.Length; ++i)
|
||||
AddTypes(ScriptCompiler.Assemblies[i], types);
|
||||
|
||||
private static CategoryEntry Load( ArrayList types, string config )
|
||||
{
|
||||
CategoryLine[] lines = CategoryLine.Load( config );
|
||||
m_RootItems = Load(types, "Data/items.cfg");
|
||||
m_RootMobiles = Load(types, "Data/mobiles.cfg");
|
||||
}
|
||||
|
||||
if ( lines.Length > 0 )
|
||||
{
|
||||
int index = 0;
|
||||
CategoryEntry root = new CategoryEntry( null, lines, ref index );
|
||||
private static CategoryEntry Load(ArrayList types, string config)
|
||||
{
|
||||
CategoryLine[] lines = CategoryLine.Load(config);
|
||||
|
||||
Fill( root, types );
|
||||
if (lines.Length > 0)
|
||||
{
|
||||
int index = 0;
|
||||
CategoryEntry root = new CategoryEntry(null, lines, ref index);
|
||||
|
||||
return root;
|
||||
}
|
||||
Fill(root, types);
|
||||
|
||||
return new CategoryEntry();
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
private static Type typeofItem = typeof( Item );
|
||||
private static Type typeofMobile = typeof( Mobile );
|
||||
private static Type typeofConstructible = typeof( ConstructibleAttribute );
|
||||
return new CategoryEntry();
|
||||
}
|
||||
|
||||
private static bool IsConstructible( Type type )
|
||||
{
|
||||
if ( !type.IsSubclassOf( typeofItem ) && !type.IsSubclassOf( typeofMobile ) )
|
||||
return false;
|
||||
private static bool IsConstructible(Type type)
|
||||
{
|
||||
if (!type.IsSubclassOf(typeofItem) && !type.IsSubclassOf(typeofMobile))
|
||||
return false;
|
||||
|
||||
ConstructorInfo ctor = type.GetConstructor( Type.EmptyTypes );
|
||||
ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes);
|
||||
|
||||
return ( ctor != null && ctor.IsDefined( typeofConstructible, false ) );
|
||||
}
|
||||
return ctor != null && ctor.IsDefined(typeofConstructible, false);
|
||||
}
|
||||
|
||||
private static void AddTypes( Assembly asm, ArrayList types )
|
||||
{
|
||||
Type[] allTypes = asm.GetTypes();
|
||||
private static void AddTypes(Assembly asm, ArrayList types)
|
||||
{
|
||||
Type[] allTypes = asm.GetTypes();
|
||||
|
||||
for ( int i = 0; i < allTypes.Length; ++i )
|
||||
{
|
||||
Type type = allTypes[i];
|
||||
for (int i = 0; i < allTypes.Length; ++i)
|
||||
{
|
||||
Type type = allTypes[i];
|
||||
|
||||
if ( type.IsAbstract )
|
||||
continue;
|
||||
if (type.IsAbstract)
|
||||
continue;
|
||||
|
||||
if ( IsConstructible( type ) )
|
||||
types.Add( type );
|
||||
}
|
||||
}
|
||||
if (IsConstructible(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 );
|
||||
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;
|
||||
if (match == null)
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
match.Matched.Add( new CategoryTypeEntry( type ) );
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
match.Matched.Add(new CategoryTypeEntry(type));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static CategoryEntry GetDeepestMatch( CategoryEntry root, Type type )
|
||||
{
|
||||
if ( !root.IsMatch( type ) )
|
||||
return null;
|
||||
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 );
|
||||
for (int i = 0; i < root.SubCategories.Length; ++i)
|
||||
{
|
||||
CategoryEntry check = GetDeepestMatch(root.SubCategories[i], type);
|
||||
|
||||
if ( check != null )
|
||||
return check;
|
||||
}
|
||||
if (check != null)
|
||||
return check;
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
public class CategorySorter : IComparer
|
||||
{
|
||||
public int Compare( object x, object y )
|
||||
{
|
||||
string a = null, b = null;
|
||||
public class CategorySorter : IComparer
|
||||
{
|
||||
public int Compare(object x, object y)
|
||||
{
|
||||
string a = null, b = null;
|
||||
|
||||
if ( x is CategoryEntry entry )
|
||||
a = entry.Title;
|
||||
else if ( x is CategoryTypeEntry xTypeEntry )
|
||||
a = xTypeEntry.Type.Name;
|
||||
if (x is CategoryEntry entry)
|
||||
a = entry.Title;
|
||||
else if (x is CategoryTypeEntry xTypeEntry)
|
||||
a = xTypeEntry.Type.Name;
|
||||
|
||||
if ( y is CategoryEntry categoryEntry )
|
||||
b = categoryEntry.Title;
|
||||
else if ( y is CategoryTypeEntry yTypeEntry )
|
||||
b = yTypeEntry.Type.Name;
|
||||
if (y is CategoryEntry categoryEntry)
|
||||
b = categoryEntry.Title;
|
||||
else if (y is CategoryTypeEntry yTypeEntry)
|
||||
b = yTypeEntry.Type.Name;
|
||||
|
||||
if ( a == null && b == null )
|
||||
return 0;
|
||||
if (a == null && b == null)
|
||||
return 0;
|
||||
|
||||
if ( a == null )
|
||||
return 1;
|
||||
if (a == null)
|
||||
return 1;
|
||||
|
||||
if ( b == null )
|
||||
return -1;
|
||||
if (b == null)
|
||||
return -1;
|
||||
|
||||
return a.CompareTo( b );
|
||||
}
|
||||
}
|
||||
return a.CompareTo(b);
|
||||
}
|
||||
}
|
||||
|
||||
public class CategoryTypeEntry
|
||||
{
|
||||
public Type Type { get; }
|
||||
public class CategoryTypeEntry
|
||||
{
|
||||
public CategoryTypeEntry(Type type)
|
||||
{
|
||||
Type = type;
|
||||
Object = Activator.CreateInstance(type);
|
||||
}
|
||||
|
||||
public object Object { get; }
|
||||
public Type Type{ get; }
|
||||
|
||||
public CategoryTypeEntry( Type type )
|
||||
{
|
||||
Type = type;
|
||||
Object = Activator.CreateInstance( type );
|
||||
}
|
||||
}
|
||||
public object Object{ get; }
|
||||
}
|
||||
|
||||
public class CategoryEntry
|
||||
{
|
||||
public string Title { get; }
|
||||
public class CategoryEntry
|
||||
{
|
||||
public CategoryEntry()
|
||||
{
|
||||
Title = "(empty)";
|
||||
Matches = new Type[0];
|
||||
SubCategories = new CategoryEntry[0];
|
||||
Matched = new ArrayList();
|
||||
}
|
||||
|
||||
public Type[] Matches { get; }
|
||||
public CategoryEntry(CategoryEntry parent, string title, CategoryEntry[] subCats)
|
||||
{
|
||||
Parent = parent;
|
||||
Title = title;
|
||||
SubCategories = subCats;
|
||||
Matches = new Type[0];
|
||||
Matched = new ArrayList();
|
||||
}
|
||||
|
||||
public CategoryEntry Parent { get; }
|
||||
public CategoryEntry(CategoryEntry parent, CategoryLine[] lines, ref int index)
|
||||
{
|
||||
Parent = parent;
|
||||
|
||||
public CategoryEntry[] SubCategories { get; }
|
||||
string text = lines[index].Text;
|
||||
|
||||
public ArrayList Matched { get; }
|
||||
int start = text.IndexOf('(');
|
||||
|
||||
public CategoryEntry()
|
||||
{
|
||||
Title = "(empty)";
|
||||
Matches = new Type[0];
|
||||
SubCategories = new CategoryEntry[0];
|
||||
Matched = new ArrayList();
|
||||
}
|
||||
if (start < 0)
|
||||
throw new FormatException($"Input string not correctly formatted ('{text}')");
|
||||
|
||||
public CategoryEntry( CategoryEntry parent, string title, CategoryEntry[] subCats )
|
||||
{
|
||||
Parent = parent;
|
||||
Title = title;
|
||||
SubCategories = subCats;
|
||||
Matches = new Type[0];
|
||||
Matched = new ArrayList();
|
||||
}
|
||||
Title = text.Substring(0, start).Trim();
|
||||
|
||||
public bool IsMatch( Type type )
|
||||
{
|
||||
bool isMatch = false;
|
||||
int end = text.IndexOf(')', ++start);
|
||||
|
||||
for ( int i = 0; !isMatch && i < Matches.Length; ++i )
|
||||
isMatch = ( type == Matches[i] || type.IsSubclassOf( Matches[i] ) );
|
||||
if (end < start)
|
||||
throw new FormatException($"Input string not correctly formatted ('{text}')");
|
||||
|
||||
return isMatch;
|
||||
}
|
||||
text = text.Substring(start, end - start);
|
||||
string[] split = text.Split(';');
|
||||
|
||||
public CategoryEntry( CategoryEntry parent, CategoryLine[] lines, ref int index )
|
||||
{
|
||||
Parent = parent;
|
||||
ArrayList list = new ArrayList();
|
||||
|
||||
string text = lines[index].Text;
|
||||
for (int i = 0; i < split.Length; ++i)
|
||||
{
|
||||
Type type = ScriptCompiler.FindTypeByName(split[i].Trim());
|
||||
|
||||
int start = text.IndexOf( '(' );
|
||||
if (type == null)
|
||||
Console.WriteLine("Match type not found ('{0}')", split[i].Trim());
|
||||
else
|
||||
list.Add(type);
|
||||
}
|
||||
|
||||
if ( start < 0 )
|
||||
throw new FormatException($"Input string not correctly formatted ('{text}')");
|
||||
Matches = (Type[])list.ToArray(typeof(Type));
|
||||
list.Clear();
|
||||
|
||||
Title = text.Substring( 0, start ).Trim();
|
||||
int ourIndentation = lines[index].Indentation;
|
||||
|
||||
int end = text.IndexOf( ')', ++start );
|
||||
++index;
|
||||
|
||||
if ( end < start )
|
||||
throw new FormatException($"Input string not correctly formatted ('{text}')");
|
||||
while (index < lines.Length && lines[index].Indentation > ourIndentation)
|
||||
list.Add(new CategoryEntry(this, lines, ref index));
|
||||
|
||||
text = text.Substring( start, end-start );
|
||||
string[] split = text.Split( ';' );
|
||||
SubCategories = (CategoryEntry[])list.ToArray(typeof(CategoryEntry));
|
||||
list.Clear();
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
Matched = list;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < split.Length; ++i )
|
||||
{
|
||||
Type type = ScriptCompiler.FindTypeByName( split[i].Trim() );
|
||||
public string Title{ get; }
|
||||
|
||||
if ( type == null )
|
||||
Console.WriteLine( "Match type not found ('{0}')", split[i].Trim() );
|
||||
else
|
||||
list.Add( type );
|
||||
}
|
||||
public Type[] Matches{ get; }
|
||||
|
||||
Matches = (Type[])list.ToArray( typeof( Type ) );
|
||||
list.Clear();
|
||||
public CategoryEntry Parent{ get; }
|
||||
|
||||
int ourIndentation = lines[index].Indentation;
|
||||
public CategoryEntry[] SubCategories{ get; }
|
||||
|
||||
++index;
|
||||
public ArrayList Matched{ get; }
|
||||
|
||||
while ( index < lines.Length && lines[index].Indentation > ourIndentation )
|
||||
list.Add( new CategoryEntry( this, lines, ref index ) );
|
||||
public bool IsMatch(Type type)
|
||||
{
|
||||
bool isMatch = false;
|
||||
|
||||
SubCategories = (CategoryEntry[])list.ToArray( typeof( CategoryEntry ) );
|
||||
list.Clear();
|
||||
for (int i = 0; !isMatch && i < Matches.Length; ++i)
|
||||
isMatch = type == Matches[i] || type.IsSubclassOf(Matches[i]);
|
||||
|
||||
Matched = list;
|
||||
}
|
||||
}
|
||||
return isMatch;
|
||||
}
|
||||
}
|
||||
|
||||
public class CategoryLine
|
||||
{
|
||||
public int Indentation { get; }
|
||||
public class CategoryLine
|
||||
{
|
||||
public CategoryLine(string input)
|
||||
{
|
||||
int index;
|
||||
|
||||
public string Text { get; }
|
||||
for (index = 0; index < input.Length; ++index)
|
||||
if (char.IsLetter(input, index))
|
||||
break;
|
||||
|
||||
public CategoryLine( string input )
|
||||
{
|
||||
int index;
|
||||
if (index >= input.Length)
|
||||
throw new FormatException($"Input string not correctly formatted ('{input}')");
|
||||
|
||||
for ( index = 0; index < input.Length; ++index )
|
||||
{
|
||||
if ( char.IsLetter( input, index ) )
|
||||
break;
|
||||
}
|
||||
Indentation = index;
|
||||
Text = input.Substring(index);
|
||||
}
|
||||
|
||||
if ( index >= input.Length )
|
||||
throw new FormatException($"Input string not correctly formatted ('{input}')");
|
||||
public int Indentation{ get; }
|
||||
|
||||
Indentation = index;
|
||||
Text = input.Substring( index );
|
||||
}
|
||||
public string Text{ get; }
|
||||
|
||||
public static CategoryLine[] Load( string path )
|
||||
{
|
||||
ArrayList list = new ArrayList();
|
||||
public static CategoryLine[] Load(string path)
|
||||
{
|
||||
ArrayList list = new ArrayList();
|
||||
|
||||
if ( File.Exists( path ) )
|
||||
{
|
||||
using ( StreamReader ip = new StreamReader( path ) )
|
||||
{
|
||||
string line;
|
||||
if (File.Exists(path))
|
||||
using (StreamReader ip = new StreamReader(path))
|
||||
{
|
||||
string line;
|
||||
|
||||
while ( (line = ip.ReadLine()) != null )
|
||||
list.Add( new CategoryLine( line ) );
|
||||
}
|
||||
}
|
||||
while ((line = ip.ReadLine()) != null)
|
||||
list.Add(new CategoryLine(line));
|
||||
}
|
||||
|
||||
return (CategoryLine[])list.ToArray( typeof( CategoryLine ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
return (CategoryLine[])list.ToArray(typeof(CategoryLine));
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,163 +1,158 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public enum ObjectTypes
|
||||
{
|
||||
Both,
|
||||
Items,
|
||||
Mobiles,
|
||||
All
|
||||
}
|
||||
public enum ObjectTypes
|
||||
{
|
||||
Both,
|
||||
Items,
|
||||
Mobiles,
|
||||
All
|
||||
}
|
||||
|
||||
public abstract class BaseCommand
|
||||
{
|
||||
public bool ListOptimized { get; set; }
|
||||
public abstract class BaseCommand
|
||||
{
|
||||
private ArrayList m_Responses, m_Failures;
|
||||
|
||||
public string[] Commands { get; set; }
|
||||
public BaseCommand()
|
||||
{
|
||||
m_Responses = new ArrayList();
|
||||
m_Failures = new ArrayList();
|
||||
}
|
||||
|
||||
public string Usage { get; set; }
|
||||
public bool ListOptimized{ get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
public string[] Commands{ get; set; }
|
||||
|
||||
public AccessLevel AccessLevel { get; set; }
|
||||
public string Usage{ get; set; }
|
||||
|
||||
public ObjectTypes ObjectTypes { get; set; }
|
||||
public string Description{ get; set; }
|
||||
|
||||
public CommandSupport Supports { get; set; }
|
||||
public AccessLevel AccessLevel{ get; set; }
|
||||
|
||||
public BaseCommand()
|
||||
{
|
||||
m_Responses = new ArrayList();
|
||||
m_Failures = new ArrayList();
|
||||
}
|
||||
public ObjectTypes ObjectTypes{ get; set; }
|
||||
|
||||
public static bool IsAccessible( Mobile from, object obj )
|
||||
{
|
||||
if ( from.AccessLevel >= AccessLevel.Administrator || obj == null )
|
||||
return true;
|
||||
public CommandSupport Supports{ get; set; }
|
||||
|
||||
Mobile mob = null;
|
||||
public static bool IsAccessible(Mobile from, object obj)
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.Administrator || obj == null)
|
||||
return true;
|
||||
|
||||
if ( obj is Mobile m )
|
||||
mob = m;
|
||||
else if ( obj is Item item )
|
||||
mob = item.RootParent as Mobile;
|
||||
Mobile mob = null;
|
||||
|
||||
return mob == null || mob == from || from.AccessLevel > mob.AccessLevel;
|
||||
}
|
||||
if (obj is Mobile m)
|
||||
mob = m;
|
||||
else if (obj is Item item)
|
||||
mob = item.RootParent as Mobile;
|
||||
|
||||
public virtual void ExecuteList( CommandEventArgs e, ArrayList list )
|
||||
{
|
||||
for ( int i = 0; i < list.Count; ++i )
|
||||
Execute( e, list[i] );
|
||||
}
|
||||
return mob == null || mob == from || from.AccessLevel > mob.AccessLevel;
|
||||
}
|
||||
|
||||
public virtual void Execute( CommandEventArgs e, object obj )
|
||||
{
|
||||
}
|
||||
public virtual void ExecuteList(CommandEventArgs e, ArrayList list)
|
||||
{
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
Execute(e, list[i]);
|
||||
}
|
||||
|
||||
public virtual bool ValidateArgs( BaseCommandImplementor impl, CommandEventArgs e )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public virtual void Execute(CommandEventArgs e, object obj)
|
||||
{
|
||||
}
|
||||
|
||||
private ArrayList m_Responses, m_Failures;
|
||||
public virtual bool ValidateArgs(BaseCommandImplementor impl, CommandEventArgs e)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private class MessageEntry
|
||||
{
|
||||
public string m_Message;
|
||||
public int m_Count;
|
||||
public void AddResponse(string message)
|
||||
{
|
||||
for (int i = 0; i < m_Responses.Count; ++i)
|
||||
{
|
||||
MessageEntry entry = (MessageEntry)m_Responses[i];
|
||||
|
||||
public MessageEntry( string message )
|
||||
{
|
||||
m_Message = message;
|
||||
m_Count = 1;
|
||||
}
|
||||
if (entry.m_Message == message)
|
||||
{
|
||||
++entry.m_Count;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if ( m_Count > 1 )
|
||||
return $"{m_Message} ({m_Count})";
|
||||
if (m_Responses.Count == 10)
|
||||
return;
|
||||
|
||||
return m_Message;
|
||||
}
|
||||
}
|
||||
m_Responses.Add(new MessageEntry(message));
|
||||
}
|
||||
|
||||
public void AddResponse( string message )
|
||||
{
|
||||
for ( int i = 0; i < m_Responses.Count; ++i )
|
||||
{
|
||||
MessageEntry entry = (MessageEntry)m_Responses[i];
|
||||
public void AddResponse(Gump gump)
|
||||
{
|
||||
m_Responses.Add(gump);
|
||||
}
|
||||
|
||||
if ( entry.m_Message == message )
|
||||
{
|
||||
++entry.m_Count;
|
||||
return;
|
||||
}
|
||||
}
|
||||
public void LogFailure(string message)
|
||||
{
|
||||
for (int i = 0; i < m_Failures.Count; ++i)
|
||||
{
|
||||
MessageEntry entry = (MessageEntry)m_Failures[i];
|
||||
|
||||
if ( m_Responses.Count == 10 )
|
||||
return;
|
||||
if (entry.m_Message == message)
|
||||
{
|
||||
++entry.m_Count;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_Responses.Add( new MessageEntry( message ) );
|
||||
}
|
||||
if (m_Failures.Count == 10)
|
||||
return;
|
||||
|
||||
public void AddResponse( Gump gump )
|
||||
{
|
||||
m_Responses.Add( gump );
|
||||
}
|
||||
m_Failures.Add(new MessageEntry(message));
|
||||
}
|
||||
|
||||
public void LogFailure( string message )
|
||||
{
|
||||
for ( int i = 0; i < m_Failures.Count; ++i )
|
||||
{
|
||||
MessageEntry entry = (MessageEntry)m_Failures[i];
|
||||
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 ( entry.m_Message == message )
|
||||
{
|
||||
++entry.m_Count;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (obj is MessageEntry entry)
|
||||
{
|
||||
from.SendMessage(entry.ToString());
|
||||
|
||||
if ( m_Failures.Count == 10 )
|
||||
return;
|
||||
if (flushToLog)
|
||||
CommandLogging.WriteLine(from, entry.ToString());
|
||||
}
|
||||
else if (obj is Gump gump)
|
||||
{
|
||||
from.SendGump(gump);
|
||||
}
|
||||
}
|
||||
else
|
||||
for (int i = 0; i < m_Failures.Count; ++i)
|
||||
from.SendMessage(((MessageEntry)m_Failures[i]).ToString());
|
||||
|
||||
m_Failures.Add( new MessageEntry( message ) );
|
||||
}
|
||||
m_Responses.Clear();
|
||||
m_Failures.Clear();
|
||||
}
|
||||
|
||||
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];
|
||||
private class MessageEntry
|
||||
{
|
||||
public int m_Count;
|
||||
public string m_Message;
|
||||
|
||||
if ( obj is MessageEntry entry )
|
||||
{
|
||||
from.SendMessage( entry.ToString() );
|
||||
public MessageEntry(string message)
|
||||
{
|
||||
m_Message = message;
|
||||
m_Count = 1;
|
||||
}
|
||||
|
||||
if ( flushToLog )
|
||||
CommandLogging.WriteLine( from, entry.ToString() );
|
||||
}
|
||||
else if ( obj is Gump gump )
|
||||
{
|
||||
from.SendGump( gump );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( int i = 0; i < m_Failures.Count; ++i )
|
||||
from.SendMessage( ((MessageEntry)m_Failures[i]).ToString() );
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
if (m_Count > 1)
|
||||
return $"{m_Message} ({m_Count})";
|
||||
|
||||
m_Responses.Clear();
|
||||
m_Failures.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_Message;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
|
|
@ -8,198 +7,204 @@ using Server.Targeting;
|
|||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public class DesignInsertCommand : BaseCommand
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
TargetCommands.Register( new DesignInsertCommand() );
|
||||
}
|
||||
public class DesignInsertCommand : BaseCommand
|
||||
{
|
||||
public enum DesignInsertResult
|
||||
{
|
||||
Valid,
|
||||
InvalidItem,
|
||||
NotInHouse,
|
||||
OutsideHouseBounds
|
||||
}
|
||||
|
||||
public DesignInsertCommand()
|
||||
{
|
||||
AccessLevel = AccessLevel.GameMaster;
|
||||
Supports = CommandSupport.Single | CommandSupport.Area;
|
||||
Commands = new[] { "DesignInsert" };
|
||||
ObjectTypes = ObjectTypes.Items;
|
||||
Usage = "DesignInsert [allItems=false]";
|
||||
Description = "Inserts multiple targeted items into a customizable house's design.";
|
||||
}
|
||||
public DesignInsertCommand()
|
||||
{
|
||||
AccessLevel = AccessLevel.GameMaster;
|
||||
Supports = CommandSupport.Single | CommandSupport.Area;
|
||||
Commands = new[] { "DesignInsert" };
|
||||
ObjectTypes = ObjectTypes.Items;
|
||||
Usage = "DesignInsert [allItems=false]";
|
||||
Description = "Inserts multiple targeted items into a customizable house's design.";
|
||||
}
|
||||
|
||||
#region Single targeting mode
|
||||
public override void Execute( CommandEventArgs e, object obj )
|
||||
{
|
||||
Target t = new DesignInsertTarget( new List<HouseFoundation>(), ( e.Length < 1 || !e.GetBoolean( 0 ) ) );
|
||||
t.Invoke( e.Mobile, obj );
|
||||
}
|
||||
public static void Initialize()
|
||||
{
|
||||
TargetCommands.Register(new DesignInsertCommand());
|
||||
}
|
||||
|
||||
private class DesignInsertTarget : Target
|
||||
{
|
||||
private List<HouseFoundation> m_Foundations;
|
||||
private bool m_StaticsOnly;
|
||||
public static DesignInsertResult ProcessInsert(Item item, bool staticsOnly, out HouseFoundation house)
|
||||
{
|
||||
house = null;
|
||||
|
||||
public DesignInsertTarget( List<HouseFoundation> foundations, bool staticsOnly )
|
||||
: base( -1, false, TargetFlags.None )
|
||||
{
|
||||
m_Foundations = foundations;
|
||||
m_StaticsOnly = staticsOnly;
|
||||
}
|
||||
if (item == null || item is BaseMulti || item is HouseSign || staticsOnly && !(item is Static))
|
||||
return DesignInsertResult.InvalidItem;
|
||||
|
||||
protected override void OnTargetCancel( Mobile from, TargetCancelType cancelType )
|
||||
{
|
||||
if ( m_Foundations.Count != 0 )
|
||||
{
|
||||
from.SendMessage( "Your changes have been committed. Updating..." );
|
||||
house = BaseHouse.FindHouseAt(item) as HouseFoundation;
|
||||
|
||||
foreach ( HouseFoundation house in m_Foundations )
|
||||
house.Delta( ItemDelta.Update );
|
||||
}
|
||||
}
|
||||
if (house == null)
|
||||
return DesignInsertResult.NotInHouse;
|
||||
|
||||
protected override void OnTarget( Mobile from, object obj )
|
||||
{
|
||||
HouseFoundation house;
|
||||
DesignInsertResult result = ProcessInsert( obj as Item, m_StaticsOnly, out house );
|
||||
int x = item.X - house.X;
|
||||
int y = item.Y - house.Y;
|
||||
int z = item.Z - house.Z;
|
||||
|
||||
switch ( result )
|
||||
{
|
||||
case DesignInsertResult.Valid:
|
||||
{
|
||||
if ( m_Foundations.Count == 0 )
|
||||
from.SendMessage( "The item has been inserted into the house design. Press ESC when you are finished." );
|
||||
else
|
||||
from.SendMessage( "The item has been inserted into the house design." );
|
||||
if (!TryInsertIntoState(house.CurrentState, item.ItemID, x, y, z))
|
||||
return DesignInsertResult.OutsideHouseBounds;
|
||||
|
||||
if ( !m_Foundations.Contains( house ) )
|
||||
m_Foundations.Add( house );
|
||||
TryInsertIntoState(house.DesignState, item.ItemID, x, y, z);
|
||||
item.Delete();
|
||||
|
||||
break;
|
||||
}
|
||||
case DesignInsertResult.InvalidItem:
|
||||
{
|
||||
from.SendMessage( "That cannot be inserted. Try again." );
|
||||
break;
|
||||
}
|
||||
case DesignInsertResult.NotInHouse:
|
||||
case DesignInsertResult.OutsideHouseBounds:
|
||||
{
|
||||
from.SendMessage( "That item is not inside a customizable house. Try again." );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return DesignInsertResult.Valid;
|
||||
}
|
||||
|
||||
from.Target = new DesignInsertTarget( m_Foundations, m_StaticsOnly );
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
private static bool TryInsertIntoState(DesignState state, int itemID, int x, int y, int z)
|
||||
{
|
||||
MultiComponentList mcl = state.Components;
|
||||
|
||||
#region Area targeting mode
|
||||
public override void ExecuteList( CommandEventArgs e, ArrayList list )
|
||||
{
|
||||
e.Mobile.SendGump( new WarningGump( 1060637, 30720,
|
||||
$"You are about to insert {list.Count} objects. This cannot be undone without a full server revert.<br><br>Continue?", 0xFFC000, 420, 280, OnConfirmCallback, new object[] { e, list, ( e.Length < 1 || !e.GetBoolean( 0 ) ) } ) );
|
||||
AddResponse( "Awaiting confirmation..." );
|
||||
}
|
||||
if (x < mcl.Min.X || y < mcl.Min.Y || x > mcl.Max.X || y > mcl.Max.Y)
|
||||
return false;
|
||||
|
||||
private void OnConfirmCallback( Mobile from, bool okay, object state )
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
CommandEventArgs e = (CommandEventArgs)states[0];
|
||||
ArrayList list = (ArrayList)states[1];
|
||||
bool staticsOnly = (bool)states[2];
|
||||
mcl.Add(itemID, x, y, z);
|
||||
state.OnRevised();
|
||||
|
||||
bool flushToLog = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( okay )
|
||||
{
|
||||
List<HouseFoundation> foundations = new List<HouseFoundation>();
|
||||
flushToLog = ( list.Count > 20 );
|
||||
#region Single targeting mode
|
||||
|
||||
for ( int i = 0; i < list.Count; ++i )
|
||||
{
|
||||
HouseFoundation house;
|
||||
DesignInsertResult result = ProcessInsert( list[i] as Item, staticsOnly, out house );
|
||||
public override void Execute(CommandEventArgs e, object obj)
|
||||
{
|
||||
Target t = new DesignInsertTarget(new List<HouseFoundation>(), e.Length < 1 || !e.GetBoolean(0));
|
||||
t.Invoke(e.Mobile, obj);
|
||||
}
|
||||
|
||||
switch ( result )
|
||||
{
|
||||
case DesignInsertResult.Valid:
|
||||
{
|
||||
AddResponse( "The item has been inserted into the house design." );
|
||||
private class DesignInsertTarget : Target
|
||||
{
|
||||
private List<HouseFoundation> m_Foundations;
|
||||
private bool m_StaticsOnly;
|
||||
|
||||
if ( !foundations.Contains( house ) )
|
||||
foundations.Add( house );
|
||||
public DesignInsertTarget(List<HouseFoundation> foundations, bool staticsOnly)
|
||||
: base(-1, false, TargetFlags.None)
|
||||
{
|
||||
m_Foundations = foundations;
|
||||
m_StaticsOnly = staticsOnly;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case DesignInsertResult.InvalidItem:
|
||||
{
|
||||
LogFailure( "That cannot be inserted." );
|
||||
break;
|
||||
}
|
||||
case DesignInsertResult.NotInHouse:
|
||||
case DesignInsertResult.OutsideHouseBounds:
|
||||
{
|
||||
LogFailure( "That item is not inside a customizable house." );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType)
|
||||
{
|
||||
if (m_Foundations.Count != 0)
|
||||
{
|
||||
from.SendMessage("Your changes have been committed. Updating...");
|
||||
|
||||
foreach ( HouseFoundation house in foundations )
|
||||
house.Delta( ItemDelta.Update );
|
||||
}
|
||||
else
|
||||
{
|
||||
AddResponse( "Command aborted." );
|
||||
}
|
||||
foreach (HouseFoundation house in m_Foundations)
|
||||
house.Delta(ItemDelta.Update);
|
||||
}
|
||||
}
|
||||
|
||||
Flush( from, flushToLog );
|
||||
}
|
||||
#endregion
|
||||
protected override void OnTarget(Mobile from, object obj)
|
||||
{
|
||||
HouseFoundation house;
|
||||
DesignInsertResult result = ProcessInsert(obj as Item, m_StaticsOnly, out house);
|
||||
|
||||
public enum DesignInsertResult
|
||||
{
|
||||
Valid,
|
||||
InvalidItem,
|
||||
NotInHouse,
|
||||
OutsideHouseBounds
|
||||
}
|
||||
switch (result)
|
||||
{
|
||||
case DesignInsertResult.Valid:
|
||||
{
|
||||
if (m_Foundations.Count == 0)
|
||||
from.SendMessage(
|
||||
"The item has been inserted into the house design. Press ESC when you are finished.");
|
||||
else
|
||||
from.SendMessage("The item has been inserted into the house design.");
|
||||
|
||||
public static DesignInsertResult ProcessInsert( Item item, bool staticsOnly, out HouseFoundation house )
|
||||
{
|
||||
house = null;
|
||||
if (!m_Foundations.Contains(house))
|
||||
m_Foundations.Add(house);
|
||||
|
||||
if ( item == null || item is BaseMulti || item is HouseSign || ( staticsOnly && !( item is Static ) ) )
|
||||
return DesignInsertResult.InvalidItem;
|
||||
break;
|
||||
}
|
||||
case DesignInsertResult.InvalidItem:
|
||||
{
|
||||
from.SendMessage("That cannot be inserted. Try again.");
|
||||
break;
|
||||
}
|
||||
case DesignInsertResult.NotInHouse:
|
||||
case DesignInsertResult.OutsideHouseBounds:
|
||||
{
|
||||
from.SendMessage("That item is not inside a customizable house. Try again.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
house = BaseHouse.FindHouseAt( item ) as HouseFoundation;
|
||||
from.Target = new DesignInsertTarget(m_Foundations, m_StaticsOnly);
|
||||
}
|
||||
}
|
||||
|
||||
if ( house == null )
|
||||
return DesignInsertResult.NotInHouse;
|
||||
#endregion
|
||||
|
||||
int x = item.X - house.X;
|
||||
int y = item.Y - house.Y;
|
||||
int z = item.Z - house.Z;
|
||||
#region Area targeting mode
|
||||
|
||||
if ( !TryInsertIntoState( house.CurrentState, item.ItemID, x, y, z ) )
|
||||
return DesignInsertResult.OutsideHouseBounds;
|
||||
public override void ExecuteList(CommandEventArgs e, ArrayList list)
|
||||
{
|
||||
e.Mobile.SendGump(new WarningGump(1060637, 30720,
|
||||
$"You are about to insert {list.Count} objects. This cannot be undone without a full server revert.<br><br>Continue?",
|
||||
0xFFC000, 420, 280, OnConfirmCallback, new object[] { e, list, e.Length < 1 || !e.GetBoolean(0) }));
|
||||
AddResponse("Awaiting confirmation...");
|
||||
}
|
||||
|
||||
TryInsertIntoState( house.DesignState, item.ItemID, x, y, z );
|
||||
item.Delete();
|
||||
private void OnConfirmCallback(Mobile from, bool okay, object state)
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
CommandEventArgs e = (CommandEventArgs)states[0];
|
||||
ArrayList list = (ArrayList)states[1];
|
||||
bool staticsOnly = (bool)states[2];
|
||||
|
||||
return DesignInsertResult.Valid;
|
||||
}
|
||||
bool flushToLog = false;
|
||||
|
||||
private static bool TryInsertIntoState( DesignState state, int itemID, int x, int y, int z )
|
||||
{
|
||||
MultiComponentList mcl = state.Components;
|
||||
if (okay)
|
||||
{
|
||||
List<HouseFoundation> foundations = new List<HouseFoundation>();
|
||||
flushToLog = list.Count > 20;
|
||||
|
||||
if ( x < mcl.Min.X || y < mcl.Min.Y || x > mcl.Max.X || y > mcl.Max.Y )
|
||||
return false;
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
{
|
||||
HouseFoundation house;
|
||||
DesignInsertResult result = ProcessInsert(list[i] as Item, staticsOnly, out house);
|
||||
|
||||
mcl.Add( itemID, x, y, z );
|
||||
state.OnRevised();
|
||||
switch (result)
|
||||
{
|
||||
case DesignInsertResult.Valid:
|
||||
{
|
||||
AddResponse("The item has been inserted into the house design.");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!foundations.Contains(house))
|
||||
foundations.Add(house);
|
||||
|
||||
break;
|
||||
}
|
||||
case DesignInsertResult.InvalidItem:
|
||||
{
|
||||
LogFailure("That cannot be inserted.");
|
||||
break;
|
||||
}
|
||||
case DesignInsertResult.NotInHouse:
|
||||
case DesignInsertResult.OutsideHouseBounds:
|
||||
{
|
||||
LogFailure("That item is not inside a customizable house.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (HouseFoundation house in foundations)
|
||||
house.Delta(ItemDelta.Update);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddResponse("Command aborted.");
|
||||
}
|
||||
|
||||
Flush(from, flushToLog);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -4,139 +4,131 @@ using System.Collections.Generic;
|
|||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public delegate BaseExtension ExtensionConstructor();
|
||||
public delegate BaseExtension ExtensionConstructor();
|
||||
|
||||
public sealed class ExtensionInfo
|
||||
{
|
||||
public static Dictionary<string, ExtensionInfo> Table { get; } = new Dictionary<string, ExtensionInfo>( StringComparer.InvariantCultureIgnoreCase );
|
||||
public sealed class ExtensionInfo
|
||||
{
|
||||
public ExtensionInfo(int order, string name, int size, ExtensionConstructor constructor)
|
||||
{
|
||||
Name = name;
|
||||
Size = size;
|
||||
|
||||
public static void Register( ExtensionInfo ext )
|
||||
{
|
||||
Table[ext.Name] = ext;
|
||||
}
|
||||
Order = order;
|
||||
|
||||
public int Order { get; }
|
||||
Constructor = constructor;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public static Dictionary<string, ExtensionInfo> Table{ get; } =
|
||||
new Dictionary<string, ExtensionInfo>(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
public int Size { get; }
|
||||
public int Order{ get; }
|
||||
|
||||
public bool IsFixedSize => ( Size >= 0 );
|
||||
public string Name{ get; }
|
||||
|
||||
public ExtensionConstructor Constructor { get; }
|
||||
public int Size{ get; }
|
||||
|
||||
public ExtensionInfo( int order, string name, int size, ExtensionConstructor constructor )
|
||||
{
|
||||
Name = name;
|
||||
Size = size;
|
||||
public bool IsFixedSize => Size >= 0;
|
||||
|
||||
Order = order;
|
||||
public ExtensionConstructor Constructor{ get; }
|
||||
|
||||
Constructor = constructor;
|
||||
}
|
||||
}
|
||||
public static void Register(ExtensionInfo ext)
|
||||
{
|
||||
Table[ext.Name] = ext;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class Extensions : List<BaseExtension>
|
||||
{
|
||||
public Extensions()
|
||||
{
|
||||
}
|
||||
public sealed class Extensions : List<BaseExtension>
|
||||
{
|
||||
public bool IsValid(object obj)
|
||||
{
|
||||
for (int i = 0; i < Count; ++i)
|
||||
if (!this[i].IsValid(obj))
|
||||
return false;
|
||||
|
||||
public bool IsValid( object obj )
|
||||
{
|
||||
for ( int i = 0; i < Count; ++i )
|
||||
{
|
||||
if ( !this[i].IsValid( obj ) )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
public void Filter(ArrayList list)
|
||||
{
|
||||
for (int i = 0; i < Count; ++i)
|
||||
this[i].Filter(list);
|
||||
}
|
||||
|
||||
public void Filter( ArrayList list )
|
||||
{
|
||||
for ( int i = 0; i < Count; ++i )
|
||||
this[i].Filter( list );
|
||||
}
|
||||
public static Extensions Parse(Mobile from, ref string[] args)
|
||||
{
|
||||
Extensions parsed = new Extensions();
|
||||
|
||||
public static Extensions Parse( Mobile from, ref string[] args )
|
||||
{
|
||||
Extensions parsed = new Extensions();
|
||||
int size = args.Length;
|
||||
|
||||
int size = args.Length;
|
||||
Type baseType = null;
|
||||
|
||||
Type baseType = null;
|
||||
for (int i = args.Length - 1; i >= 0; --i)
|
||||
{
|
||||
if (!ExtensionInfo.Table.TryGetValue(args[i], out ExtensionInfo extInfo))
|
||||
continue;
|
||||
|
||||
for ( int i = args.Length - 1; i >= 0; --i )
|
||||
{
|
||||
if ( !ExtensionInfo.Table.TryGetValue( args[i], out ExtensionInfo extInfo ) )
|
||||
continue;
|
||||
if (extInfo.IsFixedSize && i != size - extInfo.Size - 1)
|
||||
throw new Exception("Invalid extended argument count.");
|
||||
|
||||
if ( extInfo.IsFixedSize && i != ( size - extInfo.Size - 1 ) )
|
||||
throw new Exception( "Invalid extended argument count." );
|
||||
BaseExtension ext = extInfo.Constructor();
|
||||
|
||||
BaseExtension ext = extInfo.Constructor();
|
||||
ext.Parse(from, args, i + 1, size - i - 1);
|
||||
|
||||
ext.Parse( from, args, i + 1, size - i - 1 );
|
||||
if (ext is WhereExtension extension)
|
||||
baseType = extension.Conditional.Type;
|
||||
|
||||
if ( ext is WhereExtension extension )
|
||||
baseType = extension.Conditional.Type;
|
||||
parsed.Add(ext);
|
||||
|
||||
parsed.Add( ext );
|
||||
size = i;
|
||||
}
|
||||
|
||||
size = i;
|
||||
}
|
||||
parsed.Sort(delegate(BaseExtension a, BaseExtension b) { return a.Order - b.Order; });
|
||||
|
||||
parsed.Sort( delegate( BaseExtension a, BaseExtension b )
|
||||
{
|
||||
return ( a.Order - b.Order );
|
||||
} );
|
||||
AssemblyEmitter emitter = null;
|
||||
|
||||
AssemblyEmitter emitter = null;
|
||||
foreach (BaseExtension update in parsed)
|
||||
update.Optimize(from, baseType, ref emitter);
|
||||
|
||||
foreach ( BaseExtension update in parsed )
|
||||
update.Optimize( from, baseType, ref emitter );
|
||||
if (size != args.Length)
|
||||
{
|
||||
string[] old = args;
|
||||
args = new string[size];
|
||||
|
||||
if ( size != args.Length )
|
||||
{
|
||||
string[] old = args;
|
||||
args = new string[size];
|
||||
for (int i = 0; i < args.Length; ++i)
|
||||
args[i] = old[i];
|
||||
}
|
||||
|
||||
for ( int i = 0; i < args.Length; ++i )
|
||||
args[i] = old[i];
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
public abstract class BaseExtension
|
||||
{
|
||||
public abstract ExtensionInfo Info{ get; }
|
||||
|
||||
public abstract class BaseExtension
|
||||
{
|
||||
public abstract ExtensionInfo Info { get; }
|
||||
public string Name => Info.Name;
|
||||
|
||||
public string Name => Info.Name;
|
||||
public int Size => Info.Size;
|
||||
|
||||
public int Size => Info.Size;
|
||||
public bool IsFixedSize => Info.IsFixedSize;
|
||||
|
||||
public bool IsFixedSize => Info.IsFixedSize;
|
||||
public int Order => Info.Order;
|
||||
|
||||
public int Order => Info.Order;
|
||||
public virtual void Optimize(Mobile from, Type baseType, ref AssemblyEmitter assembly)
|
||||
{
|
||||
}
|
||||
|
||||
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 void Parse( Mobile from, string[] arguments, int offset, int size )
|
||||
{
|
||||
}
|
||||
public virtual bool IsValid(object obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool IsValid( object obj )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void Filter( ArrayList list )
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
public virtual void Filter(ArrayList list)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -6,242 +6,254 @@ using System.Reflection.Emit;
|
|||
|
||||
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 )
|
||||
);
|
||||
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
|
||||
);
|
||||
#region Constructor
|
||||
|
||||
ILGenerator il = ctor.GetILGenerator();
|
||||
{
|
||||
ConstructorBuilder ctor = typeBuilder.DefineConstructor(
|
||||
MethodAttributes.Public,
|
||||
CallingConventions.Standard,
|
||||
Type.EmptyTypes
|
||||
);
|
||||
|
||||
// : base()
|
||||
il.Emit( OpCodes.Ldarg_0 );
|
||||
il.Emit( OpCodes.Call, typeof( object ).GetConstructor( Type.EmptyTypes ) );
|
||||
ILGenerator il = ctor.GetILGenerator();
|
||||
|
||||
// return;
|
||||
il.Emit( OpCodes.Ret );
|
||||
}
|
||||
#endregion
|
||||
// : base()
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
|
||||
|
||||
#region IComparer
|
||||
typeBuilder.AddInterfaceImplementation( typeof( IComparer ) );
|
||||
// return;
|
||||
il.Emit(OpCodes.Ret);
|
||||
}
|
||||
|
||||
MethodBuilder compareMethod;
|
||||
#endregion
|
||||
|
||||
#region Compare
|
||||
{
|
||||
MethodEmitter emitter = new MethodEmitter( typeBuilder );
|
||||
#region IComparer
|
||||
|
||||
emitter.Define(
|
||||
/* name */ "Compare",
|
||||
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
|
||||
/* return */ typeof( int ),
|
||||
/* params */ new[] { typeof( object ), typeof( object ) } );
|
||||
typeBuilder.AddInterfaceImplementation(typeof(IComparer));
|
||||
|
||||
LocalBuilder a = emitter.CreateLocal( objectType );
|
||||
LocalBuilder b = emitter.CreateLocal( objectType );
|
||||
MethodBuilder compareMethod;
|
||||
|
||||
LocalBuilder v = emitter.CreateLocal( typeof( int ) );
|
||||
#region Compare
|
||||
|
||||
emitter.LoadArgument( 1 );
|
||||
emitter.CastAs( objectType );
|
||||
emitter.StoreLocal( a );
|
||||
{
|
||||
MethodEmitter emitter = new MethodEmitter(typeBuilder);
|
||||
|
||||
emitter.LoadArgument( 2 );
|
||||
emitter.CastAs( objectType );
|
||||
emitter.StoreLocal( b );
|
||||
emitter.Define(
|
||||
/* name */ "Compare",
|
||||
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
|
||||
/* return */ typeof(int),
|
||||
/* params */ new[] { typeof(object), typeof(object) });
|
||||
|
||||
emitter.Load( 0 );
|
||||
emitter.StoreLocal( v );
|
||||
LocalBuilder a = emitter.CreateLocal(objectType);
|
||||
LocalBuilder b = emitter.CreateLocal(objectType);
|
||||
|
||||
Label end = emitter.CreateLabel();
|
||||
LocalBuilder v = emitter.CreateLocal(typeof(int));
|
||||
|
||||
for ( int i = 0; i < props.Length; ++i )
|
||||
{
|
||||
if ( i > 0 )
|
||||
{
|
||||
emitter.LoadLocal( v );
|
||||
emitter.BranchIfTrue( end ); // if ( v != 0 ) return v;
|
||||
}
|
||||
emitter.LoadArgument(1);
|
||||
emitter.CastAs(objectType);
|
||||
emitter.StoreLocal(a);
|
||||
|
||||
Property prop = props[i];
|
||||
emitter.LoadArgument(2);
|
||||
emitter.CastAs(objectType);
|
||||
emitter.StoreLocal(b);
|
||||
|
||||
emitter.LoadLocal( a );
|
||||
emitter.Chain( prop );
|
||||
emitter.Load(0);
|
||||
emitter.StoreLocal(v);
|
||||
|
||||
bool couldCompare =
|
||||
emitter.CompareTo( 1, delegate
|
||||
{
|
||||
emitter.LoadLocal( b );
|
||||
emitter.Chain( prop );
|
||||
} );
|
||||
Label end = emitter.CreateLabel();
|
||||
|
||||
if ( !couldCompare )
|
||||
throw new InvalidOperationException( "Property is not comparable." );
|
||||
for (int i = 0; i < props.Length; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
emitter.LoadLocal(v);
|
||||
emitter.BranchIfTrue(end); // if ( v != 0 ) return v;
|
||||
}
|
||||
|
||||
emitter.StoreLocal( v );
|
||||
}
|
||||
Property prop = props[i];
|
||||
|
||||
emitter.MarkLabel( end );
|
||||
emitter.LoadLocal(a);
|
||||
emitter.Chain(prop);
|
||||
|
||||
emitter.LoadLocal( v );
|
||||
emitter.Return();
|
||||
bool couldCompare =
|
||||
emitter.CompareTo(1, delegate
|
||||
{
|
||||
emitter.LoadLocal(b);
|
||||
emitter.Chain(prop);
|
||||
});
|
||||
|
||||
typeBuilder.DefineMethodOverride(
|
||||
emitter.Method,
|
||||
typeof( IComparer ).GetMethod(
|
||||
"Compare",
|
||||
new[]
|
||||
{
|
||||
typeof( object ),
|
||||
typeof( object )
|
||||
}
|
||||
)
|
||||
);
|
||||
if (!couldCompare)
|
||||
throw new InvalidOperationException("Property is not comparable.");
|
||||
|
||||
compareMethod = emitter.Method;
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
emitter.StoreLocal(v);
|
||||
}
|
||||
|
||||
#region IEqualityComparer
|
||||
typeBuilder.AddInterfaceImplementation( typeof( IEqualityComparer<object> ) );
|
||||
emitter.MarkLabel(end);
|
||||
|
||||
#region Equals
|
||||
{
|
||||
MethodEmitter emitter = new MethodEmitter( typeBuilder );
|
||||
emitter.LoadLocal(v);
|
||||
emitter.Return();
|
||||
|
||||
emitter.Define(
|
||||
/* name */ "Equals",
|
||||
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
|
||||
/* return */ typeof( bool ),
|
||||
/* params */ new[] { typeof( object ), typeof( object ) } );
|
||||
typeBuilder.DefineMethodOverride(
|
||||
emitter.Method,
|
||||
typeof(IComparer).GetMethod(
|
||||
"Compare",
|
||||
new[]
|
||||
{
|
||||
typeof(object),
|
||||
typeof(object)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
emitter.Generator.Emit( OpCodes.Ldarg_0 );
|
||||
emitter.Generator.Emit( OpCodes.Ldarg_1 );
|
||||
emitter.Generator.Emit( OpCodes.Ldarg_2 );
|
||||
compareMethod = emitter.Method;
|
||||
}
|
||||
|
||||
emitter.Generator.Emit( OpCodes.Call, compareMethod );
|
||||
#endregion
|
||||
|
||||
emitter.Generator.Emit( OpCodes.Ldc_I4_0 );
|
||||
#endregion
|
||||
|
||||
emitter.Generator.Emit( OpCodes.Ceq );
|
||||
#region IEqualityComparer
|
||||
|
||||
emitter.Generator.Emit( OpCodes.Ret );
|
||||
typeBuilder.AddInterfaceImplementation(typeof(IEqualityComparer<object>));
|
||||
|
||||
typeBuilder.DefineMethodOverride(
|
||||
emitter.Method,
|
||||
typeof( IEqualityComparer<object> ).GetMethod(
|
||||
"Equals",
|
||||
new[]
|
||||
{
|
||||
typeof( object ),
|
||||
typeof( object )
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
#endregion
|
||||
#region Equals
|
||||
|
||||
#region GetHashCode
|
||||
{
|
||||
MethodEmitter emitter = new MethodEmitter( typeBuilder );
|
||||
{
|
||||
MethodEmitter emitter = new MethodEmitter(typeBuilder);
|
||||
|
||||
emitter.Define(
|
||||
/* name */ "GetHashCode",
|
||||
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
|
||||
/* return */ typeof( int ),
|
||||
/* params */ new[] { typeof( object ) } );
|
||||
emitter.Define(
|
||||
/* name */ "Equals",
|
||||
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
|
||||
/* return */ typeof(bool),
|
||||
/* params */ new[] { typeof(object), typeof(object) });
|
||||
|
||||
LocalBuilder obj = emitter.CreateLocal( objectType );
|
||||
emitter.Generator.Emit(OpCodes.Ldarg_0);
|
||||
emitter.Generator.Emit(OpCodes.Ldarg_1);
|
||||
emitter.Generator.Emit(OpCodes.Ldarg_2);
|
||||
|
||||
emitter.LoadArgument( 1 );
|
||||
emitter.CastAs( objectType );
|
||||
emitter.StoreLocal( obj );
|
||||
emitter.Generator.Emit(OpCodes.Call, compareMethod);
|
||||
|
||||
for ( int i = 0; i < props.Length; ++i )
|
||||
{
|
||||
Property prop = props[i];
|
||||
emitter.Generator.Emit(OpCodes.Ldc_I4_0);
|
||||
|
||||
emitter.LoadLocal( obj );
|
||||
emitter.Chain( prop );
|
||||
emitter.Generator.Emit(OpCodes.Ceq);
|
||||
|
||||
Type active = emitter.Active;
|
||||
emitter.Generator.Emit(OpCodes.Ret);
|
||||
|
||||
MethodInfo getHashCode = active.GetMethod( "GetHashCode", Type.EmptyTypes );
|
||||
typeBuilder.DefineMethodOverride(
|
||||
emitter.Method,
|
||||
typeof(IEqualityComparer<object>).GetMethod(
|
||||
"Equals",
|
||||
new[]
|
||||
{
|
||||
typeof(object),
|
||||
typeof(object)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( getHashCode == null )
|
||||
getHashCode = typeof( object ).GetMethod( "GetHashCode", Type.EmptyTypes );
|
||||
#endregion
|
||||
|
||||
if ( active != typeof( int ) )
|
||||
{
|
||||
if ( !active.IsValueType )
|
||||
{
|
||||
LocalBuilder value = emitter.AcquireTemp( active );
|
||||
#region GetHashCode
|
||||
|
||||
Label valueNotNull = emitter.CreateLabel();
|
||||
Label done = emitter.CreateLabel();
|
||||
{
|
||||
MethodEmitter emitter = new MethodEmitter(typeBuilder);
|
||||
|
||||
emitter.StoreLocal( value );
|
||||
emitter.LoadLocal( value );
|
||||
emitter.Define(
|
||||
/* name */ "GetHashCode",
|
||||
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
|
||||
/* return */ typeof(int),
|
||||
/* params */ new[] { typeof(object) });
|
||||
|
||||
emitter.BranchIfTrue( valueNotNull );
|
||||
LocalBuilder obj = emitter.CreateLocal(objectType);
|
||||
|
||||
emitter.Load( 0 );
|
||||
emitter.Pop( typeof( int ) );
|
||||
emitter.LoadArgument(1);
|
||||
emitter.CastAs(objectType);
|
||||
emitter.StoreLocal(obj);
|
||||
|
||||
emitter.Branch( done );
|
||||
for (int i = 0; i < props.Length; ++i)
|
||||
{
|
||||
Property prop = props[i];
|
||||
|
||||
emitter.MarkLabel( valueNotNull );
|
||||
emitter.LoadLocal(obj);
|
||||
emitter.Chain(prop);
|
||||
|
||||
emitter.LoadLocal( value );
|
||||
emitter.Call( getHashCode );
|
||||
Type active = emitter.Active;
|
||||
|
||||
emitter.ReleaseTemp( value );
|
||||
MethodInfo getHashCode = active.GetMethod("GetHashCode", Type.EmptyTypes);
|
||||
|
||||
emitter.MarkLabel( done );
|
||||
}
|
||||
else
|
||||
{
|
||||
emitter.Call( getHashCode );
|
||||
}
|
||||
}
|
||||
if (getHashCode == null)
|
||||
getHashCode = typeof(object).GetMethod("GetHashCode", Type.EmptyTypes);
|
||||
|
||||
if ( i > 0 )
|
||||
emitter.Xor();
|
||||
}
|
||||
if (active != typeof(int))
|
||||
{
|
||||
if (!active.IsValueType)
|
||||
{
|
||||
LocalBuilder value = emitter.AcquireTemp(active);
|
||||
|
||||
emitter.Return();
|
||||
Label valueNotNull = emitter.CreateLabel();
|
||||
Label done = emitter.CreateLabel();
|
||||
|
||||
typeBuilder.DefineMethodOverride(
|
||||
emitter.Method,
|
||||
typeof( IEqualityComparer<object> ).GetMethod(
|
||||
"GetHashCode",
|
||||
new[]
|
||||
{
|
||||
typeof( object )
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
emitter.StoreLocal(value);
|
||||
emitter.LoadLocal(value);
|
||||
|
||||
Type comparerType = typeBuilder.CreateType();
|
||||
emitter.BranchIfTrue(valueNotNull);
|
||||
|
||||
return (IComparer) Activator.CreateInstance( comparerType );
|
||||
}
|
||||
}
|
||||
}
|
||||
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[]
|
||||
{
|
||||
typeof(object)
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
Type comparerType = typeBuilder.CreateType();
|
||||
|
||||
return (IComparer)Activator.CreateInstance(comparerType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,160 +5,166 @@ using System.Reflection.Emit;
|
|||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public sealed class OrderInfo
|
||||
{
|
||||
private int m_Order;
|
||||
public sealed class OrderInfo
|
||||
{
|
||||
private int m_Order;
|
||||
|
||||
public Property Property { get; set; }
|
||||
public OrderInfo(Property property, bool isAscending)
|
||||
{
|
||||
Property = property;
|
||||
|
||||
public bool IsAscending
|
||||
{
|
||||
get => ( m_Order > 0 );
|
||||
set => m_Order = ( value ? +1 : -1 );
|
||||
}
|
||||
IsAscending = isAscending;
|
||||
}
|
||||
|
||||
public bool IsDescending
|
||||
{
|
||||
get => ( m_Order < 0 );
|
||||
set => m_Order = ( value ? -1 : +1 );
|
||||
}
|
||||
public Property Property{ get; set; }
|
||||
|
||||
public int Sign
|
||||
{
|
||||
get => Math.Sign( m_Order );
|
||||
set
|
||||
{
|
||||
m_Order = Math.Sign( value );
|
||||
public bool IsAscending
|
||||
{
|
||||
get => m_Order > 0;
|
||||
set => m_Order = value ? +1 : -1;
|
||||
}
|
||||
|
||||
if ( m_Order == 0 )
|
||||
throw new InvalidOperationException( "Sign cannot be zero." );
|
||||
}
|
||||
}
|
||||
public bool IsDescending
|
||||
{
|
||||
get => m_Order < 0;
|
||||
set => m_Order = value ? -1 : +1;
|
||||
}
|
||||
|
||||
public OrderInfo( Property property, bool isAscending )
|
||||
{
|
||||
Property = property;
|
||||
public int Sign
|
||||
{
|
||||
get => Math.Sign(m_Order);
|
||||
set
|
||||
{
|
||||
m_Order = Math.Sign(value);
|
||||
|
||||
IsAscending = isAscending;
|
||||
}
|
||||
}
|
||||
if (m_Order == 0)
|
||||
throw new InvalidOperationException("Sign cannot be zero.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SortCompiler
|
||||
{
|
||||
public static IComparer Compile( AssemblyEmitter assembly, Type objectType, OrderInfo[] orders )
|
||||
{
|
||||
TypeBuilder typeBuilder = assembly.DefineType(
|
||||
"__sort",
|
||||
TypeAttributes.Public,
|
||||
typeof( object )
|
||||
);
|
||||
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
|
||||
);
|
||||
#region Constructor
|
||||
|
||||
ILGenerator il = ctor.GetILGenerator();
|
||||
{
|
||||
ConstructorBuilder ctor = typeBuilder.DefineConstructor(
|
||||
MethodAttributes.Public,
|
||||
CallingConventions.Standard,
|
||||
Type.EmptyTypes
|
||||
);
|
||||
|
||||
// : base()
|
||||
il.Emit( OpCodes.Ldarg_0 );
|
||||
il.Emit( OpCodes.Call, typeof( object ).GetConstructor( Type.EmptyTypes ) );
|
||||
ILGenerator il = ctor.GetILGenerator();
|
||||
|
||||
// return;
|
||||
il.Emit( OpCodes.Ret );
|
||||
}
|
||||
#endregion
|
||||
// : base()
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
|
||||
|
||||
#region IComparer
|
||||
typeBuilder.AddInterfaceImplementation( typeof( IComparer ) );
|
||||
// return;
|
||||
il.Emit(OpCodes.Ret);
|
||||
}
|
||||
|
||||
MethodBuilder compareMethod;
|
||||
#endregion
|
||||
|
||||
#region Compare
|
||||
{
|
||||
MethodEmitter emitter = new MethodEmitter( typeBuilder );
|
||||
#region IComparer
|
||||
|
||||
emitter.Define(
|
||||
/* name */ "Compare",
|
||||
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
|
||||
/* return */ typeof( int ),
|
||||
/* params */ new[] { typeof( object ), typeof( object ) } );
|
||||
typeBuilder.AddInterfaceImplementation(typeof(IComparer));
|
||||
|
||||
LocalBuilder a = emitter.CreateLocal( objectType );
|
||||
LocalBuilder b = emitter.CreateLocal( objectType );
|
||||
MethodBuilder compareMethod;
|
||||
|
||||
LocalBuilder v = emitter.CreateLocal( typeof( int ) );
|
||||
#region Compare
|
||||
|
||||
emitter.LoadArgument( 1 );
|
||||
emitter.CastAs( objectType );
|
||||
emitter.StoreLocal( a );
|
||||
{
|
||||
MethodEmitter emitter = new MethodEmitter(typeBuilder);
|
||||
|
||||
emitter.LoadArgument( 2 );
|
||||
emitter.CastAs( objectType );
|
||||
emitter.StoreLocal( b );
|
||||
emitter.Define(
|
||||
/* name */ "Compare",
|
||||
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
|
||||
/* return */ typeof(int),
|
||||
/* params */ new[] { typeof(object), typeof(object) });
|
||||
|
||||
emitter.Load( 0 );
|
||||
emitter.StoreLocal( v );
|
||||
LocalBuilder a = emitter.CreateLocal(objectType);
|
||||
LocalBuilder b = emitter.CreateLocal(objectType);
|
||||
|
||||
Label end = emitter.CreateLabel();
|
||||
LocalBuilder v = emitter.CreateLocal(typeof(int));
|
||||
|
||||
for ( int i = 0; i < orders.Length; ++i )
|
||||
{
|
||||
if ( i > 0 )
|
||||
{
|
||||
emitter.LoadLocal( v );
|
||||
emitter.BranchIfTrue( end ); // if ( v != 0 ) return v;
|
||||
}
|
||||
emitter.LoadArgument(1);
|
||||
emitter.CastAs(objectType);
|
||||
emitter.StoreLocal(a);
|
||||
|
||||
OrderInfo orderInfo = orders[i];
|
||||
emitter.LoadArgument(2);
|
||||
emitter.CastAs(objectType);
|
||||
emitter.StoreLocal(b);
|
||||
|
||||
Property prop = orderInfo.Property;
|
||||
int sign = orderInfo.Sign;
|
||||
emitter.Load(0);
|
||||
emitter.StoreLocal(v);
|
||||
|
||||
emitter.LoadLocal( a );
|
||||
emitter.Chain( prop );
|
||||
Label end = emitter.CreateLabel();
|
||||
|
||||
bool couldCompare =
|
||||
emitter.CompareTo( sign, delegate
|
||||
{
|
||||
emitter.LoadLocal( b );
|
||||
emitter.Chain( prop );
|
||||
} );
|
||||
for (int i = 0; i < orders.Length; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
emitter.LoadLocal(v);
|
||||
emitter.BranchIfTrue(end); // if ( v != 0 ) return v;
|
||||
}
|
||||
|
||||
if ( !couldCompare )
|
||||
throw new InvalidOperationException( "Property is not comparable." );
|
||||
OrderInfo orderInfo = orders[i];
|
||||
|
||||
emitter.StoreLocal( v );
|
||||
}
|
||||
Property prop = orderInfo.Property;
|
||||
int sign = orderInfo.Sign;
|
||||
|
||||
emitter.MarkLabel( end );
|
||||
emitter.LoadLocal(a);
|
||||
emitter.Chain(prop);
|
||||
|
||||
emitter.LoadLocal( v );
|
||||
emitter.Return();
|
||||
bool couldCompare =
|
||||
emitter.CompareTo(sign, delegate
|
||||
{
|
||||
emitter.LoadLocal(b);
|
||||
emitter.Chain(prop);
|
||||
});
|
||||
|
||||
typeBuilder.DefineMethodOverride(
|
||||
emitter.Method,
|
||||
typeof( IComparer ).GetMethod(
|
||||
"Compare",
|
||||
new[]
|
||||
{
|
||||
typeof( object ),
|
||||
typeof( object )
|
||||
}
|
||||
)
|
||||
);
|
||||
if (!couldCompare)
|
||||
throw new InvalidOperationException("Property is not comparable.");
|
||||
|
||||
compareMethod = emitter.Method;
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
emitter.StoreLocal(v);
|
||||
}
|
||||
|
||||
Type comparerType = typeBuilder.CreateType();
|
||||
emitter.MarkLabel(end);
|
||||
|
||||
return (IComparer) Activator.CreateInstance( comparerType );
|
||||
}
|
||||
}
|
||||
}
|
||||
emitter.LoadLocal(v);
|
||||
emitter.Return();
|
||||
|
||||
typeBuilder.DefineMethodOverride(
|
||||
emitter.Method,
|
||||
typeof(IComparer).GetMethod(
|
||||
"Compare",
|
||||
new[]
|
||||
{
|
||||
typeof(object),
|
||||
typeof(object)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
compareMethod = emitter.Method;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
Type comparerType = typeBuilder.CreateType();
|
||||
|
||||
return (IComparer)Activator.CreateInstance(comparerType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,81 +4,82 @@ using System.Collections.Generic;
|
|||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public sealed class DistinctExtension : BaseExtension
|
||||
{
|
||||
public static ExtensionInfo ExtInfo = new ExtensionInfo( 30, "Distinct", -1, delegate { return new DistinctExtension(); } );
|
||||
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 );
|
||||
}
|
||||
private IComparer m_Comparer;
|
||||
|
||||
public override ExtensionInfo Info => ExtInfo;
|
||||
private List<Property> m_Properties;
|
||||
|
||||
private List<Property> m_Properties;
|
||||
public DistinctExtension()
|
||||
{
|
||||
m_Properties = new List<Property>();
|
||||
}
|
||||
|
||||
private IComparer m_Comparer;
|
||||
public override ExtensionInfo Info => ExtInfo;
|
||||
|
||||
public DistinctExtension()
|
||||
{
|
||||
m_Properties = new List<Property>();
|
||||
}
|
||||
public static void Initialize()
|
||||
{
|
||||
ExtensionInfo.Register(ExtInfo);
|
||||
}
|
||||
|
||||
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." );
|
||||
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 );
|
||||
}
|
||||
foreach (Property prop in m_Properties)
|
||||
{
|
||||
prop.BindTo(baseType, PropertyAccess.Read);
|
||||
prop.CheckAccess(from);
|
||||
}
|
||||
|
||||
if ( assembly == null )
|
||||
assembly = new AssemblyEmitter( "__dynamic", false );
|
||||
if (assembly == null)
|
||||
assembly = new AssemblyEmitter("__dynamic", false);
|
||||
|
||||
m_Comparer = DistinctCompiler.Compile( assembly, baseType, m_Properties.ToArray() );
|
||||
}
|
||||
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." );
|
||||
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;
|
||||
int end = offset + size;
|
||||
|
||||
while ( offset < end )
|
||||
{
|
||||
string binding = arguments[offset++];
|
||||
while (offset < end)
|
||||
{
|
||||
string binding = arguments[offset++];
|
||||
|
||||
m_Properties.Add( new Property( binding ) );
|
||||
}
|
||||
}
|
||||
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." );
|
||||
public override void Filter(ArrayList list)
|
||||
{
|
||||
if (m_Comparer == null)
|
||||
throw new InvalidOperationException("The extension must first be optimized.");
|
||||
|
||||
ArrayList copy = new ArrayList( list );
|
||||
ArrayList copy = new ArrayList(list);
|
||||
|
||||
copy.Sort( m_Comparer );
|
||||
copy.Sort(m_Comparer);
|
||||
|
||||
list.Clear();
|
||||
list.Clear();
|
||||
|
||||
object last = null;
|
||||
object last = null;
|
||||
|
||||
for ( int i = 0; i < copy.Count; ++i )
|
||||
{
|
||||
object obj = copy[i];
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (last == null || m_Comparer.Compare(obj, last) != 0)
|
||||
{
|
||||
list.Add(obj);
|
||||
last = obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,35 +3,31 @@ using System.Collections;
|
|||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public sealed class LimitExtension : BaseExtension
|
||||
{
|
||||
public static ExtensionInfo ExtInfo = new ExtensionInfo( 80, "Limit", 1, delegate { return new LimitExtension(); } );
|
||||
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 => ExtInfo;
|
||||
|
||||
public override ExtensionInfo Info => ExtInfo;
|
||||
public int Limit{ get; private set; }
|
||||
|
||||
public int Limit { get; private set; }
|
||||
public static void Initialize()
|
||||
{
|
||||
ExtensionInfo.Register(ExtInfo);
|
||||
}
|
||||
|
||||
public LimitExtension()
|
||||
{
|
||||
}
|
||||
public override void Parse(Mobile from, string[] arguments, int offset, int size)
|
||||
{
|
||||
Limit = Utility.ToInt32(arguments[offset]);
|
||||
|
||||
public override void Parse( Mobile from, string[] arguments, int offset, int size )
|
||||
{
|
||||
Limit = Utility.ToInt32( arguments[offset] );
|
||||
if (Limit < 0)
|
||||
throw new Exception("Limit cannot be less than zero.");
|
||||
}
|
||||
|
||||
if ( Limit < 0 )
|
||||
throw new Exception( "Limit cannot be less than zero." );
|
||||
}
|
||||
|
||||
public override void Filter( ArrayList list )
|
||||
{
|
||||
if ( list.Count > Limit )
|
||||
list.RemoveRange( Limit, list.Count - Limit );
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void Filter(ArrayList list)
|
||||
{
|
||||
if (list.Count > Limit)
|
||||
list.RemoveRange(Limit, list.Count - Limit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,101 +4,101 @@ using System.Collections.Generic;
|
|||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public sealed class SortExtension : BaseExtension
|
||||
{
|
||||
public static ExtensionInfo ExtInfo = new ExtensionInfo( 40, "Order", -1, delegate { return new SortExtension(); } );
|
||||
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 );
|
||||
}
|
||||
private IComparer m_Comparer;
|
||||
|
||||
public override ExtensionInfo Info => ExtInfo;
|
||||
private List<OrderInfo> m_Orders;
|
||||
|
||||
private List<OrderInfo> m_Orders;
|
||||
public SortExtension()
|
||||
{
|
||||
m_Orders = new List<OrderInfo>();
|
||||
}
|
||||
|
||||
private IComparer m_Comparer;
|
||||
public override ExtensionInfo Info => ExtInfo;
|
||||
|
||||
public SortExtension()
|
||||
{
|
||||
m_Orders = new List<OrderInfo>();
|
||||
}
|
||||
public static void Initialize()
|
||||
{
|
||||
ExtensionInfo.Register(ExtInfo);
|
||||
}
|
||||
|
||||
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." );
|
||||
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 );
|
||||
}
|
||||
foreach (OrderInfo order in m_Orders)
|
||||
{
|
||||
order.Property.BindTo(baseType, PropertyAccess.Read);
|
||||
order.Property.CheckAccess(from);
|
||||
}
|
||||
|
||||
if ( assembly == null )
|
||||
assembly = new AssemblyEmitter( "__dynamic", false );
|
||||
if (assembly == null)
|
||||
assembly = new AssemblyEmitter("__dynamic", false);
|
||||
|
||||
m_Comparer = SortCompiler.Compile( assembly, baseType, m_Orders.ToArray() );
|
||||
}
|
||||
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." );
|
||||
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 (Insensitive.Equals(arguments[offset], "by"))
|
||||
{
|
||||
++offset;
|
||||
--size;
|
||||
|
||||
if ( size < 1 )
|
||||
throw new Exception( "Invalid ordering syntax." );
|
||||
}
|
||||
if (size < 1)
|
||||
throw new Exception("Invalid ordering syntax.");
|
||||
}
|
||||
|
||||
int end = offset + size;
|
||||
int end = offset + size;
|
||||
|
||||
while ( offset < end )
|
||||
{
|
||||
string binding = arguments[offset++];
|
||||
while (offset < end)
|
||||
{
|
||||
string binding = arguments[offset++];
|
||||
|
||||
bool isAscending = true;
|
||||
bool isAscending = true;
|
||||
|
||||
if ( offset < end )
|
||||
{
|
||||
string next = arguments[offset];
|
||||
if (offset < end)
|
||||
{
|
||||
string next = arguments[offset];
|
||||
|
||||
switch ( next.ToLower() )
|
||||
{
|
||||
case "+":
|
||||
case "up":
|
||||
case "asc":
|
||||
case "ascending":
|
||||
isAscending = true;
|
||||
++offset;
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
case "-":
|
||||
case "down":
|
||||
case "desc":
|
||||
case "descending":
|
||||
isAscending = false;
|
||||
++offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Property property = new Property( binding );
|
||||
Property property = new Property(binding);
|
||||
|
||||
m_Orders.Add( new OrderInfo( property, isAscending ) );
|
||||
}
|
||||
}
|
||||
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." );
|
||||
public override void Filter(ArrayList list)
|
||||
{
|
||||
if (m_Comparer == null)
|
||||
throw new InvalidOperationException("The extension must first be optimized.");
|
||||
|
||||
list.Sort( m_Comparer );
|
||||
}
|
||||
}
|
||||
}
|
||||
list.Sort(m_Comparer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,42 +2,38 @@ using System;
|
|||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public sealed class WhereExtension : BaseExtension
|
||||
{
|
||||
public static ExtensionInfo ExtInfo = new ExtensionInfo( 20, "Where", -1, delegate { return new WhereExtension(); } );
|
||||
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 => ExtInfo;
|
||||
|
||||
public override ExtensionInfo Info => ExtInfo;
|
||||
public ObjectConditional Conditional{ get; private set; }
|
||||
|
||||
public ObjectConditional Conditional { get; private set; }
|
||||
public static void Initialize()
|
||||
{
|
||||
ExtensionInfo.Register(ExtInfo);
|
||||
}
|
||||
|
||||
public WhereExtension()
|
||||
{
|
||||
}
|
||||
public override void Optimize(Mobile from, Type baseType, ref AssemblyEmitter assembly)
|
||||
{
|
||||
if (baseType == null)
|
||||
throw new InvalidOperationException("Insanity.");
|
||||
|
||||
public override void Optimize( Mobile from, Type baseType, ref AssemblyEmitter assembly )
|
||||
{
|
||||
if ( baseType == null )
|
||||
throw new InvalidOperationException( "Insanity." );
|
||||
Conditional.Compile(ref assembly);
|
||||
}
|
||||
|
||||
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.");
|
||||
|
||||
public override void Parse( Mobile from, string[] arguments, int offset, int size )
|
||||
{
|
||||
if ( size < 1 )
|
||||
throw new Exception( "Invalid condition syntax." );
|
||||
Conditional = ObjectConditional.ParseDirect(from, arguments, offset, size);
|
||||
}
|
||||
|
||||
Conditional = ObjectConditional.ParseDirect( from, arguments, offset, size );
|
||||
}
|
||||
|
||||
public override bool IsValid( object obj )
|
||||
{
|
||||
return Conditional.CheckCondition( obj );
|
||||
}
|
||||
}
|
||||
}
|
||||
public override bool IsValid(object obj)
|
||||
{
|
||||
return Conditional.CheckCondition(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,72 +3,73 @@ using System.Collections;
|
|||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public class AreaCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public static AreaCommandImplementor Instance { get; private set; }
|
||||
public class AreaCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public AreaCommandImplementor()
|
||||
{
|
||||
Accessors = new[] { "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 AreaCommandImplementor()
|
||||
{
|
||||
Accessors = new[]{ "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.";
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
}
|
||||
public static AreaCommandImplementor Instance{ get; private set; }
|
||||
|
||||
public override void Process( Mobile from, BaseCommand command, string[] args )
|
||||
{
|
||||
BoundingBoxPicker.Begin( from, OnTarget, new object[]{ command, args } );
|
||||
}
|
||||
public override void Process(Mobile from, BaseCommand command, string[] args)
|
||||
{
|
||||
BoundingBoxPicker.Begin(from, 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];
|
||||
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 );
|
||||
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 );
|
||||
Extensions ext = Extensions.Parse(from, ref args);
|
||||
|
||||
bool items, mobiles;
|
||||
bool items, mobiles;
|
||||
|
||||
if ( !CheckObjectTypes( from, command, ext, out items, out mobiles ) )
|
||||
return;
|
||||
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
|
||||
return;
|
||||
|
||||
IPooledEnumerable<IEntity> eable;
|
||||
IPooledEnumerable<IEntity> eable;
|
||||
|
||||
if (items || mobiles)
|
||||
eable = map.GetObjectsInBounds(rect, items, mobiles);
|
||||
else
|
||||
return;
|
||||
if (items || mobiles)
|
||||
eable = map.GetObjectsInBounds(rect, items, mobiles);
|
||||
else
|
||||
return;
|
||||
|
||||
ArrayList objs = new ArrayList();
|
||||
ArrayList objs = new ArrayList();
|
||||
|
||||
foreach ( IEntity obj in eable )
|
||||
{
|
||||
if ( mobiles && obj is Mobile && !BaseCommand.IsAccessible( from, obj ) )
|
||||
continue;
|
||||
foreach (IEntity obj in eable)
|
||||
{
|
||||
if (mobiles && obj is Mobile && !BaseCommand.IsAccessible(from, obj))
|
||||
continue;
|
||||
|
||||
if ( ext.IsValid( obj ) )
|
||||
objs.Add( obj );
|
||||
}
|
||||
if (ext.IsValid(obj))
|
||||
objs.Add(obj);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
eable.Free();
|
||||
|
||||
ext.Filter( objs );
|
||||
ext.Filter(objs);
|
||||
|
||||
RunCommand( from, objs, command, args );
|
||||
}
|
||||
catch ( Exception ex )
|
||||
{
|
||||
from.SendMessage( ex.Message );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RunCommand(from, objs, command, args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
from.SendMessage(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,299 +5,294 @@ using System.Text;
|
|||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
[Flags]
|
||||
public enum CommandSupport
|
||||
{
|
||||
Single = 0x0001,
|
||||
Global = 0x0002,
|
||||
Online = 0x0004,
|
||||
Multi = 0x0008,
|
||||
Area = 0x0010,
|
||||
Self = 0x0020,
|
||||
Region = 0x0040,
|
||||
Contained = 0x0080,
|
||||
IPAddress = 0x0100,
|
||||
[Flags]
|
||||
public enum CommandSupport
|
||||
{
|
||||
Single = 0x0001,
|
||||
Global = 0x0002,
|
||||
Online = 0x0004,
|
||||
Multi = 0x0008,
|
||||
Area = 0x0010,
|
||||
Self = 0x0020,
|
||||
Region = 0x0040,
|
||||
Contained = 0x0080,
|
||||
IPAddress = 0x0100,
|
||||
|
||||
All = Single | Global | Online | Multi | Area | Self | Region | Contained | IPAddress,
|
||||
AllMobiles = All & ~Contained,
|
||||
AllNPCs = All & ~(IPAddress | Online | Self | Contained),
|
||||
AllItems = All & ~(IPAddress | Online | Self | Region),
|
||||
All = Single | Global | Online | Multi | Area | Self | Region | Contained | IPAddress,
|
||||
AllMobiles = All & ~Contained,
|
||||
AllNPCs = All & ~(IPAddress | Online | Self | Contained),
|
||||
AllItems = All & ~(IPAddress | Online | Self | Region),
|
||||
|
||||
Simple = Single | Multi,
|
||||
Complex = Global | Online | Area | Region | Contained | IPAddress
|
||||
}
|
||||
Simple = Single | Multi,
|
||||
Complex = Global | Online | Area | Region | Contained | IPAddress
|
||||
}
|
||||
|
||||
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() );
|
||||
Register( new IPAddressCommandImplementor() );
|
||||
public abstract class BaseCommandImplementor
|
||||
{
|
||||
private static List<BaseCommandImplementor> m_Implementors;
|
||||
|
||||
Register( new RangeCommandImplementor() );
|
||||
Register( new ScreenCommandImplementor() );
|
||||
Register( new FacetCommandImplementor() );
|
||||
}
|
||||
public BaseCommandImplementor()
|
||||
{
|
||||
Commands = new Dictionary<string, BaseCommand>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public bool SupportsConditionals { get; set; }
|
||||
public bool SupportsConditionals{ get; set; }
|
||||
|
||||
public string[] Accessors { get; set; }
|
||||
public string[] Accessors{ get; set; }
|
||||
|
||||
public string Usage { get; set; }
|
||||
public string Usage{ get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
public string Description{ get; set; }
|
||||
|
||||
public AccessLevel AccessLevel { get; set; }
|
||||
public AccessLevel AccessLevel{ get; set; }
|
||||
|
||||
public CommandSupport SupportRequirement { get; set; }
|
||||
public CommandSupport SupportRequirement{ get; set; }
|
||||
|
||||
public Dictionary<string, BaseCommand> Commands { get; }
|
||||
public Dictionary<string, BaseCommand> Commands{ get; }
|
||||
|
||||
public BaseCommandImplementor()
|
||||
{
|
||||
Commands = new Dictionary<string, BaseCommand>( StringComparer.OrdinalIgnoreCase );
|
||||
}
|
||||
public static List<BaseCommandImplementor> Implementors
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Implementors == null)
|
||||
{
|
||||
m_Implementors = new List<BaseCommandImplementor>();
|
||||
RegisterImplementors();
|
||||
}
|
||||
|
||||
public virtual void Compile( Mobile from, BaseCommand command, ref string[] args, ref object obj )
|
||||
{
|
||||
obj = null;
|
||||
}
|
||||
return m_Implementors;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Register( BaseCommand command )
|
||||
{
|
||||
for ( int i = 0; i < command.Commands.Length; ++i )
|
||||
Commands[command.Commands[i]] = command;
|
||||
}
|
||||
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());
|
||||
Register(new IPAddressCommandImplementor());
|
||||
|
||||
public bool CheckObjectTypes( Mobile from, BaseCommand command, Extensions ext, out bool items, out bool mobiles )
|
||||
{
|
||||
items = mobiles = false;
|
||||
Register(new RangeCommandImplementor());
|
||||
Register(new ScreenCommandImplementor());
|
||||
Register(new FacetCommandImplementor());
|
||||
}
|
||||
|
||||
ObjectConditional cond = ObjectConditional.Empty;
|
||||
public virtual void Compile(Mobile from, BaseCommand command, ref string[] args, ref object obj)
|
||||
{
|
||||
obj = null;
|
||||
}
|
||||
|
||||
foreach ( BaseExtension check in ext )
|
||||
{
|
||||
if ( check is WhereExtension extension )
|
||||
{
|
||||
cond = extension.Conditional;
|
||||
public virtual void Register(BaseCommand command)
|
||||
{
|
||||
for (int i = 0; i < command.Commands.Length; ++i)
|
||||
Commands[command.Commands[i]] = command;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
public bool CheckObjectTypes(Mobile from, BaseCommand command, Extensions ext, out bool items, out bool mobiles)
|
||||
{
|
||||
items = mobiles = false;
|
||||
|
||||
bool condIsItem = cond.IsItem;
|
||||
bool condIsMobile = cond.IsMobile;
|
||||
ObjectConditional cond = ObjectConditional.Empty;
|
||||
|
||||
switch ( command.ObjectTypes )
|
||||
{
|
||||
case ObjectTypes.All:
|
||||
case ObjectTypes.Both:
|
||||
{
|
||||
if ( condIsItem )
|
||||
items = true;
|
||||
foreach (BaseExtension check in ext)
|
||||
if (check is WhereExtension extension)
|
||||
{
|
||||
cond = extension.Conditional;
|
||||
|
||||
if ( condIsMobile )
|
||||
mobiles = true;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ObjectTypes.Items:
|
||||
{
|
||||
if ( condIsItem )
|
||||
{
|
||||
items = true;
|
||||
}
|
||||
else if ( condIsMobile )
|
||||
{
|
||||
from.SendMessage( "You may not use a mobile type condition for this command." );
|
||||
return false;
|
||||
}
|
||||
bool condIsItem = cond.IsItem;
|
||||
bool condIsMobile = cond.IsMobile;
|
||||
|
||||
break;
|
||||
}
|
||||
case ObjectTypes.Mobiles:
|
||||
{
|
||||
if ( condIsMobile )
|
||||
{
|
||||
mobiles = true;
|
||||
}
|
||||
else if ( condIsItem )
|
||||
{
|
||||
from.SendMessage( "You may not use an item type condition for this command." );
|
||||
return false;
|
||||
}
|
||||
switch (command.ObjectTypes)
|
||||
{
|
||||
case ObjectTypes.All:
|
||||
case ObjectTypes.Both:
|
||||
{
|
||||
if (condIsItem)
|
||||
items = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (condIsMobile)
|
||||
mobiles = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObjectTypes.Items:
|
||||
{
|
||||
if (condIsItem)
|
||||
{
|
||||
items = true;
|
||||
}
|
||||
else if (condIsMobile)
|
||||
{
|
||||
from.SendMessage("You may not use a mobile type condition for this command.");
|
||||
return false;
|
||||
}
|
||||
|
||||
public void RunCommand( Mobile from, BaseCommand command, string[] args )
|
||||
{
|
||||
try
|
||||
{
|
||||
object obj = null;
|
||||
break;
|
||||
}
|
||||
case ObjectTypes.Mobiles:
|
||||
{
|
||||
if (condIsMobile)
|
||||
{
|
||||
mobiles = true;
|
||||
}
|
||||
else if (condIsItem)
|
||||
{
|
||||
from.SendMessage("You may not use an item type condition for this command.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Compile( from, command, ref args, ref obj );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RunCommand( from, obj, command, args );
|
||||
}
|
||||
catch ( Exception ex )
|
||||
{
|
||||
from.SendMessage( ex.Message );
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public string GenerateArgString( string[] args )
|
||||
{
|
||||
if ( args.Length == 0 )
|
||||
return "";
|
||||
public void RunCommand(Mobile from, BaseCommand command, string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
object obj = null;
|
||||
|
||||
// NOTE: this does not preserve the case where quotation marks are used on a single word
|
||||
Compile(from, command, ref args, ref obj);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
RunCommand(from, obj, command, args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
from.SendMessage(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0; i < args.Length; ++i )
|
||||
{
|
||||
if ( i > 0 )
|
||||
sb.Append( ' ' );
|
||||
public string GenerateArgString(string[] args)
|
||||
{
|
||||
if (args.Length == 0)
|
||||
return "";
|
||||
|
||||
if ( args[i].IndexOf( ' ' ) >= 0 )
|
||||
{
|
||||
sb.Append( '"' );
|
||||
sb.Append( args[i] );
|
||||
sb.Append( '"' );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append( args[i] );
|
||||
}
|
||||
}
|
||||
// NOTE: this does not preserve the case where quotation marks are used on a single word
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
public void RunCommand( Mobile from, object obj, BaseCommand command, string[] args )
|
||||
{
|
||||
// try
|
||||
// {
|
||||
CommandEventArgs e = new CommandEventArgs( from, command.Commands[0], GenerateArgString( args ), args );
|
||||
for (int i = 0; i < args.Length; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
sb.Append(' ');
|
||||
|
||||
if ( !command.ValidateArgs( this, e ) )
|
||||
return;
|
||||
if (args[i].IndexOf(' ') >= 0)
|
||||
{
|
||||
sb.Append('"');
|
||||
sb.Append(args[i]);
|
||||
sb.Append('"');
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bool flushToLog = false;
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
if ( obj is ArrayList list )
|
||||
{
|
||||
if ( list.Count > 20 )
|
||||
CommandLogging.Enabled = false;
|
||||
else if ( list.Count == 0 )
|
||||
command.LogFailure( "Nothing was found to use this command on." );
|
||||
public void RunCommand(Mobile from, object obj, BaseCommand command, string[] args)
|
||||
{
|
||||
// try
|
||||
// {
|
||||
CommandEventArgs e = new CommandEventArgs(from, command.Commands[0], GenerateArgString(args), args);
|
||||
|
||||
command.ExecuteList( e, list );
|
||||
if (!command.ValidateArgs(this, e))
|
||||
return;
|
||||
|
||||
if ( list.Count > 20 )
|
||||
{
|
||||
flushToLog = true;
|
||||
CommandLogging.Enabled = true;
|
||||
}
|
||||
}
|
||||
else if ( obj != null )
|
||||
{
|
||||
if ( command.ListOptimized )
|
||||
{
|
||||
command.ExecuteList( e, new ArrayList{ obj } );
|
||||
}
|
||||
else
|
||||
{
|
||||
command.Execute( e, obj );
|
||||
}
|
||||
}
|
||||
bool flushToLog = false;
|
||||
|
||||
command.Flush( from, flushToLog );
|
||||
// }
|
||||
// catch ( Exception ex )
|
||||
// {
|
||||
// from.SendMessage( ex.Message );
|
||||
// }
|
||||
}
|
||||
if (obj is ArrayList list)
|
||||
{
|
||||
if (list.Count > 20)
|
||||
CommandLogging.Enabled = false;
|
||||
else if (list.Count == 0)
|
||||
command.LogFailure("Nothing was found to use this command on.");
|
||||
|
||||
public virtual void Process( Mobile from, BaseCommand command, string[] args )
|
||||
{
|
||||
RunCommand( from, command, args );
|
||||
}
|
||||
command.ExecuteList(e, list);
|
||||
|
||||
public virtual void Execute( CommandEventArgs e )
|
||||
{
|
||||
if ( e.Length >= 1 )
|
||||
{
|
||||
Commands.TryGetValue( e.GetString( 0 ), out BaseCommand command );
|
||||
if (list.Count > 20)
|
||||
{
|
||||
flushToLog = true;
|
||||
CommandLogging.Enabled = true;
|
||||
}
|
||||
}
|
||||
else if (obj != null)
|
||||
{
|
||||
if (command.ListOptimized)
|
||||
command.ExecuteList(e, new ArrayList { obj });
|
||||
else
|
||||
command.Execute(e, obj);
|
||||
}
|
||||
|
||||
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];
|
||||
command.Flush(from, flushToLog);
|
||||
// }
|
||||
// catch ( Exception ex )
|
||||
// {
|
||||
// from.SendMessage( ex.Message );
|
||||
// }
|
||||
}
|
||||
|
||||
for ( int i = 0; i < args.Length; ++i )
|
||||
args[i] = oldArgs[i + 1];
|
||||
public virtual void Process(Mobile from, BaseCommand command, string[] args)
|
||||
{
|
||||
RunCommand(from, command, args);
|
||||
}
|
||||
|
||||
Process( e.Mobile, command, args );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Mobile.SendMessage( "You must supply a command name." );
|
||||
}
|
||||
}
|
||||
public virtual void Execute(CommandEventArgs e)
|
||||
{
|
||||
if (e.Length >= 1)
|
||||
{
|
||||
Commands.TryGetValue(e.GetString(0), out BaseCommand command);
|
||||
|
||||
public void Register()
|
||||
{
|
||||
if ( Accessors == null )
|
||||
return;
|
||||
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 < Accessors.Length; ++i )
|
||||
CommandSystem.Register( Accessors[i], AccessLevel, Execute );
|
||||
}
|
||||
for (int i = 0; i < args.Length; ++i)
|
||||
args[i] = oldArgs[i + 1];
|
||||
|
||||
public static void Register( BaseCommandImplementor impl )
|
||||
{
|
||||
m_Implementors.Add( impl );
|
||||
impl.Register();
|
||||
}
|
||||
Process(e.Mobile, command, args);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Mobile.SendMessage("You must supply a command name.");
|
||||
}
|
||||
}
|
||||
|
||||
private static List<BaseCommandImplementor> m_Implementors;
|
||||
public void Register()
|
||||
{
|
||||
if (Accessors == null)
|
||||
return;
|
||||
|
||||
public static List<BaseCommandImplementor> Implementors
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( m_Implementors == null )
|
||||
{
|
||||
m_Implementors = new List<BaseCommandImplementor>();
|
||||
RegisterImplementors();
|
||||
}
|
||||
for (int i = 0; i < Accessors.Length; ++i)
|
||||
CommandSystem.Register(Accessors[i], AccessLevel, Execute);
|
||||
}
|
||||
|
||||
return m_Implementors;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void Register(BaseCommandImplementor impl)
|
||||
{
|
||||
m_Implementors.Add(impl);
|
||||
impl.Register();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,80 +5,76 @@ using Server.Targeting;
|
|||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public class ContainedCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public ContainedCommandImplementor()
|
||||
{
|
||||
Accessors = new[]{ "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 class ContainedCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public ContainedCommandImplementor()
|
||||
{
|
||||
Accessors = new[] { "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 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;
|
||||
}
|
||||
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];
|
||||
object[] states = (object[])state;
|
||||
BaseCommand command = (BaseCommand)states[0];
|
||||
string[] args = (string[])states[1];
|
||||
|
||||
if ( command.ObjectTypes == ObjectTypes.Mobiles )
|
||||
return; // sanity check
|
||||
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 );
|
||||
if (!(targeted is Container))
|
||||
from.SendMessage("That is not a container.");
|
||||
else
|
||||
try
|
||||
{
|
||||
Extensions ext = Extensions.Parse(from, ref args);
|
||||
|
||||
bool items, mobiles;
|
||||
bool items, mobiles;
|
||||
|
||||
if ( !CheckObjectTypes( from, command, ext, out items, out mobiles ) )
|
||||
return;
|
||||
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
|
||||
return;
|
||||
|
||||
if ( !items )
|
||||
{
|
||||
from.SendMessage( "This command only works on items." );
|
||||
return;
|
||||
}
|
||||
if (!items)
|
||||
{
|
||||
from.SendMessage("This command only works on items.");
|
||||
return;
|
||||
}
|
||||
|
||||
Container cont = (Container)targeted;
|
||||
Container cont = (Container)targeted;
|
||||
|
||||
Item[] found = cont.FindItemsByType( typeof( Item ), true );
|
||||
Item[] found = cont.FindItemsByType(typeof(Item), true);
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
ArrayList list = new ArrayList();
|
||||
|
||||
for ( int i = 0; i < found.Length; ++i )
|
||||
{
|
||||
if ( ext.IsValid( found[i] ) )
|
||||
list.Add( found[i] );
|
||||
}
|
||||
for (int i = 0; i < found.Length; ++i)
|
||||
if (ext.IsValid(found[i]))
|
||||
list.Add(found[i]);
|
||||
|
||||
ext.Filter( list );
|
||||
ext.Filter(list);
|
||||
|
||||
RunCommand( from, list, command, args );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
from.SendMessage( e.Message );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RunCommand(from, list, command, args);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
from.SendMessage(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +1,32 @@
|
|||
namespace Server.Commands.Generic
|
||||
{
|
||||
public class FacetCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public FacetCommandImplementor()
|
||||
{
|
||||
Accessors = new[]{ "Facet" };
|
||||
SupportRequirement = CommandSupport.Area;
|
||||
SupportsConditionals = true;
|
||||
AccessLevel = AccessLevel.GameMaster;
|
||||
Usage = "Facet <command> [condition]";
|
||||
Description = "Invokes the command on all appropriate objects within your facet's map bounds. Optional condition arguments can further restrict the set of objects.";
|
||||
}
|
||||
public class FacetCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public FacetCommandImplementor()
|
||||
{
|
||||
Accessors = new[] { "Facet" };
|
||||
SupportRequirement = CommandSupport.Area;
|
||||
SupportsConditionals = true;
|
||||
AccessLevel = AccessLevel.GameMaster;
|
||||
Usage = "Facet <command> [condition]";
|
||||
Description =
|
||||
"Invokes the command on all appropriate objects within your facet's map bounds. Optional condition arguments can further restrict the set of objects.";
|
||||
}
|
||||
|
||||
public override void Process( Mobile from, BaseCommand command, string[] args )
|
||||
{
|
||||
AreaCommandImplementor impl = AreaCommandImplementor.Instance;
|
||||
public override void Process(Mobile from, BaseCommand command, string[] args)
|
||||
{
|
||||
AreaCommandImplementor impl = AreaCommandImplementor.Instance;
|
||||
|
||||
if ( impl == null )
|
||||
return;
|
||||
if (impl == null)
|
||||
return;
|
||||
|
||||
Map map = from.Map;
|
||||
Map map = from.Map;
|
||||
|
||||
if ( map == null || map == Map.Internal )
|
||||
return;
|
||||
if (map == null || map == Map.Internal)
|
||||
return;
|
||||
|
||||
impl.OnTarget( from, map, Point3D.Zero, new Point3D( map.Width - 1, map.Height - 1, 0 ), new object[] { command, args } );
|
||||
}
|
||||
}
|
||||
}
|
||||
impl.OnTarget(from, map, Point3D.Zero, new Point3D(map.Width - 1, map.Height - 1, 0),
|
||||
new object[] { command, args });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,57 +3,50 @@ using System.Collections;
|
|||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public class GlobalCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public GlobalCommandImplementor()
|
||||
{
|
||||
Accessors = new[]{ "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 class GlobalCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public GlobalCommandImplementor()
|
||||
{
|
||||
Accessors = new[] { "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 );
|
||||
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;
|
||||
bool items, mobiles;
|
||||
|
||||
if ( !CheckObjectTypes( from, command, ext, out items, out mobiles ) )
|
||||
return;
|
||||
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
|
||||
return;
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
ArrayList list = new ArrayList();
|
||||
|
||||
if ( items )
|
||||
{
|
||||
foreach ( Item item in World.Items.Values )
|
||||
{
|
||||
if ( ext.IsValid( item ) )
|
||||
list.Add( item );
|
||||
}
|
||||
}
|
||||
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 );
|
||||
}
|
||||
}
|
||||
if (mobiles)
|
||||
foreach (Mobile mob in World.Mobiles.Values)
|
||||
if (ext.IsValid(mob))
|
||||
list.Add(mob);
|
||||
|
||||
ext.Filter( list );
|
||||
ext.Filter(list);
|
||||
|
||||
obj = list;
|
||||
}
|
||||
catch ( Exception ex )
|
||||
{
|
||||
from.SendMessage( ex.Message );
|
||||
}
|
||||
}
|
||||
}
|
||||
obj = list;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
from.SendMessage(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,63 +1,65 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public class IPAddressCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public IPAddressCommandImplementor()
|
||||
{
|
||||
Accessors = new[]{ "IPAddress" };
|
||||
SupportRequirement = CommandSupport.IPAddress;
|
||||
SupportsConditionals = true;
|
||||
AccessLevel = AccessLevel.Administrator;
|
||||
Usage = "IPAddress <command> [condition]";
|
||||
Description = "Invokes the command on one mobile from each IP address that is logged in. Optional condition arguments can further restrict the set of objects.";
|
||||
}
|
||||
public class IPAddressCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public IPAddressCommandImplementor()
|
||||
{
|
||||
Accessors = new[] { "IPAddress" };
|
||||
SupportRequirement = CommandSupport.IPAddress;
|
||||
SupportsConditionals = true;
|
||||
AccessLevel = AccessLevel.Administrator;
|
||||
Usage = "IPAddress <command> [condition]";
|
||||
Description =
|
||||
"Invokes the command on one mobile from each IP address that is 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 );
|
||||
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;
|
||||
bool items, mobiles;
|
||||
|
||||
if ( !CheckObjectTypes( from, command, ext, out items, out mobiles ) )
|
||||
return;
|
||||
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
|
||||
return;
|
||||
|
||||
if ( !mobiles ) // sanity check
|
||||
{
|
||||
command.LogFailure( "This command does not support items." );
|
||||
return;
|
||||
}
|
||||
if (!mobiles) // sanity check
|
||||
{
|
||||
command.LogFailure("This command does not support items.");
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
ArrayList addresses = new ArrayList();
|
||||
ArrayList list = new ArrayList();
|
||||
ArrayList addresses = new ArrayList();
|
||||
|
||||
System.Collections.Generic.List<NetState> states = NetState.Instances;
|
||||
List<NetState> states = NetState.Instances;
|
||||
|
||||
for ( int i = 0; i < states.Count; ++i )
|
||||
{
|
||||
NetState ns = (NetState)states[i];
|
||||
Mobile mob = ns.Mobile;
|
||||
for (int i = 0; i < states.Count; ++i)
|
||||
{
|
||||
NetState ns = states[i];
|
||||
Mobile mob = ns.Mobile;
|
||||
|
||||
if ( mob != null && !addresses.Contains( ns.Address ) && ext.IsValid( mob ) )
|
||||
{
|
||||
list.Add( mob );
|
||||
addresses.Add( ns.Address );
|
||||
}
|
||||
}
|
||||
if (mob != null && !addresses.Contains(ns.Address) && ext.IsValid(mob))
|
||||
{
|
||||
list.Add(mob);
|
||||
addresses.Add(ns.Address);
|
||||
}
|
||||
}
|
||||
|
||||
ext.Filter( list );
|
||||
ext.Filter(list);
|
||||
|
||||
obj = list;
|
||||
}
|
||||
catch ( Exception ex )
|
||||
{
|
||||
from.SendMessage( ex.Message );
|
||||
}
|
||||
}
|
||||
}
|
||||
obj = list;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
from.SendMessage(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,73 +2,76 @@ using Server.Targeting;
|
|||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public class MultiCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public MultiCommandImplementor()
|
||||
{
|
||||
Accessors = new[]{ "Multi", "m" };
|
||||
SupportRequirement = CommandSupport.Multi;
|
||||
AccessLevel = AccessLevel.Counselor;
|
||||
Usage = "Multi <command>";
|
||||
Description = "Invokes the command on multiple targeted objects.";
|
||||
}
|
||||
public class MultiCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public MultiCommandImplementor()
|
||||
{
|
||||
Accessors = new[] { "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 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];
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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.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;
|
||||
}
|
||||
case ObjectTypes.Mobiles:
|
||||
{
|
||||
if (!(targeted is Mobile))
|
||||
{
|
||||
from.SendMessage("This command only works on mobiles.");
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RunCommand( from, targeted, command, args );
|
||||
RunCommand(from, targeted, command, args);
|
||||
|
||||
from.BeginTarget( -1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback( OnTarget ), new object[]{ command, args } );
|
||||
}
|
||||
}
|
||||
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback(OnTarget),
|
||||
new object[] { command, args });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,245 +4,247 @@ 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 );
|
||||
public sealed class ObjectConditional
|
||||
{
|
||||
private static readonly Type typeofItem = typeof(Item);
|
||||
private static readonly Type typeofMobile = typeof(Mobile);
|
||||
|
||||
private ICondition[][] m_Conditions;
|
||||
public static readonly ObjectConditional Empty = new ObjectConditional(null, null);
|
||||
|
||||
private IConditional[] m_Conditionals;
|
||||
private IConditional[] m_Conditionals;
|
||||
|
||||
public Type Type { get; }
|
||||
private ICondition[][] m_Conditions;
|
||||
|
||||
public bool IsItem => ( Type == null || Type == typeofItem || Type.IsSubclassOf( typeofItem ) );
|
||||
public ObjectConditional(Type objectType, ICondition[][] conditions)
|
||||
{
|
||||
Type = objectType;
|
||||
m_Conditions = conditions;
|
||||
}
|
||||
|
||||
public bool IsMobile => ( Type == null || Type == typeofMobile || Type.IsSubclassOf( typeofMobile ) );
|
||||
public Type Type{ get; }
|
||||
|
||||
public static readonly ObjectConditional Empty = new ObjectConditional( null, null );
|
||||
public bool IsItem => Type == null || Type == typeofItem || Type.IsSubclassOf(typeofItem);
|
||||
|
||||
public bool HasCompiled => ( m_Conditionals != null );
|
||||
public bool IsMobile => Type == null || Type == typeofMobile || Type.IsSubclassOf(typeofMobile);
|
||||
|
||||
public void Compile( ref AssemblyEmitter emitter )
|
||||
{
|
||||
if ( emitter == null )
|
||||
emitter = new AssemblyEmitter( "__dynamic", false );
|
||||
public bool HasCompiled => m_Conditionals != null;
|
||||
|
||||
m_Conditionals = new IConditional[m_Conditions.Length];
|
||||
public void Compile(ref AssemblyEmitter emitter)
|
||||
{
|
||||
if (emitter == null)
|
||||
emitter = new AssemblyEmitter("__dynamic", false);
|
||||
|
||||
for ( int i = 0; i < m_Conditionals.Length; ++i )
|
||||
m_Conditionals[i] = ConditionalCompiler.Compile( emitter, Type, m_Conditions[i], i );
|
||||
}
|
||||
m_Conditionals = new IConditional[m_Conditions.Length];
|
||||
|
||||
public bool CheckCondition( object obj )
|
||||
{
|
||||
if ( Type == null )
|
||||
return true; // null type means no condition
|
||||
for (int i = 0; i < m_Conditionals.Length; ++i)
|
||||
m_Conditionals[i] = ConditionalCompiler.Compile(emitter, Type, m_Conditions[i], i);
|
||||
}
|
||||
|
||||
if ( !HasCompiled )
|
||||
{
|
||||
AssemblyEmitter emitter = null;
|
||||
public bool CheckCondition(object obj)
|
||||
{
|
||||
if (Type == null)
|
||||
return true; // null type means no condition
|
||||
|
||||
Compile( ref emitter );
|
||||
}
|
||||
if (!HasCompiled)
|
||||
{
|
||||
AssemblyEmitter emitter = null;
|
||||
|
||||
for ( int i = 0; i < m_Conditionals.Length; ++i )
|
||||
{
|
||||
if ( m_Conditionals[i].Verify( obj ) )
|
||||
return true;
|
||||
}
|
||||
Compile(ref emitter);
|
||||
}
|
||||
|
||||
return false; // all conditions false
|
||||
}
|
||||
for (int i = 0; i < m_Conditionals.Length; ++i)
|
||||
if (m_Conditionals[i].Verify(obj))
|
||||
return true;
|
||||
|
||||
public static ObjectConditional Parse( Mobile from, ref string[] args )
|
||||
{
|
||||
string[] conditionArgs = null;
|
||||
return false; // all conditions false
|
||||
}
|
||||
|
||||
for ( int i = 0; i < args.Length; ++i )
|
||||
{
|
||||
if ( Insensitive.Equals( args[i], "where" ) )
|
||||
{
|
||||
string[] origArgs = args;
|
||||
public static ObjectConditional Parse(Mobile from, ref string[] args)
|
||||
{
|
||||
string[] conditionArgs = null;
|
||||
|
||||
args = new string[i];
|
||||
for (int i = 0; i < args.Length; ++i)
|
||||
if (Insensitive.Equals(args[i], "where"))
|
||||
{
|
||||
string[] origArgs = args;
|
||||
|
||||
for ( int j = 0; j < args.Length; ++j )
|
||||
args[j] = origArgs[j];
|
||||
args = new string[i];
|
||||
|
||||
conditionArgs = new string[origArgs.Length - i - 1];
|
||||
for (int j = 0; j < args.Length; ++j)
|
||||
args[j] = origArgs[j];
|
||||
|
||||
for ( int j = 0; j < conditionArgs.Length; ++j )
|
||||
conditionArgs[j] = origArgs[i + j + 1];
|
||||
conditionArgs = new string[origArgs.Length - i - 1];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < conditionArgs.Length; ++j)
|
||||
conditionArgs[j] = origArgs[i + j + 1];
|
||||
|
||||
return ParseDirect( from, conditionArgs, 0, conditionArgs.Length );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
public static ObjectConditional ParseDirect( Mobile from, string[] args, int offset, int size )
|
||||
{
|
||||
if ( args == null || size == 0 )
|
||||
return Empty;
|
||||
return ParseDirect(from, conditionArgs, 0, conditionArgs.Length);
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
public static ObjectConditional ParseDirect(Mobile from, string[] args, int offset, int size)
|
||||
{
|
||||
if (args == null || size == 0)
|
||||
return Empty;
|
||||
|
||||
Type objectType = ScriptCompiler.FindTypeByName( args[offset + index], true );
|
||||
int index = 0;
|
||||
|
||||
if ( objectType == null )
|
||||
throw new Exception($"No type with that name ({args[offset + index]}) was found.");
|
||||
Type objectType = ScriptCompiler.FindTypeByName(args[offset + index], true);
|
||||
|
||||
++index;
|
||||
if (objectType == null)
|
||||
throw new Exception($"No type with that name ({args[offset + index]}) was found.");
|
||||
|
||||
List<ICondition[]> conditions = new List<ICondition[]>();
|
||||
List<ICondition> current = new List<ICondition>();
|
||||
++index;
|
||||
|
||||
current.Add( TypeCondition.Default );
|
||||
List<ICondition[]> conditions = new List<ICondition[]>();
|
||||
List<ICondition> current = new List<ICondition>();
|
||||
|
||||
while ( index < size )
|
||||
{
|
||||
string cur = args[offset + index];
|
||||
current.Add(TypeCondition.Default);
|
||||
|
||||
bool inverse = false;
|
||||
while (index < size)
|
||||
{
|
||||
string cur = args[offset + index];
|
||||
|
||||
if ( Insensitive.Equals( cur, "not" ) || cur == "!" )
|
||||
{
|
||||
inverse = true;
|
||||
++index;
|
||||
bool inverse = false;
|
||||
|
||||
if ( index >= size )
|
||||
throw new Exception( "Improperly formatted object conditional." );
|
||||
}
|
||||
else if ( Insensitive.Equals( cur, "or" ) || cur == "||" )
|
||||
{
|
||||
if ( current.Count > 1 )
|
||||
{
|
||||
conditions.Add( current.ToArray() );
|
||||
if (Insensitive.Equals(cur, "not") || cur == "!")
|
||||
{
|
||||
inverse = true;
|
||||
++index;
|
||||
|
||||
current.Clear();
|
||||
current.Add( TypeCondition.Default );
|
||||
}
|
||||
if (index >= size)
|
||||
throw new Exception("Improperly formatted object conditional.");
|
||||
}
|
||||
else if (Insensitive.Equals(cur, "or") || cur == "||")
|
||||
{
|
||||
if (current.Count > 1)
|
||||
{
|
||||
conditions.Add(current.ToArray());
|
||||
|
||||
++index;
|
||||
current.Clear();
|
||||
current.Add(TypeCondition.Default);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
++index;
|
||||
|
||||
string binding = args[offset + index];
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( index >= size )
|
||||
throw new Exception( "Improperly formatted object conditional." );
|
||||
string binding = args[offset + index];
|
||||
index++;
|
||||
|
||||
string oper = args[offset + index];
|
||||
index++;
|
||||
if (index >= size)
|
||||
throw new Exception("Improperly formatted object conditional.");
|
||||
|
||||
if ( index >= size )
|
||||
throw new Exception( "Improperly formatted object conditional." );
|
||||
string oper = args[offset + index];
|
||||
index++;
|
||||
|
||||
string val = args[offset + index];
|
||||
index++;
|
||||
if (index >= size)
|
||||
throw new Exception("Improperly formatted object conditional.");
|
||||
|
||||
Property prop = new Property( binding );
|
||||
string val = args[offset + index];
|
||||
index++;
|
||||
|
||||
prop.BindTo( objectType, PropertyAccess.Read );
|
||||
prop.CheckAccess( from );
|
||||
Property prop = new Property(binding);
|
||||
|
||||
ICondition condition = null;
|
||||
prop.BindTo(objectType, PropertyAccess.Read);
|
||||
prop.CheckAccess(from);
|
||||
|
||||
switch ( oper )
|
||||
{
|
||||
#region Equality
|
||||
case "=":
|
||||
case "==":
|
||||
case "is":
|
||||
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.Equal, val );
|
||||
break;
|
||||
ICondition condition = null;
|
||||
|
||||
case "!=":
|
||||
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.NotEqual, val );
|
||||
break;
|
||||
#endregion
|
||||
switch (oper)
|
||||
{
|
||||
#region Equality
|
||||
|
||||
#region Relational
|
||||
case ">":
|
||||
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.Greater, val );
|
||||
break;
|
||||
case "=":
|
||||
case "==":
|
||||
case "is":
|
||||
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.Equal, val);
|
||||
break;
|
||||
|
||||
case "<":
|
||||
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.Lesser, val );
|
||||
break;
|
||||
case "!=":
|
||||
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.NotEqual, val);
|
||||
break;
|
||||
|
||||
case ">=":
|
||||
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.GreaterEqual, val );
|
||||
break;
|
||||
#endregion
|
||||
|
||||
case "<=":
|
||||
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.LesserEqual, val );
|
||||
break;
|
||||
#endregion
|
||||
#region Relational
|
||||
|
||||
#region Strings
|
||||
case "==~":
|
||||
case "~==":
|
||||
case "=~":
|
||||
case "~=":
|
||||
case "is~":
|
||||
case "~is":
|
||||
condition = new StringCondition( prop, inverse, StringOperator.Equal, val, true );
|
||||
break;
|
||||
case ">":
|
||||
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.Greater, val);
|
||||
break;
|
||||
|
||||
case "!=~":
|
||||
case "~!=":
|
||||
condition = new StringCondition( prop, inverse, StringOperator.NotEqual, val, true );
|
||||
break;
|
||||
case "<":
|
||||
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.Lesser, val);
|
||||
break;
|
||||
|
||||
case "starts":
|
||||
condition = new StringCondition( prop, inverse, StringOperator.StartsWith, val, false );
|
||||
break;
|
||||
case ">=":
|
||||
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.GreaterEqual, val);
|
||||
break;
|
||||
|
||||
case "starts~":
|
||||
case "~starts":
|
||||
condition = new StringCondition( prop, inverse, StringOperator.StartsWith, val, true );
|
||||
break;
|
||||
case "<=":
|
||||
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.LesserEqual, val);
|
||||
break;
|
||||
|
||||
case "ends":
|
||||
condition = new StringCondition( prop, inverse, StringOperator.EndsWith, val, false );
|
||||
break;
|
||||
#endregion
|
||||
|
||||
case "ends~":
|
||||
case "~ends":
|
||||
condition = new StringCondition( prop, inverse, StringOperator.EndsWith, val, true );
|
||||
break;
|
||||
#region Strings
|
||||
|
||||
case "contains":
|
||||
condition = new StringCondition( prop, inverse, StringOperator.Contains, val, false );
|
||||
break;
|
||||
case "==~":
|
||||
case "~==":
|
||||
case "=~":
|
||||
case "~=":
|
||||
case "is~":
|
||||
case "~is":
|
||||
condition = new StringCondition(prop, inverse, StringOperator.Equal, val, true);
|
||||
break;
|
||||
|
||||
case "contains~":
|
||||
case "~contains":
|
||||
condition = new StringCondition( prop, inverse, StringOperator.Contains, val, true );
|
||||
break;
|
||||
#endregion
|
||||
}
|
||||
case "!=~":
|
||||
case "~!=":
|
||||
condition = new StringCondition(prop, inverse, StringOperator.NotEqual, val, true);
|
||||
break;
|
||||
|
||||
if ( condition == null )
|
||||
throw new InvalidOperationException($"Unrecognized operator (\"{oper}\").");
|
||||
case "starts":
|
||||
condition = new StringCondition(prop, inverse, StringOperator.StartsWith, val, false);
|
||||
break;
|
||||
|
||||
current.Add( condition );
|
||||
}
|
||||
case "starts~":
|
||||
case "~starts":
|
||||
condition = new StringCondition(prop, inverse, StringOperator.StartsWith, val, true);
|
||||
break;
|
||||
|
||||
conditions.Add( current.ToArray() );
|
||||
case "ends":
|
||||
condition = new StringCondition(prop, inverse, StringOperator.EndsWith, val, false);
|
||||
break;
|
||||
|
||||
return new ObjectConditional( objectType, conditions.ToArray() );
|
||||
}
|
||||
case "ends~":
|
||||
case "~ends":
|
||||
condition = new StringCondition(prop, inverse, StringOperator.EndsWith, val, true);
|
||||
break;
|
||||
|
||||
public ObjectConditional( Type objectType, ICondition[][] conditions )
|
||||
{
|
||||
Type = objectType;
|
||||
m_Conditions = conditions;
|
||||
}
|
||||
}
|
||||
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($"Unrecognized operator (\"{oper}\").");
|
||||
|
||||
current.Add(condition);
|
||||
}
|
||||
|
||||
conditions.Add(current.ToArray());
|
||||
|
||||
return new ObjectConditional(objectType, conditions.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,62 +5,63 @@ using Server.Network;
|
|||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public class OnlineCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public OnlineCommandImplementor()
|
||||
{
|
||||
Accessors = new[]{ "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 class OnlineCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public OnlineCommandImplementor()
|
||||
{
|
||||
Accessors = new[] { "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 );
|
||||
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;
|
||||
bool items, mobiles;
|
||||
|
||||
if ( !CheckObjectTypes( from, command, ext, out items, out mobiles ) )
|
||||
return;
|
||||
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
|
||||
return;
|
||||
|
||||
if ( !mobiles ) // sanity check
|
||||
{
|
||||
command.LogFailure( "This command does not support items." );
|
||||
return;
|
||||
}
|
||||
if (!mobiles) // sanity check
|
||||
{
|
||||
command.LogFailure("This command does not support items.");
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
ArrayList list = new ArrayList();
|
||||
|
||||
List<NetState> states = NetState.Instances;
|
||||
List<NetState> states = NetState.Instances;
|
||||
|
||||
for ( int i = 0; i < states.Count; ++i )
|
||||
{
|
||||
NetState ns = states[i];
|
||||
Mobile mob = ns.Mobile;
|
||||
for (int i = 0; i < states.Count; ++i)
|
||||
{
|
||||
NetState ns = states[i];
|
||||
Mobile mob = ns.Mobile;
|
||||
|
||||
if ( mob == null )
|
||||
continue;
|
||||
if (mob == null)
|
||||
continue;
|
||||
|
||||
if ( !BaseCommand.IsAccessible( from, mob ) )
|
||||
continue;
|
||||
if (!BaseCommand.IsAccessible(from, mob))
|
||||
continue;
|
||||
|
||||
if ( ext.IsValid( mob ) )
|
||||
list.Add( mob );
|
||||
}
|
||||
if (ext.IsValid(mob))
|
||||
list.Add(mob);
|
||||
}
|
||||
|
||||
ext.Filter( list );
|
||||
ext.Filter(list);
|
||||
|
||||
obj = list;
|
||||
}
|
||||
catch ( Exception ex )
|
||||
{
|
||||
from.SendMessage( ex.Message );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
obj = list;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
from.SendMessage(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,77 +1,79 @@
|
|||
namespace Server.Commands.Generic
|
||||
{
|
||||
public class RangeCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public static RangeCommandImplementor Instance { get; private set; }
|
||||
public class RangeCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public RangeCommandImplementor()
|
||||
{
|
||||
Accessors = new[] { "Range" };
|
||||
SupportRequirement = CommandSupport.Area;
|
||||
SupportsConditionals = true;
|
||||
AccessLevel = AccessLevel.GameMaster;
|
||||
Usage = "Range <range> <command> [condition]";
|
||||
Description =
|
||||
"Invokes the command on all appropriate objects within a specified range of you. Optional condition arguments can further restrict the set of objects.";
|
||||
|
||||
public RangeCommandImplementor()
|
||||
{
|
||||
Accessors = new[]{ "Range" };
|
||||
SupportRequirement = CommandSupport.Area;
|
||||
SupportsConditionals = true;
|
||||
AccessLevel = AccessLevel.GameMaster;
|
||||
Usage = "Range <range> <command> [condition]";
|
||||
Description = "Invokes the command on all appropriate objects within a specified range of you. Optional condition arguments can further restrict the set of objects.";
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
}
|
||||
public static RangeCommandImplementor Instance{ get; private set; }
|
||||
|
||||
public override void Execute( CommandEventArgs e )
|
||||
{
|
||||
if ( e.Length >= 2 )
|
||||
{
|
||||
int range = e.GetInt32( 0 );
|
||||
public override void Execute(CommandEventArgs e)
|
||||
{
|
||||
if (e.Length >= 2)
|
||||
{
|
||||
int range = e.GetInt32(0);
|
||||
|
||||
if ( range < 0 )
|
||||
{
|
||||
e.Mobile.SendMessage( "The range must not be negative." );
|
||||
}
|
||||
else
|
||||
{
|
||||
Commands.TryGetValue( e.GetString( 1 ), out BaseCommand command );
|
||||
if (range < 0)
|
||||
{
|
||||
e.Mobile.SendMessage("The range must not be negative.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Commands.TryGetValue(e.GetString(1), out BaseCommand 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];
|
||||
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];
|
||||
for (int i = 0; i < args.Length; ++i)
|
||||
args[i] = oldArgs[i + 2];
|
||||
|
||||
Process( range, e.Mobile, command, args );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Mobile.SendMessage( "You must supply a range and a command name." );
|
||||
}
|
||||
}
|
||||
Process(range, e.Mobile, command, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Mobile.SendMessage("You must supply a range and a command name.");
|
||||
}
|
||||
}
|
||||
|
||||
public void Process( int range, Mobile from, BaseCommand command, string[] args )
|
||||
{
|
||||
AreaCommandImplementor impl = AreaCommandImplementor.Instance;
|
||||
public void Process(int range, Mobile from, BaseCommand command, string[] args)
|
||||
{
|
||||
AreaCommandImplementor impl = AreaCommandImplementor.Instance;
|
||||
|
||||
if ( impl == null )
|
||||
return;
|
||||
if (impl == null)
|
||||
return;
|
||||
|
||||
Map map = from.Map;
|
||||
Map map = from.Map;
|
||||
|
||||
if ( map == null || map == Map.Internal )
|
||||
return;
|
||||
if (map == null || map == Map.Internal)
|
||||
return;
|
||||
|
||||
Point3D start = new Point3D( from.X - range, from.Y - range, from.Z );
|
||||
Point3D end = new Point3D( from.X + range, from.Y + range, from.Z );
|
||||
Point3D start = new Point3D(from.X - range, from.Y - range, from.Z);
|
||||
Point3D end = new Point3D(from.X + range, from.Y + range, from.Z);
|
||||
|
||||
impl.OnTarget( from, map, start, end, new object[] { command, args } );
|
||||
}
|
||||
}
|
||||
}
|
||||
impl.OnTarget(from, map, start, end, new object[] { command, args });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,58 +3,59 @@ using System.Collections;
|
|||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public class RegionCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public RegionCommandImplementor()
|
||||
{
|
||||
Accessors = new[]{ "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 class RegionCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public RegionCommandImplementor()
|
||||
{
|
||||
Accessors = new[] { "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 );
|
||||
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;
|
||||
bool items, mobiles;
|
||||
|
||||
if ( !CheckObjectTypes( from, command, ext, out items, out mobiles ) )
|
||||
return;
|
||||
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
|
||||
return;
|
||||
|
||||
Region reg = from.Region;
|
||||
Region reg = from.Region;
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
ArrayList list = new ArrayList();
|
||||
|
||||
if ( mobiles )
|
||||
{
|
||||
foreach ( Mobile mob in reg.GetMobiles() )
|
||||
{
|
||||
if ( !BaseCommand.IsAccessible( from, mob ) )
|
||||
continue;
|
||||
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;
|
||||
}
|
||||
if (ext.IsValid(mob))
|
||||
list.Add(mob);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
command.LogFailure("This command does not support items.");
|
||||
return;
|
||||
}
|
||||
|
||||
ext.Filter( list );
|
||||
ext.Filter(list);
|
||||
|
||||
obj = list;
|
||||
}
|
||||
catch ( Exception ex )
|
||||
{
|
||||
from.SendMessage( ex.Message );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
obj = list;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
from.SendMessage(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +1,23 @@
|
|||
namespace Server.Commands.Generic
|
||||
{
|
||||
public class ScreenCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public ScreenCommandImplementor()
|
||||
{
|
||||
Accessors = new[]{ "Screen" };
|
||||
SupportRequirement = CommandSupport.Area;
|
||||
SupportsConditionals = true;
|
||||
AccessLevel = AccessLevel.GameMaster;
|
||||
Usage = "Screen <command> [condition]";
|
||||
Description = "Invokes the command on all appropriate objects in your screen. Optional condition arguments can further restrict the set of objects.";
|
||||
}
|
||||
public class ScreenCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public ScreenCommandImplementor()
|
||||
{
|
||||
Accessors = new[] { "Screen" };
|
||||
SupportRequirement = CommandSupport.Area;
|
||||
SupportsConditionals = true;
|
||||
AccessLevel = AccessLevel.GameMaster;
|
||||
Usage = "Screen <command> [condition]";
|
||||
Description =
|
||||
"Invokes the command on all appropriate objects in your screen. Optional condition arguments can further restrict the set of objects.";
|
||||
}
|
||||
|
||||
public override void Process( Mobile from, BaseCommand command, string[] args )
|
||||
{
|
||||
RangeCommandImplementor impl = RangeCommandImplementor.Instance;
|
||||
public override void Process(Mobile from, BaseCommand command, string[] args)
|
||||
{
|
||||
RangeCommandImplementor impl = RangeCommandImplementor.Instance;
|
||||
|
||||
impl?.Process( 18, from, command, args );
|
||||
}
|
||||
}
|
||||
}
|
||||
impl?.Process(18, from, command, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +1,22 @@
|
|||
namespace Server.Commands.Generic
|
||||
{
|
||||
public class SelfCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public SelfCommandImplementor()
|
||||
{
|
||||
Accessors = new[]{ "Self" };
|
||||
SupportRequirement = CommandSupport.Self;
|
||||
AccessLevel = AccessLevel.Counselor;
|
||||
Usage = "Self <command>";
|
||||
Description = "Invokes the command on the commanding player.";
|
||||
}
|
||||
public class SelfCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public SelfCommandImplementor()
|
||||
{
|
||||
Accessors = new[] { "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
|
||||
public override void Compile(Mobile from, BaseCommand command, ref string[] args, ref object obj)
|
||||
{
|
||||
if (command.ObjectTypes == ObjectTypes.Items)
|
||||
return; // sanity check
|
||||
|
||||
obj = from;
|
||||
}
|
||||
}
|
||||
obj = from;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,95 +1,96 @@
|
|||
namespace Server.Commands.Generic
|
||||
{
|
||||
public class SerialCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public SerialCommandImplementor()
|
||||
{
|
||||
Accessors = new[]{ "Serial" };
|
||||
SupportRequirement = CommandSupport.Single;
|
||||
AccessLevel = AccessLevel.Counselor;
|
||||
Usage = "Serial <serial> <command>";
|
||||
Description = "Invokes the command on a single object by serial.";
|
||||
}
|
||||
public class SerialCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public SerialCommandImplementor()
|
||||
{
|
||||
Accessors = new[] { "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 );
|
||||
public override void Execute(CommandEventArgs e)
|
||||
{
|
||||
if (e.Length >= 2)
|
||||
{
|
||||
Serial serial = e.GetInt32(0);
|
||||
|
||||
object obj = null;
|
||||
object obj = null;
|
||||
|
||||
if ( serial.IsItem )
|
||||
obj = World.FindItem( serial );
|
||||
else if ( serial.IsMobile )
|
||||
obj = World.FindMobile( serial );
|
||||
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
|
||||
{
|
||||
Commands.TryGetValue( e.GetString( 1 ), out BaseCommand command );
|
||||
if (obj == null)
|
||||
{
|
||||
e.Mobile.SendMessage("That is not a valid serial.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Commands.TryGetValue(e.GetString(1), out BaseCommand 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
|
||||
{
|
||||
switch ( command.ObjectTypes )
|
||||
{
|
||||
case ObjectTypes.Both:
|
||||
{
|
||||
if ( !(obj is Item) && !(obj is Mobile) )
|
||||
{
|
||||
e.Mobile.SendMessage( "This command does not work on that." );
|
||||
return;
|
||||
}
|
||||
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
|
||||
{
|
||||
switch (command.ObjectTypes)
|
||||
{
|
||||
// case ObjectTypes.Both:
|
||||
// {
|
||||
// if (!(obj is Item) && !(obj is Mobile))
|
||||
// {
|
||||
// e.Mobile.SendMessage("This command does not work on that.");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// break;
|
||||
// }
|
||||
case ObjectTypes.Items:
|
||||
{
|
||||
if (!(obj is Item))
|
||||
{
|
||||
e.Mobile.SendMessage("This command only works on items.");
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ObjectTypes.Items:
|
||||
{
|
||||
if ( !(obj is Item) )
|
||||
{
|
||||
e.Mobile.SendMessage( "This command only works on items." );
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObjectTypes.Mobiles:
|
||||
{
|
||||
if (!(obj is Mobile))
|
||||
{
|
||||
e.Mobile.SendMessage("This command only works on mobiles.");
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ObjectTypes.Mobiles:
|
||||
{
|
||||
if ( !(obj is Mobile) )
|
||||
{
|
||||
e.Mobile.SendMessage( "This command only works on mobiles." );
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
string[] oldArgs = e.Arguments;
|
||||
string[] args = new string[oldArgs.Length - 2];
|
||||
|
||||
string[] oldArgs = e.Arguments;
|
||||
string[] args = new string[oldArgs.Length - 2];
|
||||
for (int i = 0; i < args.Length; ++i)
|
||||
args[i] = oldArgs[i + 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." );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RunCommand(e.Mobile, obj, command, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Mobile.SendMessage("You must supply an object serial and a command name.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,90 +2,92 @@ using Server.Targeting;
|
|||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public class SingleCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public SingleCommandImplementor()
|
||||
{
|
||||
Accessors = new[]{ "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 class SingleCommandImplementor : BaseCommandImplementor
|
||||
{
|
||||
public SingleCommandImplementor()
|
||||
{
|
||||
Accessors = new[] { "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 );
|
||||
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, Redirect );
|
||||
}
|
||||
for (int i = 0; i < command.Commands.Length; ++i)
|
||||
CommandSystem.Register(command.Commands[i], command.AccessLevel, Redirect);
|
||||
}
|
||||
|
||||
public void Redirect( CommandEventArgs e )
|
||||
{
|
||||
Commands.TryGetValue( e.Command, out BaseCommand command );
|
||||
public void Redirect(CommandEventArgs e)
|
||||
{
|
||||
Commands.TryGetValue(e.Command, out BaseCommand 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 );
|
||||
}
|
||||
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 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;
|
||||
}
|
||||
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];
|
||||
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;
|
||||
}
|
||||
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.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;
|
||||
}
|
||||
case ObjectTypes.Mobiles:
|
||||
{
|
||||
if (!(targeted is Mobile))
|
||||
{
|
||||
from.SendMessage("This command only works on mobiles.");
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RunCommand( from, targeted, command, args );
|
||||
}
|
||||
}
|
||||
}
|
||||
RunCommand(from, targeted, command, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,413 +1,411 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Server.Commands.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
using Server.Commands.Generic;
|
||||
using CommandInfo=Server.Commands.Docs.DocCommandEntry;
|
||||
using CommandInfoSorter=Server.Commands.Docs.CommandEntrySorter;
|
||||
using CommandInfo = Server.Commands.Docs.DocCommandEntry;
|
||||
using CommandInfoSorter = Server.Commands.Docs.CommandEntrySorter;
|
||||
|
||||
namespace Server.Commands
|
||||
{
|
||||
public class HelpInfo
|
||||
{
|
||||
public static Dictionary<string, CommandInfo> HelpInfos { get; } = new Dictionary<string, CommandInfo>();
|
||||
public class HelpInfo
|
||||
{
|
||||
public static Dictionary<string, CommandInfo> HelpInfos{ get; } = new Dictionary<string, CommandInfo>();
|
||||
|
||||
public static List<CommandInfo> SortedHelpInfo { get; private set; } = new List<CommandInfo>();
|
||||
public static List<CommandInfo> SortedHelpInfo{ get; private set; } = new List<CommandInfo>();
|
||||
|
||||
[CallPriority( 100 )]
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "HelpInfo", AccessLevel.Player, HelpInfo_OnCommand );
|
||||
[CallPriority(100)]
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("HelpInfo", AccessLevel.Player, HelpInfo_OnCommand);
|
||||
|
||||
FillTable();
|
||||
}
|
||||
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();
|
||||
if (HelpInfos.TryGetValue( arg, out CommandInfo c ))
|
||||
{
|
||||
Mobile m = e.Mobile;
|
||||
[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();
|
||||
if (HelpInfos.TryGetValue(arg, out CommandInfo 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." );
|
||||
if (m.AccessLevel >= c.AccessLevel)
|
||||
m.SendGump(new CommandInfoGump(c));
|
||||
else
|
||||
m.SendMessage("You don't have access to that command.");
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
e.Mobile.SendMessage($"Command '{arg}' not found!");
|
||||
}
|
||||
e.Mobile.SendMessage($"Command '{arg}' not found!");
|
||||
}
|
||||
|
||||
e.Mobile.SendGump( new CommandListGump( 0, e.Mobile, null ) );
|
||||
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>();
|
||||
|
||||
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);
|
||||
|
||||
commands.Sort();
|
||||
commands.Reverse();
|
||||
Docs.Clean( commands );
|
||||
for (int i = 0; i < commands.Count; ++i)
|
||||
{
|
||||
CommandEntry e = commands[i];
|
||||
|
||||
for( int i = 0; i < commands.Count; ++i )
|
||||
{
|
||||
CommandEntry e =commands[i];
|
||||
MethodInfo mi = e.Handler.Method;
|
||||
|
||||
MethodInfo mi = e.Handler.Method;
|
||||
object[] attrs = mi.GetCustomAttributes(typeof(UsageAttribute), false);
|
||||
|
||||
object[] attrs = mi.GetCustomAttributes( typeof( UsageAttribute ), false );
|
||||
if (attrs.Length == 0)
|
||||
continue;
|
||||
|
||||
if ( attrs.Length == 0 )
|
||||
continue;
|
||||
UsageAttribute usage = attrs[0] as UsageAttribute;
|
||||
|
||||
UsageAttribute usage = attrs[0] as UsageAttribute;
|
||||
attrs = mi.GetCustomAttributes(typeof(DescriptionAttribute), false);
|
||||
|
||||
attrs = mi.GetCustomAttributes( typeof( DescriptionAttribute ), false );
|
||||
if (attrs.Length == 0)
|
||||
continue;
|
||||
|
||||
if ( attrs.Length == 0 )
|
||||
continue;
|
||||
if (usage == null || !(attrs[0] is DescriptionAttribute desc))
|
||||
continue;
|
||||
|
||||
if ( usage == null || !(attrs[0] is DescriptionAttribute desc) )
|
||||
continue;
|
||||
attrs = mi.GetCustomAttributes(typeof(AliasesAttribute), false);
|
||||
|
||||
attrs = mi.GetCustomAttributes( typeof( AliasesAttribute ), false );
|
||||
AliasesAttribute aliases = attrs.Length == 0 ? null : attrs[0] as AliasesAttribute;
|
||||
|
||||
AliasesAttribute aliases = (attrs.Length == 0 ? null : attrs[0] as AliasesAttribute);
|
||||
string descString = desc.Description.Replace("<", "(").Replace(">", ")");
|
||||
|
||||
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));
|
||||
|
||||
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];
|
||||
|
||||
for( int j = 0; j < aliases.Aliases.Length; j++ )
|
||||
{
|
||||
string[] newAliases = new string[aliases.Aliases.Length];
|
||||
aliases.Aliases.CopyTo(newAliases, 0);
|
||||
|
||||
aliases.Aliases.CopyTo( newAliases, 0 );
|
||||
newAliases[j] = e.Command;
|
||||
|
||||
newAliases[j] = e.Command;
|
||||
list.Add(new CommandInfo(e.AccessLevel, aliases.Aliases[j], newAliases, usage.Usage, descString));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
for( int i = 0; i < TargetCommands.AllCommands.Count; ++i )
|
||||
{
|
||||
BaseCommand command = TargetCommands.AllCommands[i];
|
||||
string usage = command.Usage;
|
||||
string desc = command.Description;
|
||||
|
||||
string usage = command.Usage;
|
||||
string desc = command.Description;
|
||||
if (usage == null || desc == null)
|
||||
continue;
|
||||
|
||||
if ( usage == null || desc == null )
|
||||
continue;
|
||||
string[] cmds = command.Commands;
|
||||
string cmd = cmds[0];
|
||||
string[] aliases = new string[cmds.Length - 1];
|
||||
|
||||
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];
|
||||
|
||||
for( int j = 0; j < aliases.Length; ++j )
|
||||
aliases[j] = cmds[j + 1];
|
||||
desc = desc.Replace("<", "(").Replace(">", ")");
|
||||
|
||||
desc = desc.Replace( "<", "(" ).Replace( ">", ")" );
|
||||
if (command.Supports != CommandSupport.Single)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(50 + desc.Length);
|
||||
|
||||
if ( command.Supports != CommandSupport.Single )
|
||||
{
|
||||
StringBuilder sb = new StringBuilder( 50 + desc.Length );
|
||||
sb.Append("Modifiers: ");
|
||||
|
||||
sb.Append( "Modifiers: " );
|
||||
if ((command.Supports & CommandSupport.Global) != 0)
|
||||
sb.Append("<i>Global</i>, ");
|
||||
|
||||
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.Online) != 0 )
|
||||
sb.Append( "<i>Online</i>, " );
|
||||
if ((command.Supports & CommandSupport.Region) != 0)
|
||||
sb.Append("<i>Region</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.Contained) != 0 )
|
||||
sb.Append( "<i>Contained</i>, " );
|
||||
if ((command.Supports & CommandSupport.Multi) != 0)
|
||||
sb.Append("<i>Multi</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.Area) != 0 )
|
||||
sb.Append( "<i>Area</i>, " );
|
||||
if ((command.Supports & CommandSupport.Self) != 0)
|
||||
sb.Append("<i>Self</i>, ");
|
||||
|
||||
if ( (command.Supports & CommandSupport.Self) != 0 )
|
||||
sb.Append( "<i>Self</i>, " );
|
||||
sb.Remove(sb.Length - 2, 2);
|
||||
sb.Append("<br>");
|
||||
sb.Append(desc);
|
||||
|
||||
sb.Remove( sb.Length - 2, 2 );
|
||||
sb.Append( "<br>" );
|
||||
sb.Append( desc );
|
||||
desc = sb.ToString();
|
||||
}
|
||||
|
||||
desc = sb.ToString();
|
||||
}
|
||||
list.Add(new CommandInfo(command.AccessLevel, cmd, aliases, usage, desc));
|
||||
|
||||
list.Add( new CommandInfo( command.AccessLevel, cmd, aliases, usage, desc ) );
|
||||
for (int j = 0; j < aliases.Length; j++)
|
||||
{
|
||||
string[] newAliases = new string[aliases.Length];
|
||||
|
||||
for( int j = 0; j < aliases.Length; j++ )
|
||||
{
|
||||
string[] newAliases = new string[aliases.Length];
|
||||
aliases.CopyTo(newAliases, 0);
|
||||
|
||||
aliases.CopyTo( newAliases, 0 );
|
||||
newAliases[j] = cmd;
|
||||
|
||||
newAliases[j] = cmd;
|
||||
list.Add(new CommandInfo(command.AccessLevel, aliases[j], newAliases, usage, desc));
|
||||
}
|
||||
}
|
||||
|
||||
list.Add( new CommandInfo( command.AccessLevel, aliases[j], newAliases, usage, desc ) );
|
||||
}
|
||||
}
|
||||
List<BaseCommandImplementor> commandImpls = BaseCommandImplementor.Implementors;
|
||||
|
||||
List<BaseCommandImplementor> commandImpls = BaseCommandImplementor.Implementors;
|
||||
for (int i = 0; i < commandImpls.Count; ++i)
|
||||
{
|
||||
BaseCommandImplementor command = commandImpls[i];
|
||||
|
||||
for( int i = 0; i < commandImpls.Count; ++i )
|
||||
{
|
||||
BaseCommandImplementor command = commandImpls[i];
|
||||
string usage = command.Usage;
|
||||
string desc = command.Description;
|
||||
|
||||
string usage = command.Usage;
|
||||
string desc = command.Description;
|
||||
if (usage == null || desc == null)
|
||||
continue;
|
||||
|
||||
if ( usage == null || desc == null )
|
||||
continue;
|
||||
string[] cmds = command.Accessors;
|
||||
string cmd = cmds[0];
|
||||
string[] aliases = new string[cmds.Length - 1];
|
||||
|
||||
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];
|
||||
|
||||
for( int j = 0; j < aliases.Length; ++j )
|
||||
aliases[j] = cmds[j + 1];
|
||||
desc = desc.Replace("<", ")").Replace(">", ")");
|
||||
|
||||
desc = desc.Replace( "<", ")" ).Replace( ">", ")" );
|
||||
list.Add(new CommandInfo(command.AccessLevel, cmd, aliases, usage, desc));
|
||||
|
||||
list.Add( new CommandInfo( command.AccessLevel, cmd, aliases, usage, desc ) );
|
||||
for (int j = 0; j < aliases.Length; j++)
|
||||
{
|
||||
string[] newAliases = new string[aliases.Length];
|
||||
|
||||
for( int j = 0; j < aliases.Length; j++ )
|
||||
{
|
||||
string[] newAliases = new string[aliases.Length];
|
||||
aliases.CopyTo(newAliases, 0);
|
||||
|
||||
aliases.CopyTo( newAliases, 0 );
|
||||
newAliases[j] = cmd;
|
||||
|
||||
newAliases[j] = cmd;
|
||||
list.Add(new CommandInfo(command.AccessLevel, aliases[j], newAliases, usage, desc));
|
||||
}
|
||||
}
|
||||
|
||||
list.Add( new CommandInfo( command.AccessLevel, aliases[j], newAliases, usage, desc ) );
|
||||
}
|
||||
}
|
||||
list.Sort(new CommandInfoSorter());
|
||||
|
||||
list.Sort( new CommandInfoSorter() );
|
||||
SortedHelpInfo = list;
|
||||
|
||||
SortedHelpInfo = list;
|
||||
foreach (CommandInfo c in SortedHelpInfo)
|
||||
if (!HelpInfos.ContainsKey(c.Name.ToLower()))
|
||||
HelpInfos.Add(c.Name.ToLower(), c);
|
||||
}
|
||||
|
||||
foreach( CommandInfo c in SortedHelpInfo )
|
||||
{
|
||||
if ( !HelpInfos.ContainsKey( c.Name.ToLower() ) )
|
||||
HelpInfos.Add( c.Name.ToLower(), c );
|
||||
}
|
||||
}
|
||||
public class CommandListGump : BaseGridGump
|
||||
{
|
||||
private const int EntriesPerPage = 15;
|
||||
private List<CommandInfo> m_List;
|
||||
|
||||
public class CommandListGump : BaseGridGump
|
||||
{
|
||||
private const int EntriesPerPage = 15;
|
||||
private int m_Page;
|
||||
|
||||
int m_Page;
|
||||
List<CommandInfo> m_List;
|
||||
public CommandListGump(int page, Mobile from, List<CommandInfo> list)
|
||||
: base(30, 30)
|
||||
{
|
||||
m_Page = page;
|
||||
|
||||
public CommandListGump( int page, Mobile from, List<CommandInfo> list )
|
||||
: base( 30, 30 )
|
||||
{
|
||||
m_Page = page;
|
||||
if (list == null)
|
||||
{
|
||||
m_List = new List<CommandInfo>();
|
||||
|
||||
if ( list == null )
|
||||
{
|
||||
m_List = new List<CommandInfo>();
|
||||
foreach (CommandInfo c in SortedHelpInfo)
|
||||
if (from.AccessLevel >= c.AccessLevel)
|
||||
m_List.Add(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_List = list;
|
||||
}
|
||||
|
||||
foreach( CommandInfo c in SortedHelpInfo )
|
||||
{
|
||||
if ( from.AccessLevel >= c.AccessLevel )
|
||||
m_List.Add( c );
|
||||
}
|
||||
}
|
||||
else
|
||||
m_List = list;
|
||||
|
||||
AddNewPage();
|
||||
|
||||
AddNewPage();
|
||||
if (m_Page > 0)
|
||||
AddEntryButton(20, ArrowLeftID1, ArrowLeftID2, 1, ArrowLeftWidth, ArrowLeftHeight);
|
||||
else
|
||||
AddEntryHeader(20);
|
||||
|
||||
if ( m_Page > 0 )
|
||||
AddEntryButton( 20, ArrowLeftID1, ArrowLeftID2, 1, ArrowLeftWidth, ArrowLeftHeight );
|
||||
else
|
||||
AddEntryHeader( 20 );
|
||||
AddEntryHtml(160, Center(
|
||||
$"Page {m_Page + 1} of {(m_List.Count + EntriesPerPage - 1) / EntriesPerPage}"));
|
||||
|
||||
AddEntryHtml( 160, Center(
|
||||
$"Page {m_Page + 1} of {(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 < 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 $"<BASEFONT COLOR=#{color:X6}>{text}</BASEFONT>";
|
||||
}
|
||||
|
||||
public string Center( string text )
|
||||
{
|
||||
return $"<CENTER>{text}</CENTER>";
|
||||
}
|
||||
|
||||
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($"Alias{(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 );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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 < 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 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($"Alias{(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 );
|
||||
}
|
||||
|
||||
public string Color(string text, int color)
|
||||
{
|
||||
return $"<BASEFONT COLOR=#{color:X6}>{text}</BASEFONT>";
|
||||
}
|
||||
|
||||
public string Center(string text)
|
||||
{
|
||||
return $"<CENTER>{text}</CENTER>";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,137 +1,139 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Server.Accounting;
|
||||
|
||||
namespace Server.Commands
|
||||
{
|
||||
public class CommandLogging
|
||||
{
|
||||
public static bool Enabled { get; set; } = true;
|
||||
public class CommandLogging
|
||||
{
|
||||
private static char[] m_NotSafe = { '\\', '/', ':', '*', '?', '"', '<', '>', '|' };
|
||||
public static bool Enabled{ get; set; } = true;
|
||||
|
||||
public static StreamWriter Output { get; private set; }
|
||||
public static StreamWriter Output{ get; private set; }
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.Command += EventSink_Command;
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.Command += EventSink_Command;
|
||||
|
||||
if ( !Directory.Exists( "Logs" ) )
|
||||
Directory.CreateDirectory( "Logs" );
|
||||
if (!Directory.Exists("Logs"))
|
||||
Directory.CreateDirectory("Logs");
|
||||
|
||||
string directory = "Logs/Commands";
|
||||
string directory = "Logs/Commands";
|
||||
|
||||
if ( !Directory.Exists( directory ) )
|
||||
Directory.CreateDirectory( directory );
|
||||
if (!Directory.Exists(directory))
|
||||
Directory.CreateDirectory(directory);
|
||||
|
||||
try
|
||||
{
|
||||
Output = new StreamWriter( Path.Combine( directory, $"{DateTime.UtcNow.ToLongDateString()}.log"), true );
|
||||
try
|
||||
{
|
||||
Output = new StreamWriter(Path.Combine(directory, $"{DateTime.UtcNow.ToLongDateString()}.log"), true);
|
||||
|
||||
Output.AutoFlush = true;
|
||||
Output.AutoFlush = true;
|
||||
|
||||
Output.WriteLine( "##############################" );
|
||||
Output.WriteLine( "Log started on {0}", DateTime.UtcNow );
|
||||
Output.WriteLine();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
Output.WriteLine("##############################");
|
||||
Output.WriteLine("Log started on {0}", DateTime.UtcNow);
|
||||
Output.WriteLine();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static object Format( object o )
|
||||
{
|
||||
if ( o is Mobile m )
|
||||
{
|
||||
if ( m.Account == null )
|
||||
return $"{m} (no account)";
|
||||
public static object Format(object o)
|
||||
{
|
||||
if (o is Mobile m)
|
||||
{
|
||||
if (m.Account == null)
|
||||
return $"{m} (no account)";
|
||||
|
||||
return $"{m} ('{m.Account.Username}')";
|
||||
}
|
||||
if ( o is Item item )
|
||||
{
|
||||
return $"0x{item.Serial.Value:X} ({item.GetType().Name})";
|
||||
}
|
||||
return $"{m} ('{m.Account.Username}')";
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
if (o is Item item) return $"0x{item.Serial.Value:X} ({item.GetType().Name})";
|
||||
|
||||
public static void WriteLine( Mobile from, string format, params object[] args )
|
||||
{
|
||||
if ( !Enabled )
|
||||
return;
|
||||
return o;
|
||||
}
|
||||
|
||||
WriteLine( from, string.Format( format, args ) );
|
||||
}
|
||||
public static void WriteLine(Mobile from, string format, params object[] args)
|
||||
{
|
||||
if (!Enabled)
|
||||
return;
|
||||
|
||||
public static void WriteLine( Mobile from, string text )
|
||||
{
|
||||
if ( !Enabled )
|
||||
return;
|
||||
WriteLine(from, string.Format(format, args));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Output.WriteLine( "{0}: {1}: {2}", DateTime.UtcNow, from.NetState, text );
|
||||
public static void WriteLine(Mobile from, string text)
|
||||
{
|
||||
if (!Enabled)
|
||||
return;
|
||||
|
||||
string path = Core.BaseDirectory;
|
||||
try
|
||||
{
|
||||
Output.WriteLine("{0}: {1}: {2}", DateTime.UtcNow, from.NetState, text);
|
||||
|
||||
string name = ( !(from.Account is Account acct) ? from.Name : acct.Username );
|
||||
string path = Core.BaseDirectory;
|
||||
|
||||
AppendPath( ref path, "Logs" );
|
||||
AppendPath( ref path, "Commands" );
|
||||
AppendPath( ref path, from.AccessLevel.ToString() );
|
||||
path = Path.Combine( path, $"{name}.log");
|
||||
string name = !(from.Account is Account acct) ? from.Name : acct.Username;
|
||||
|
||||
using ( StreamWriter sw = new StreamWriter( path, true ) )
|
||||
sw.WriteLine( "{0}: {1}: {2}", DateTime.UtcNow, from.NetState, text );
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
AppendPath(ref path, "Logs");
|
||||
AppendPath(ref path, "Commands");
|
||||
AppendPath(ref path, from.AccessLevel.ToString());
|
||||
path = Path.Combine(path, $"{name}.log");
|
||||
|
||||
private static char[] m_NotSafe = { '\\', '/', ':', '*', '?', '"', '<', '>', '|' };
|
||||
using (StreamWriter sw = new StreamWriter(path, true))
|
||||
{
|
||||
sw.WriteLine("{0}: {1}: {2}", DateTime.UtcNow, from.NetState, text);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static void AppendPath( ref string path, string toAppend )
|
||||
{
|
||||
path = Path.Combine( path, toAppend );
|
||||
public static void AppendPath(ref string path, string toAppend)
|
||||
{
|
||||
path = Path.Combine(path, toAppend);
|
||||
|
||||
if ( !Directory.Exists( path ) )
|
||||
Directory.CreateDirectory( path );
|
||||
}
|
||||
if (!Directory.Exists(path))
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
public static string Safe( string ip )
|
||||
{
|
||||
if ( ip == null )
|
||||
return "null";
|
||||
public static string Safe(string ip)
|
||||
{
|
||||
if (ip == null)
|
||||
return "null";
|
||||
|
||||
ip = ip.Trim();
|
||||
ip = ip.Trim();
|
||||
|
||||
if ( ip.Length == 0 )
|
||||
return "empty";
|
||||
if (ip.Length == 0)
|
||||
return "empty";
|
||||
|
||||
bool isSafe = true;
|
||||
bool isSafe = true;
|
||||
|
||||
for ( int i = 0; isSafe && i < m_NotSafe.Length; ++i )
|
||||
isSafe = ( ip.IndexOf( m_NotSafe[i] ) == -1 );
|
||||
for (int i = 0; isSafe && i < m_NotSafe.Length; ++i)
|
||||
isSafe = ip.IndexOf(m_NotSafe[i]) == -1;
|
||||
|
||||
if ( isSafe )
|
||||
return ip;
|
||||
if (isSafe)
|
||||
return ip;
|
||||
|
||||
System.Text.StringBuilder sb = new System.Text.StringBuilder( ip );
|
||||
StringBuilder sb = new StringBuilder(ip);
|
||||
|
||||
for ( int i = 0; i < m_NotSafe.Length; ++i )
|
||||
sb.Replace( m_NotSafe[i], '_' );
|
||||
for (int i = 0; i < m_NotSafe.Length; ++i)
|
||||
sb.Replace(m_NotSafe[i], '_');
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
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 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,396 +1,399 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Server.Diagnostics;
|
||||
|
||||
namespace Server.Commands
|
||||
{
|
||||
public class Profiling
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "DumpTimers", AccessLevel.Administrator, DumpTimers_OnCommand );
|
||||
CommandSystem.Register( "CountObjects", AccessLevel.Administrator, CountObjects_OnCommand );
|
||||
CommandSystem.Register( "ProfileWorld", AccessLevel.Administrator, ProfileWorld_OnCommand );
|
||||
CommandSystem.Register( "TraceInternal", AccessLevel.Administrator, TraceInternal_OnCommand );
|
||||
CommandSystem.Register( "TraceExpanded", AccessLevel.Administrator, TraceExpanded_OnCommand );
|
||||
CommandSystem.Register( "WriteProfiles", AccessLevel.Administrator, WriteProfiles_OnCommand );
|
||||
CommandSystem.Register( "SetProfiles", AccessLevel.Administrator, 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.UtcNow );
|
||||
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 intObj )
|
||||
return intObj;
|
||||
|
||||
if ( obj is int[] list )
|
||||
{
|
||||
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();
|
||||
public class Profiling
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("DumpTimers", AccessLevel.Administrator, DumpTimers_OnCommand);
|
||||
CommandSystem.Register("CountObjects", AccessLevel.Administrator, CountObjects_OnCommand);
|
||||
CommandSystem.Register("ProfileWorld", AccessLevel.Administrator, ProfileWorld_OnCommand);
|
||||
CommandSystem.Register("TraceInternal", AccessLevel.Administrator, TraceInternal_OnCommand);
|
||||
CommandSystem.Register("TraceExpanded", AccessLevel.Administrator, TraceExpanded_OnCommand);
|
||||
CommandSystem.Register("WriteProfiles", AccessLevel.Administrator, WriteProfiles_OnCommand);
|
||||
CommandSystem.Register("SetProfiles", AccessLevel.Administrator, 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.UtcNow);
|
||||
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
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[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 = 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 = 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.UtcNow);
|
||||
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
|
||||
{
|
||||
if (!(typeTable[itemType] is int[] countTable))
|
||||
typeTable[itemType] = countTable = new int[9];
|
||||
|
||||
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];
|
||||
|
||||
foreach ( Item item in World.Items.Values )
|
||||
{
|
||||
Type type = item.GetType();
|
||||
/*if ( ( flags & ExpandFlag.TempFlag ) != 0 )
|
||||
++countTable[5];
|
||||
|
||||
object o = (object)table[type];
|
||||
if ( ( flags & ExpandFlag.SaveFlag ) != 0 )
|
||||
++countTable[6];*/
|
||||
|
||||
if ((flags & ExpandFlag.Weight) != 0)
|
||||
++countTable[7];
|
||||
|
||||
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.UtcNow );
|
||||
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
|
||||
{
|
||||
if ( !(typeTable[itemType] is int[] countTable) )
|
||||
typeTable[itemType] = countTable = new int[9];
|
||||
|
||||
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];
|
||||
|
||||
if ((flags & ExpandFlag.Spawner) != 0)
|
||||
++countTable[8];
|
||||
|
||||
itemType = itemType.BaseType;
|
||||
} while ( itemType != typeof( object ) );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using ( StreamWriter op = new StreamWriter( "expandedItems.log", true ) )
|
||||
{
|
||||
string[] names = {
|
||||
"Name",
|
||||
"Items",
|
||||
"Bounce",
|
||||
"Holder",
|
||||
"Blessed",
|
||||
"TempFlag",
|
||||
"SaveFlag",
|
||||
"Weight",
|
||||
"Spawner"
|
||||
};
|
||||
|
||||
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[]{ 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.UtcNow );
|
||||
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
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((flags & ExpandFlag.Spawner) != 0)
|
||||
++countTable[8];
|
||||
|
||||
itemType = itemType.BaseType;
|
||||
} while (itemType != typeof(object));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using (StreamWriter op = new StreamWriter("expandedItems.log", true))
|
||||
{
|
||||
string[] names =
|
||||
{
|
||||
"Name",
|
||||
"Items",
|
||||
"Bounce",
|
||||
"Holder",
|
||||
"Blessed",
|
||||
"TempFlag",
|
||||
"SaveFlag",
|
||||
"Weight",
|
||||
"Spawner"
|
||||
};
|
||||
|
||||
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[] { 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.UtcNow);
|
||||
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
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
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 intObj)
|
||||
return intObj;
|
||||
|
||||
if (obj is int[] list)
|
||||
{
|
||||
int total = 0;
|
||||
|
||||
for (int i = 0; i < list.Length; ++i)
|
||||
total += list[i];
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -2,18 +2,18 @@
|
|||
|
||||
namespace Server.Commands
|
||||
{
|
||||
public class ShardTime
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "Time", AccessLevel.Player, Time_OnCommand );
|
||||
}
|
||||
public class ShardTime
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("Time", AccessLevel.Player, Time_OnCommand);
|
||||
}
|
||||
|
||||
[Usage( "Time" )]
|
||||
[Description( "Returns the server's local time." )]
|
||||
private static void Time_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
e.Mobile.SendMessage( DateTime.UtcNow.ToString() );
|
||||
}
|
||||
}
|
||||
[Usage("Time")]
|
||||
[Description("Returns the server's local time.")]
|
||||
private static void Time_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.SendMessage(DateTime.UtcNow.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,134 +4,145 @@ using Server.Items;
|
|||
|
||||
namespace Server.Commands
|
||||
{
|
||||
public class SignParser
|
||||
{
|
||||
private class SignEntry
|
||||
{
|
||||
public string m_Text;
|
||||
public Point3D m_Location;
|
||||
public int m_ItemID;
|
||||
public int m_Map;
|
||||
public class SignParser
|
||||
{
|
||||
private static Queue<Item> m_ToDelete = new Queue<Item>();
|
||||
|
||||
public SignEntry( string text, Point3D pt, int itemID, int mapLoc )
|
||||
{
|
||||
m_Text = text;
|
||||
m_Location = pt;
|
||||
m_ItemID = itemID;
|
||||
m_Map = mapLoc;
|
||||
}
|
||||
}
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("SignGen", AccessLevel.Administrator, SignGen_OnCommand);
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "SignGen", AccessLevel.Administrator, SignGen_OnCommand );
|
||||
}
|
||||
[Usage("SignGen")]
|
||||
[Description("Generates world/shop signs on all facets.")]
|
||||
public static void SignGen_OnCommand(CommandEventArgs c)
|
||||
{
|
||||
Parse(c.Mobile);
|
||||
}
|
||||
|
||||
[Usage( "SignGen" )]
|
||||
[Description( "Generates world/shop signs on all facets." )]
|
||||
public static void SignGen_OnCommand( CommandEventArgs c )
|
||||
{
|
||||
Parse( c.Mobile );
|
||||
}
|
||||
public static void Parse(Mobile from)
|
||||
{
|
||||
string cfg = Path.Combine(Core.BaseDirectory, "Data/signs.cfg");
|
||||
|
||||
public static void Parse( Mobile from )
|
||||
{
|
||||
string cfg = Path.Combine( Core.BaseDirectory, "Data/signs.cfg" );
|
||||
if (File.Exists(cfg))
|
||||
{
|
||||
List<SignEntry> list = new List<SignEntry>();
|
||||
from.SendMessage("Generating signs, please wait.");
|
||||
|
||||
if ( File.Exists( cfg ) )
|
||||
{
|
||||
List<SignEntry> list = new List<SignEntry>();
|
||||
from.SendMessage( "Generating signs, please wait." );
|
||||
using (StreamReader ip = new StreamReader(cfg))
|
||||
{
|
||||
string line;
|
||||
|
||||
using ( StreamReader ip = new StreamReader( cfg ) )
|
||||
{
|
||||
string line;
|
||||
while ((line = ip.ReadLine()) != null)
|
||||
{
|
||||
string[] split = line.Split(' ');
|
||||
|
||||
while ( (line = ip.ReadLine()) != null )
|
||||
{
|
||||
string[] split = line.Split( ' ' );
|
||||
SignEntry e = new SignEntry(
|
||||
line.Substring(split[0].Length + 1 + split[1].Length + 1 + split[2].Length + 1 +
|
||||
split[3].Length + 1 + split[4].Length + 1),
|
||||
new Point3D(Utility.ToInt32(split[2]), Utility.ToInt32(split[3]), Utility.ToInt32(split[4])),
|
||||
Utility.ToInt32(split[1]), Utility.ToInt32(split[0]));
|
||||
|
||||
SignEntry e = new SignEntry(
|
||||
line.Substring( split[0].Length + 1 + split[1].Length + 1 + split[2].Length + 1 + split[3].Length + 1 + split[4].Length + 1 ),
|
||||
new Point3D( Utility.ToInt32( split[2] ), Utility.ToInt32( split[3] ), Utility.ToInt32( split[4] ) ),
|
||||
Utility.ToInt32( split[1] ), Utility.ToInt32( split[0] ) );
|
||||
list.Add(e);
|
||||
}
|
||||
}
|
||||
|
||||
list.Add( e );
|
||||
}
|
||||
}
|
||||
Map[] brit = { Map.Felucca, Map.Trammel };
|
||||
Map[] fel = { Map.Felucca };
|
||||
Map[] tram = { Map.Trammel };
|
||||
Map[] ilsh = { Map.Ilshenar };
|
||||
Map[] malas = { Map.Malas };
|
||||
Map[] tokuno = { Map.Tokuno };
|
||||
|
||||
Map[] brit = { Map.Felucca, Map.Trammel };
|
||||
Map[] fel = { Map.Felucca };
|
||||
Map[] tram = { Map.Trammel };
|
||||
Map[] ilsh = { Map.Ilshenar };
|
||||
Map[] malas = { Map.Malas };
|
||||
Map[] tokuno = { Map.Tokuno };
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
{
|
||||
SignEntry e = list[i];
|
||||
Map[] maps = null;
|
||||
|
||||
for ( int i = 0; i < list.Count; ++i )
|
||||
{
|
||||
SignEntry e = list[i];
|
||||
Map[] maps = null;
|
||||
switch (e.m_Map)
|
||||
{
|
||||
case 0:
|
||||
maps = brit;
|
||||
break; // Trammel and Felucca
|
||||
case 1:
|
||||
maps = fel;
|
||||
break; // Felucca
|
||||
case 2:
|
||||
maps = tram;
|
||||
break; // Trammel
|
||||
case 3:
|
||||
maps = ilsh;
|
||||
break; // Ilshenar
|
||||
case 4:
|
||||
maps = malas;
|
||||
break; // Malas
|
||||
case 5:
|
||||
maps = tokuno;
|
||||
break; // Tokuno Islands
|
||||
}
|
||||
|
||||
switch ( e.m_Map )
|
||||
{
|
||||
case 0: maps = brit; break; // Trammel and Felucca
|
||||
case 1: maps = fel; break; // Felucca
|
||||
case 2: maps = tram; break; // Trammel
|
||||
case 3: maps = ilsh; break; // Ilshenar
|
||||
case 4: maps = malas; break; // Malas
|
||||
case 5: maps = tokuno; break; // Tokuno Islands
|
||||
}
|
||||
for (int j = 0; maps != null && j < maps.Length; ++j)
|
||||
Add_Static(e.m_ItemID, e.m_Location, maps[j], e.m_Text);
|
||||
}
|
||||
|
||||
for ( int j = 0; maps != null && j < maps.Length; ++j )
|
||||
Add_Static( e.m_ItemID, e.m_Location, maps[j], e.m_Text );
|
||||
}
|
||||
from.SendMessage("Sign generating complete.");
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage("{0} not found!", cfg);
|
||||
}
|
||||
}
|
||||
|
||||
from.SendMessage( "Sign generating complete." );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage( "{0} not found!", cfg );
|
||||
}
|
||||
}
|
||||
public static void Add_Static(int itemID, Point3D location, Map map, string name)
|
||||
{
|
||||
IPooledEnumerable<Item> eable = map.GetItemsInRange(location, 0);
|
||||
|
||||
private static Queue<Item> m_ToDelete = new Queue<Item>();
|
||||
foreach (Item item in eable)
|
||||
if (item is Sign && item.Z == location.Z && item.ItemID == itemID)
|
||||
m_ToDelete.Enqueue(item);
|
||||
|
||||
public static void Add_Static( int itemID, Point3D location, Map map, string name )
|
||||
{
|
||||
IPooledEnumerable<Item> eable = map.GetItemsInRange( location, 0 );
|
||||
eable.Free();
|
||||
|
||||
foreach ( Item item in eable )
|
||||
{
|
||||
if ( item is Sign && item.Z == location.Z && item.ItemID == itemID )
|
||||
m_ToDelete.Enqueue( item );
|
||||
}
|
||||
while (m_ToDelete.Count > 0)
|
||||
m_ToDelete.Dequeue().Delete();
|
||||
|
||||
eable.Free();
|
||||
Item sign;
|
||||
|
||||
while ( m_ToDelete.Count > 0 )
|
||||
m_ToDelete.Dequeue().Delete();
|
||||
if (name.StartsWith("#"))
|
||||
{
|
||||
sign = new LocalizedSign(itemID, Utility.ToInt32(name.Substring(1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
sign = new Sign(itemID);
|
||||
sign.Name = name;
|
||||
}
|
||||
|
||||
Item sign;
|
||||
if (map == Map.Malas)
|
||||
{
|
||||
if (location.X >= 965 && location.Y >= 502 && location.X <= 1012 && location.Y <= 537)
|
||||
sign.Hue = 0x47E;
|
||||
else if (location.X >= 1960 && location.Y >= 1278 && location.X < 2106 && location.Y < 1413)
|
||||
sign.Hue = 0x44E;
|
||||
}
|
||||
|
||||
if ( name.StartsWith( "#" ) )
|
||||
{
|
||||
sign = new LocalizedSign( itemID, Utility.ToInt32( name.Substring( 1 ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
sign = new Sign( itemID );
|
||||
sign.Name = name;
|
||||
}
|
||||
sign.MoveToWorld(location, map);
|
||||
}
|
||||
|
||||
if ( map == Map.Malas )
|
||||
{
|
||||
if ( location.X >= 965 && location.Y >= 502 && location.X <= 1012 && location.Y <= 537 )
|
||||
sign.Hue = 0x47E;
|
||||
else if ( location.X >= 1960 && location.Y >= 1278 && location.X < 2106 && location.Y < 1413 )
|
||||
sign.Hue = 0x44E;
|
||||
}
|
||||
private class SignEntry
|
||||
{
|
||||
public int m_ItemID;
|
||||
public Point3D m_Location;
|
||||
public int m_Map;
|
||||
public string m_Text;
|
||||
|
||||
sign.MoveToWorld( location, map );
|
||||
}
|
||||
}
|
||||
}
|
||||
public SignEntry(string text, Point3D pt, int itemID, int mapLoc)
|
||||
{
|
||||
m_Text = text;
|
||||
m_Location = pt;
|
||||
m_ItemID = itemID;
|
||||
m_Map = mapLoc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,141 +3,129 @@ using Server.Targeting;
|
|||
|
||||
namespace Server.Commands
|
||||
{
|
||||
public class SkillsCommand
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "SetSkill", AccessLevel.GameMaster, SetSkill_OnCommand );
|
||||
CommandSystem.Register( "GetSkill", AccessLevel.GameMaster, GetSkill_OnCommand );
|
||||
CommandSystem.Register( "SetAllSkills", AccessLevel.GameMaster, SetAllSkills_OnCommand );
|
||||
}
|
||||
public class SkillsCommand
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("SetSkill", AccessLevel.GameMaster, SetSkill_OnCommand);
|
||||
CommandSystem.Register("GetSkill", AccessLevel.GameMaster, GetSkill_OnCommand);
|
||||
CommandSystem.Register("SetAllSkills", AccessLevel.GameMaster, 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;
|
||||
if ( Enum.TryParse( arg.GetString( 0 ), true, out skill ) )
|
||||
{
|
||||
arg.Mobile.Target = new SkillTarget( skill, arg.GetDouble( 1 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
arg.Mobile.SendLocalizedMessage( 1005631 ); // You have specified an invalid skill to set.
|
||||
}
|
||||
}
|
||||
}
|
||||
[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;
|
||||
if (Enum.TryParse(arg.GetString(0), true, out skill))
|
||||
arg.Mobile.Target = new SkillTarget(skill, arg.GetDouble(1));
|
||||
else
|
||||
arg.Mobile.SendLocalizedMessage(1005631); // You have specified an invalid skill to set.
|
||||
}
|
||||
}
|
||||
|
||||
[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("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;
|
||||
if ( Enum.TryParse( arg.GetString( 0 ), true, out skill ) )
|
||||
{
|
||||
arg.Mobile.Target = new SkillTarget( skill );
|
||||
}
|
||||
else
|
||||
{
|
||||
arg.Mobile.SendMessage( "You have specified an invalid skill to get." );
|
||||
}
|
||||
}
|
||||
}
|
||||
[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;
|
||||
if (Enum.TryParse(arg.GetString(0), true, out skill))
|
||||
arg.Mobile.Target = new SkillTarget(skill);
|
||||
else
|
||||
arg.Mobile.SendMessage("You have specified an invalid skill to get.");
|
||||
}
|
||||
}
|
||||
|
||||
public class AllSkillsTarget : Target
|
||||
{
|
||||
private double m_Value;
|
||||
public class AllSkillsTarget : Target
|
||||
{
|
||||
private double m_Value;
|
||||
|
||||
public AllSkillsTarget( double value ) : base( -1, false, TargetFlags.None )
|
||||
{
|
||||
m_Value = 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 targ )
|
||||
{
|
||||
Server.Skills skills = targ.Skills;
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (targeted is Mobile targ)
|
||||
{
|
||||
Server.Skills skills = targ.Skills;
|
||||
|
||||
for ( int i = 0; i < skills.Length; ++i )
|
||||
skills[i].Base = m_Value;
|
||||
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!" );
|
||||
}
|
||||
}
|
||||
}
|
||||
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 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, 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;
|
||||
}
|
||||
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 targ )
|
||||
{
|
||||
Skill skill = targ.Skills[m_Skill];
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (targeted is Mobile targ)
|
||||
{
|
||||
Skill skill = targ.Skills[m_Skill];
|
||||
|
||||
if ( skill == null )
|
||||
return;
|
||||
if (skill == null)
|
||||
return;
|
||||
|
||||
if ( m_Set )
|
||||
{
|
||||
skill.Base = m_Value;
|
||||
CommandLogging.LogChangeProperty( from, targ, $"{m_Skill}.Base", m_Value.ToString() );
|
||||
}
|
||||
if (m_Set)
|
||||
{
|
||||
skill.Base = m_Value;
|
||||
CommandLogging.LogChangeProperty(from, targ, $"{m_Skill}.Base", m_Value.ToString());
|
||||
}
|
||||
|
||||
from.SendMessage( "{0} : {1} (Base: {2})", m_Skill, skill.Value, skill.Base );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage( "That does not have skills!" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
from.SendMessage("{0} : {1} (Base: {2})", m_Skill, skill.Value, skill.Base);
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage("That does not have skills!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +1,38 @@
|
|||
using Server.Targeting;
|
||||
using Server.Gumps;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Commands
|
||||
{
|
||||
public class Skills
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
Register();
|
||||
}
|
||||
public class Skills
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
Register();
|
||||
}
|
||||
|
||||
public static void Register()
|
||||
{
|
||||
CommandSystem.Register( "Skills", AccessLevel.Counselor, Skills_OnCommand );
|
||||
}
|
||||
public static void Register()
|
||||
{
|
||||
CommandSystem.Register("Skills", AccessLevel.Counselor, Skills_OnCommand);
|
||||
}
|
||||
|
||||
private class SkillsTarget : Target
|
||||
{
|
||||
public SkillsTarget( ) : base( -1, true, TargetFlags.None )
|
||||
{
|
||||
}
|
||||
[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();
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object o )
|
||||
{
|
||||
if ( o is Mobile mobile )
|
||||
from.SendGump( new SkillsGump( from, mobile ) );
|
||||
}
|
||||
}
|
||||
private class SkillsTarget : Target
|
||||
{
|
||||
public SkillsTarget() : base(-1, true, TargetFlags.None)
|
||||
{
|
||||
}
|
||||
|
||||
[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();
|
||||
}
|
||||
}
|
||||
}
|
||||
protected override void OnTarget(Mobile from, object o)
|
||||
{
|
||||
if (o is Mobile mobile)
|
||||
from.SendGump(new SkillsGump(from, mobile));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,142 +1,141 @@
|
|||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
using Server.Network;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Commands
|
||||
{
|
||||
public class VisibilityList
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.Login += OnLogin;
|
||||
public class VisibilityList
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.Login += OnLogin;
|
||||
|
||||
CommandSystem.Register( "Vis", AccessLevel.Counselor, Vis_OnCommand );
|
||||
CommandSystem.Register( "VisList", AccessLevel.Counselor, VisList_OnCommand );
|
||||
CommandSystem.Register( "VisClear", AccessLevel.Counselor, VisClear_OnCommand );
|
||||
}
|
||||
CommandSystem.Register("Vis", AccessLevel.Counselor, Vis_OnCommand);
|
||||
CommandSystem.Register("VisList", AccessLevel.Counselor, VisList_OnCommand);
|
||||
CommandSystem.Register("VisClear", AccessLevel.Counselor, VisClear_OnCommand);
|
||||
}
|
||||
|
||||
public static void OnLogin( LoginEventArgs e )
|
||||
{
|
||||
if ( e.Mobile is PlayerMobile pm )
|
||||
{
|
||||
pm.VisibilityList.Clear();
|
||||
}
|
||||
}
|
||||
public static void OnLogin(LoginEventArgs e)
|
||||
{
|
||||
if (e.Mobile is PlayerMobile pm) 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("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 pm )
|
||||
{
|
||||
List<Mobile> list = pm.VisibilityList;
|
||||
[Usage("VisList")]
|
||||
[Description("Shows the names of everyone in your visibility list.")]
|
||||
public static void VisList_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if (e.Mobile is PlayerMobile pm)
|
||||
{
|
||||
List<Mobile> list = pm.VisibilityList;
|
||||
|
||||
if ( list.Count > 0 )
|
||||
{
|
||||
pm.SendMessage( "You are visible to {0} mobile{1}:", list.Count, list.Count == 1 ? "" : "s" );
|
||||
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." );
|
||||
}
|
||||
}
|
||||
}
|
||||
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 pm )
|
||||
{
|
||||
List<Mobile> list = new List<Mobile>( pm.VisibilityList );
|
||||
[Usage("VisClear")]
|
||||
[Description("Removes everyone from your visibility list.")]
|
||||
public static void VisClear_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if (e.Mobile is PlayerMobile pm)
|
||||
{
|
||||
List<Mobile> list = new List<Mobile>(pm.VisibilityList);
|
||||
|
||||
pm.VisibilityList.Clear();
|
||||
pm.SendMessage( "Your visibility list has been cleared." );
|
||||
pm.VisibilityList.Clear();
|
||||
pm.SendMessage("Your visibility list has been cleared.");
|
||||
|
||||
for ( int i = 0; i < list.Count; ++i )
|
||||
{
|
||||
Mobile m = list[i];
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
{
|
||||
Mobile m = list[i];
|
||||
|
||||
if ( !m.CanSee( pm ) && Utility.InUpdateRange( m, pm ) )
|
||||
m.Send( pm.RemovePacket );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!m.CanSee(pm) && Utility.InUpdateRange(m, pm))
|
||||
m.Send(pm.RemovePacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class VisTarget : Target
|
||||
{
|
||||
public VisTarget() : base( -1, false, TargetFlags.None )
|
||||
{
|
||||
}
|
||||
private class VisTarget : Target
|
||||
{
|
||||
public VisTarget() : base(-1, false, TargetFlags.None)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object targeted )
|
||||
{
|
||||
if ( from is PlayerMobile pm && targeted is Mobile targ )
|
||||
{
|
||||
if ( targ.AccessLevel <= pm.AccessLevel )
|
||||
{
|
||||
List<Mobile> list = pm.VisibilityList;
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (from is PlayerMobile pm && targeted is Mobile targ)
|
||||
{
|
||||
if (targ.AccessLevel <= pm.AccessLevel)
|
||||
{
|
||||
List<Mobile> list = pm.VisibilityList;
|
||||
|
||||
if ( list.Contains( targ ) )
|
||||
{
|
||||
list.Remove( targ );
|
||||
pm.SendMessage( "{0} has been removed from your visibility list.", targ.Name );
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add( targ );
|
||||
pm.SendMessage( "{0} has been added to your visibility list.", targ.Name );
|
||||
}
|
||||
if (list.Contains(targ))
|
||||
{
|
||||
list.Remove(targ);
|
||||
pm.SendMessage("{0} has been removed from your visibility list.", targ.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(targ);
|
||||
pm.SendMessage("{0} has been added to your visibility list.", targ.Name);
|
||||
}
|
||||
|
||||
if ( Utility.InUpdateRange( targ, from ) )
|
||||
{
|
||||
NetState ns = targ.NetState;
|
||||
if (Utility.InUpdateRange(targ, from))
|
||||
{
|
||||
NetState ns = targ.NetState;
|
||||
|
||||
if ( ns != null ) {
|
||||
if ( targ.CanSee( pm ) )
|
||||
{
|
||||
ns.Send(MobileIncoming.Create(ns, targ, pm));
|
||||
if (ns != null)
|
||||
{
|
||||
if (targ.CanSee(pm))
|
||||
{
|
||||
ns.Send(MobileIncoming.Create(ns, targ, pm));
|
||||
|
||||
if ( ObjectPropertyList.Enabled )
|
||||
{
|
||||
ns.Send( pm.OPLPacket );
|
||||
if (ObjectPropertyList.Enabled)
|
||||
{
|
||||
ns.Send(pm.OPLPacket);
|
||||
|
||||
foreach ( Item item in pm.Items )
|
||||
ns.Send( item.OPLPacket );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ns.Send( pm.RemovePacket );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pm.SendMessage( "They can already see you!" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage( "Add only mobiles to your visibility list." );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (Item item in pm.Items)
|
||||
ns.Send(item.OPLPacket);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ns.Send(pm.RemovePacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pm.SendMessage("They can already see you!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage("Add only mobiles to your visibility list.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,96 +5,95 @@ using Server.Multis;
|
|||
|
||||
namespace Server.Commands
|
||||
{
|
||||
public class Wipe
|
||||
{
|
||||
[Flags]
|
||||
public enum WipeType
|
||||
{
|
||||
Items = 0x01,
|
||||
Mobiles = 0x02,
|
||||
Multis = 0x04,
|
||||
All = Items | Mobiles | Multis
|
||||
}
|
||||
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, WipeAll_OnCommand );
|
||||
CommandSystem.Register( "WipeItems", AccessLevel.GameMaster, WipeItems_OnCommand );
|
||||
CommandSystem.Register( "WipeNPCs", AccessLevel.GameMaster, WipeNPCs_OnCommand );
|
||||
CommandSystem.Register( "WipeMultis", AccessLevel.GameMaster, WipeMultis_OnCommand );
|
||||
}
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("Wipe", AccessLevel.GameMaster, WipeAll_OnCommand);
|
||||
CommandSystem.Register("WipeItems", AccessLevel.GameMaster, WipeItems_OnCommand);
|
||||
CommandSystem.Register("WipeNPCs", AccessLevel.GameMaster, WipeNPCs_OnCommand);
|
||||
CommandSystem.Register("WipeMultis", AccessLevel.GameMaster, 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("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("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("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 );
|
||||
}
|
||||
[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, WipeBox_Callback, type );
|
||||
}
|
||||
public static void BeginWipe(Mobile from, WipeType type)
|
||||
{
|
||||
BoundingBoxPicker.Begin(from, 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 );
|
||||
}
|
||||
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 );
|
||||
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 );
|
||||
bool mobiles = (type & WipeType.Mobiles) != 0;
|
||||
bool multis = (type & WipeType.Multis) != 0;
|
||||
bool items = (type & WipeType.Items) != 0;
|
||||
|
||||
List<IEntity> toDelete = new List<IEntity>();
|
||||
List<IEntity> toDelete = new List<IEntity>();
|
||||
|
||||
Rectangle2D rect = new Rectangle2D( start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1 );
|
||||
Rectangle2D rect = new Rectangle2D(start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1);
|
||||
|
||||
IPooledEnumerable<IEntity> eable;
|
||||
IPooledEnumerable<IEntity> eable;
|
||||
|
||||
if ( (items || multis) && mobiles )
|
||||
eable = map.GetObjectsInBounds( rect, items || multis, mobiles );
|
||||
else
|
||||
return;
|
||||
if ((items || multis) && mobiles)
|
||||
eable = map.GetObjectsInBounds(rect, items || multis, mobiles);
|
||||
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) && !mobile.Player )
|
||||
toDelete.Add( mobile );
|
||||
}
|
||||
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 && !mobile.Player)
|
||||
toDelete.Add(mobile);
|
||||
|
||||
eable.Free();
|
||||
eable.Free();
|
||||
|
||||
for ( int i = 0; i < toDelete.Count; ++i )
|
||||
toDelete[i].Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < toDelete.Count; ++i)
|
||||
toDelete[i].Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,36 +2,36 @@ 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 class AddToPartyEntry : ContextMenuEntry
|
||||
{
|
||||
private Mobile m_From;
|
||||
private Mobile m_Target;
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
Party p = Party.Get( m_From );
|
||||
Party mp = Party.Get( m_Target );
|
||||
public AddToPartyEntry(Mobile from, Mobile target) : base(0197, 12)
|
||||
{
|
||||
m_From = from;
|
||||
m_Target = 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +1,60 @@
|
|||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.ContextMenus
|
||||
{
|
||||
public class AddToSpellbookEntry : ContextMenuEntry
|
||||
{
|
||||
public AddToSpellbookEntry() : base( 6144, 3 )
|
||||
{
|
||||
}
|
||||
public class AddToSpellbookEntry : ContextMenuEntry
|
||||
{
|
||||
public AddToSpellbookEntry() : base(6144, 3)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if ( Owner.From.CheckAlive() && Owner.Target is SpellScroll scroll )
|
||||
Owner.From.Target = new InternalTarget( scroll );
|
||||
}
|
||||
public override void OnClick()
|
||||
{
|
||||
if (Owner.From.CheckAlive() && Owner.Target is SpellScroll scroll)
|
||||
Owner.From.Target = new InternalTarget(scroll);
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
private SpellScroll m_Scroll;
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
private SpellScroll m_Scroll;
|
||||
|
||||
public InternalTarget( SpellScroll scroll ) : base( 3, false, TargetFlags.None )
|
||||
{
|
||||
m_Scroll = 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 book )
|
||||
{
|
||||
if ( from.CheckAlive() && !m_Scroll.Deleted && m_Scroll.Movable && m_Scroll.Amount >= 1 && m_Scroll.CheckItemUse( from ) )
|
||||
{
|
||||
SpellbookType type = Spellbook.GetTypeForSpell( m_Scroll.SpellID );
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (targeted is Spellbook book)
|
||||
if (from.CheckAlive() && !m_Scroll.Deleted && m_Scroll.Movable && m_Scroll.Amount >= 1 &&
|
||||
m_Scroll.CheckItemUse(from))
|
||||
{
|
||||
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 (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;
|
||||
if (val >= 0 && val < book.BookCount)
|
||||
{
|
||||
book.Content |= (ulong)1 << val;
|
||||
|
||||
m_Scroll.Consume();
|
||||
m_Scroll.Consume();
|
||||
|
||||
from.Send( new Network.PlaySound( 0x249, book.GetWorldLocation() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
from.Send(new PlaySound(0x249, book.GetWorldLocation()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,23 +2,23 @@ using Server.Items;
|
|||
|
||||
namespace Server.ContextMenus
|
||||
{
|
||||
public class EatEntry : ContextMenuEntry
|
||||
{
|
||||
private Mobile m_From;
|
||||
private Food m_Food;
|
||||
public class EatEntry : ContextMenuEntry
|
||||
{
|
||||
private Food m_Food;
|
||||
private Mobile m_From;
|
||||
|
||||
public EatEntry( Mobile from, Food food ) : base( 6135, 1 )
|
||||
{
|
||||
m_From = from;
|
||||
m_Food = 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;
|
||||
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 );
|
||||
}
|
||||
}
|
||||
m_Food.Eat(m_From);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,26 +2,26 @@ using Server.Multis;
|
|||
|
||||
namespace Server.ContextMenus
|
||||
{
|
||||
public class EjectPlayerEntry : ContextMenuEntry
|
||||
{
|
||||
private Mobile m_From;
|
||||
private Mobile m_Target;
|
||||
private BaseHouse m_TargetHouse;
|
||||
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 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;
|
||||
public override void OnClick()
|
||||
{
|
||||
if (!m_From.Alive || m_TargetHouse.Deleted || !m_TargetHouse.IsFriend(m_From))
|
||||
return;
|
||||
|
||||
if ( m_Target is Mobile mobile )
|
||||
m_TargetHouse.Kick( m_From, mobile );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_Target is Mobile mobile)
|
||||
m_TargetHouse.Kick(m_From, mobile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +1,23 @@
|
|||
namespace Server.ContextMenus
|
||||
{
|
||||
public class OpenBankEntry : ContextMenuEntry
|
||||
{
|
||||
private Mobile m_Banker;
|
||||
public class OpenBankEntry : ContextMenuEntry
|
||||
{
|
||||
private Mobile m_Banker;
|
||||
|
||||
public OpenBankEntry( Mobile from, Mobile banker ) : base( 6105, 12 )
|
||||
{
|
||||
m_Banker = banker;
|
||||
}
|
||||
public OpenBankEntry(Mobile from, Mobile banker) : base(6105, 12)
|
||||
{
|
||||
m_Banker = banker;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if ( !Owner.From.CheckAlive() )
|
||||
return;
|
||||
public override void OnClick()
|
||||
{
|
||||
if (!Owner.From.CheckAlive())
|
||||
return;
|
||||
|
||||
if ( Owner.From.Criminal )
|
||||
{
|
||||
m_Banker.Say( 500378 ); // Thou art a criminal and cannot access thy bank box.
|
||||
}
|
||||
else
|
||||
{
|
||||
Owner.From.BankBox.Open();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Owner.From.Criminal)
|
||||
m_Banker.Say(500378); // Thou art a criminal and cannot access thy bank box.
|
||||
else
|
||||
Owner.From.BankBox.Open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +1,30 @@
|
|||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.ContextMenus
|
||||
{
|
||||
public class TeachEntry : ContextMenuEntry
|
||||
{
|
||||
private SkillName m_Skill;
|
||||
private BaseCreature m_Mobile;
|
||||
private Mobile m_From;
|
||||
public class TeachEntry : ContextMenuEntry
|
||||
{
|
||||
private Mobile m_From;
|
||||
private BaseCreature m_Mobile;
|
||||
private SkillName m_Skill;
|
||||
|
||||
public TeachEntry( SkillName skill, BaseCreature m, Mobile from, bool enabled ) : base( 6000 + (int)skill )
|
||||
{
|
||||
m_Skill = skill;
|
||||
m_Mobile = m;
|
||||
m_From = 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;
|
||||
}
|
||||
if (!enabled)
|
||||
Flags |= CMEFlags.Disabled;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if ( !m_From.CheckAlive() )
|
||||
return;
|
||||
public override void OnClick()
|
||||
{
|
||||
if (!m_From.CheckAlive())
|
||||
return;
|
||||
|
||||
m_Mobile.Teach( m_Skill, m_From, 0, false );
|
||||
}
|
||||
}
|
||||
m_Mobile.Teach(m_Skill, m_From, 0, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,62 +1,62 @@
|
|||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class BOBFilter
|
||||
{
|
||||
public bool IsDefault => ( Type == 0 && Quality == 0 && Material == 0 && Quantity == 0 );
|
||||
public class BOBFilter
|
||||
{
|
||||
public BOBFilter()
|
||||
{
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Type = 0;
|
||||
Quality = 0;
|
||||
Material = 0;
|
||||
Quantity = 0;
|
||||
}
|
||||
public BOBFilter(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
public int Type { get; set; }
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
Type = reader.ReadEncodedInt();
|
||||
Quality = reader.ReadEncodedInt();
|
||||
Material = reader.ReadEncodedInt();
|
||||
Quantity = reader.ReadEncodedInt();
|
||||
|
||||
public int Quality { get; set; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Material { get; set; }
|
||||
public bool IsDefault => Type == 0 && Quality == 0 && Material == 0 && Quantity == 0;
|
||||
|
||||
public int Quantity { get; set; }
|
||||
public int Type{ get; set; }
|
||||
|
||||
public BOBFilter()
|
||||
{
|
||||
}
|
||||
public int Quality{ get; set; }
|
||||
|
||||
public BOBFilter( GenericReader reader )
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
public int Material{ get; set; }
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
Type = reader.ReadEncodedInt();
|
||||
Quality = reader.ReadEncodedInt();
|
||||
Material = reader.ReadEncodedInt();
|
||||
Quantity = reader.ReadEncodedInt();
|
||||
public int Quantity{ get; set; }
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Clear()
|
||||
{
|
||||
Type = 0;
|
||||
Quality = 0;
|
||||
Material = 0;
|
||||
Quantity = 0;
|
||||
}
|
||||
|
||||
public void Serialize( GenericWriter writer )
|
||||
{
|
||||
if ( IsDefault )
|
||||
{
|
||||
writer.WriteEncodedInt( 0 ); // version
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteEncodedInt( 1 ); // version
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
if (IsDefault)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteEncodedInt(1); // version
|
||||
|
||||
writer.WriteEncodedInt( Type );
|
||||
writer.WriteEncodedInt( Quality );
|
||||
writer.WriteEncodedInt( Material );
|
||||
writer.WriteEncodedInt( Quantity );
|
||||
}
|
||||
}
|
||||
}
|
||||
writer.WriteEncodedInt(Type);
|
||||
writer.WriteEncodedInt(Quality);
|
||||
writer.WriteEncodedInt(Material);
|
||||
writer.WriteEncodedInt(Quantity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,206 +1,224 @@
|
|||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class BOBFilterGump : Gump
|
||||
{
|
||||
private PlayerMobile m_From;
|
||||
private BulkOrderBook m_Book;
|
||||
public class BOBFilterGump : Gump
|
||||
{
|
||||
private const int LabelColor = 0x7FFF;
|
||||
|
||||
private const int LabelColor = 0x7FFF;
|
||||
private static int[,] m_MaterialFilters =
|
||||
{
|
||||
{ 1044067, 1 }, // Blacksmithy
|
||||
{ 1062226, 3 }, // Iron
|
||||
{ 1018332, 4 }, // Dull Copper
|
||||
{ 1018333, 5 }, // Shadow Iron
|
||||
{ 1018334, 6 }, // Copper
|
||||
{ 1018335, 7 }, // Bronze
|
||||
|
||||
private static int[,] m_MaterialFilters = {
|
||||
{ 1044067, 1 }, // Blacksmithy
|
||||
{ 1062226, 3 }, // Iron
|
||||
{ 1018332, 4 }, // Dull Copper
|
||||
{ 1018333, 5 }, // Shadow Iron
|
||||
{ 1018334, 6 }, // Copper
|
||||
{ 1018335, 7 }, // Bronze
|
||||
{ 0, 0 }, // --Blank--
|
||||
{ 1018336, 8 }, // Golden
|
||||
{ 1018337, 9 }, // Agapite
|
||||
{ 1018338, 10 }, // Verite
|
||||
{ 1018339, 11 }, // Valorite
|
||||
{ 0, 0 }, // --Blank--
|
||||
|
||||
{ 0, 0 }, // --Blank--
|
||||
{ 1018336, 8 }, // Golden
|
||||
{ 1018337, 9 }, // Agapite
|
||||
{ 1018338, 10 }, // Verite
|
||||
{ 1018339, 11 }, // Valorite
|
||||
{ 0, 0 }, // --Blank--
|
||||
{ 1044094, 2 }, // Tailoring
|
||||
{ 1044286, 12 }, // Cloth
|
||||
{ 1062235, 13 }, // Leather
|
||||
{ 1062236, 14 }, // Spined
|
||||
{ 1062237, 15 }, // Horned
|
||||
{ 1062238, 16 } // Barbed
|
||||
};
|
||||
|
||||
{ 1044094, 2 }, // Tailoring
|
||||
{ 1044286, 12 }, // Cloth
|
||||
{ 1062235, 13 }, // Leather
|
||||
{ 1062236, 14 }, // Spined
|
||||
{ 1062237, 15 }, // Horned
|
||||
{ 1062238, 16 } // Barbed
|
||||
};
|
||||
private static int[,] m_TypeFilters =
|
||||
{
|
||||
{ 1062229, 0 }, // All
|
||||
{ 1062224, 1 }, // Small
|
||||
{ 1062225, 2 } // Large
|
||||
};
|
||||
|
||||
private static int[,] m_TypeFilters = {
|
||||
{ 1062229, 0 }, // All
|
||||
{ 1062224, 1 }, // Small
|
||||
{ 1062225, 2 } // Large
|
||||
};
|
||||
private static int[,] m_QualityFilters =
|
||||
{
|
||||
{ 1062229, 0 }, // All
|
||||
{ 1011542, 1 }, // Normal
|
||||
{ 1060636, 2 } // Exceptional
|
||||
};
|
||||
|
||||
private static int[,] m_QualityFilters = {
|
||||
{ 1062229, 0 }, // All
|
||||
{ 1011542, 1 }, // Normal
|
||||
{ 1060636, 2 } // Exceptional
|
||||
};
|
||||
private static int[,] m_AmountFilters =
|
||||
{
|
||||
{ 1062229, 0 }, // All
|
||||
{ 1049706, 1 }, // 10
|
||||
{ 1016007, 2 }, // 15
|
||||
{ 1062239, 3 } // 20
|
||||
};
|
||||
|
||||
private static int[,] m_AmountFilters = {
|
||||
{ 1062229, 0 }, // All
|
||||
{ 1049706, 1 }, // 10
|
||||
{ 1016007, 2 }, // 15
|
||||
{ 1062239, 3 } // 20
|
||||
};
|
||||
private static int[][,] m_Filters =
|
||||
{
|
||||
m_TypeFilters,
|
||||
m_QualityFilters,
|
||||
m_MaterialFilters,
|
||||
m_AmountFilters
|
||||
};
|
||||
|
||||
private static int[][,] m_Filters = {
|
||||
m_TypeFilters,
|
||||
m_QualityFilters,
|
||||
m_MaterialFilters,
|
||||
m_AmountFilters
|
||||
};
|
||||
private static int[] m_XOffsets_Type = { 0, 75, 170 };
|
||||
private static int[] m_XOffsets_Quality = { 0, 75, 170 };
|
||||
private static int[] m_XOffsets_Amount = { 0, 75, 180, 275 };
|
||||
private static int[] m_XOffsets_Material = { 0, 105, 210, 305, 390, 485 };
|
||||
|
||||
private static int[] m_XOffsets_Type = { 0, 75, 170 };
|
||||
private static int[] m_XOffsets_Quality = { 0, 75, 170 };
|
||||
private static int[] m_XOffsets_Amount = { 0, 75, 180, 275 };
|
||||
private static int[] m_XOffsets_Material = { 0, 105, 210, 305, 390, 485 };
|
||||
private static int[] m_XWidths_Small = { 50, 50, 70, 50 };
|
||||
private static int[] m_XWidths_Large = { 80, 50, 50, 50, 50, 50 };
|
||||
private BulkOrderBook m_Book;
|
||||
private PlayerMobile m_From;
|
||||
|
||||
private static int[] m_XWidths_Small = { 50, 50, 70, 50 };
|
||||
private static int[] m_XWidths_Large = { 80, 50, 50, 50, 50, 50 };
|
||||
public BOBFilterGump(PlayerMobile from, BulkOrderBook book) : base(12, 24)
|
||||
{
|
||||
from.CloseGump(typeof(BOBGump));
|
||||
from.CloseGump(typeof(BOBFilterGump));
|
||||
|
||||
private void AddFilterList( int x, int y, int[] xOffsets, int yOffset, int[,] filters, int[] xWidths, int filterValue, int filterIndex )
|
||||
{
|
||||
for ( int i = 0; i < filters.GetLength( 0 ); ++i )
|
||||
{
|
||||
int number = filters[i, 0];
|
||||
m_From = from;
|
||||
m_Book = book;
|
||||
|
||||
if ( number == 0 )
|
||||
continue;
|
||||
BOBFilter f = from.UseOwnFilter ? from.BOBFilter : book.Filter;
|
||||
|
||||
bool isSelected = ( filters[i, 1] == filterValue );
|
||||
AddPage(0);
|
||||
|
||||
if ( !isSelected && (i % xOffsets.Length) == 0 )
|
||||
isSelected = ( filterValue == 0 );
|
||||
AddBackground(10, 10, 600, 439, 5054);
|
||||
|
||||
AddHtmlLocalized( x + 35 + xOffsets[i % xOffsets.Length], y + ((i / xOffsets.Length) * yOffset), xWidths[i % xOffsets.Length], 32, number, isSelected ? 16927 : LabelColor, false, false );
|
||||
AddButton( x + xOffsets[i % xOffsets.Length], y + ((i / xOffsets.Length) * yOffset), 4005, 4007, 4 + filterIndex + (i * 4), GumpButtonType.Reply, 0 );
|
||||
}
|
||||
}
|
||||
AddImageTiled(18, 20, 583, 420, 2624);
|
||||
AddAlphaRegion(18, 20, 583, 420);
|
||||
|
||||
public override void OnResponse( Network.NetState sender, RelayInfo info )
|
||||
{
|
||||
BOBFilter f = ( m_From.UseOwnFilter ? m_From.BOBFilter : m_Book.Filter );
|
||||
AddImage(5, 5, 10460);
|
||||
AddImage(585, 5, 10460);
|
||||
AddImage(5, 424, 10460);
|
||||
AddImage(585, 424, 10460);
|
||||
|
||||
int index = info.ButtonID;
|
||||
AddHtmlLocalized(270, 32, 200, 32, 1062223, LabelColor, false, false); // Filter Preference
|
||||
|
||||
switch ( index )
|
||||
{
|
||||
case 0: // Apply
|
||||
{
|
||||
m_From.SendGump( new BOBGump( m_From, m_Book ) );
|
||||
AddHtmlLocalized(26, 64, 120, 32, 1062228, LabelColor, false, false); // Bulk Order Type
|
||||
AddFilterList(25, 96, m_XOffsets_Type, 40, m_TypeFilters, m_XWidths_Small, f.Type, 0);
|
||||
|
||||
break;
|
||||
}
|
||||
case 1: // Set Book Filter
|
||||
{
|
||||
m_From.UseOwnFilter = false;
|
||||
m_From.SendGump( new BOBFilterGump( m_From, m_Book ) );
|
||||
AddHtmlLocalized(320, 64, 50, 32, 1062215, LabelColor, false, false); // Quality
|
||||
AddFilterList(320, 96, m_XOffsets_Quality, 40, m_QualityFilters, m_XWidths_Small, f.Quality, 1);
|
||||
|
||||
break;
|
||||
}
|
||||
case 2: // Set Your Filter
|
||||
{
|
||||
m_From.UseOwnFilter = true;
|
||||
m_From.SendGump( new BOBFilterGump( m_From, m_Book ) );
|
||||
AddHtmlLocalized(26, 160, 120, 32, 1062232, LabelColor, false, false); // Material Type
|
||||
AddFilterList(25, 192, m_XOffsets_Material, 40, m_MaterialFilters, m_XWidths_Large, f.Material, 2);
|
||||
|
||||
break;
|
||||
}
|
||||
case 3: // Clear Filter
|
||||
{
|
||||
f.Clear();
|
||||
m_From.SendGump( new BOBFilterGump( m_From, m_Book ) );
|
||||
AddHtmlLocalized(26, 320, 120, 32, 1062217, LabelColor, false, false); // Amount
|
||||
AddFilterList(25, 352, m_XOffsets_Amount, 40, m_AmountFilters, m_XWidths_Small, f.Quantity, 3);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
index -= 4;
|
||||
AddHtmlLocalized(75, 416, 120, 32, 1062477, from.UseOwnFilter ? LabelColor : 16927, false,
|
||||
false); // Set Book Filter
|
||||
AddButton(40, 416, 4005, 4007, 1, GumpButtonType.Reply, 0);
|
||||
|
||||
int type = index % 4;
|
||||
index /= 4;
|
||||
AddHtmlLocalized(235, 416, 120, 32, 1062478, from.UseOwnFilter ? 16927 : LabelColor, false,
|
||||
false); // Set Your Filter
|
||||
AddButton(200, 416, 4005, 4007, 2, GumpButtonType.Reply, 0);
|
||||
|
||||
if ( type >= 0 && type < m_Filters.Length )
|
||||
{
|
||||
int[,] filters = m_Filters[type];
|
||||
AddHtmlLocalized(405, 416, 120, 32, 1062231, LabelColor, false, false); // Clear Filter
|
||||
AddButton(370, 416, 4005, 4007, 3, GumpButtonType.Reply, 0);
|
||||
|
||||
if ( index >= 0 && index < filters.GetLength( 0 ) )
|
||||
{
|
||||
if ( filters[index, 0] == 0 )
|
||||
break;
|
||||
AddHtmlLocalized(540, 416, 50, 32, 1011046, LabelColor, false, false); // APPLY
|
||||
AddButton(505, 416, 4017, 4018, 0, GumpButtonType.Reply, 0);
|
||||
}
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case 0: f.Type = filters[index, 1]; break;
|
||||
case 1: f.Quality = filters[index, 1]; break;
|
||||
case 2: f.Material = filters[index, 1]; break;
|
||||
case 3: f.Quantity = filters[index, 1]; break;
|
||||
}
|
||||
private void AddFilterList(int x, int y, int[] xOffsets, int yOffset, int[,] filters, int[] xWidths, int filterValue,
|
||||
int filterIndex)
|
||||
{
|
||||
for (int i = 0; i < filters.GetLength(0); ++i)
|
||||
{
|
||||
int number = filters[i, 0];
|
||||
|
||||
m_From.SendGump( new BOBFilterGump( m_From, m_Book ) );
|
||||
}
|
||||
}
|
||||
if (number == 0)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool isSelected = filters[i, 1] == filterValue;
|
||||
|
||||
public BOBFilterGump( PlayerMobile from, BulkOrderBook book ) : base( 12, 24 )
|
||||
{
|
||||
from.CloseGump( typeof( BOBGump ) );
|
||||
from.CloseGump( typeof( BOBFilterGump ) );
|
||||
if (!isSelected && i % xOffsets.Length == 0)
|
||||
isSelected = filterValue == 0;
|
||||
|
||||
m_From = from;
|
||||
m_Book = book;
|
||||
AddHtmlLocalized(x + 35 + xOffsets[i % xOffsets.Length], y + i / xOffsets.Length * yOffset,
|
||||
xWidths[i % xOffsets.Length], 32, number, isSelected ? 16927 : LabelColor, false, false);
|
||||
AddButton(x + xOffsets[i % xOffsets.Length], y + i / xOffsets.Length * yOffset, 4005, 4007,
|
||||
4 + filterIndex + i * 4, GumpButtonType.Reply, 0);
|
||||
}
|
||||
}
|
||||
|
||||
BOBFilter f = ( from.UseOwnFilter ? from.BOBFilter : book.Filter );
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
BOBFilter f = m_From.UseOwnFilter ? m_From.BOBFilter : m_Book.Filter;
|
||||
|
||||
AddPage( 0 );
|
||||
int index = info.ButtonID;
|
||||
|
||||
AddBackground( 10, 10, 600, 439, 5054 );
|
||||
switch (index)
|
||||
{
|
||||
case 0: // Apply
|
||||
{
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book));
|
||||
|
||||
AddImageTiled( 18, 20, 583, 420, 2624 );
|
||||
AddAlphaRegion( 18, 20, 583, 420 );
|
||||
break;
|
||||
}
|
||||
case 1: // Set Book Filter
|
||||
{
|
||||
m_From.UseOwnFilter = false;
|
||||
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
|
||||
|
||||
AddImage( 5, 5, 10460 );
|
||||
AddImage( 585, 5, 10460 );
|
||||
AddImage( 5, 424, 10460 );
|
||||
AddImage( 585, 424, 10460 );
|
||||
break;
|
||||
}
|
||||
case 2: // Set Your Filter
|
||||
{
|
||||
m_From.UseOwnFilter = true;
|
||||
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
|
||||
|
||||
AddHtmlLocalized( 270, 32, 200, 32, 1062223, LabelColor, false, false ); // Filter Preference
|
||||
break;
|
||||
}
|
||||
case 3: // Clear Filter
|
||||
{
|
||||
f.Clear();
|
||||
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
|
||||
|
||||
AddHtmlLocalized( 26, 64, 120, 32, 1062228, LabelColor, false, false ); // Bulk Order Type
|
||||
AddFilterList( 25, 96, m_XOffsets_Type, 40, m_TypeFilters, m_XWidths_Small, f.Type, 0 );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
index -= 4;
|
||||
|
||||
AddHtmlLocalized( 320, 64, 50, 32, 1062215, LabelColor, false, false ); // Quality
|
||||
AddFilterList( 320, 96, m_XOffsets_Quality, 40, m_QualityFilters, m_XWidths_Small, f.Quality, 1 );
|
||||
int type = index % 4;
|
||||
index /= 4;
|
||||
|
||||
AddHtmlLocalized( 26, 160, 120, 32, 1062232, LabelColor, false, false ); // Material Type
|
||||
AddFilterList( 25, 192, m_XOffsets_Material, 40, m_MaterialFilters, m_XWidths_Large, f.Material, 2 );
|
||||
if (type >= 0 && type < m_Filters.Length)
|
||||
{
|
||||
int[,] filters = m_Filters[type];
|
||||
|
||||
AddHtmlLocalized( 26, 320, 120, 32, 1062217, LabelColor, false, false ); // Amount
|
||||
AddFilterList( 25, 352, m_XOffsets_Amount, 40, m_AmountFilters, m_XWidths_Small, f.Quantity, 3 );
|
||||
if (index >= 0 && index < filters.GetLength(0))
|
||||
{
|
||||
if (filters[index, 0] == 0)
|
||||
break;
|
||||
|
||||
AddHtmlLocalized( 75, 416, 120, 32, 1062477, ( from.UseOwnFilter ? LabelColor : 16927 ), false, false ); // Set Book Filter
|
||||
AddButton( 40, 416, 4005, 4007, 1, GumpButtonType.Reply, 0 );
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
f.Type = filters[index, 1];
|
||||
break;
|
||||
case 1:
|
||||
f.Quality = filters[index, 1];
|
||||
break;
|
||||
case 2:
|
||||
f.Material = filters[index, 1];
|
||||
break;
|
||||
case 3:
|
||||
f.Quantity = filters[index, 1];
|
||||
break;
|
||||
}
|
||||
|
||||
AddHtmlLocalized( 235, 416, 120, 32, 1062478, ( from.UseOwnFilter ? 16927 : LabelColor ), false, false ); // Set Your Filter
|
||||
AddButton( 200, 416, 4005, 4007, 2, GumpButtonType.Reply, 0 );
|
||||
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
|
||||
}
|
||||
}
|
||||
|
||||
AddHtmlLocalized( 405, 416, 120, 32, 1062231, LabelColor, false, false ); // Clear Filter
|
||||
AddButton( 370, 416, 4005, 4007, 3, GumpButtonType.Reply, 0 );
|
||||
|
||||
AddHtmlLocalized( 540, 416, 50, 32, 1011046, LabelColor, false, false ); // APPLY
|
||||
AddButton( 505, 416, 4017, 4018, 0, GumpButtonType.Reply, 0 );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,106 +1,107 @@
|
|||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class BOBLargeEntry
|
||||
{
|
||||
public bool RequireExceptional { get; }
|
||||
public class BOBLargeEntry
|
||||
{
|
||||
public BOBLargeEntry(LargeBOD bod)
|
||||
{
|
||||
RequireExceptional = bod.RequireExceptional;
|
||||
|
||||
public BODType DeedType { get; }
|
||||
if (bod is LargeTailorBOD)
|
||||
DeedType = BODType.Tailor;
|
||||
else if (bod is LargeSmithBOD)
|
||||
DeedType = BODType.Smith;
|
||||
|
||||
public BulkMaterialType Material { get; }
|
||||
Material = bod.Material;
|
||||
AmountMax = bod.AmountMax;
|
||||
|
||||
public int AmountMax { get; }
|
||||
Entries = new BOBLargeSubEntry[bod.Entries.Length];
|
||||
|
||||
public int Price { get; set; }
|
||||
for (int i = 0; i < Entries.Length; ++i)
|
||||
Entries[i] = new BOBLargeSubEntry(bod.Entries[i]);
|
||||
}
|
||||
|
||||
public BOBLargeSubEntry[] Entries { get; }
|
||||
public BOBLargeEntry(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
public Item Reconstruct()
|
||||
{
|
||||
LargeBOD bod = null;
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
RequireExceptional = reader.ReadBool();
|
||||
|
||||
if ( DeedType == BODType.Smith )
|
||||
bod = new LargeSmithBOD( AmountMax, RequireExceptional, Material, ReconstructEntries() );
|
||||
else if ( DeedType == BODType.Tailor )
|
||||
bod = new LargeTailorBOD( AmountMax, RequireExceptional, Material, ReconstructEntries() );
|
||||
DeedType = (BODType)reader.ReadEncodedInt();
|
||||
|
||||
for ( int i = 0; bod != null && i < bod.Entries.Length; ++i )
|
||||
bod.Entries[i].Owner = bod;
|
||||
Material = (BulkMaterialType)reader.ReadEncodedInt();
|
||||
AmountMax = reader.ReadEncodedInt();
|
||||
Price = reader.ReadEncodedInt();
|
||||
|
||||
return bod;
|
||||
}
|
||||
Entries = new BOBLargeSubEntry[reader.ReadEncodedInt()];
|
||||
|
||||
private LargeBulkEntry[] ReconstructEntries()
|
||||
{
|
||||
LargeBulkEntry[] entries = new LargeBulkEntry[Entries.Length];
|
||||
for (int i = 0; i < Entries.Length; ++i)
|
||||
Entries[i] = new BOBLargeSubEntry(reader);
|
||||
|
||||
for ( int i = 0; i < Entries.Length; ++i )
|
||||
{
|
||||
entries[i] = new LargeBulkEntry( null, new SmallBulkEntry( Entries[i].ItemType, Entries[i].Number, Entries[i].Graphic ) );
|
||||
entries[i].Amount = Entries[i].AmountCur;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
public bool RequireExceptional{ get; }
|
||||
|
||||
public BOBLargeEntry( LargeBOD bod )
|
||||
{
|
||||
RequireExceptional = bod.RequireExceptional;
|
||||
public BODType DeedType{ get; }
|
||||
|
||||
if ( bod is LargeTailorBOD )
|
||||
DeedType = BODType.Tailor;
|
||||
else if ( bod is LargeSmithBOD )
|
||||
DeedType = BODType.Smith;
|
||||
public BulkMaterialType Material{ get; }
|
||||
|
||||
Material = bod.Material;
|
||||
AmountMax = bod.AmountMax;
|
||||
public int AmountMax{ get; }
|
||||
|
||||
Entries = new BOBLargeSubEntry[bod.Entries.Length];
|
||||
public int Price{ get; set; }
|
||||
|
||||
for ( int i = 0; i < Entries.Length; ++i )
|
||||
Entries[i] = new BOBLargeSubEntry( bod.Entries[i] );
|
||||
}
|
||||
public BOBLargeSubEntry[] Entries{ get; }
|
||||
|
||||
public BOBLargeEntry( GenericReader reader )
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
public Item Reconstruct()
|
||||
{
|
||||
LargeBOD bod = null;
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
RequireExceptional = reader.ReadBool();
|
||||
if (DeedType == BODType.Smith)
|
||||
bod = new LargeSmithBOD(AmountMax, RequireExceptional, Material, ReconstructEntries());
|
||||
else if (DeedType == BODType.Tailor)
|
||||
bod = new LargeTailorBOD(AmountMax, RequireExceptional, Material, ReconstructEntries());
|
||||
|
||||
DeedType = (BODType)reader.ReadEncodedInt();
|
||||
for (int i = 0; bod != null && i < bod.Entries.Length; ++i)
|
||||
bod.Entries[i].Owner = bod;
|
||||
|
||||
Material = (BulkMaterialType)reader.ReadEncodedInt();
|
||||
AmountMax = reader.ReadEncodedInt();
|
||||
Price = reader.ReadEncodedInt();
|
||||
return bod;
|
||||
}
|
||||
|
||||
Entries = new BOBLargeSubEntry[reader.ReadEncodedInt()];
|
||||
private LargeBulkEntry[] ReconstructEntries()
|
||||
{
|
||||
LargeBulkEntry[] entries = new LargeBulkEntry[Entries.Length];
|
||||
|
||||
for ( int i = 0; i < Entries.Length; ++i )
|
||||
Entries[i] = new BOBLargeSubEntry( reader );
|
||||
for (int i = 0; i < Entries.Length; ++i)
|
||||
{
|
||||
entries[i] = new LargeBulkEntry(null,
|
||||
new SmallBulkEntry(Entries[i].ItemType, Entries[i].Number, Entries[i].Graphic));
|
||||
entries[i].Amount = Entries[i].AmountCur;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
public void Serialize( GenericWriter writer )
|
||||
{
|
||||
writer.WriteEncodedInt( 0 ); // version
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write( (bool) RequireExceptional );
|
||||
writer.Write(RequireExceptional);
|
||||
|
||||
writer.WriteEncodedInt( (int) DeedType );
|
||||
writer.WriteEncodedInt( (int) Material );
|
||||
writer.WriteEncodedInt( (int) AmountMax );
|
||||
writer.WriteEncodedInt( (int) Price );
|
||||
writer.WriteEncodedInt((int)DeedType);
|
||||
writer.WriteEncodedInt((int)Material);
|
||||
writer.WriteEncodedInt(AmountMax);
|
||||
writer.WriteEncodedInt(Price);
|
||||
|
||||
writer.WriteEncodedInt( (int) Entries.Length );
|
||||
writer.WriteEncodedInt(Entries.Length);
|
||||
|
||||
for ( int i = 0; i < Entries.Length; ++i )
|
||||
Entries[i].Serialize( writer );
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < Entries.Length; ++i)
|
||||
Entries[i].Serialize(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,55 +2,55 @@ using System;
|
|||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class BOBLargeSubEntry
|
||||
{
|
||||
public Type ItemType { get; }
|
||||
public class BOBLargeSubEntry
|
||||
{
|
||||
public BOBLargeSubEntry(LargeBulkEntry lbe)
|
||||
{
|
||||
ItemType = lbe.Details.Type;
|
||||
AmountCur = lbe.Amount;
|
||||
Number = lbe.Details.Number;
|
||||
Graphic = lbe.Details.Graphic;
|
||||
}
|
||||
|
||||
public int AmountCur { get; }
|
||||
public BOBLargeSubEntry(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
public int Number { get; }
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
string type = reader.ReadString();
|
||||
|
||||
public int Graphic { get; }
|
||||
if (type != null)
|
||||
ItemType = ScriptCompiler.FindTypeByFullName(type);
|
||||
|
||||
public BOBLargeSubEntry( LargeBulkEntry lbe )
|
||||
{
|
||||
ItemType = lbe.Details.Type;
|
||||
AmountCur = lbe.Amount;
|
||||
Number = lbe.Details.Number;
|
||||
Graphic = lbe.Details.Graphic;
|
||||
}
|
||||
AmountCur = reader.ReadEncodedInt();
|
||||
Number = reader.ReadEncodedInt();
|
||||
Graphic = reader.ReadEncodedInt();
|
||||
|
||||
public BOBLargeSubEntry( GenericReader reader )
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
string type = reader.ReadString();
|
||||
public Type ItemType{ get; }
|
||||
|
||||
if ( type != null )
|
||||
ItemType = ScriptCompiler.FindTypeByFullName( type );
|
||||
public int AmountCur{ get; }
|
||||
|
||||
AmountCur = reader.ReadEncodedInt();
|
||||
Number = reader.ReadEncodedInt();
|
||||
Graphic = reader.ReadEncodedInt();
|
||||
public int Number{ get; }
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public int Graphic{ get; }
|
||||
|
||||
public void Serialize( GenericWriter writer )
|
||||
{
|
||||
writer.WriteEncodedInt( 0 ); // version
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write( ItemType == null ? null : ItemType.FullName );
|
||||
writer.Write(ItemType == null ? null : ItemType.FullName);
|
||||
|
||||
writer.WriteEncodedInt( (int) AmountCur );
|
||||
writer.WriteEncodedInt( (int) Number );
|
||||
writer.WriteEncodedInt( (int) Graphic );
|
||||
}
|
||||
}
|
||||
writer.WriteEncodedInt(AmountCur);
|
||||
writer.WriteEncodedInt(Number);
|
||||
writer.WriteEncodedInt(Graphic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,99 +2,99 @@ using System;
|
|||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class BOBSmallEntry
|
||||
{
|
||||
public Type ItemType { get; }
|
||||
public class BOBSmallEntry
|
||||
{
|
||||
public BOBSmallEntry(SmallBOD bod)
|
||||
{
|
||||
ItemType = bod.Type;
|
||||
RequireExceptional = bod.RequireExceptional;
|
||||
|
||||
public bool RequireExceptional { get; }
|
||||
if (bod is SmallTailorBOD)
|
||||
DeedType = BODType.Tailor;
|
||||
else if (bod is SmallSmithBOD)
|
||||
DeedType = BODType.Smith;
|
||||
|
||||
public BODType DeedType { get; }
|
||||
Material = bod.Material;
|
||||
AmountCur = bod.AmountCur;
|
||||
AmountMax = bod.AmountMax;
|
||||
Number = bod.Number;
|
||||
Graphic = bod.Graphic;
|
||||
}
|
||||
|
||||
public BulkMaterialType Material { get; }
|
||||
public BOBSmallEntry(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
public int AmountCur { get; }
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
string type = reader.ReadString();
|
||||
|
||||
public int AmountMax { get; }
|
||||
if (type != null)
|
||||
ItemType = ScriptCompiler.FindTypeByFullName(type);
|
||||
|
||||
public int Number { get; }
|
||||
RequireExceptional = reader.ReadBool();
|
||||
|
||||
public int Graphic { get; }
|
||||
DeedType = (BODType)reader.ReadEncodedInt();
|
||||
|
||||
public int Price { get; set; }
|
||||
Material = (BulkMaterialType)reader.ReadEncodedInt();
|
||||
AmountCur = reader.ReadEncodedInt();
|
||||
AmountMax = reader.ReadEncodedInt();
|
||||
Number = reader.ReadEncodedInt();
|
||||
Graphic = reader.ReadEncodedInt();
|
||||
Price = reader.ReadEncodedInt();
|
||||
|
||||
public Item Reconstruct()
|
||||
{
|
||||
SmallBOD bod = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( DeedType == BODType.Smith )
|
||||
bod = new SmallSmithBOD( AmountCur, AmountMax, ItemType, Number, Graphic, RequireExceptional, Material );
|
||||
else if ( DeedType == BODType.Tailor )
|
||||
bod = new SmallTailorBOD( AmountCur, AmountMax, ItemType, Number, Graphic, RequireExceptional, Material );
|
||||
public Type ItemType{ get; }
|
||||
|
||||
return bod;
|
||||
}
|
||||
public bool RequireExceptional{ get; }
|
||||
|
||||
public BOBSmallEntry( SmallBOD bod )
|
||||
{
|
||||
ItemType = bod.Type;
|
||||
RequireExceptional = bod.RequireExceptional;
|
||||
public BODType DeedType{ get; }
|
||||
|
||||
if ( bod is SmallTailorBOD )
|
||||
DeedType = BODType.Tailor;
|
||||
else if ( bod is SmallSmithBOD )
|
||||
DeedType = BODType.Smith;
|
||||
public BulkMaterialType Material{ get; }
|
||||
|
||||
Material = bod.Material;
|
||||
AmountCur = bod.AmountCur;
|
||||
AmountMax = bod.AmountMax;
|
||||
Number = bod.Number;
|
||||
Graphic = bod.Graphic;
|
||||
}
|
||||
public int AmountCur{ get; }
|
||||
|
||||
public BOBSmallEntry( GenericReader reader )
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
public int AmountMax{ get; }
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
string type = reader.ReadString();
|
||||
public int Number{ get; }
|
||||
|
||||
if ( type != null )
|
||||
ItemType = ScriptCompiler.FindTypeByFullName( type );
|
||||
public int Graphic{ get; }
|
||||
|
||||
RequireExceptional = reader.ReadBool();
|
||||
public int Price{ get; set; }
|
||||
|
||||
DeedType = (BODType)reader.ReadEncodedInt();
|
||||
public Item Reconstruct()
|
||||
{
|
||||
SmallBOD bod = null;
|
||||
|
||||
Material = (BulkMaterialType)reader.ReadEncodedInt();
|
||||
AmountCur = reader.ReadEncodedInt();
|
||||
AmountMax = reader.ReadEncodedInt();
|
||||
Number = reader.ReadEncodedInt();
|
||||
Graphic = reader.ReadEncodedInt();
|
||||
Price = reader.ReadEncodedInt();
|
||||
if (DeedType == BODType.Smith)
|
||||
bod = new SmallSmithBOD(AmountCur, AmountMax, ItemType, Number, Graphic, RequireExceptional, Material);
|
||||
else if (DeedType == BODType.Tailor)
|
||||
bod = new SmallTailorBOD(AmountCur, AmountMax, ItemType, Number, Graphic, RequireExceptional, Material);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bod;
|
||||
}
|
||||
|
||||
public void Serialize( GenericWriter writer )
|
||||
{
|
||||
writer.WriteEncodedInt( 0 ); // version
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write( ItemType == null ? null : ItemType.FullName );
|
||||
writer.Write(ItemType == null ? null : ItemType.FullName);
|
||||
|
||||
writer.Write( (bool) RequireExceptional );
|
||||
writer.Write(RequireExceptional);
|
||||
|
||||
writer.WriteEncodedInt( (int) DeedType );
|
||||
writer.WriteEncodedInt( (int) Material );
|
||||
writer.WriteEncodedInt( (int) AmountCur );
|
||||
writer.WriteEncodedInt( (int) AmountMax );
|
||||
writer.WriteEncodedInt( (int) Number );
|
||||
writer.WriteEncodedInt( (int) Graphic );
|
||||
writer.WriteEncodedInt( (int) Price );
|
||||
}
|
||||
}
|
||||
writer.WriteEncodedInt((int)DeedType);
|
||||
writer.WriteEncodedInt((int)Material);
|
||||
writer.WriteEncodedInt(AmountCur);
|
||||
writer.WriteEncodedInt(AmountMax);
|
||||
writer.WriteEncodedInt(Number);
|
||||
writer.WriteEncodedInt(Graphic);
|
||||
writer.WriteEncodedInt(Price);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,136 +1,140 @@
|
|||
using Server.Items;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class BODBuyGump : Gump
|
||||
{
|
||||
private PlayerMobile m_From;
|
||||
private BulkOrderBook m_Book;
|
||||
private object m_Object;
|
||||
private int m_Price;
|
||||
private int m_Page;
|
||||
public class BODBuyGump : Gump
|
||||
{
|
||||
private BulkOrderBook m_Book;
|
||||
private PlayerMobile m_From;
|
||||
private object m_Object;
|
||||
private int m_Page;
|
||||
private int m_Price;
|
||||
|
||||
public override void OnResponse( Network.NetState sender, RelayInfo info )
|
||||
{
|
||||
if ( info.ButtonID == 2 )
|
||||
{
|
||||
PlayerVendor pv = m_Book.RootParent as PlayerVendor;
|
||||
public BODBuyGump(PlayerMobile from, BulkOrderBook book, object obj, int page, int price) : base(100, 200)
|
||||
{
|
||||
m_From = from;
|
||||
m_Book = book;
|
||||
m_Object = obj;
|
||||
m_Price = price;
|
||||
m_Page = page;
|
||||
|
||||
if ( m_Book.Entries.Contains( m_Object ) && pv != null )
|
||||
{
|
||||
int price = 0;
|
||||
AddPage(0);
|
||||
|
||||
VendorItem vi = pv.GetVendorItem( m_Book );
|
||||
AddBackground(100, 10, 300, 150, 5054);
|
||||
|
||||
if ( vi != null && !vi.IsForSale )
|
||||
{
|
||||
if ( m_Object is BOBLargeEntry entry )
|
||||
price = entry.Price;
|
||||
else
|
||||
price = ((BOBSmallEntry)m_Object).Price;
|
||||
}
|
||||
AddHtmlLocalized(125, 20, 250, 24, 1019070, false, false); // You have agreed to purchase:
|
||||
AddHtmlLocalized(125, 45, 250, 24, 1045151, false, false); // a bulk order deed
|
||||
|
||||
if ( price != m_Price )
|
||||
{
|
||||
pv.SayTo( m_From, "The price has been been changed. If you like, you may offer to purchase the item again." );
|
||||
}
|
||||
else if ( price == 0 )
|
||||
{
|
||||
pv.SayTo( m_From, 1062382 ); // The deed selected is not available.
|
||||
}
|
||||
else
|
||||
{
|
||||
Item item = null;
|
||||
AddHtmlLocalized(125, 70, 250, 24, 1019071, false, false); // for the amount of:
|
||||
AddLabel(125, 95, 0, price.ToString());
|
||||
|
||||
if ( m_Object is BOBLargeEntry entry )
|
||||
item = entry.Reconstruct();
|
||||
else
|
||||
item = ((BOBSmallEntry)m_Object).Reconstruct();
|
||||
AddButton(250, 130, 4005, 4007, 1, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(282, 130, 100, 24, 1011012, false, false); // CANCEL
|
||||
|
||||
if ( item == null )
|
||||
{
|
||||
m_From.SendMessage( "Internal error. The bulk order deed could not be reconstructed." );
|
||||
}
|
||||
else
|
||||
{
|
||||
pv.Say( m_From.Name );
|
||||
AddButton(120, 130, 4005, 4007, 2, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(152, 130, 100, 24, 1011036, false, false); // OKAY
|
||||
}
|
||||
|
||||
Container pack = m_From.Backpack;
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 2)
|
||||
{
|
||||
PlayerVendor pv = m_Book.RootParent as PlayerVendor;
|
||||
|
||||
if ( (pack == null) || ((pack != null) && (!pack.CheckHold(m_From, item, true, true, 0, item.PileWeight + item.TotalWeight)) ) )
|
||||
{
|
||||
pv.SayTo(m_From, 503204); // You do not have room in your backpack for this
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((pack != null && pack.ConsumeTotal( typeof( Gold ), price )) || Banker.Withdraw( m_From, price ) )
|
||||
{
|
||||
m_Book.Entries.Remove( m_Object );
|
||||
m_Book.InvalidateProperties();
|
||||
pv.HoldGold += price;
|
||||
m_From.AddToBackpack( item );
|
||||
m_From.SendLocalizedMessage( 1045152 ); // The bulk order deed has been placed in your backpack.
|
||||
if (m_Book.Entries.Contains(m_Object) && pv != null)
|
||||
{
|
||||
int price = 0;
|
||||
|
||||
if ( m_Book.Entries.Count / 5 < m_Book.ItemCount )
|
||||
{
|
||||
m_Book.ItemCount--;
|
||||
m_Book.InvalidateItems();
|
||||
}
|
||||
VendorItem vi = pv.GetVendorItem(m_Book);
|
||||
|
||||
if ( m_Book.Entries.Count > 0 )
|
||||
m_From.SendGump( new BOBGump( m_From, m_Book, m_Page, null ) );
|
||||
else
|
||||
m_From.SendLocalizedMessage( 1062381 ); // The book is empty.
|
||||
}
|
||||
else
|
||||
{
|
||||
pv.SayTo( m_From, 503205 ); // You cannot afford this item.
|
||||
item.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pv == null )
|
||||
m_From.SendLocalizedMessage( 1062382 ); // The deed selected is not available.
|
||||
else
|
||||
pv.SayTo( m_From, 1062382 ); // The deed selected is not available.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendLocalizedMessage( 503207 ); // Cancelled purchase.
|
||||
}
|
||||
}
|
||||
if (vi != null && !vi.IsForSale)
|
||||
{
|
||||
if (m_Object is BOBLargeEntry entry)
|
||||
price = entry.Price;
|
||||
else
|
||||
price = ((BOBSmallEntry)m_Object).Price;
|
||||
}
|
||||
|
||||
public BODBuyGump( PlayerMobile from, BulkOrderBook book, object obj, int page, int price ) : base( 100, 200 )
|
||||
{
|
||||
m_From = from;
|
||||
m_Book = book;
|
||||
m_Object = obj;
|
||||
m_Price = price;
|
||||
m_Page = page;
|
||||
if (price != m_Price)
|
||||
{
|
||||
pv.SayTo(m_From,
|
||||
"The price has been been changed. If you like, you may offer to purchase the item again.");
|
||||
}
|
||||
else if (price == 0)
|
||||
{
|
||||
pv.SayTo(m_From, 1062382); // The deed selected is not available.
|
||||
}
|
||||
else
|
||||
{
|
||||
Item item = null;
|
||||
|
||||
AddPage( 0 );
|
||||
if (m_Object is BOBLargeEntry entry)
|
||||
item = entry.Reconstruct();
|
||||
else
|
||||
item = ((BOBSmallEntry)m_Object).Reconstruct();
|
||||
|
||||
AddBackground( 100, 10, 300, 150, 5054 );
|
||||
if (item == null)
|
||||
{
|
||||
m_From.SendMessage("Internal error. The bulk order deed could not be reconstructed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
pv.Say(m_From.Name);
|
||||
|
||||
AddHtmlLocalized( 125, 20, 250, 24, 1019070, false, false ); // You have agreed to purchase:
|
||||
AddHtmlLocalized( 125, 45, 250, 24, 1045151, false, false ); // a bulk order deed
|
||||
Container pack = m_From.Backpack;
|
||||
|
||||
AddHtmlLocalized( 125, 70, 250, 24, 1019071, false, false ); // for the amount of:
|
||||
AddLabel( 125, 95, 0, price.ToString() );
|
||||
if (pack == null || pack != null && !pack.CheckHold(m_From, item, true, true, 0,
|
||||
item.PileWeight + item.TotalWeight))
|
||||
{
|
||||
pv.SayTo(m_From, 503204); // You do not have room in your backpack for this
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pack != null && pack.ConsumeTotal(typeof(Gold), price) || Banker.Withdraw(m_From, price))
|
||||
{
|
||||
m_Book.Entries.Remove(m_Object);
|
||||
m_Book.InvalidateProperties();
|
||||
pv.HoldGold += price;
|
||||
m_From.AddToBackpack(item);
|
||||
m_From.SendLocalizedMessage(
|
||||
1045152); // The bulk order deed has been placed in your backpack.
|
||||
|
||||
AddButton( 250, 130, 4005, 4007, 1, GumpButtonType.Reply, 0 );
|
||||
AddHtmlLocalized( 282, 130, 100, 24, 1011012, false, false ); // CANCEL
|
||||
if (m_Book.Entries.Count / 5 < m_Book.ItemCount)
|
||||
{
|
||||
m_Book.ItemCount--;
|
||||
m_Book.InvalidateItems();
|
||||
}
|
||||
|
||||
AddButton( 120, 130, 4005, 4007, 2, GumpButtonType.Reply, 0 );
|
||||
AddHtmlLocalized( 152, 130, 100, 24, 1011036, false, false ); // OKAY
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_Book.Entries.Count > 0)
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page, null));
|
||||
else
|
||||
m_From.SendLocalizedMessage(1062381); // The book is empty.
|
||||
}
|
||||
else
|
||||
{
|
||||
pv.SayTo(m_From, 503205); // You cannot afford this item.
|
||||
item.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pv == null)
|
||||
m_From.SendLocalizedMessage(1062382); // The deed selected is not available.
|
||||
else
|
||||
pv.SayTo(m_From, 1062382); // The deed selected is not available.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendLocalizedMessage(503207); // Cancelled purchase.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public enum BODType
|
||||
{
|
||||
Smith,
|
||||
Tailor
|
||||
}
|
||||
public enum BODType
|
||||
{
|
||||
Smith,
|
||||
Tailor
|
||||
}
|
||||
}
|
||||
|
|
@ -3,42 +3,42 @@ using Server.Items;
|
|||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public enum BulkMaterialType
|
||||
{
|
||||
None,
|
||||
DullCopper,
|
||||
ShadowIron,
|
||||
Copper,
|
||||
Bronze,
|
||||
Gold,
|
||||
Agapite,
|
||||
Verite,
|
||||
Valorite,
|
||||
Spined,
|
||||
Horned,
|
||||
Barbed
|
||||
}
|
||||
public enum BulkMaterialType
|
||||
{
|
||||
None,
|
||||
DullCopper,
|
||||
ShadowIron,
|
||||
Copper,
|
||||
Bronze,
|
||||
Gold,
|
||||
Agapite,
|
||||
Verite,
|
||||
Valorite,
|
||||
Spined,
|
||||
Horned,
|
||||
Barbed
|
||||
}
|
||||
|
||||
public enum BulkGenericType
|
||||
{
|
||||
Iron,
|
||||
Cloth,
|
||||
Leather
|
||||
}
|
||||
public enum BulkGenericType
|
||||
{
|
||||
Iron,
|
||||
Cloth,
|
||||
Leather
|
||||
}
|
||||
|
||||
public class BGTClassifier
|
||||
{
|
||||
public static BulkGenericType Classify( BODType deedType, Type itemType )
|
||||
{
|
||||
if ( deedType == BODType.Tailor )
|
||||
{
|
||||
if ( itemType == null || itemType.IsSubclassOf( typeof( BaseArmor ) ) || itemType.IsSubclassOf( typeof( BaseShoes ) ) )
|
||||
return BulkGenericType.Leather;
|
||||
public class BGTClassifier
|
||||
{
|
||||
public static BulkGenericType Classify(BODType deedType, Type itemType)
|
||||
{
|
||||
if (deedType == BODType.Tailor)
|
||||
{
|
||||
if (itemType == null || itemType.IsSubclassOf(typeof(BaseArmor)) || itemType.IsSubclassOf(typeof(BaseShoes)))
|
||||
return BulkGenericType.Leather;
|
||||
|
||||
return BulkGenericType.Cloth;
|
||||
}
|
||||
return BulkGenericType.Cloth;
|
||||
}
|
||||
|
||||
return BulkGenericType.Iron;
|
||||
}
|
||||
}
|
||||
return BulkGenericType.Iron;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,102 +3,105 @@ using Server.Network;
|
|||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class LargeBODAcceptGump : Gump
|
||||
{
|
||||
private LargeBOD m_Deed;
|
||||
private Mobile m_From;
|
||||
public class LargeBODAcceptGump : Gump
|
||||
{
|
||||
private LargeBOD m_Deed;
|
||||
private Mobile m_From;
|
||||
|
||||
public LargeBODAcceptGump( Mobile from, LargeBOD deed ) : base( 50, 50 )
|
||||
{
|
||||
m_From = from;
|
||||
m_Deed = deed;
|
||||
public LargeBODAcceptGump(Mobile from, LargeBOD deed) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Deed = deed;
|
||||
|
||||
m_From.CloseGump( typeof( LargeBODAcceptGump ) );
|
||||
m_From.CloseGump( typeof( SmallBODAcceptGump ) );
|
||||
m_From.CloseGump(typeof(LargeBODAcceptGump));
|
||||
m_From.CloseGump(typeof(SmallBODAcceptGump));
|
||||
|
||||
LargeBulkEntry[] entries = deed.Entries;
|
||||
LargeBulkEntry[] entries = deed.Entries;
|
||||
|
||||
AddPage( 0 );
|
||||
AddPage(0);
|
||||
|
||||
AddBackground( 25, 10, 430, 240 + (entries.Length * 24), 5054 );
|
||||
AddBackground(25, 10, 430, 240 + entries.Length * 24, 5054);
|
||||
|
||||
AddImageTiled( 33, 20, 413, 221 + (entries.Length * 24), 2624 );
|
||||
AddAlphaRegion( 33, 20, 413, 221 + (entries.Length * 24) );
|
||||
AddImageTiled(33, 20, 413, 221 + entries.Length * 24, 2624);
|
||||
AddAlphaRegion(33, 20, 413, 221 + entries.Length * 24);
|
||||
|
||||
AddImage( 20, 5, 10460 );
|
||||
AddImage( 430, 5, 10460 );
|
||||
AddImage( 20, 225 + (entries.Length * 24), 10460 );
|
||||
AddImage( 430, 225 + (entries.Length * 24), 10460 );
|
||||
AddImage(20, 5, 10460);
|
||||
AddImage(430, 5, 10460);
|
||||
AddImage(20, 225 + entries.Length * 24, 10460);
|
||||
AddImage(430, 225 + entries.Length * 24, 10460);
|
||||
|
||||
AddHtmlLocalized( 180, 25, 120, 20, 1045134, 0x7FFF, false, false ); // A large bulk order
|
||||
AddHtmlLocalized(180, 25, 120, 20, 1045134, 0x7FFF, false, false); // A large bulk order
|
||||
|
||||
AddHtmlLocalized( 40, 48, 350, 20, 1045135, 0x7FFF, false, false ); // Ah! Thanks for the goods! Would you help me out?
|
||||
AddHtmlLocalized(40, 48, 350, 20, 1045135, 0x7FFF, false,
|
||||
false); // Ah! Thanks for the goods! Would you help me out?
|
||||
|
||||
AddHtmlLocalized( 40, 72, 210, 20, 1045138, 0x7FFF, false, false ); // Amount to make:
|
||||
AddLabel( 250, 72, 1152, deed.AmountMax.ToString() );
|
||||
AddHtmlLocalized(40, 72, 210, 20, 1045138, 0x7FFF, false, false); // Amount to make:
|
||||
AddLabel(250, 72, 1152, deed.AmountMax.ToString());
|
||||
|
||||
AddHtmlLocalized( 40, 96, 120, 20, 1045137, 0x7FFF, false, false ); // Items requested:
|
||||
AddHtmlLocalized(40, 96, 120, 20, 1045137, 0x7FFF, false, false); // Items requested:
|
||||
|
||||
int y = 120;
|
||||
int y = 120;
|
||||
|
||||
for ( int i = 0; i < entries.Length; ++i, y += 24 )
|
||||
AddHtmlLocalized( 40, y, 210, 20, entries[i].Details.Number, 0x7FFF, false, false );
|
||||
for (int i = 0; i < entries.Length; ++i, y += 24)
|
||||
AddHtmlLocalized(40, y, 210, 20, entries[i].Details.Number, 0x7FFF, false, false);
|
||||
|
||||
if ( deed.RequireExceptional || deed.Material != BulkMaterialType.None )
|
||||
{
|
||||
AddHtmlLocalized( 40, y, 210, 20, 1045140, 0x7FFF, false, false ); // Special requirements to meet:
|
||||
y += 24;
|
||||
if (deed.RequireExceptional || deed.Material != BulkMaterialType.None)
|
||||
{
|
||||
AddHtmlLocalized(40, y, 210, 20, 1045140, 0x7FFF, false, false); // Special requirements to meet:
|
||||
y += 24;
|
||||
|
||||
if ( deed.RequireExceptional )
|
||||
{
|
||||
AddHtmlLocalized( 40, y, 350, 20, 1045141, 0x7FFF, false, false ); // All items must be exceptional.
|
||||
y += 24;
|
||||
}
|
||||
if (deed.RequireExceptional)
|
||||
{
|
||||
AddHtmlLocalized(40, y, 350, 20, 1045141, 0x7FFF, false, false); // All items must be exceptional.
|
||||
y += 24;
|
||||
}
|
||||
|
||||
if ( deed.Material != BulkMaterialType.None )
|
||||
{
|
||||
AddHtmlLocalized( 40, y, 350, 20, GetMaterialNumberFor( deed.Material ), 0x7FFF, false, false ); // All items must be made with x material.
|
||||
y += 24;
|
||||
}
|
||||
}
|
||||
if (deed.Material != BulkMaterialType.None)
|
||||
{
|
||||
AddHtmlLocalized(40, y, 350, 20, GetMaterialNumberFor(deed.Material), 0x7FFF, false,
|
||||
false); // All items must be made with x material.
|
||||
y += 24;
|
||||
}
|
||||
}
|
||||
|
||||
AddHtmlLocalized( 40, 192 + (entries.Length * 24), 350, 20, 1045139, 0x7FFF, false, false ); // Do you want to accept this order?
|
||||
AddHtmlLocalized(40, 192 + entries.Length * 24, 350, 20, 1045139, 0x7FFF, false,
|
||||
false); // Do you want to accept this order?
|
||||
|
||||
AddButton( 100, 216 + (entries.Length * 24), 4005, 4007, 1, GumpButtonType.Reply, 0 );
|
||||
AddHtmlLocalized( 135, 216 + (entries.Length * 24), 120, 20, 1006044, 0x7FFF, false, false ); // Ok
|
||||
AddButton(100, 216 + entries.Length * 24, 4005, 4007, 1, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(135, 216 + entries.Length * 24, 120, 20, 1006044, 0x7FFF, false, false); // Ok
|
||||
|
||||
AddButton( 275, 216 + (entries.Length * 24), 4005, 4007, 0, GumpButtonType.Reply, 0 );
|
||||
AddHtmlLocalized( 310, 216 + (entries.Length * 24), 120, 20, 1011012, 0x7FFF, false, false ); // CANCEL
|
||||
}
|
||||
AddButton(275, 216 + entries.Length * 24, 4005, 4007, 0, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(310, 216 + entries.Length * 24, 120, 20, 1011012, 0x7FFF, false, false); // CANCEL
|
||||
}
|
||||
|
||||
public override void OnResponse( NetState sender, RelayInfo info )
|
||||
{
|
||||
if ( info.ButtonID == 1 ) // Ok
|
||||
{
|
||||
if ( m_From.PlaceInBackpack( m_Deed ) )
|
||||
{
|
||||
m_From.SendLocalizedMessage( 1045152 ); // The bulk order deed has been placed in your backpack.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendLocalizedMessage( 1045150 ); // There is not enough room in your backpack for the deed.
|
||||
m_Deed.Delete();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Deed.Delete();
|
||||
}
|
||||
}
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 1) // Ok
|
||||
{
|
||||
if (m_From.PlaceInBackpack(m_Deed))
|
||||
{
|
||||
m_From.SendLocalizedMessage(1045152); // The bulk order deed has been placed in your backpack.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendLocalizedMessage(1045150); // There is not enough room in your backpack for the deed.
|
||||
m_Deed.Delete();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Deed.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetMaterialNumberFor( BulkMaterialType material )
|
||||
{
|
||||
if ( material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite )
|
||||
return 1045142 + (int)(material - BulkMaterialType.DullCopper);
|
||||
if ( material >= BulkMaterialType.Spined && material <= BulkMaterialType.Barbed )
|
||||
return 1049348 + (int)(material - BulkMaterialType.Spined);
|
||||
public static int GetMaterialNumberFor(BulkMaterialType material)
|
||||
{
|
||||
if (material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite)
|
||||
return 1045142 + (material - BulkMaterialType.DullCopper);
|
||||
if (material >= BulkMaterialType.Spined && material <= BulkMaterialType.Barbed)
|
||||
return 1049348 + (material - BulkMaterialType.Spined);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,96 +3,98 @@ using Server.Network;
|
|||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class LargeBODGump : Gump
|
||||
{
|
||||
private LargeBOD m_Deed;
|
||||
private Mobile m_From;
|
||||
public class LargeBODGump : Gump
|
||||
{
|
||||
private LargeBOD m_Deed;
|
||||
private Mobile m_From;
|
||||
|
||||
public LargeBODGump( Mobile from, LargeBOD deed ) : base( 25, 25 )
|
||||
{
|
||||
m_From = from;
|
||||
m_Deed = deed;
|
||||
public LargeBODGump(Mobile from, LargeBOD deed) : base(25, 25)
|
||||
{
|
||||
m_From = from;
|
||||
m_Deed = deed;
|
||||
|
||||
m_From.CloseGump( typeof( LargeBODGump ) );
|
||||
m_From.CloseGump( typeof( SmallBODGump ) );
|
||||
m_From.CloseGump(typeof(LargeBODGump));
|
||||
m_From.CloseGump(typeof(SmallBODGump));
|
||||
|
||||
LargeBulkEntry[] entries = deed.Entries;
|
||||
LargeBulkEntry[] entries = deed.Entries;
|
||||
|
||||
AddPage( 0 );
|
||||
AddPage(0);
|
||||
|
||||
AddBackground( 50, 10, 455, 236 + (entries.Length * 24), 5054 );
|
||||
AddBackground(50, 10, 455, 236 + entries.Length * 24, 5054);
|
||||
|
||||
AddImageTiled( 58, 20, 438, 217 + (entries.Length * 24), 2624 );
|
||||
AddAlphaRegion( 58, 20, 438, 217 + (entries.Length * 24) );
|
||||
AddImageTiled(58, 20, 438, 217 + entries.Length * 24, 2624);
|
||||
AddAlphaRegion(58, 20, 438, 217 + entries.Length * 24);
|
||||
|
||||
AddImage( 45, 5, 10460 );
|
||||
AddImage( 480, 5, 10460 );
|
||||
AddImage( 45, 221 + (entries.Length * 24), 10460 );
|
||||
AddImage( 480, 221 + (entries.Length * 24), 10460 );
|
||||
AddImage(45, 5, 10460);
|
||||
AddImage(480, 5, 10460);
|
||||
AddImage(45, 221 + entries.Length * 24, 10460);
|
||||
AddImage(480, 221 + entries.Length * 24, 10460);
|
||||
|
||||
AddHtmlLocalized( 225, 25, 120, 20, 1045134, 0x7FFF, false, false ); // A large bulk order
|
||||
AddHtmlLocalized(225, 25, 120, 20, 1045134, 0x7FFF, false, false); // A large bulk order
|
||||
|
||||
AddHtmlLocalized( 75, 48, 250, 20, 1045138, 0x7FFF, false, false ); // Amount to make:
|
||||
AddLabel( 275, 48, 1152, deed.AmountMax.ToString() );
|
||||
AddHtmlLocalized(75, 48, 250, 20, 1045138, 0x7FFF, false, false); // Amount to make:
|
||||
AddLabel(275, 48, 1152, deed.AmountMax.ToString());
|
||||
|
||||
AddHtmlLocalized( 75, 72, 120, 20, 1045137, 0x7FFF, false, false ); // Items requested:
|
||||
AddHtmlLocalized( 275, 76, 200, 20, 1045153, 0x7FFF, false, false ); // Amount finished:
|
||||
AddHtmlLocalized(75, 72, 120, 20, 1045137, 0x7FFF, false, false); // Items requested:
|
||||
AddHtmlLocalized(275, 76, 200, 20, 1045153, 0x7FFF, false, false); // Amount finished:
|
||||
|
||||
int y = 96;
|
||||
int y = 96;
|
||||
|
||||
for ( int i = 0; i < entries.Length; ++i )
|
||||
{
|
||||
LargeBulkEntry entry = entries[i];
|
||||
SmallBulkEntry details = entry.Details;
|
||||
for (int i = 0; i < entries.Length; ++i)
|
||||
{
|
||||
LargeBulkEntry entry = entries[i];
|
||||
SmallBulkEntry details = entry.Details;
|
||||
|
||||
AddHtmlLocalized( 75, y, 210, 20, details.Number, 0x7FFF, false, false );
|
||||
AddLabel( 275, y, 0x480, entry.Amount.ToString() );
|
||||
AddHtmlLocalized(75, y, 210, 20, details.Number, 0x7FFF, false, false);
|
||||
AddLabel(275, y, 0x480, entry.Amount.ToString());
|
||||
|
||||
y += 24;
|
||||
}
|
||||
y += 24;
|
||||
}
|
||||
|
||||
if ( deed.RequireExceptional || deed.Material != BulkMaterialType.None )
|
||||
{
|
||||
AddHtmlLocalized( 75, y, 200, 20, 1045140, 0x7FFF, false, false ); // Special requirements to meet:
|
||||
y += 24;
|
||||
}
|
||||
if (deed.RequireExceptional || deed.Material != BulkMaterialType.None)
|
||||
{
|
||||
AddHtmlLocalized(75, y, 200, 20, 1045140, 0x7FFF, false, false); // Special requirements to meet:
|
||||
y += 24;
|
||||
}
|
||||
|
||||
if ( deed.RequireExceptional )
|
||||
{
|
||||
AddHtmlLocalized( 75, y, 300, 20, 1045141, 0x7FFF, false, false ); // All items must be exceptional.
|
||||
y += 24;
|
||||
}
|
||||
if (deed.RequireExceptional)
|
||||
{
|
||||
AddHtmlLocalized(75, y, 300, 20, 1045141, 0x7FFF, false, false); // All items must be exceptional.
|
||||
y += 24;
|
||||
}
|
||||
|
||||
if ( deed.Material != BulkMaterialType.None )
|
||||
AddHtmlLocalized( 75, y, 300, 20, GetMaterialNumberFor( deed.Material ), 0x7FFF, false, false ); // All items must be made with x material.
|
||||
if (deed.Material != BulkMaterialType.None)
|
||||
AddHtmlLocalized(75, y, 300, 20, GetMaterialNumberFor(deed.Material), 0x7FFF, false,
|
||||
false); // All items must be made with x material.
|
||||
|
||||
AddButton( 125, 168 + (entries.Length * 24), 4005, 4007, 2, GumpButtonType.Reply, 0 );
|
||||
AddHtmlLocalized( 160, 168 + (entries.Length * 24), 300, 20, 1045155, 0x7FFF, false, false ); // Combine this deed with another deed.
|
||||
AddButton(125, 168 + entries.Length * 24, 4005, 4007, 2, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(160, 168 + entries.Length * 24, 300, 20, 1045155, 0x7FFF, false,
|
||||
false); // Combine this deed with another deed.
|
||||
|
||||
AddButton( 125, 192 + (entries.Length * 24), 4005, 4007, 1, GumpButtonType.Reply, 0 );
|
||||
AddHtmlLocalized( 160, 192 + (entries.Length * 24), 120, 20, 1011441, 0x7FFF, false, false ); // EXIT
|
||||
}
|
||||
AddButton(125, 192 + entries.Length * 24, 4005, 4007, 1, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(160, 192 + entries.Length * 24, 120, 20, 1011441, 0x7FFF, false, false); // EXIT
|
||||
}
|
||||
|
||||
public override void OnResponse( NetState sender, RelayInfo info )
|
||||
{
|
||||
if ( m_Deed.Deleted || !m_Deed.IsChildOf( m_From.Backpack ) )
|
||||
return;
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (m_Deed.Deleted || !m_Deed.IsChildOf(m_From.Backpack))
|
||||
return;
|
||||
|
||||
if ( info.ButtonID == 2 ) // Combine
|
||||
{
|
||||
m_From.SendGump( new LargeBODGump( m_From, m_Deed ) );
|
||||
m_Deed.BeginCombine( m_From );
|
||||
}
|
||||
}
|
||||
if (info.ButtonID == 2) // Combine
|
||||
{
|
||||
m_From.SendGump(new LargeBODGump(m_From, m_Deed));
|
||||
m_Deed.BeginCombine(m_From);
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetMaterialNumberFor( BulkMaterialType material )
|
||||
{
|
||||
if ( material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite )
|
||||
return 1045142 + (int)(material - BulkMaterialType.DullCopper);
|
||||
if ( material >= BulkMaterialType.Spined && material <= BulkMaterialType.Barbed )
|
||||
return 1049348 + (int)(material - BulkMaterialType.Spined);
|
||||
public static int GetMaterialNumberFor(BulkMaterialType material)
|
||||
{
|
||||
if (material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite)
|
||||
return 1045142 + (material - BulkMaterialType.DullCopper);
|
||||
if (material >= BulkMaterialType.Spined && material <= BulkMaterialType.Barbed)
|
||||
return 1049348 + (material - BulkMaterialType.Spined);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,21 +2,21 @@ using Server.Targeting;
|
|||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class LargeBODTarget : Target
|
||||
{
|
||||
private LargeBOD m_Deed;
|
||||
public class LargeBODTarget : Target
|
||||
{
|
||||
private LargeBOD m_Deed;
|
||||
|
||||
public LargeBODTarget( LargeBOD deed ) : base( 18, false, TargetFlags.None )
|
||||
{
|
||||
m_Deed = deed;
|
||||
}
|
||||
public LargeBODTarget(LargeBOD deed) : base(18, false, TargetFlags.None)
|
||||
{
|
||||
m_Deed = deed;
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object targeted )
|
||||
{
|
||||
if ( m_Deed.Deleted || !m_Deed.IsChildOf( from.Backpack ) )
|
||||
return;
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (m_Deed.Deleted || !m_Deed.IsChildOf(from.Backpack))
|
||||
return;
|
||||
|
||||
m_Deed.EndCombine( from, targeted );
|
||||
}
|
||||
}
|
||||
m_Deed.EndCombine(from, targeted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,132 +1,150 @@
|
|||
using Mat = Server.Engines.BulkOrders.BulkMaterialType;
|
||||
using System.Collections.Generic;
|
||||
using Mat = Server.Engines.BulkOrders.BulkMaterialType;
|
||||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
[TypeAlias( "Scripts.Engines.BulkOrders.LargeSmithBOD" )]
|
||||
public class LargeSmithBOD : LargeBOD
|
||||
{
|
||||
public static double[] m_BlacksmithMaterialChances = {
|
||||
0.501953125, // None
|
||||
0.250000000, // Dull Copper
|
||||
0.125000000, // Shadow Iron
|
||||
0.062500000, // Copper
|
||||
0.031250000, // Bronze
|
||||
0.015625000, // Gold
|
||||
0.007812500, // Agapite
|
||||
0.003906250, // Verite
|
||||
0.001953125 // Valorite
|
||||
};
|
||||
[TypeAlias("Scripts.Engines.BulkOrders.LargeSmithBOD")]
|
||||
public class LargeSmithBOD : LargeBOD
|
||||
{
|
||||
public static double[] m_BlacksmithMaterialChances =
|
||||
{
|
||||
0.501953125, // None
|
||||
0.250000000, // Dull Copper
|
||||
0.125000000, // Shadow Iron
|
||||
0.062500000, // Copper
|
||||
0.031250000, // Bronze
|
||||
0.015625000, // Gold
|
||||
0.007812500, // Agapite
|
||||
0.003906250, // Verite
|
||||
0.001953125 // Valorite
|
||||
};
|
||||
|
||||
public override int ComputeFame()
|
||||
{
|
||||
return SmithRewardCalculator.Instance.ComputeFame( this );
|
||||
}
|
||||
[Constructible]
|
||||
public LargeSmithBOD()
|
||||
{
|
||||
LargeBulkEntry[] entries;
|
||||
bool useMaterials = true;
|
||||
|
||||
public override int ComputeGold()
|
||||
{
|
||||
return SmithRewardCalculator.Instance.ComputeGold( this );
|
||||
}
|
||||
int rand = Utility.Random(8);
|
||||
|
||||
[Constructible]
|
||||
public LargeSmithBOD()
|
||||
{
|
||||
LargeBulkEntry[] entries;
|
||||
bool useMaterials = true;
|
||||
switch (rand)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.LargeRing);
|
||||
break;
|
||||
case 1:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.LargePlate);
|
||||
break;
|
||||
case 2:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.LargeChain);
|
||||
break;
|
||||
case 3:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.LargeAxes);
|
||||
break;
|
||||
case 4:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.LargeFencing);
|
||||
break;
|
||||
case 5:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.LargeMaces);
|
||||
break;
|
||||
case 6:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.LargePolearms);
|
||||
break;
|
||||
case 7:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.LargeSwords);
|
||||
break;
|
||||
}
|
||||
|
||||
int rand = Utility.Random( 8 );
|
||||
if (rand > 2 && rand < 8)
|
||||
useMaterials = false;
|
||||
|
||||
switch ( rand )
|
||||
{
|
||||
default:
|
||||
case 0: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeRing ); break;
|
||||
case 1: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargePlate ); break;
|
||||
case 2: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeChain ); break;
|
||||
case 3: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeAxes ); break;
|
||||
case 4: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeFencing ); break;
|
||||
case 5: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeMaces ); break;
|
||||
case 6: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargePolearms ); break;
|
||||
case 7: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeSwords ); break;
|
||||
}
|
||||
int hue = 0x44E;
|
||||
int amountMax = Utility.RandomList(10, 15, 20, 20);
|
||||
bool reqExceptional = 0.825 > Utility.RandomDouble();
|
||||
|
||||
if ( rand > 2 && rand < 8 )
|
||||
useMaterials = false;
|
||||
BulkMaterialType material;
|
||||
|
||||
int hue = 0x44E;
|
||||
int amountMax = Utility.RandomList( 10, 15, 20, 20 );
|
||||
bool reqExceptional = ( 0.825 > Utility.RandomDouble() );
|
||||
if (useMaterials)
|
||||
material = GetRandomMaterial(BulkMaterialType.DullCopper, m_BlacksmithMaterialChances);
|
||||
else
|
||||
material = BulkMaterialType.None;
|
||||
|
||||
BulkMaterialType material;
|
||||
Hue = hue;
|
||||
AmountMax = amountMax;
|
||||
Entries = entries;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = material;
|
||||
}
|
||||
|
||||
if ( useMaterials )
|
||||
material = GetRandomMaterial( BulkMaterialType.DullCopper, m_BlacksmithMaterialChances );
|
||||
else
|
||||
material = BulkMaterialType.None;
|
||||
public LargeSmithBOD(int amountMax, bool reqExceptional, BulkMaterialType mat, LargeBulkEntry[] entries)
|
||||
{
|
||||
Hue = 0x44E;
|
||||
AmountMax = amountMax;
|
||||
Entries = entries;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = mat;
|
||||
}
|
||||
|
||||
Hue = hue;
|
||||
AmountMax = amountMax;
|
||||
Entries = entries;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = material;
|
||||
}
|
||||
public LargeSmithBOD(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public LargeSmithBOD( int amountMax, bool reqExceptional, BulkMaterialType mat, LargeBulkEntry[] entries )
|
||||
{
|
||||
Hue = 0x44E;
|
||||
AmountMax = amountMax;
|
||||
Entries = entries;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = mat;
|
||||
}
|
||||
public override int ComputeFame()
|
||||
{
|
||||
return SmithRewardCalculator.Instance.ComputeFame(this);
|
||||
}
|
||||
|
||||
public override List<Item> ComputeRewards( bool full )
|
||||
{
|
||||
List<Item> list = new List<Item>();
|
||||
public override int ComputeGold()
|
||||
{
|
||||
return SmithRewardCalculator.Instance.ComputeGold(this);
|
||||
}
|
||||
|
||||
RewardGroup rewardGroup = SmithRewardCalculator.Instance.LookupRewards( SmithRewardCalculator.Instance.ComputePoints( this ) );
|
||||
public override List<Item> ComputeRewards(bool full)
|
||||
{
|
||||
List<Item> list = new List<Item>();
|
||||
|
||||
if ( rewardGroup != null )
|
||||
{
|
||||
if ( full )
|
||||
{
|
||||
for ( int i = 0; i < rewardGroup.Items.Length; ++i )
|
||||
{
|
||||
Item item = rewardGroup.Items[i].Construct();
|
||||
RewardGroup rewardGroup =
|
||||
SmithRewardCalculator.Instance.LookupRewards(SmithRewardCalculator.Instance.ComputePoints(this));
|
||||
|
||||
if ( item != null )
|
||||
list.Add( item );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RewardItem rewardItem = rewardGroup.AcquireItem();
|
||||
if (rewardGroup != null)
|
||||
{
|
||||
if (full)
|
||||
{
|
||||
for (int i = 0; i < rewardGroup.Items.Length; ++i)
|
||||
{
|
||||
Item item = rewardGroup.Items[i].Construct();
|
||||
|
||||
Item item = rewardItem?.Construct();
|
||||
if (item != null)
|
||||
list.Add(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RewardItem rewardItem = rewardGroup.AcquireItem();
|
||||
|
||||
if ( item != null )
|
||||
list.Add( item );
|
||||
}
|
||||
}
|
||||
Item item = rewardItem?.Construct();
|
||||
|
||||
return list;
|
||||
}
|
||||
if (item != null)
|
||||
list.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public LargeSmithBOD( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,127 +1,162 @@
|
|||
using Mat = Server.Engines.BulkOrders.BulkMaterialType;
|
||||
using System.Collections.Generic;
|
||||
using Mat = Server.Engines.BulkOrders.BulkMaterialType;
|
||||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class LargeTailorBOD : LargeBOD
|
||||
{
|
||||
public static double[] m_TailoringMaterialChances = {
|
||||
0.857421875, // None
|
||||
0.125000000, // Spined
|
||||
0.015625000, // Horned
|
||||
0.001953125 // Barbed
|
||||
};
|
||||
public class LargeTailorBOD : LargeBOD
|
||||
{
|
||||
public static double[] m_TailoringMaterialChances =
|
||||
{
|
||||
0.857421875, // None
|
||||
0.125000000, // Spined
|
||||
0.015625000, // Horned
|
||||
0.001953125 // Barbed
|
||||
};
|
||||
|
||||
public override int ComputeFame()
|
||||
{
|
||||
return TailorRewardCalculator.Instance.ComputeFame( this );
|
||||
}
|
||||
[Constructible]
|
||||
public LargeTailorBOD()
|
||||
{
|
||||
LargeBulkEntry[] entries;
|
||||
bool useMaterials = false;
|
||||
|
||||
public override int ComputeGold()
|
||||
{
|
||||
return TailorRewardCalculator.Instance.ComputeGold( this );
|
||||
}
|
||||
switch (Utility.Random(14))
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.Farmer);
|
||||
break;
|
||||
case 1:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.FemaleLeatherSet);
|
||||
useMaterials = true;
|
||||
break;
|
||||
case 2:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.FisherGirl);
|
||||
break;
|
||||
case 3:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.Gypsy);
|
||||
break;
|
||||
case 4:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.HatSet);
|
||||
break;
|
||||
case 5:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.Jester);
|
||||
break;
|
||||
case 6:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.Lady);
|
||||
break;
|
||||
case 7:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.MaleLeatherSet);
|
||||
useMaterials = true;
|
||||
break;
|
||||
case 8:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.Pirate);
|
||||
break;
|
||||
case 9:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.ShoeSet);
|
||||
useMaterials = Core.ML;
|
||||
break;
|
||||
case 10:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.StuddedSet);
|
||||
useMaterials = true;
|
||||
break;
|
||||
case 11:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.TownCrier);
|
||||
break;
|
||||
case 12:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.Wizard);
|
||||
break;
|
||||
case 13:
|
||||
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.BoneSet);
|
||||
useMaterials = true;
|
||||
break;
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public LargeTailorBOD()
|
||||
{
|
||||
LargeBulkEntry[] entries;
|
||||
bool useMaterials = false;
|
||||
int hue = 0x483;
|
||||
int amountMax = Utility.RandomList(10, 15, 20, 20);
|
||||
bool reqExceptional = 0.825 > Utility.RandomDouble();
|
||||
|
||||
switch ( Utility.Random( 14 ) )
|
||||
{
|
||||
default:
|
||||
case 0: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.Farmer ); break;
|
||||
case 1: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.FemaleLeatherSet ); useMaterials = true; break;
|
||||
case 2: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.FisherGirl ); break;
|
||||
case 3: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.Gypsy ); break;
|
||||
case 4: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.HatSet ); break;
|
||||
case 5: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.Jester ); break;
|
||||
case 6: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.Lady ); break;
|
||||
case 7: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.MaleLeatherSet ); useMaterials = true; break;
|
||||
case 8: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.Pirate ); break;
|
||||
case 9: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.ShoeSet ); useMaterials = Core.ML; break;
|
||||
case 10: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.StuddedSet ); useMaterials = true; break;
|
||||
case 11: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.TownCrier ); break;
|
||||
case 12: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.Wizard ); break;
|
||||
case 13: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.BoneSet ); useMaterials = true; break;
|
||||
}
|
||||
BulkMaterialType material;
|
||||
|
||||
int hue = 0x483;
|
||||
int amountMax = Utility.RandomList( 10, 15, 20, 20 );
|
||||
bool reqExceptional = ( 0.825 > Utility.RandomDouble() );
|
||||
if (useMaterials)
|
||||
material = GetRandomMaterial(BulkMaterialType.Spined, m_TailoringMaterialChances);
|
||||
else
|
||||
material = BulkMaterialType.None;
|
||||
|
||||
BulkMaterialType material;
|
||||
Hue = hue;
|
||||
AmountMax = amountMax;
|
||||
Entries = entries;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = material;
|
||||
}
|
||||
|
||||
if ( useMaterials )
|
||||
material = GetRandomMaterial( BulkMaterialType.Spined, m_TailoringMaterialChances );
|
||||
else
|
||||
material = BulkMaterialType.None;
|
||||
public LargeTailorBOD(int amountMax, bool reqExceptional, BulkMaterialType mat, LargeBulkEntry[] entries)
|
||||
{
|
||||
Hue = 0x483;
|
||||
AmountMax = amountMax;
|
||||
Entries = entries;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = mat;
|
||||
}
|
||||
|
||||
Hue = hue;
|
||||
AmountMax = amountMax;
|
||||
Entries = entries;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = material;
|
||||
}
|
||||
public LargeTailorBOD(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public LargeTailorBOD( int amountMax, bool reqExceptional, BulkMaterialType mat, LargeBulkEntry[] entries )
|
||||
{
|
||||
Hue = 0x483;
|
||||
AmountMax = amountMax;
|
||||
Entries = entries;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = mat;
|
||||
}
|
||||
public override int ComputeFame()
|
||||
{
|
||||
return TailorRewardCalculator.Instance.ComputeFame(this);
|
||||
}
|
||||
|
||||
public override List<Item> ComputeRewards( bool full )
|
||||
{
|
||||
List<Item> list = new List<Item>();
|
||||
public override int ComputeGold()
|
||||
{
|
||||
return TailorRewardCalculator.Instance.ComputeGold(this);
|
||||
}
|
||||
|
||||
RewardGroup rewardGroup = TailorRewardCalculator.Instance.LookupRewards( TailorRewardCalculator.Instance.ComputePoints( this ) );
|
||||
public override List<Item> ComputeRewards(bool full)
|
||||
{
|
||||
List<Item> list = new List<Item>();
|
||||
|
||||
if ( rewardGroup != null )
|
||||
{
|
||||
if ( full )
|
||||
{
|
||||
for ( int i = 0; i < rewardGroup.Items.Length; ++i )
|
||||
{
|
||||
Item item = rewardGroup.Items[i].Construct();
|
||||
RewardGroup rewardGroup =
|
||||
TailorRewardCalculator.Instance.LookupRewards(TailorRewardCalculator.Instance.ComputePoints(this));
|
||||
|
||||
if ( item != null )
|
||||
list.Add( item );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RewardItem rewardItem = rewardGroup.AcquireItem();
|
||||
if (rewardGroup != null)
|
||||
{
|
||||
if (full)
|
||||
{
|
||||
for (int i = 0; i < rewardGroup.Items.Length; ++i)
|
||||
{
|
||||
Item item = rewardGroup.Items[i].Construct();
|
||||
|
||||
Item item = rewardItem?.Construct();
|
||||
if (item != null)
|
||||
list.Add(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RewardItem rewardItem = rewardGroup.AcquireItem();
|
||||
|
||||
if ( item != null )
|
||||
list.Add( item );
|
||||
}
|
||||
}
|
||||
Item item = rewardItem?.Construct();
|
||||
|
||||
return list;
|
||||
}
|
||||
if (item != null)
|
||||
list.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public LargeTailorBOD( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,290 +1,329 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
[TypeAlias( "Scripts.Engines.BulkOrders.SmallBOD" )]
|
||||
public abstract class SmallBOD : Item
|
||||
{
|
||||
private int m_AmountCur, m_AmountMax;
|
||||
private int m_Number;
|
||||
private bool m_RequireExceptional;
|
||||
private BulkMaterialType m_Material;
|
||||
[TypeAlias("Scripts.Engines.BulkOrders.SmallBOD")]
|
||||
public abstract class SmallBOD : Item
|
||||
{
|
||||
private int m_AmountCur, m_AmountMax;
|
||||
private BulkMaterialType m_Material;
|
||||
private int m_Number;
|
||||
private bool m_RequireExceptional;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int AmountCur{ get => m_AmountCur;
|
||||
set{ m_AmountCur = value; InvalidateProperties(); } }
|
||||
[Constructible]
|
||||
public SmallBOD(int hue, int amountMax, Type type, int number, int graphic, bool requireExeptional,
|
||||
BulkMaterialType material) : base(Core.AOS ? 0x2258 : 0x14EF)
|
||||
{
|
||||
Weight = 1.0;
|
||||
Hue = hue; // Blacksmith: 0x44E; Tailoring: 0x483
|
||||
LootType = LootType.Blessed;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int AmountMax{ get => m_AmountMax;
|
||||
set{ m_AmountMax = value; InvalidateProperties(); } }
|
||||
m_AmountMax = amountMax;
|
||||
Type = type;
|
||||
m_Number = number;
|
||||
Graphic = graphic;
|
||||
m_RequireExceptional = requireExeptional;
|
||||
m_Material = material;
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Type Type { get; set; }
|
||||
public SmallBOD() : base(Core.AOS ? 0x2258 : 0x14EF)
|
||||
{
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Number{ get => m_Number;
|
||||
set{ m_Number = value; InvalidateProperties(); } }
|
||||
public SmallBOD(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Graphic { get; set; }
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int AmountCur
|
||||
{
|
||||
get => m_AmountCur;
|
||||
set
|
||||
{
|
||||
m_AmountCur = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool RequireExceptional{ get => m_RequireExceptional;
|
||||
set{ m_RequireExceptional = value; InvalidateProperties(); } }
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int AmountMax
|
||||
{
|
||||
get => m_AmountMax;
|
||||
set
|
||||
{
|
||||
m_AmountMax = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public BulkMaterialType Material{ get => m_Material;
|
||||
set{ m_Material = value; InvalidateProperties(); } }
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Type Type{ get; set; }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool Complete => ( m_AmountCur == m_AmountMax );
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Number
|
||||
{
|
||||
get => m_Number;
|
||||
set
|
||||
{
|
||||
m_Number = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1045151; // a bulk order deed
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Graphic{ get; set; }
|
||||
|
||||
[Constructible]
|
||||
public SmallBOD( int hue, int amountMax, Type type, int number, int graphic, bool requireExeptional, BulkMaterialType material ) : base( Core.AOS ? 0x2258 : 0x14EF )
|
||||
{
|
||||
Weight = 1.0;
|
||||
Hue = hue; // Blacksmith: 0x44E; Tailoring: 0x483
|
||||
LootType = LootType.Blessed;
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool RequireExceptional
|
||||
{
|
||||
get => m_RequireExceptional;
|
||||
set
|
||||
{
|
||||
m_RequireExceptional = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
m_AmountMax = amountMax;
|
||||
Type = type;
|
||||
m_Number = number;
|
||||
Graphic = graphic;
|
||||
m_RequireExceptional = requireExeptional;
|
||||
m_Material = material;
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public BulkMaterialType Material
|
||||
{
|
||||
get => m_Material;
|
||||
set
|
||||
{
|
||||
m_Material = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public SmallBOD() : base( Core.AOS ? 0x2258 : 0x14EF )
|
||||
{
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Complete => m_AmountCur == m_AmountMax;
|
||||
|
||||
public static BulkMaterialType GetRandomMaterial( BulkMaterialType start, double[] chances )
|
||||
{
|
||||
double random = Utility.RandomDouble();
|
||||
public override int LabelNumber => 1045151; // a bulk order deed
|
||||
|
||||
for ( int i = 0; i < chances.Length; ++i )
|
||||
{
|
||||
if ( random < chances[i] )
|
||||
return ( i == 0 ? BulkMaterialType.None : start + (i - 1) );
|
||||
public static BulkMaterialType GetRandomMaterial(BulkMaterialType start, double[] chances)
|
||||
{
|
||||
double random = Utility.RandomDouble();
|
||||
|
||||
random -= chances[i];
|
||||
}
|
||||
for (int i = 0; i < chances.Length; ++i)
|
||||
{
|
||||
if (random < chances[i])
|
||||
return i == 0 ? BulkMaterialType.None : start + (i - 1);
|
||||
|
||||
return BulkMaterialType.None;
|
||||
}
|
||||
random -= chances[i];
|
||||
}
|
||||
|
||||
public override void GetProperties( ObjectPropertyList list )
|
||||
{
|
||||
base.GetProperties( list );
|
||||
return BulkMaterialType.None;
|
||||
}
|
||||
|
||||
list.Add( 1060654 ); // small bulk order
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if ( m_RequireExceptional )
|
||||
list.Add( 1045141 ); // All items must be exceptional.
|
||||
list.Add(1060654); // small bulk order
|
||||
|
||||
if ( m_Material != BulkMaterialType.None )
|
||||
list.Add( SmallBODGump.GetMaterialNumberFor( m_Material ) ); // All items must be made with x material.
|
||||
if (m_RequireExceptional)
|
||||
list.Add(1045141); // All items must be exceptional.
|
||||
|
||||
list.Add( 1060656, m_AmountMax.ToString() ); // amount to make: ~1_val~
|
||||
list.Add( 1060658, "#{0}\t{1}", m_Number, m_AmountCur ); // ~1_val~: ~2_val~
|
||||
}
|
||||
if (m_Material != BulkMaterialType.None)
|
||||
list.Add(SmallBODGump.GetMaterialNumberFor(m_Material)); // All items must be made with x material.
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( IsChildOf( from.Backpack ) || InSecureTrade || RootParent is PlayerVendor )
|
||||
from.SendGump( new SmallBODGump( from, this ) );
|
||||
else
|
||||
from.SendLocalizedMessage( 1045156 ); // You must have the deed in your backpack to use it.
|
||||
}
|
||||
list.Add(1060656, m_AmountMax.ToString()); // amount to make: ~1_val~
|
||||
list.Add(1060658, "#{0}\t{1}", m_Number, m_AmountCur); // ~1_val~: ~2_val~
|
||||
}
|
||||
|
||||
public override void OnDoubleClickNotAccessible( Mobile from )
|
||||
{
|
||||
OnDoubleClick( from );
|
||||
}
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (IsChildOf(from.Backpack) || InSecureTrade || RootParent is PlayerVendor)
|
||||
from.SendGump(new SmallBODGump(from, this));
|
||||
else
|
||||
from.SendLocalizedMessage(1045156); // You must have the deed in your backpack to use it.
|
||||
}
|
||||
|
||||
public override void OnDoubleClickSecureTrade( Mobile from )
|
||||
{
|
||||
OnDoubleClick( from );
|
||||
}
|
||||
public override void OnDoubleClickNotAccessible(Mobile from)
|
||||
{
|
||||
OnDoubleClick(from);
|
||||
}
|
||||
|
||||
public void BeginCombine( Mobile from )
|
||||
{
|
||||
if ( m_AmountCur < m_AmountMax )
|
||||
from.Target = new SmallBODTarget( this );
|
||||
else
|
||||
from.SendLocalizedMessage( 1045166 ); // The maximum amount of requested items have already been combined to this deed.
|
||||
}
|
||||
public override void OnDoubleClickSecureTrade(Mobile from)
|
||||
{
|
||||
OnDoubleClick(from);
|
||||
}
|
||||
|
||||
public abstract List<Item> ComputeRewards( bool full );
|
||||
public abstract int ComputeGold();
|
||||
public abstract int ComputeFame();
|
||||
public void BeginCombine(Mobile from)
|
||||
{
|
||||
if (m_AmountCur < m_AmountMax)
|
||||
from.Target = new SmallBODTarget(this);
|
||||
else
|
||||
from.SendLocalizedMessage(
|
||||
1045166); // The maximum amount of requested items have already been combined to this deed.
|
||||
}
|
||||
|
||||
public virtual void GetRewards( out Item reward, out int gold, out int fame )
|
||||
{
|
||||
reward = null;
|
||||
gold = ComputeGold();
|
||||
fame = ComputeFame();
|
||||
public abstract List<Item> ComputeRewards(bool full);
|
||||
public abstract int ComputeGold();
|
||||
public abstract int ComputeFame();
|
||||
|
||||
List<Item> rewards = ComputeRewards( false );
|
||||
public virtual void GetRewards(out Item reward, out int gold, out int fame)
|
||||
{
|
||||
reward = null;
|
||||
gold = ComputeGold();
|
||||
fame = ComputeFame();
|
||||
|
||||
if ( rewards.Count > 0 )
|
||||
{
|
||||
reward = rewards[Utility.Random( rewards.Count )];
|
||||
List<Item> rewards = ComputeRewards(false);
|
||||
|
||||
for ( int i = 0; i < rewards.Count; ++i )
|
||||
{
|
||||
if ( rewards[i] != reward )
|
||||
rewards[i].Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rewards.Count > 0)
|
||||
{
|
||||
reward = rewards[Utility.Random(rewards.Count)];
|
||||
|
||||
public static BulkMaterialType GetMaterial( CraftResource resource )
|
||||
{
|
||||
switch ( resource )
|
||||
{
|
||||
case CraftResource.DullCopper: return BulkMaterialType.DullCopper;
|
||||
case CraftResource.ShadowIron: return BulkMaterialType.ShadowIron;
|
||||
case CraftResource.Copper: return BulkMaterialType.Copper;
|
||||
case CraftResource.Bronze: return BulkMaterialType.Bronze;
|
||||
case CraftResource.Gold: return BulkMaterialType.Gold;
|
||||
case CraftResource.Agapite: return BulkMaterialType.Agapite;
|
||||
case CraftResource.Verite: return BulkMaterialType.Verite;
|
||||
case CraftResource.Valorite: return BulkMaterialType.Valorite;
|
||||
case CraftResource.SpinedLeather: return BulkMaterialType.Spined;
|
||||
case CraftResource.HornedLeather: return BulkMaterialType.Horned;
|
||||
case CraftResource.BarbedLeather: return BulkMaterialType.Barbed;
|
||||
}
|
||||
for (int i = 0; i < rewards.Count; ++i)
|
||||
if (rewards[i] != reward)
|
||||
rewards[i].Delete();
|
||||
}
|
||||
}
|
||||
|
||||
return BulkMaterialType.None;
|
||||
}
|
||||
public static BulkMaterialType GetMaterial(CraftResource resource)
|
||||
{
|
||||
switch (resource)
|
||||
{
|
||||
case CraftResource.DullCopper: return BulkMaterialType.DullCopper;
|
||||
case CraftResource.ShadowIron: return BulkMaterialType.ShadowIron;
|
||||
case CraftResource.Copper: return BulkMaterialType.Copper;
|
||||
case CraftResource.Bronze: return BulkMaterialType.Bronze;
|
||||
case CraftResource.Gold: return BulkMaterialType.Gold;
|
||||
case CraftResource.Agapite: return BulkMaterialType.Agapite;
|
||||
case CraftResource.Verite: return BulkMaterialType.Verite;
|
||||
case CraftResource.Valorite: return BulkMaterialType.Valorite;
|
||||
case CraftResource.SpinedLeather: return BulkMaterialType.Spined;
|
||||
case CraftResource.HornedLeather: return BulkMaterialType.Horned;
|
||||
case CraftResource.BarbedLeather: return BulkMaterialType.Barbed;
|
||||
}
|
||||
|
||||
public void EndCombine( Mobile from, object o )
|
||||
{
|
||||
if ( o is Item item && item.IsChildOf( from.Backpack ) )
|
||||
{
|
||||
Type objectType = item.GetType();
|
||||
return BulkMaterialType.None;
|
||||
}
|
||||
|
||||
if ( m_AmountCur >= m_AmountMax )
|
||||
{
|
||||
from.SendLocalizedMessage( 1045166 ); // The maximum amount of requested items have already been combined to this deed.
|
||||
}
|
||||
else if ( Type == null || (objectType != Type && !objectType.IsSubclassOf( Type )) || (!(item is BaseWeapon) && !(item is BaseArmor) && !(item is BaseClothing)) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1045169 ); // The item is not in the request.
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseArmor armor = item as BaseArmor;
|
||||
BaseClothing clothing = item as BaseClothing;
|
||||
public void EndCombine(Mobile from, object o)
|
||||
{
|
||||
if (o is Item item && item.IsChildOf(from.Backpack))
|
||||
{
|
||||
Type objectType = item.GetType();
|
||||
|
||||
BulkMaterialType material = GetMaterial( armor?.Resource ?? clothing?.Resource ?? CraftResource.None );
|
||||
if (m_AmountCur >= m_AmountMax)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1045166); // The maximum amount of requested items have already been combined to this deed.
|
||||
}
|
||||
else if (Type == null || objectType != Type && !objectType.IsSubclassOf(Type) ||
|
||||
!(item is BaseWeapon) && !(item is BaseArmor) && !(item is BaseClothing))
|
||||
{
|
||||
from.SendLocalizedMessage(1045169); // The item is not in the request.
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseArmor armor = item as BaseArmor;
|
||||
BaseClothing clothing = item as BaseClothing;
|
||||
|
||||
if ( m_Material >= BulkMaterialType.DullCopper && m_Material <= BulkMaterialType.Valorite && material != m_Material )
|
||||
{
|
||||
from.SendLocalizedMessage( 1045168 ); // The item is not made from the requested ore.
|
||||
}
|
||||
else if ( m_Material >= BulkMaterialType.Spined && m_Material <= BulkMaterialType.Barbed && material != m_Material )
|
||||
{
|
||||
from.SendLocalizedMessage( 1049352 ); // The item is not made from the requested leather type.
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isExceptional;
|
||||
BulkMaterialType material = GetMaterial(armor?.Resource ?? clothing?.Resource ?? CraftResource.None);
|
||||
|
||||
if ( item is BaseWeapon weapon )
|
||||
isExceptional = weapon.Quality == WeaponQuality.Exceptional;
|
||||
else if ( armor != null )
|
||||
isExceptional = armor.Quality == ArmorQuality.Exceptional;
|
||||
else
|
||||
isExceptional = clothing.Quality == ClothingQuality.Exceptional;
|
||||
if (m_Material >= BulkMaterialType.DullCopper && m_Material <= BulkMaterialType.Valorite &&
|
||||
material != m_Material)
|
||||
{
|
||||
from.SendLocalizedMessage(1045168); // The item is not made from the requested ore.
|
||||
}
|
||||
else if (m_Material >= BulkMaterialType.Spined && m_Material <= BulkMaterialType.Barbed &&
|
||||
material != m_Material)
|
||||
{
|
||||
from.SendLocalizedMessage(1049352); // The item is not made from the requested leather type.
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isExceptional;
|
||||
|
||||
if ( m_RequireExceptional && !isExceptional )
|
||||
{
|
||||
from.SendLocalizedMessage( 1045167 ); // The item must be exceptional.
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Delete();
|
||||
++AmountCur;
|
||||
if (item is BaseWeapon weapon)
|
||||
isExceptional = weapon.Quality == WeaponQuality.Exceptional;
|
||||
else if (armor != null)
|
||||
isExceptional = armor.Quality == ArmorQuality.Exceptional;
|
||||
else
|
||||
isExceptional = clothing.Quality == ClothingQuality.Exceptional;
|
||||
|
||||
from.SendLocalizedMessage( 1045170 ); // The item has been combined with the deed.
|
||||
if (m_RequireExceptional && !isExceptional)
|
||||
{
|
||||
from.SendLocalizedMessage(1045167); // The item must be exceptional.
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Delete();
|
||||
++AmountCur;
|
||||
|
||||
from.SendGump( new SmallBODGump( from, this ) );
|
||||
from.SendLocalizedMessage(1045170); // The item has been combined with the deed.
|
||||
|
||||
if ( m_AmountCur < m_AmountMax )
|
||||
BeginCombine( from );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1045158 ); // You must have the item in your backpack to target it.
|
||||
}
|
||||
}
|
||||
from.SendGump(new SmallBODGump(from, this));
|
||||
|
||||
public SmallBOD( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
if (m_AmountCur < m_AmountMax)
|
||||
BeginCombine(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1045158); // You must have the item in your backpack to target it.
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write( m_AmountCur );
|
||||
writer.Write( m_AmountMax );
|
||||
writer.Write( Type == null ? null : Type.FullName );
|
||||
writer.Write( m_Number );
|
||||
writer.Write( Graphic );
|
||||
writer.Write( m_RequireExceptional );
|
||||
writer.Write( (int) m_Material );
|
||||
}
|
||||
writer.Write(m_AmountCur);
|
||||
writer.Write(m_AmountMax);
|
||||
writer.Write(Type == null ? null : Type.FullName);
|
||||
writer.Write(m_Number);
|
||||
writer.Write(Graphic);
|
||||
writer.Write(m_RequireExceptional);
|
||||
writer.Write((int)m_Material);
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_AmountCur = reader.ReadInt();
|
||||
m_AmountMax = reader.ReadInt();
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_AmountCur = reader.ReadInt();
|
||||
m_AmountMax = reader.ReadInt();
|
||||
|
||||
string type = reader.ReadString();
|
||||
string type = reader.ReadString();
|
||||
|
||||
if ( type != null )
|
||||
Type = ScriptCompiler.FindTypeByFullName( type );
|
||||
if (type != null)
|
||||
Type = ScriptCompiler.FindTypeByFullName(type);
|
||||
|
||||
m_Number = reader.ReadInt();
|
||||
Graphic = reader.ReadInt();
|
||||
m_RequireExceptional = reader.ReadBool();
|
||||
m_Material = (BulkMaterialType)reader.ReadInt();
|
||||
m_Number = reader.ReadInt();
|
||||
Graphic = reader.ReadInt();
|
||||
m_RequireExceptional = reader.ReadBool();
|
||||
m_Material = (BulkMaterialType)reader.ReadInt();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( Weight == 0.0 )
|
||||
Weight = 1.0;
|
||||
if (Weight == 0.0)
|
||||
Weight = 1.0;
|
||||
|
||||
if ( Core.AOS && ItemID == 0x14EF )
|
||||
ItemID = 0x2258;
|
||||
if (Core.AOS && ItemID == 0x14EF)
|
||||
ItemID = 0x2258;
|
||||
|
||||
if ( Parent == null && Map == Map.Internal && Location == Point3D.Zero )
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Parent == null && Map == Map.Internal && Location == Point3D.Zero)
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,89 +3,91 @@ using Server.Network;
|
|||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class SmallBODAcceptGump : Gump
|
||||
{
|
||||
private SmallBOD m_Deed;
|
||||
private Mobile m_From;
|
||||
public class SmallBODAcceptGump : Gump
|
||||
{
|
||||
private SmallBOD m_Deed;
|
||||
private Mobile m_From;
|
||||
|
||||
public SmallBODAcceptGump( Mobile from, SmallBOD deed ) : base( 50, 50 )
|
||||
{
|
||||
m_From = from;
|
||||
m_Deed = deed;
|
||||
public SmallBODAcceptGump(Mobile from, SmallBOD deed) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Deed = deed;
|
||||
|
||||
m_From.CloseGump( typeof( LargeBODAcceptGump ) );
|
||||
m_From.CloseGump( typeof( SmallBODAcceptGump ) );
|
||||
m_From.CloseGump(typeof(LargeBODAcceptGump));
|
||||
m_From.CloseGump(typeof(SmallBODAcceptGump));
|
||||
|
||||
AddPage( 0 );
|
||||
AddPage(0);
|
||||
|
||||
AddBackground( 25, 10, 430, 264, 5054 );
|
||||
AddBackground(25, 10, 430, 264, 5054);
|
||||
|
||||
AddImageTiled( 33, 20, 413, 245, 2624 );
|
||||
AddAlphaRegion( 33, 20, 413, 245 );
|
||||
AddImageTiled(33, 20, 413, 245, 2624);
|
||||
AddAlphaRegion(33, 20, 413, 245);
|
||||
|
||||
AddImage( 20, 5, 10460 );
|
||||
AddImage( 430, 5, 10460 );
|
||||
AddImage( 20, 249, 10460 );
|
||||
AddImage( 430, 249, 10460 );
|
||||
AddImage(20, 5, 10460);
|
||||
AddImage(430, 5, 10460);
|
||||
AddImage(20, 249, 10460);
|
||||
AddImage(430, 249, 10460);
|
||||
|
||||
AddHtmlLocalized( 190, 25, 120, 20, 1045133, 0x7FFF, false, false ); // A bulk order
|
||||
AddHtmlLocalized( 40, 48, 350, 20, 1045135, 0x7FFF, false, false ); // Ah! Thanks for the goods! Would you help me out?
|
||||
AddHtmlLocalized(190, 25, 120, 20, 1045133, 0x7FFF, false, false); // A bulk order
|
||||
AddHtmlLocalized(40, 48, 350, 20, 1045135, 0x7FFF, false,
|
||||
false); // Ah! Thanks for the goods! Would you help me out?
|
||||
|
||||
AddHtmlLocalized( 40, 72, 210, 20, 1045138, 0x7FFF, false, false ); // Amount to make:
|
||||
AddLabel( 250, 72, 1152, deed.AmountMax.ToString() );
|
||||
AddHtmlLocalized(40, 72, 210, 20, 1045138, 0x7FFF, false, false); // Amount to make:
|
||||
AddLabel(250, 72, 1152, deed.AmountMax.ToString());
|
||||
|
||||
AddHtmlLocalized( 40, 96, 120, 20, 1045136, 0x7FFF, false, false ); // Item requested:
|
||||
AddItem( 385, 96, deed.Graphic );
|
||||
AddHtmlLocalized( 40, 120, 210, 20, deed.Number, 0xFFFFFF, false, false );
|
||||
AddHtmlLocalized(40, 96, 120, 20, 1045136, 0x7FFF, false, false); // Item requested:
|
||||
AddItem(385, 96, deed.Graphic);
|
||||
AddHtmlLocalized(40, 120, 210, 20, deed.Number, 0xFFFFFF, false, false);
|
||||
|
||||
if ( deed.RequireExceptional || deed.Material != BulkMaterialType.None )
|
||||
{
|
||||
AddHtmlLocalized( 40, 144, 210, 20, 1045140, 0x7FFF, false, false ); // Special requirements to meet:
|
||||
if (deed.RequireExceptional || deed.Material != BulkMaterialType.None)
|
||||
{
|
||||
AddHtmlLocalized(40, 144, 210, 20, 1045140, 0x7FFF, false, false); // Special requirements to meet:
|
||||
|
||||
if ( deed.RequireExceptional )
|
||||
AddHtmlLocalized( 40, 168, 350, 20, 1045141, 0x7FFF, false, false ); // All items must be exceptional.
|
||||
if (deed.RequireExceptional)
|
||||
AddHtmlLocalized(40, 168, 350, 20, 1045141, 0x7FFF, false, false); // All items must be exceptional.
|
||||
|
||||
if ( deed.Material != BulkMaterialType.None )
|
||||
AddHtmlLocalized( 40, deed.RequireExceptional ? 192 : 168, 350, 20, GetMaterialNumberFor( deed.Material ), 0x7FFF, false, false ); // All items must be made with x material.
|
||||
}
|
||||
if (deed.Material != BulkMaterialType.None)
|
||||
AddHtmlLocalized(40, deed.RequireExceptional ? 192 : 168, 350, 20, GetMaterialNumberFor(deed.Material),
|
||||
0x7FFF, false, false); // All items must be made with x material.
|
||||
}
|
||||
|
||||
AddHtmlLocalized( 40, 216, 350, 20, 1045139, 0x7FFF, false, false ); // Do you want to accept this order?
|
||||
AddHtmlLocalized(40, 216, 350, 20, 1045139, 0x7FFF, false, false); // Do you want to accept this order?
|
||||
|
||||
AddButton( 100, 240, 4005, 4007, 1, GumpButtonType.Reply, 0 );
|
||||
AddHtmlLocalized( 135, 240, 120, 20, 1006044, 0x7FFF, false, false ); // Ok
|
||||
AddButton(100, 240, 4005, 4007, 1, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(135, 240, 120, 20, 1006044, 0x7FFF, false, false); // Ok
|
||||
|
||||
AddButton( 275, 240, 4005, 4007, 0, GumpButtonType.Reply, 0 );
|
||||
AddHtmlLocalized( 310, 240, 120, 20, 1011012, 0x7FFF, false, false ); // CANCEL
|
||||
}
|
||||
AddButton(275, 240, 4005, 4007, 0, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(310, 240, 120, 20, 1011012, 0x7FFF, false, false); // CANCEL
|
||||
}
|
||||
|
||||
public override void OnResponse( NetState sender, RelayInfo info )
|
||||
{
|
||||
if ( info.ButtonID == 1 ) // Ok
|
||||
{
|
||||
if ( m_From.PlaceInBackpack( m_Deed ) )
|
||||
{
|
||||
m_From.SendLocalizedMessage( 1045152 ); // The bulk order deed has been placed in your backpack.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendLocalizedMessage( 1045150 ); // There is not enough room in your backpack for the deed.
|
||||
m_Deed.Delete();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Deed.Delete();
|
||||
}
|
||||
}
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 1) // Ok
|
||||
{
|
||||
if (m_From.PlaceInBackpack(m_Deed))
|
||||
{
|
||||
m_From.SendLocalizedMessage(1045152); // The bulk order deed has been placed in your backpack.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendLocalizedMessage(1045150); // There is not enough room in your backpack for the deed.
|
||||
m_Deed.Delete();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Deed.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetMaterialNumberFor( BulkMaterialType material )
|
||||
{
|
||||
if ( material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite )
|
||||
return 1045142 + (int)(material - BulkMaterialType.DullCopper);
|
||||
if ( material >= BulkMaterialType.Spined && material <= BulkMaterialType.Barbed )
|
||||
return 1049348 + (int)(material - BulkMaterialType.Spined);
|
||||
public static int GetMaterialNumberFor(BulkMaterialType material)
|
||||
{
|
||||
if (material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite)
|
||||
return 1045142 + (material - BulkMaterialType.DullCopper);
|
||||
if (material >= BulkMaterialType.Spined && material <= BulkMaterialType.Barbed)
|
||||
return 1049348 + (material - BulkMaterialType.Spined);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,79 +3,80 @@ using Server.Network;
|
|||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class SmallBODGump : Gump
|
||||
{
|
||||
private SmallBOD m_Deed;
|
||||
private Mobile m_From;
|
||||
public class SmallBODGump : Gump
|
||||
{
|
||||
private SmallBOD m_Deed;
|
||||
private Mobile m_From;
|
||||
|
||||
public SmallBODGump( Mobile from, SmallBOD deed ) : base( 25, 25 )
|
||||
{
|
||||
m_From = from;
|
||||
m_Deed = deed;
|
||||
public SmallBODGump(Mobile from, SmallBOD deed) : base(25, 25)
|
||||
{
|
||||
m_From = from;
|
||||
m_Deed = deed;
|
||||
|
||||
m_From.CloseGump( typeof( LargeBODGump ) );
|
||||
m_From.CloseGump( typeof( SmallBODGump ) );
|
||||
m_From.CloseGump(typeof(LargeBODGump));
|
||||
m_From.CloseGump(typeof(SmallBODGump));
|
||||
|
||||
AddPage( 0 );
|
||||
AddPage(0);
|
||||
|
||||
AddBackground( 50, 10, 455, 260, 5054 );
|
||||
AddImageTiled( 58, 20, 438, 241, 2624 );
|
||||
AddAlphaRegion( 58, 20, 438, 241 );
|
||||
AddBackground(50, 10, 455, 260, 5054);
|
||||
AddImageTiled(58, 20, 438, 241, 2624);
|
||||
AddAlphaRegion(58, 20, 438, 241);
|
||||
|
||||
AddImage( 45, 5, 10460 );
|
||||
AddImage( 480, 5, 10460 );
|
||||
AddImage( 45, 245, 10460 );
|
||||
AddImage( 480, 245, 10460 );
|
||||
AddImage(45, 5, 10460);
|
||||
AddImage(480, 5, 10460);
|
||||
AddImage(45, 245, 10460);
|
||||
AddImage(480, 245, 10460);
|
||||
|
||||
AddHtmlLocalized( 225, 25, 120, 20, 1045133, 0x7FFF, false, false ); // A bulk order
|
||||
AddHtmlLocalized(225, 25, 120, 20, 1045133, 0x7FFF, false, false); // A bulk order
|
||||
|
||||
AddHtmlLocalized( 75, 48, 250, 20, 1045138, 0x7FFF, false, false ); // Amount to make:
|
||||
AddLabel( 275, 48, 1152, deed.AmountMax.ToString() );
|
||||
AddHtmlLocalized(75, 48, 250, 20, 1045138, 0x7FFF, false, false); // Amount to make:
|
||||
AddLabel(275, 48, 1152, deed.AmountMax.ToString());
|
||||
|
||||
AddHtmlLocalized( 275, 76, 200, 20, 1045153, 0x7FFF, false, false ); // Amount finished:
|
||||
AddHtmlLocalized( 75, 72, 120, 20, 1045136, 0x7FFF, false, false ); // Item requested:
|
||||
AddHtmlLocalized(275, 76, 200, 20, 1045153, 0x7FFF, false, false); // Amount finished:
|
||||
AddHtmlLocalized(75, 72, 120, 20, 1045136, 0x7FFF, false, false); // Item requested:
|
||||
|
||||
AddItem( 410, 72, deed.Graphic );
|
||||
AddItem(410, 72, deed.Graphic);
|
||||
|
||||
AddHtmlLocalized( 75, 96, 210, 20, deed.Number, 0x7FFF, false, false );
|
||||
AddLabel( 275, 96, 0x480, deed.AmountCur.ToString() );
|
||||
AddHtmlLocalized(75, 96, 210, 20, deed.Number, 0x7FFF, false, false);
|
||||
AddLabel(275, 96, 0x480, deed.AmountCur.ToString());
|
||||
|
||||
if ( deed.RequireExceptional || deed.Material != BulkMaterialType.None )
|
||||
AddHtmlLocalized( 75, 120, 200, 20, 1045140, 0x7FFF, false, false ); // Special requirements to meet:
|
||||
if (deed.RequireExceptional || deed.Material != BulkMaterialType.None)
|
||||
AddHtmlLocalized(75, 120, 200, 20, 1045140, 0x7FFF, false, false); // Special requirements to meet:
|
||||
|
||||
if ( deed.RequireExceptional )
|
||||
AddHtmlLocalized( 75, 144, 300, 20, 1045141, 0x7FFF, false, false ); // All items must be exceptional.
|
||||
if (deed.RequireExceptional)
|
||||
AddHtmlLocalized(75, 144, 300, 20, 1045141, 0x7FFF, false, false); // All items must be exceptional.
|
||||
|
||||
if ( deed.Material != BulkMaterialType.None )
|
||||
AddHtmlLocalized( 75, deed.RequireExceptional ? 168 : 144, 300, 20, GetMaterialNumberFor( deed.Material ), 0x7FFF, false, false ); // All items must be made with x material.
|
||||
if (deed.Material != BulkMaterialType.None)
|
||||
AddHtmlLocalized(75, deed.RequireExceptional ? 168 : 144, 300, 20, GetMaterialNumberFor(deed.Material),
|
||||
0x7FFF, false, false); // All items must be made with x material.
|
||||
|
||||
AddButton( 125, 192, 4005, 4007, 2, GumpButtonType.Reply, 0 );
|
||||
AddHtmlLocalized( 160, 192, 300, 20, 1045154, 0x7FFF, false, false ); // Combine this deed with the item requested.
|
||||
AddButton(125, 192, 4005, 4007, 2, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(160, 192, 300, 20, 1045154, 0x7FFF, false, false); // Combine this deed with the item requested.
|
||||
|
||||
AddButton( 125, 216, 4005, 4007, 1, GumpButtonType.Reply, 0 );
|
||||
AddHtmlLocalized( 160, 216, 120, 20, 1011441, 0x7FFF, false, false ); // EXIT
|
||||
}
|
||||
AddButton(125, 216, 4005, 4007, 1, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(160, 216, 120, 20, 1011441, 0x7FFF, false, false); // EXIT
|
||||
}
|
||||
|
||||
public override void OnResponse( NetState sender, RelayInfo info )
|
||||
{
|
||||
if ( m_Deed.Deleted || !m_Deed.IsChildOf( m_From.Backpack ) )
|
||||
return;
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (m_Deed.Deleted || !m_Deed.IsChildOf(m_From.Backpack))
|
||||
return;
|
||||
|
||||
if ( info.ButtonID == 2 ) // Combine
|
||||
{
|
||||
m_From.SendGump( new SmallBODGump( m_From, m_Deed ) );
|
||||
m_Deed.BeginCombine( m_From );
|
||||
}
|
||||
}
|
||||
if (info.ButtonID == 2) // Combine
|
||||
{
|
||||
m_From.SendGump(new SmallBODGump(m_From, m_Deed));
|
||||
m_Deed.BeginCombine(m_From);
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetMaterialNumberFor( BulkMaterialType material )
|
||||
{
|
||||
if ( material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite )
|
||||
return 1045142 + (int)(material - BulkMaterialType.DullCopper);
|
||||
if ( material >= BulkMaterialType.Spined && material <= BulkMaterialType.Barbed )
|
||||
return 1049348 + (int)(material - BulkMaterialType.Spined);
|
||||
public static int GetMaterialNumberFor(BulkMaterialType material)
|
||||
{
|
||||
if (material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite)
|
||||
return 1045142 + (material - BulkMaterialType.DullCopper);
|
||||
if (material >= BulkMaterialType.Spined && material <= BulkMaterialType.Barbed)
|
||||
return 1049348 + (material - BulkMaterialType.Spined);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,21 +2,21 @@ using Server.Targeting;
|
|||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class SmallBODTarget : Target
|
||||
{
|
||||
private SmallBOD m_Deed;
|
||||
public class SmallBODTarget : Target
|
||||
{
|
||||
private SmallBOD m_Deed;
|
||||
|
||||
public SmallBODTarget( SmallBOD deed ) : base( 18, false, TargetFlags.None )
|
||||
{
|
||||
m_Deed = deed;
|
||||
}
|
||||
public SmallBODTarget(SmallBOD deed) : base(18, false, TargetFlags.None)
|
||||
{
|
||||
m_Deed = deed;
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object targeted )
|
||||
{
|
||||
if ( m_Deed.Deleted || !m_Deed.IsChildOf( from.Backpack ) )
|
||||
return;
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (m_Deed.Deleted || !m_Deed.IsChildOf(from.Backpack))
|
||||
return;
|
||||
|
||||
m_Deed.EndCombine( from, targeted );
|
||||
}
|
||||
}
|
||||
m_Deed.EndCombine(from, targeted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,234 +5,257 @@ using Mat = Server.Engines.BulkOrders.BulkMaterialType;
|
|||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
[TypeAlias( "Scripts.Engines.BulkOrders.SmallSmithBOD" )]
|
||||
public class SmallSmithBOD : SmallBOD
|
||||
{
|
||||
public static double[] m_BlacksmithMaterialChances = {
|
||||
0.501953125, // None
|
||||
0.250000000, // Dull Copper
|
||||
0.125000000, // Shadow Iron
|
||||
0.062500000, // Copper
|
||||
0.031250000, // Bronze
|
||||
0.015625000, // Gold
|
||||
0.007812500, // Agapite
|
||||
0.003906250, // Verite
|
||||
0.001953125 // Valorite
|
||||
};
|
||||
[TypeAlias("Scripts.Engines.BulkOrders.SmallSmithBOD")]
|
||||
public class SmallSmithBOD : SmallBOD
|
||||
{
|
||||
public static double[] m_BlacksmithMaterialChances =
|
||||
{
|
||||
0.501953125, // None
|
||||
0.250000000, // Dull Copper
|
||||
0.125000000, // Shadow Iron
|
||||
0.062500000, // Copper
|
||||
0.031250000, // Bronze
|
||||
0.015625000, // Gold
|
||||
0.007812500, // Agapite
|
||||
0.003906250, // Verite
|
||||
0.001953125 // Valorite
|
||||
};
|
||||
|
||||
public override int ComputeFame()
|
||||
{
|
||||
return SmithRewardCalculator.Instance.ComputeFame( this );
|
||||
}
|
||||
private SmallSmithBOD(SmallBulkEntry entry, BulkMaterialType material, int amountMax, bool reqExceptional)
|
||||
{
|
||||
Hue = 0x44E;
|
||||
AmountMax = amountMax;
|
||||
Type = entry.Type;
|
||||
Number = entry.Number;
|
||||
Graphic = entry.Graphic;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = material;
|
||||
}
|
||||
|
||||
public override int ComputeGold()
|
||||
{
|
||||
return SmithRewardCalculator.Instance.ComputeGold( this );
|
||||
}
|
||||
[Constructible]
|
||||
public SmallSmithBOD()
|
||||
{
|
||||
SmallBulkEntry[] entries;
|
||||
bool useMaterials;
|
||||
|
||||
public override List<Item> ComputeRewards( bool full )
|
||||
{
|
||||
List<Item> list = new List<Item>();
|
||||
if (useMaterials = Utility.RandomBool())
|
||||
entries = SmallBulkEntry.BlacksmithArmor;
|
||||
else
|
||||
entries = SmallBulkEntry.BlacksmithWeapons;
|
||||
|
||||
RewardGroup rewardGroup = SmithRewardCalculator.Instance.LookupRewards( SmithRewardCalculator.Instance.ComputePoints( this ) );
|
||||
if (entries.Length > 0)
|
||||
{
|
||||
int hue = 0x44E;
|
||||
int amountMax = Utility.RandomList(10, 15, 20);
|
||||
|
||||
if ( rewardGroup != null )
|
||||
{
|
||||
if ( full )
|
||||
{
|
||||
for ( int i = 0; i < rewardGroup.Items.Length; ++i )
|
||||
{
|
||||
Item item = rewardGroup.Items[i].Construct();
|
||||
BulkMaterialType material;
|
||||
|
||||
if ( item != null )
|
||||
list.Add( item );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RewardItem rewardItem = rewardGroup.AcquireItem();
|
||||
if (useMaterials)
|
||||
material = GetRandomMaterial(BulkMaterialType.DullCopper, m_BlacksmithMaterialChances);
|
||||
else
|
||||
material = BulkMaterialType.None;
|
||||
|
||||
Item item = rewardItem?.Construct();
|
||||
bool reqExceptional = Utility.RandomBool() || material == BulkMaterialType.None;
|
||||
|
||||
if ( item != null )
|
||||
list.Add( item );
|
||||
}
|
||||
}
|
||||
SmallBulkEntry entry = entries[Utility.Random(entries.Length)];
|
||||
|
||||
return list;
|
||||
}
|
||||
Hue = hue;
|
||||
AmountMax = amountMax;
|
||||
Type = entry.Type;
|
||||
Number = entry.Number;
|
||||
Graphic = entry.Graphic;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = material;
|
||||
}
|
||||
}
|
||||
|
||||
public static SmallSmithBOD CreateRandomFor( Mobile m )
|
||||
{
|
||||
SmallBulkEntry[] entries;
|
||||
bool useMaterials;
|
||||
public SmallSmithBOD(int amountCur, int amountMax, Type type, int number, int graphic, bool reqExceptional,
|
||||
BulkMaterialType mat)
|
||||
{
|
||||
Hue = 0x44E;
|
||||
AmountMax = amountMax;
|
||||
AmountCur = amountCur;
|
||||
Type = type;
|
||||
Number = number;
|
||||
Graphic = graphic;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = mat;
|
||||
}
|
||||
|
||||
if ( useMaterials = Utility.RandomBool() )
|
||||
entries = SmallBulkEntry.BlacksmithArmor;
|
||||
else
|
||||
entries = SmallBulkEntry.BlacksmithWeapons;
|
||||
public SmallSmithBOD(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
if ( entries.Length > 0 )
|
||||
{
|
||||
double theirSkill = m.Skills[SkillName.Blacksmith].Base;
|
||||
int amountMax;
|
||||
public override int ComputeFame()
|
||||
{
|
||||
return SmithRewardCalculator.Instance.ComputeFame(this);
|
||||
}
|
||||
|
||||
if ( theirSkill >= 70.1 )
|
||||
amountMax = Utility.RandomList( 10, 15, 20, 20 );
|
||||
else if ( theirSkill >= 50.1 )
|
||||
amountMax = Utility.RandomList( 10, 15, 15, 20 );
|
||||
else
|
||||
amountMax = Utility.RandomList( 10, 10, 15, 20 );
|
||||
public override int ComputeGold()
|
||||
{
|
||||
return SmithRewardCalculator.Instance.ComputeGold(this);
|
||||
}
|
||||
|
||||
BulkMaterialType material = BulkMaterialType.None;
|
||||
public override List<Item> ComputeRewards(bool full)
|
||||
{
|
||||
List<Item> list = new List<Item>();
|
||||
|
||||
if ( useMaterials && theirSkill >= 70.1 )
|
||||
{
|
||||
for ( int i = 0; i < 20; ++i )
|
||||
{
|
||||
BulkMaterialType check = GetRandomMaterial( BulkMaterialType.DullCopper, m_BlacksmithMaterialChances );
|
||||
double skillReq = 0.0;
|
||||
RewardGroup rewardGroup =
|
||||
SmithRewardCalculator.Instance.LookupRewards(SmithRewardCalculator.Instance.ComputePoints(this));
|
||||
|
||||
switch ( check )
|
||||
{
|
||||
case BulkMaterialType.DullCopper: skillReq = 65.0; break;
|
||||
case BulkMaterialType.ShadowIron: skillReq = 70.0; break;
|
||||
case BulkMaterialType.Copper: skillReq = 75.0; break;
|
||||
case BulkMaterialType.Bronze: skillReq = 80.0; break;
|
||||
case BulkMaterialType.Gold: skillReq = 85.0; break;
|
||||
case BulkMaterialType.Agapite: skillReq = 90.0; break;
|
||||
case BulkMaterialType.Verite: skillReq = 95.0; break;
|
||||
case BulkMaterialType.Valorite: skillReq = 100.0; break;
|
||||
case BulkMaterialType.Spined: skillReq = 65.0; break;
|
||||
case BulkMaterialType.Horned: skillReq = 80.0; break;
|
||||
case BulkMaterialType.Barbed: skillReq = 99.0; break;
|
||||
}
|
||||
if (rewardGroup != null)
|
||||
{
|
||||
if (full)
|
||||
{
|
||||
for (int i = 0; i < rewardGroup.Items.Length; ++i)
|
||||
{
|
||||
Item item = rewardGroup.Items[i].Construct();
|
||||
|
||||
if ( theirSkill >= skillReq )
|
||||
{
|
||||
material = check;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (item != null)
|
||||
list.Add(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RewardItem rewardItem = rewardGroup.AcquireItem();
|
||||
|
||||
double excChance = 0.0;
|
||||
Item item = rewardItem?.Construct();
|
||||
|
||||
if ( theirSkill >= 70.1 )
|
||||
excChance = (theirSkill + 80.0) / 200.0;
|
||||
if (item != null)
|
||||
list.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
bool reqExceptional = ( excChance > Utility.RandomDouble() );
|
||||
return list;
|
||||
}
|
||||
|
||||
CraftSystem system = DefBlacksmithy.CraftSystem;
|
||||
public static SmallSmithBOD CreateRandomFor(Mobile m)
|
||||
{
|
||||
SmallBulkEntry[] entries;
|
||||
bool useMaterials;
|
||||
|
||||
List<SmallBulkEntry> validEntries = new List<SmallBulkEntry>();
|
||||
if (useMaterials = Utility.RandomBool())
|
||||
entries = SmallBulkEntry.BlacksmithArmor;
|
||||
else
|
||||
entries = SmallBulkEntry.BlacksmithWeapons;
|
||||
|
||||
for ( int i = 0; i < entries.Length; ++i )
|
||||
{
|
||||
CraftItem item = system.CraftItems.SearchFor( entries[i].Type );
|
||||
if (entries.Length > 0)
|
||||
{
|
||||
double theirSkill = m.Skills[SkillName.Blacksmith].Base;
|
||||
int amountMax;
|
||||
|
||||
if ( item != null )
|
||||
{
|
||||
bool allRequiredSkills = true;
|
||||
double chance = item.GetSuccessChance( m, null, system, false, ref allRequiredSkills );
|
||||
if (theirSkill >= 70.1)
|
||||
amountMax = Utility.RandomList(10, 15, 20, 20);
|
||||
else if (theirSkill >= 50.1)
|
||||
amountMax = Utility.RandomList(10, 15, 15, 20);
|
||||
else
|
||||
amountMax = Utility.RandomList(10, 10, 15, 20);
|
||||
|
||||
if ( allRequiredSkills && chance >= 0.0 )
|
||||
{
|
||||
if ( reqExceptional )
|
||||
chance = item.GetExceptionalChance( system, chance, m );
|
||||
BulkMaterialType material = BulkMaterialType.None;
|
||||
|
||||
if ( chance > 0.0 )
|
||||
validEntries.Add( entries[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (useMaterials && theirSkill >= 70.1)
|
||||
for (int i = 0; i < 20; ++i)
|
||||
{
|
||||
BulkMaterialType check = GetRandomMaterial(BulkMaterialType.DullCopper, m_BlacksmithMaterialChances);
|
||||
double skillReq = 0.0;
|
||||
|
||||
if ( validEntries.Count > 0 )
|
||||
{
|
||||
SmallBulkEntry entry = validEntries[Utility.Random( validEntries.Count )];
|
||||
return new SmallSmithBOD( entry, material, amountMax, reqExceptional );
|
||||
}
|
||||
}
|
||||
switch (check)
|
||||
{
|
||||
case BulkMaterialType.DullCopper:
|
||||
skillReq = 65.0;
|
||||
break;
|
||||
case BulkMaterialType.ShadowIron:
|
||||
skillReq = 70.0;
|
||||
break;
|
||||
case BulkMaterialType.Copper:
|
||||
skillReq = 75.0;
|
||||
break;
|
||||
case BulkMaterialType.Bronze:
|
||||
skillReq = 80.0;
|
||||
break;
|
||||
case BulkMaterialType.Gold:
|
||||
skillReq = 85.0;
|
||||
break;
|
||||
case BulkMaterialType.Agapite:
|
||||
skillReq = 90.0;
|
||||
break;
|
||||
case BulkMaterialType.Verite:
|
||||
skillReq = 95.0;
|
||||
break;
|
||||
case BulkMaterialType.Valorite:
|
||||
skillReq = 100.0;
|
||||
break;
|
||||
case BulkMaterialType.Spined:
|
||||
skillReq = 65.0;
|
||||
break;
|
||||
case BulkMaterialType.Horned:
|
||||
skillReq = 80.0;
|
||||
break;
|
||||
case BulkMaterialType.Barbed:
|
||||
skillReq = 99.0;
|
||||
break;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
if (theirSkill >= skillReq)
|
||||
{
|
||||
material = check;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private SmallSmithBOD( SmallBulkEntry entry, BulkMaterialType material, int amountMax, bool reqExceptional )
|
||||
{
|
||||
Hue = 0x44E;
|
||||
AmountMax = amountMax;
|
||||
Type = entry.Type;
|
||||
Number = entry.Number;
|
||||
Graphic = entry.Graphic;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = material;
|
||||
}
|
||||
double excChance = 0.0;
|
||||
|
||||
[Constructible]
|
||||
public SmallSmithBOD()
|
||||
{
|
||||
SmallBulkEntry[] entries;
|
||||
bool useMaterials;
|
||||
if (theirSkill >= 70.1)
|
||||
excChance = (theirSkill + 80.0) / 200.0;
|
||||
|
||||
if ( useMaterials = Utility.RandomBool() )
|
||||
entries = SmallBulkEntry.BlacksmithArmor;
|
||||
else
|
||||
entries = SmallBulkEntry.BlacksmithWeapons;
|
||||
bool reqExceptional = excChance > Utility.RandomDouble();
|
||||
|
||||
if ( entries.Length > 0 )
|
||||
{
|
||||
int hue = 0x44E;
|
||||
int amountMax = Utility.RandomList( 10, 15, 20 );
|
||||
CraftSystem system = DefBlacksmithy.CraftSystem;
|
||||
|
||||
BulkMaterialType material;
|
||||
List<SmallBulkEntry> validEntries = new List<SmallBulkEntry>();
|
||||
|
||||
if ( useMaterials )
|
||||
material = GetRandomMaterial( BulkMaterialType.DullCopper, m_BlacksmithMaterialChances );
|
||||
else
|
||||
material = BulkMaterialType.None;
|
||||
for (int i = 0; i < entries.Length; ++i)
|
||||
{
|
||||
CraftItem item = system.CraftItems.SearchFor(entries[i].Type);
|
||||
|
||||
bool reqExceptional = Utility.RandomBool() || (material == BulkMaterialType.None);
|
||||
if (item != null)
|
||||
{
|
||||
bool allRequiredSkills = true;
|
||||
double chance = item.GetSuccessChance(m, null, system, false, ref allRequiredSkills);
|
||||
|
||||
SmallBulkEntry entry = entries[Utility.Random( entries.Length )];
|
||||
if (allRequiredSkills && chance >= 0.0)
|
||||
{
|
||||
if (reqExceptional)
|
||||
chance = item.GetExceptionalChance(system, chance, m);
|
||||
|
||||
Hue = hue;
|
||||
AmountMax = amountMax;
|
||||
Type = entry.Type;
|
||||
Number = entry.Number;
|
||||
Graphic = entry.Graphic;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = material;
|
||||
}
|
||||
}
|
||||
if (chance > 0.0)
|
||||
validEntries.Add(entries[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SmallSmithBOD( int amountCur, int amountMax, Type type, int number, int graphic, bool reqExceptional, BulkMaterialType mat )
|
||||
{
|
||||
Hue = 0x44E;
|
||||
AmountMax = amountMax;
|
||||
AmountCur = amountCur;
|
||||
Type = type;
|
||||
Number = number;
|
||||
Graphic = graphic;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = mat;
|
||||
}
|
||||
if (validEntries.Count > 0)
|
||||
{
|
||||
SmallBulkEntry entry = validEntries[Utility.Random(validEntries.Count)];
|
||||
return new SmallSmithBOD(entry, material, amountMax, reqExceptional);
|
||||
}
|
||||
}
|
||||
|
||||
public SmallSmithBOD( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,227 +4,247 @@ using Server.Engines.Craft;
|
|||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class SmallTailorBOD : SmallBOD
|
||||
{
|
||||
public static double[] m_TailoringMaterialChances = {
|
||||
0.857421875, // None
|
||||
0.125000000, // Spined
|
||||
0.015625000, // Horned
|
||||
0.001953125 // Barbed
|
||||
};
|
||||
public class SmallTailorBOD : SmallBOD
|
||||
{
|
||||
public static double[] m_TailoringMaterialChances =
|
||||
{
|
||||
0.857421875, // None
|
||||
0.125000000, // Spined
|
||||
0.015625000, // Horned
|
||||
0.001953125 // Barbed
|
||||
};
|
||||
|
||||
public override int ComputeFame()
|
||||
{
|
||||
return TailorRewardCalculator.Instance.ComputeFame( this );
|
||||
}
|
||||
private SmallTailorBOD(SmallBulkEntry entry, BulkMaterialType material, int amountMax, bool reqExceptional)
|
||||
{
|
||||
Hue = 0x483;
|
||||
AmountMax = amountMax;
|
||||
Type = entry.Type;
|
||||
Number = entry.Number;
|
||||
Graphic = entry.Graphic;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = material;
|
||||
}
|
||||
|
||||
public override int ComputeGold()
|
||||
{
|
||||
return TailorRewardCalculator.Instance.ComputeGold( this );
|
||||
}
|
||||
[Constructible]
|
||||
public SmallTailorBOD()
|
||||
{
|
||||
SmallBulkEntry[] entries;
|
||||
bool useMaterials;
|
||||
|
||||
public override List<Item> ComputeRewards( bool full )
|
||||
{
|
||||
List<Item> list = new List<Item>();
|
||||
if (useMaterials = Utility.RandomBool())
|
||||
entries = SmallBulkEntry.TailorLeather;
|
||||
else
|
||||
entries = SmallBulkEntry.TailorCloth;
|
||||
|
||||
RewardGroup rewardGroup = TailorRewardCalculator.Instance.LookupRewards( TailorRewardCalculator.Instance.ComputePoints( this ) );
|
||||
if (entries.Length > 0)
|
||||
{
|
||||
int hue = 0x483;
|
||||
int amountMax = Utility.RandomList(10, 15, 20);
|
||||
|
||||
if ( rewardGroup != null )
|
||||
{
|
||||
if ( full )
|
||||
{
|
||||
for ( int i = 0; i < rewardGroup.Items.Length; ++i )
|
||||
{
|
||||
Item item = rewardGroup.Items[i].Construct();
|
||||
BulkMaterialType material;
|
||||
|
||||
if ( item != null )
|
||||
list.Add( item );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RewardItem rewardItem = rewardGroup.AcquireItem();
|
||||
if (useMaterials)
|
||||
material = GetRandomMaterial(BulkMaterialType.Spined, m_TailoringMaterialChances);
|
||||
else
|
||||
material = BulkMaterialType.None;
|
||||
|
||||
Item item = rewardItem?.Construct();
|
||||
bool reqExceptional = Utility.RandomBool() || material == BulkMaterialType.None;
|
||||
|
||||
if ( item != null )
|
||||
list.Add( item );
|
||||
}
|
||||
}
|
||||
SmallBulkEntry entry = entries[Utility.Random(entries.Length)];
|
||||
|
||||
return list;
|
||||
}
|
||||
Hue = hue;
|
||||
AmountMax = amountMax;
|
||||
Type = entry.Type;
|
||||
Number = entry.Number;
|
||||
Graphic = entry.Graphic;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = material;
|
||||
}
|
||||
}
|
||||
|
||||
public static SmallTailorBOD CreateRandomFor( Mobile m )
|
||||
{
|
||||
SmallBulkEntry[] entries;
|
||||
bool useMaterials = Utility.RandomBool();
|
||||
public SmallTailorBOD(int amountCur, int amountMax, Type type, int number, int graphic, bool reqExceptional,
|
||||
BulkMaterialType mat)
|
||||
{
|
||||
Hue = 0x483;
|
||||
AmountMax = amountMax;
|
||||
AmountCur = amountCur;
|
||||
Type = type;
|
||||
Number = number;
|
||||
Graphic = graphic;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = mat;
|
||||
}
|
||||
|
||||
double theirSkill = m.Skills[SkillName.Tailoring].Base;
|
||||
if ( useMaterials && theirSkill >= 6.2 ) // Ugly, but the easiest leather BOD is Leather Cap which requires at least 6.2 skill.
|
||||
entries = SmallBulkEntry.TailorLeather;
|
||||
else
|
||||
entries = SmallBulkEntry.TailorCloth;
|
||||
public SmallTailorBOD(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
if ( entries.Length > 0 )
|
||||
{
|
||||
int amountMax;
|
||||
public override int ComputeFame()
|
||||
{
|
||||
return TailorRewardCalculator.Instance.ComputeFame(this);
|
||||
}
|
||||
|
||||
if ( theirSkill >= 70.1 )
|
||||
amountMax = Utility.RandomList( 10, 15, 20, 20 );
|
||||
else if ( theirSkill >= 50.1 )
|
||||
amountMax = Utility.RandomList( 10, 15, 15, 20 );
|
||||
else
|
||||
amountMax = Utility.RandomList( 10, 10, 15, 20 );
|
||||
public override int ComputeGold()
|
||||
{
|
||||
return TailorRewardCalculator.Instance.ComputeGold(this);
|
||||
}
|
||||
|
||||
BulkMaterialType material = BulkMaterialType.None;
|
||||
public override List<Item> ComputeRewards(bool full)
|
||||
{
|
||||
List<Item> list = new List<Item>();
|
||||
|
||||
if ( useMaterials && theirSkill >= 70.1 )
|
||||
{
|
||||
for ( int i = 0; i < 20; ++i )
|
||||
{
|
||||
BulkMaterialType check = GetRandomMaterial( BulkMaterialType.Spined, m_TailoringMaterialChances );
|
||||
double skillReq = 0.0;
|
||||
RewardGroup rewardGroup =
|
||||
TailorRewardCalculator.Instance.LookupRewards(TailorRewardCalculator.Instance.ComputePoints(this));
|
||||
|
||||
switch ( check )
|
||||
{
|
||||
case BulkMaterialType.DullCopper: skillReq = 65.0; break;
|
||||
case BulkMaterialType.Bronze: skillReq = 80.0; break;
|
||||
case BulkMaterialType.Gold: skillReq = 85.0; break;
|
||||
case BulkMaterialType.Agapite: skillReq = 90.0; break;
|
||||
case BulkMaterialType.Verite: skillReq = 95.0; break;
|
||||
case BulkMaterialType.Valorite: skillReq = 100.0; break;
|
||||
case BulkMaterialType.Spined: skillReq = 65.0; break;
|
||||
case BulkMaterialType.Horned: skillReq = 80.0; break;
|
||||
case BulkMaterialType.Barbed: skillReq = 99.0; break;
|
||||
}
|
||||
if (rewardGroup != null)
|
||||
{
|
||||
if (full)
|
||||
{
|
||||
for (int i = 0; i < rewardGroup.Items.Length; ++i)
|
||||
{
|
||||
Item item = rewardGroup.Items[i].Construct();
|
||||
|
||||
if ( theirSkill >= skillReq )
|
||||
{
|
||||
material = check;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (item != null)
|
||||
list.Add(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RewardItem rewardItem = rewardGroup.AcquireItem();
|
||||
|
||||
double excChance = 0.0;
|
||||
Item item = rewardItem?.Construct();
|
||||
|
||||
if ( theirSkill >= 70.1 )
|
||||
excChance = (theirSkill + 80.0) / 200.0;
|
||||
if (item != null)
|
||||
list.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
bool reqExceptional = ( excChance > Utility.RandomDouble() );
|
||||
return list;
|
||||
}
|
||||
|
||||
public static SmallTailorBOD CreateRandomFor(Mobile m)
|
||||
{
|
||||
SmallBulkEntry[] entries;
|
||||
bool useMaterials = Utility.RandomBool();
|
||||
|
||||
double theirSkill = m.Skills[SkillName.Tailoring].Base;
|
||||
if (useMaterials && theirSkill >= 6.2
|
||||
) // Ugly, but the easiest leather BOD is Leather Cap which requires at least 6.2 skill.
|
||||
entries = SmallBulkEntry.TailorLeather;
|
||||
else
|
||||
entries = SmallBulkEntry.TailorCloth;
|
||||
|
||||
if (entries.Length > 0)
|
||||
{
|
||||
int amountMax;
|
||||
|
||||
if (theirSkill >= 70.1)
|
||||
amountMax = Utility.RandomList(10, 15, 20, 20);
|
||||
else if (theirSkill >= 50.1)
|
||||
amountMax = Utility.RandomList(10, 15, 15, 20);
|
||||
else
|
||||
amountMax = Utility.RandomList(10, 10, 15, 20);
|
||||
|
||||
BulkMaterialType material = BulkMaterialType.None;
|
||||
|
||||
if (useMaterials && theirSkill >= 70.1)
|
||||
for (int i = 0; i < 20; ++i)
|
||||
{
|
||||
BulkMaterialType check = GetRandomMaterial(BulkMaterialType.Spined, m_TailoringMaterialChances);
|
||||
double skillReq = 0.0;
|
||||
|
||||
switch (check)
|
||||
{
|
||||
case BulkMaterialType.DullCopper:
|
||||
skillReq = 65.0;
|
||||
break;
|
||||
case BulkMaterialType.Bronze:
|
||||
skillReq = 80.0;
|
||||
break;
|
||||
case BulkMaterialType.Gold:
|
||||
skillReq = 85.0;
|
||||
break;
|
||||
case BulkMaterialType.Agapite:
|
||||
skillReq = 90.0;
|
||||
break;
|
||||
case BulkMaterialType.Verite:
|
||||
skillReq = 95.0;
|
||||
break;
|
||||
case BulkMaterialType.Valorite:
|
||||
skillReq = 100.0;
|
||||
break;
|
||||
case BulkMaterialType.Spined:
|
||||
skillReq = 65.0;
|
||||
break;
|
||||
case BulkMaterialType.Horned:
|
||||
skillReq = 80.0;
|
||||
break;
|
||||
case BulkMaterialType.Barbed:
|
||||
skillReq = 99.0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (theirSkill >= skillReq)
|
||||
{
|
||||
material = check;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double excChance = 0.0;
|
||||
|
||||
if (theirSkill >= 70.1)
|
||||
excChance = (theirSkill + 80.0) / 200.0;
|
||||
|
||||
bool reqExceptional = excChance > Utility.RandomDouble();
|
||||
|
||||
|
||||
CraftSystem system = DefTailoring.CraftSystem;
|
||||
CraftSystem system = DefTailoring.CraftSystem;
|
||||
|
||||
List<SmallBulkEntry> validEntries = new List<SmallBulkEntry>();
|
||||
List<SmallBulkEntry> validEntries = new List<SmallBulkEntry>();
|
||||
|
||||
for ( int i = 0; i < entries.Length; ++i )
|
||||
{
|
||||
CraftItem item = system.CraftItems.SearchFor( entries[i].Type );
|
||||
for (int i = 0; i < entries.Length; ++i)
|
||||
{
|
||||
CraftItem item = system.CraftItems.SearchFor(entries[i].Type);
|
||||
|
||||
if ( item != null )
|
||||
{
|
||||
bool allRequiredSkills = true;
|
||||
double chance = item.GetSuccessChance( m, null, system, false, ref allRequiredSkills );
|
||||
if (item != null)
|
||||
{
|
||||
bool allRequiredSkills = true;
|
||||
double chance = item.GetSuccessChance(m, null, system, false, ref allRequiredSkills);
|
||||
|
||||
if ( allRequiredSkills && chance >= 0.0 )
|
||||
{
|
||||
if ( reqExceptional )
|
||||
chance = item.GetExceptionalChance( system, chance, m );
|
||||
if (allRequiredSkills && chance >= 0.0)
|
||||
{
|
||||
if (reqExceptional)
|
||||
chance = item.GetExceptionalChance(system, chance, m);
|
||||
|
||||
if ( chance > 0.0 )
|
||||
validEntries.Add( entries[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chance > 0.0)
|
||||
validEntries.Add(entries[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( validEntries.Count > 0 )
|
||||
{
|
||||
SmallBulkEntry entry = validEntries[Utility.Random( validEntries.Count )];
|
||||
return new SmallTailorBOD( entry, material, amountMax, reqExceptional );
|
||||
}
|
||||
}
|
||||
if (validEntries.Count > 0)
|
||||
{
|
||||
SmallBulkEntry entry = validEntries[Utility.Random(validEntries.Count)];
|
||||
return new SmallTailorBOD(entry, material, amountMax, reqExceptional);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private SmallTailorBOD( SmallBulkEntry entry, BulkMaterialType material, int amountMax, bool reqExceptional )
|
||||
{
|
||||
Hue = 0x483;
|
||||
AmountMax = amountMax;
|
||||
Type = entry.Type;
|
||||
Number = entry.Number;
|
||||
Graphic = entry.Graphic;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = material;
|
||||
}
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
[Constructible]
|
||||
public SmallTailorBOD()
|
||||
{
|
||||
SmallBulkEntry[] entries;
|
||||
bool useMaterials;
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
if ( useMaterials = Utility.RandomBool() )
|
||||
entries = SmallBulkEntry.TailorLeather;
|
||||
else
|
||||
entries = SmallBulkEntry.TailorCloth;
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
if ( entries.Length > 0 )
|
||||
{
|
||||
int hue = 0x483;
|
||||
int amountMax = Utility.RandomList( 10, 15, 20 );
|
||||
|
||||
BulkMaterialType material;
|
||||
|
||||
if ( useMaterials )
|
||||
material = GetRandomMaterial( BulkMaterialType.Spined, m_TailoringMaterialChances );
|
||||
else
|
||||
material = BulkMaterialType.None;
|
||||
|
||||
bool reqExceptional = Utility.RandomBool() || (material == BulkMaterialType.None);
|
||||
|
||||
SmallBulkEntry entry = entries[Utility.Random( entries.Length )];
|
||||
|
||||
Hue = hue;
|
||||
AmountMax = amountMax;
|
||||
Type = entry.Type;
|
||||
Number = entry.Number;
|
||||
Graphic = entry.Graphic;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = material;
|
||||
}
|
||||
}
|
||||
|
||||
public SmallTailorBOD( int amountCur, int amountMax, Type type, int number, int graphic, bool reqExceptional, BulkMaterialType mat )
|
||||
{
|
||||
Hue = 0x483;
|
||||
AmountMax = amountMax;
|
||||
AmountCur = amountCur;
|
||||
Type = type;
|
||||
Number = number;
|
||||
Graphic = graphic;
|
||||
RequireExceptional = reqExceptional;
|
||||
Material = mat;
|
||||
}
|
||||
|
||||
public SmallTailorBOD( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,53 +2,53 @@ using Server.Items;
|
|||
|
||||
namespace Server.Engines.CannedEvil
|
||||
{
|
||||
public class ChampionAltar : PentagramAddon
|
||||
{
|
||||
private ChampionSpawn m_Spawn;
|
||||
public class ChampionAltar : PentagramAddon
|
||||
{
|
||||
private ChampionSpawn m_Spawn;
|
||||
|
||||
public ChampionAltar( ChampionSpawn spawn )
|
||||
{
|
||||
m_Spawn = spawn;
|
||||
}
|
||||
public ChampionAltar(ChampionSpawn spawn)
|
||||
{
|
||||
m_Spawn = spawn;
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
public ChampionAltar(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
m_Spawn?.Delete();
|
||||
}
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
public ChampionAltar( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
m_Spawn?.Delete();
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write( m_Spawn );
|
||||
}
|
||||
writer.Write(m_Spawn);
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Spawn = reader.ReadItem() as ChampionSpawn;
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Spawn = reader.ReadItem() as ChampionSpawn;
|
||||
|
||||
if ( m_Spawn == null )
|
||||
Delete();
|
||||
if (m_Spawn == null)
|
||||
Delete();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,84 +2,84 @@ using Server.Items;
|
|||
|
||||
namespace Server.Engines.CannedEvil
|
||||
{
|
||||
public class ChampionPlatform : BaseAddon
|
||||
{
|
||||
private ChampionSpawn m_Spawn;
|
||||
public class ChampionPlatform : BaseAddon
|
||||
{
|
||||
private ChampionSpawn m_Spawn;
|
||||
|
||||
public ChampionPlatform( ChampionSpawn spawn )
|
||||
{
|
||||
m_Spawn = spawn;
|
||||
public ChampionPlatform(ChampionSpawn spawn)
|
||||
{
|
||||
m_Spawn = spawn;
|
||||
|
||||
for ( int x = -2; x <= 2; ++x )
|
||||
for ( int y = -2; y <= 2; ++y )
|
||||
AddComponent( 0x750, x, y, -5 );
|
||||
for (int x = -2; x <= 2; ++x)
|
||||
for (int y = -2; y <= 2; ++y)
|
||||
AddComponent(0x750, x, y, -5);
|
||||
|
||||
for ( int x = -1; x <= 1; ++x )
|
||||
for ( int y = -1; y <= 1; ++y )
|
||||
AddComponent( 0x750, x, y, 0 );
|
||||
for (int x = -1; x <= 1; ++x)
|
||||
for (int y = -1; y <= 1; ++y)
|
||||
AddComponent(0x750, x, y, 0);
|
||||
|
||||
for ( int i = -1; i <= 1; ++i )
|
||||
{
|
||||
AddComponent( 0x751, i, 2, 0 );
|
||||
AddComponent( 0x752, 2, i, 0 );
|
||||
for (int i = -1; i <= 1; ++i)
|
||||
{
|
||||
AddComponent(0x751, i, 2, 0);
|
||||
AddComponent(0x752, 2, i, 0);
|
||||
|
||||
AddComponent( 0x753, i, -2, 0 );
|
||||
AddComponent( 0x754, -2, i, 0 );
|
||||
}
|
||||
AddComponent(0x753, i, -2, 0);
|
||||
AddComponent(0x754, -2, i, 0);
|
||||
}
|
||||
|
||||
AddComponent( 0x759, -2, -2, 0 );
|
||||
AddComponent( 0x75A, 2, 2, 0 );
|
||||
AddComponent( 0x75B, -2, 2, 0 );
|
||||
AddComponent( 0x75C, 2, -2, 0 );
|
||||
}
|
||||
AddComponent(0x759, -2, -2, 0);
|
||||
AddComponent(0x75A, 2, 2, 0);
|
||||
AddComponent(0x75B, -2, 2, 0);
|
||||
AddComponent(0x75C, 2, -2, 0);
|
||||
}
|
||||
|
||||
public void AddComponent( int id, int x, int y, int z )
|
||||
{
|
||||
AddonComponent ac = new AddonComponent( id );
|
||||
public ChampionPlatform(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
ac.Hue = 0x497;
|
||||
public void AddComponent(int id, int x, int y, int z)
|
||||
{
|
||||
AddonComponent ac = new AddonComponent(id);
|
||||
|
||||
AddComponent( ac, x, y, z );
|
||||
}
|
||||
ac.Hue = 0x497;
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
AddComponent(ac, x, y, z);
|
||||
}
|
||||
|
||||
m_Spawn?.Delete();
|
||||
}
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
public ChampionPlatform( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
m_Spawn?.Delete();
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write( m_Spawn );
|
||||
}
|
||||
writer.Write(m_Spawn);
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Spawn = reader.ReadItem() as ChampionSpawn;
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Spawn = reader.ReadItem() as ChampionSpawn;
|
||||
|
||||
if ( m_Spawn == null )
|
||||
Delete();
|
||||
if (m_Spawn == null)
|
||||
Delete();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,71 +2,88 @@ using Server.Engines.CannedEvil;
|
|||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ChampionSkull : Item
|
||||
{
|
||||
private ChampionSkullType m_Type;
|
||||
public class ChampionSkull : Item
|
||||
{
|
||||
private ChampionSkullType m_Type;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public ChampionSkullType Type{ get => m_Type;
|
||||
set{ m_Type = value; InvalidateProperties(); } }
|
||||
[Constructible]
|
||||
public ChampionSkull(ChampionSkullType type) : base(0x1AE1)
|
||||
{
|
||||
m_Type = type;
|
||||
LootType = LootType.Cursed;
|
||||
|
||||
public override int LabelNumber => 1049479 + (int)m_Type;
|
||||
// TODO: All hue values
|
||||
switch (type)
|
||||
{
|
||||
case ChampionSkullType.Power:
|
||||
Hue = 0x159;
|
||||
break;
|
||||
case ChampionSkullType.Venom:
|
||||
Hue = 0x172;
|
||||
break;
|
||||
case ChampionSkullType.Greed:
|
||||
Hue = 0x1EE;
|
||||
break;
|
||||
case ChampionSkullType.Death:
|
||||
Hue = 0x025;
|
||||
break;
|
||||
case ChampionSkullType.Pain:
|
||||
Hue = 0x035;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public ChampionSkull( ChampionSkullType type ) : base( 0x1AE1 )
|
||||
{
|
||||
m_Type = type;
|
||||
LootType = LootType.Cursed;
|
||||
public ChampionSkull(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
// TODO: All hue values
|
||||
switch ( type )
|
||||
{
|
||||
case ChampionSkullType.Power: Hue = 0x159; break;
|
||||
case ChampionSkullType.Venom: Hue = 0x172; break;
|
||||
case ChampionSkullType.Greed: Hue = 0x1EE; break;
|
||||
case ChampionSkullType.Death: Hue = 0x025; break;
|
||||
case ChampionSkullType.Pain: Hue = 0x035; break;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public ChampionSkullType Type
|
||||
{
|
||||
get => m_Type;
|
||||
set
|
||||
{
|
||||
m_Type = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public ChampionSkull( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
public override int LabelNumber => 1049479 + (int)m_Type;
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 1 ); // version
|
||||
writer.Write(1); // version
|
||||
|
||||
writer.Write( (int) m_Type );
|
||||
}
|
||||
writer.Write((int)m_Type);
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
m_Type = (ChampionSkullType)reader.ReadInt();
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
m_Type = (ChampionSkullType)reader.ReadInt();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( version == 0 )
|
||||
{
|
||||
if ( LootType != LootType.Cursed )
|
||||
LootType = LootType.Cursed;
|
||||
if (version == 0)
|
||||
{
|
||||
if (LootType != LootType.Cursed)
|
||||
LootType = LootType.Cursed;
|
||||
|
||||
if ( Insured )
|
||||
Insured = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Insured)
|
||||
Insured = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,172 +1,184 @@
|
|||
using Server.Items;
|
||||
using Server.Targeting;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Engines.CannedEvil
|
||||
{
|
||||
public class ChampionSkullBrazier : AddonComponent
|
||||
{
|
||||
private ChampionSkullType m_Type;
|
||||
private Item m_Skull;
|
||||
public class ChampionSkullBrazier : AddonComponent
|
||||
{
|
||||
private Item m_Skull;
|
||||
private ChampionSkullType m_Type;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public ChampionSkullPlatform Platform { get; private set; }
|
||||
public ChampionSkullBrazier(ChampionSkullPlatform platform, ChampionSkullType type) : base(0x19BB)
|
||||
{
|
||||
Hue = 0x455;
|
||||
Light = LightType.Circle300;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public ChampionSkullType Type{ get => m_Type;
|
||||
set{ m_Type = value; InvalidateProperties(); } }
|
||||
Platform = platform;
|
||||
m_Type = type;
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Item Skull{ get => m_Skull;
|
||||
set{ m_Skull = value;
|
||||
Platform?.Validate();
|
||||
} }
|
||||
public ChampionSkullBrazier(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1049489 + (int)m_Type;
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public ChampionSkullPlatform Platform{ get; private set; }
|
||||
|
||||
public ChampionSkullBrazier( ChampionSkullPlatform platform, ChampionSkullType type ) : base( 0x19BB )
|
||||
{
|
||||
Hue = 0x455;
|
||||
Light = LightType.Circle300;
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public ChampionSkullType Type
|
||||
{
|
||||
get => m_Type;
|
||||
set
|
||||
{
|
||||
m_Type = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
Platform = platform;
|
||||
m_Type = type;
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Item Skull
|
||||
{
|
||||
get => m_Skull;
|
||||
set
|
||||
{
|
||||
m_Skull = value;
|
||||
Platform?.Validate();
|
||||
}
|
||||
}
|
||||
|
||||
public ChampionSkullBrazier( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
public override int LabelNumber => 1049489 + (int)m_Type;
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
Platform?.Validate();
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
Platform?.Validate();
|
||||
|
||||
BeginSacrifice( from );
|
||||
}
|
||||
BeginSacrifice(from);
|
||||
}
|
||||
|
||||
public void BeginSacrifice( Mobile from )
|
||||
{
|
||||
if ( Deleted )
|
||||
return;
|
||||
public void BeginSacrifice(Mobile from)
|
||||
{
|
||||
if (Deleted)
|
||||
return;
|
||||
|
||||
if ( m_Skull != null && m_Skull.Deleted )
|
||||
Skull = null;
|
||||
if (m_Skull != null && m_Skull.Deleted)
|
||||
Skull = null;
|
||||
|
||||
if ( from.Map != Map || !from.InRange( GetWorldLocation(), 3 ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 500446 ); // That is too far away.
|
||||
}
|
||||
else if ( !Harrower.CanSpawn )
|
||||
{
|
||||
from.SendMessage( "The harrower has already been spawned." );
|
||||
}
|
||||
else if ( m_Skull == null )
|
||||
{
|
||||
from.SendLocalizedMessage( 1049485 ); // What would you like to sacrifice?
|
||||
from.Target = new SacrificeTarget( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
SendLocalizedMessageTo( from, 1049487, "" ); // I already have my champions awakening skull!
|
||||
}
|
||||
}
|
||||
if (from.Map != Map || !from.InRange(GetWorldLocation(), 3))
|
||||
{
|
||||
from.SendLocalizedMessage(500446); // That is too far away.
|
||||
}
|
||||
else if (!Harrower.CanSpawn)
|
||||
{
|
||||
from.SendMessage("The harrower has already been spawned.");
|
||||
}
|
||||
else if (m_Skull == null)
|
||||
{
|
||||
from.SendLocalizedMessage(1049485); // What would you like to sacrifice?
|
||||
from.Target = new SacrificeTarget(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendLocalizedMessageTo(from, 1049487, ""); // I already have my champions awakening skull!
|
||||
}
|
||||
}
|
||||
|
||||
public void EndSacrifice( Mobile from, ChampionSkull skull )
|
||||
{
|
||||
if ( Deleted )
|
||||
return;
|
||||
public void EndSacrifice(Mobile from, ChampionSkull skull)
|
||||
{
|
||||
if (Deleted)
|
||||
return;
|
||||
|
||||
if ( m_Skull != null && m_Skull.Deleted )
|
||||
Skull = null;
|
||||
if (m_Skull != null && m_Skull.Deleted)
|
||||
Skull = null;
|
||||
|
||||
if ( from.Map != Map || !from.InRange( GetWorldLocation(), 3 ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 500446 ); // That is too far away.
|
||||
}
|
||||
else if ( !Harrower.CanSpawn )
|
||||
{
|
||||
from.SendMessage( "The harrower has already been spawned." );
|
||||
}
|
||||
else if ( skull == null )
|
||||
{
|
||||
SendLocalizedMessageTo( from, 1049488, "" ); // That is not my champions awakening skull!
|
||||
}
|
||||
else if ( m_Skull != null )
|
||||
{
|
||||
SendLocalizedMessageTo( from, 1049487, "" ); // I already have my champions awakening skull!
|
||||
}
|
||||
else if ( !skull.IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1049486 ); // You can only sacrifice items that are in your backpack!
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( skull.Type == Type )
|
||||
{
|
||||
skull.Movable = false;
|
||||
skull.MoveToWorld( GetWorldTop(), Map );
|
||||
if (from.Map != Map || !from.InRange(GetWorldLocation(), 3))
|
||||
{
|
||||
from.SendLocalizedMessage(500446); // That is too far away.
|
||||
}
|
||||
else if (!Harrower.CanSpawn)
|
||||
{
|
||||
from.SendMessage("The harrower has already been spawned.");
|
||||
}
|
||||
else if (skull == null)
|
||||
{
|
||||
SendLocalizedMessageTo(from, 1049488, ""); // That is not my champions awakening skull!
|
||||
}
|
||||
else if (m_Skull != null)
|
||||
{
|
||||
SendLocalizedMessageTo(from, 1049487, ""); // I already have my champions awakening skull!
|
||||
}
|
||||
else if (!skull.IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1049486); // You can only sacrifice items that are in your backpack!
|
||||
}
|
||||
else
|
||||
{
|
||||
if (skull.Type == Type)
|
||||
{
|
||||
skull.Movable = false;
|
||||
skull.MoveToWorld(GetWorldTop(), Map);
|
||||
|
||||
Skull = skull;
|
||||
}
|
||||
else
|
||||
{
|
||||
SendLocalizedMessageTo( from, 1049488, "" ); // That is not my champions awakening skull!
|
||||
}
|
||||
}
|
||||
}
|
||||
Skull = skull;
|
||||
}
|
||||
else
|
||||
{
|
||||
SendLocalizedMessageTo(from, 1049488, ""); // That is not my champions awakening skull!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SacrificeTarget : Target
|
||||
{
|
||||
private ChampionSkullBrazier m_Brazier;
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
public SacrificeTarget( ChampionSkullBrazier brazier ) : base( 12, false, TargetFlags.None )
|
||||
{
|
||||
m_Brazier = brazier;
|
||||
}
|
||||
writer.Write(0); // version
|
||||
|
||||
protected override void OnTarget( Mobile from, object targeted )
|
||||
{
|
||||
m_Brazier.EndSacrifice( from, targeted as ChampionSkull );
|
||||
}
|
||||
}
|
||||
writer.Write((int)m_Type);
|
||||
writer.Write(Platform);
|
||||
writer.Write(m_Skull);
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
int version = reader.ReadInt();
|
||||
|
||||
writer.Write( (int) m_Type );
|
||||
writer.Write( Platform );
|
||||
writer.Write( m_Skull );
|
||||
}
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Type = (ChampionSkullType)reader.ReadInt();
|
||||
Platform = reader.ReadItem() as ChampionSkullPlatform;
|
||||
m_Skull = reader.ReadItem();
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
if (Platform == null)
|
||||
Delete();
|
||||
|
||||
int version = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Type = (ChampionSkullType)reader.ReadInt();
|
||||
Platform = reader.ReadItem() as ChampionSkullPlatform;
|
||||
m_Skull = reader.ReadItem();
|
||||
if (Hue == 0x497)
|
||||
Hue = 0x455;
|
||||
|
||||
if ( Platform == null )
|
||||
Delete();
|
||||
if (Light != LightType.Circle300)
|
||||
Light = LightType.Circle300;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
private class SacrificeTarget : Target
|
||||
{
|
||||
private ChampionSkullBrazier m_Brazier;
|
||||
|
||||
if ( Hue == 0x497 )
|
||||
Hue = 0x455;
|
||||
public SacrificeTarget(ChampionSkullBrazier brazier) : base(12, false, TargetFlags.None)
|
||||
{
|
||||
m_Brazier = brazier;
|
||||
}
|
||||
|
||||
if ( Light != LightType.Circle300 )
|
||||
Light = LightType.Circle300;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
m_Brazier.EndSacrifice(from, targeted as ChampionSkull);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,125 +3,126 @@ using Server.Mobiles;
|
|||
|
||||
namespace Server.Engines.CannedEvil
|
||||
{
|
||||
public class ChampionSkullPlatform : BaseAddon
|
||||
{
|
||||
private ChampionSkullBrazier m_Power, m_Enlightenment, m_Venom, m_Pain, m_Greed, m_Death;
|
||||
public class ChampionSkullPlatform : BaseAddon
|
||||
{
|
||||
private ChampionSkullBrazier m_Power, m_Enlightenment, m_Venom, m_Pain, m_Greed, m_Death;
|
||||
|
||||
[Constructible]
|
||||
public ChampionSkullPlatform()
|
||||
{
|
||||
AddComponent( new AddonComponent( 0x71A ), -1, -1, -1 );
|
||||
AddComponent( new AddonComponent( 0x709 ), 0, -1, -1 );
|
||||
AddComponent( new AddonComponent( 0x709 ), 1, -1, -1 );
|
||||
AddComponent( new AddonComponent( 0x709 ), -1, 0, -1 );
|
||||
AddComponent( new AddonComponent( 0x709 ), 0, 0, -1 );
|
||||
AddComponent( new AddonComponent( 0x709 ), 1, 0, -1 );
|
||||
AddComponent( new AddonComponent( 0x709 ), -1, 1, -1 );
|
||||
AddComponent( new AddonComponent( 0x709 ), 0, 1, -1 );
|
||||
AddComponent( new AddonComponent( 0x71B ), 1, 1, -1 );
|
||||
[Constructible]
|
||||
public ChampionSkullPlatform()
|
||||
{
|
||||
AddComponent(new AddonComponent(0x71A), -1, -1, -1);
|
||||
AddComponent(new AddonComponent(0x709), 0, -1, -1);
|
||||
AddComponent(new AddonComponent(0x709), 1, -1, -1);
|
||||
AddComponent(new AddonComponent(0x709), -1, 0, -1);
|
||||
AddComponent(new AddonComponent(0x709), 0, 0, -1);
|
||||
AddComponent(new AddonComponent(0x709), 1, 0, -1);
|
||||
AddComponent(new AddonComponent(0x709), -1, 1, -1);
|
||||
AddComponent(new AddonComponent(0x709), 0, 1, -1);
|
||||
AddComponent(new AddonComponent(0x71B), 1, 1, -1);
|
||||
|
||||
AddComponent( new AddonComponent( 0x50F ), 0, -1, 4 );
|
||||
AddComponent( m_Power = new ChampionSkullBrazier( this, ChampionSkullType.Power ), 0, -1, 5 );
|
||||
AddComponent(new AddonComponent(0x50F), 0, -1, 4);
|
||||
AddComponent(m_Power = new ChampionSkullBrazier(this, ChampionSkullType.Power), 0, -1, 5);
|
||||
|
||||
AddComponent( new AddonComponent( 0x50F ), 1, -1, 4 );
|
||||
AddComponent( m_Enlightenment = new ChampionSkullBrazier( this, ChampionSkullType.Enlightenment ), 1, -1, 5 );
|
||||
AddComponent(new AddonComponent(0x50F), 1, -1, 4);
|
||||
AddComponent(m_Enlightenment = new ChampionSkullBrazier(this, ChampionSkullType.Enlightenment), 1, -1, 5);
|
||||
|
||||
AddComponent( new AddonComponent( 0x50F ), -1, 0, 4 );
|
||||
AddComponent( m_Venom = new ChampionSkullBrazier( this, ChampionSkullType.Venom ), -1, 0, 5 );
|
||||
AddComponent(new AddonComponent(0x50F), -1, 0, 4);
|
||||
AddComponent(m_Venom = new ChampionSkullBrazier(this, ChampionSkullType.Venom), -1, 0, 5);
|
||||
|
||||
AddComponent( new AddonComponent( 0x50F ), 1, 0, 4 );
|
||||
AddComponent( m_Pain = new ChampionSkullBrazier( this, ChampionSkullType.Pain ), 1, 0, 5 );
|
||||
AddComponent(new AddonComponent(0x50F), 1, 0, 4);
|
||||
AddComponent(m_Pain = new ChampionSkullBrazier(this, ChampionSkullType.Pain), 1, 0, 5);
|
||||
|
||||
AddComponent( new AddonComponent( 0x50F ), -1, 1, 4 );
|
||||
AddComponent( m_Greed = new ChampionSkullBrazier( this, ChampionSkullType.Greed ), -1, 1, 5 );
|
||||
AddComponent(new AddonComponent(0x50F), -1, 1, 4);
|
||||
AddComponent(m_Greed = new ChampionSkullBrazier(this, ChampionSkullType.Greed), -1, 1, 5);
|
||||
|
||||
AddComponent( new AddonComponent( 0x50F ), 0, 1, 4 );
|
||||
AddComponent( m_Death = new ChampionSkullBrazier( this, ChampionSkullType.Death ), 0, 1, 5 );
|
||||
AddComponent(new AddonComponent(0x50F), 0, 1, 4);
|
||||
AddComponent(m_Death = new ChampionSkullBrazier(this, ChampionSkullType.Death), 0, 1, 5);
|
||||
|
||||
AddonComponent comp = new LocalizedAddonComponent( 0x20D2, 1049495 );
|
||||
comp.Hue = 0x482;
|
||||
AddComponent( comp, 0, 0, 5 );
|
||||
AddonComponent comp = new LocalizedAddonComponent(0x20D2, 1049495);
|
||||
comp.Hue = 0x482;
|
||||
AddComponent(comp, 0, 0, 5);
|
||||
|
||||
comp = new LocalizedAddonComponent( 0x0BCF, 1049496 );
|
||||
comp.Hue = 0x482;
|
||||
AddComponent( comp, 0, 2, -7 );
|
||||
comp = new LocalizedAddonComponent(0x0BCF, 1049496);
|
||||
comp.Hue = 0x482;
|
||||
AddComponent(comp, 0, 2, -7);
|
||||
|
||||
comp = new LocalizedAddonComponent( 0x0BD0, 1049497 );
|
||||
comp.Hue = 0x482;
|
||||
AddComponent( comp, 2, 0, -7 );
|
||||
}
|
||||
comp = new LocalizedAddonComponent(0x0BD0, 1049497);
|
||||
comp.Hue = 0x482;
|
||||
AddComponent(comp, 2, 0, -7);
|
||||
}
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
if ( Validate( m_Power ) && Validate( m_Enlightenment ) && Validate( m_Venom ) && Validate( m_Pain ) && Validate( m_Greed ) && Validate( m_Death ) )
|
||||
{
|
||||
Mobile harrower = Harrower.Spawn( new Point3D( X, Y, Z + 6 ), Map );
|
||||
public ChampionSkullPlatform(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
if ( harrower == null )
|
||||
return;
|
||||
public void Validate()
|
||||
{
|
||||
if (Validate(m_Power) && Validate(m_Enlightenment) && Validate(m_Venom) && Validate(m_Pain) &&
|
||||
Validate(m_Greed) && Validate(m_Death))
|
||||
{
|
||||
Mobile harrower = Harrower.Spawn(new Point3D(X, Y, Z + 6), Map);
|
||||
|
||||
Clear( m_Power );
|
||||
Clear( m_Enlightenment );
|
||||
Clear( m_Venom );
|
||||
Clear( m_Pain );
|
||||
Clear( m_Greed );
|
||||
Clear( m_Death );
|
||||
}
|
||||
}
|
||||
if (harrower == null)
|
||||
return;
|
||||
|
||||
public void Clear( ChampionSkullBrazier brazier )
|
||||
{
|
||||
if ( brazier != null )
|
||||
{
|
||||
Effects.SendBoltEffect( brazier );
|
||||
Clear(m_Power);
|
||||
Clear(m_Enlightenment);
|
||||
Clear(m_Venom);
|
||||
Clear(m_Pain);
|
||||
Clear(m_Greed);
|
||||
Clear(m_Death);
|
||||
}
|
||||
}
|
||||
|
||||
brazier.Skull?.Delete();
|
||||
}
|
||||
}
|
||||
public void Clear(ChampionSkullBrazier brazier)
|
||||
{
|
||||
if (brazier != null)
|
||||
{
|
||||
Effects.SendBoltEffect(brazier);
|
||||
|
||||
public bool Validate( ChampionSkullBrazier brazier )
|
||||
{
|
||||
return ( brazier?.Skull != null && !brazier.Skull.Deleted );
|
||||
}
|
||||
brazier.Skull?.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public ChampionSkullPlatform( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
public bool Validate(ChampionSkullBrazier brazier)
|
||||
{
|
||||
return brazier?.Skull != null && !brazier.Skull.Deleted;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write( m_Power );
|
||||
writer.Write( m_Enlightenment );
|
||||
writer.Write( m_Venom );
|
||||
writer.Write( m_Pain );
|
||||
writer.Write( m_Greed );
|
||||
writer.Write( m_Death );
|
||||
}
|
||||
writer.Write(m_Power);
|
||||
writer.Write(m_Enlightenment);
|
||||
writer.Write(m_Venom);
|
||||
writer.Write(m_Pain);
|
||||
writer.Write(m_Greed);
|
||||
writer.Write(m_Death);
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Power = reader.ReadItem() as ChampionSkullBrazier;
|
||||
m_Enlightenment = reader.ReadItem() as ChampionSkullBrazier;
|
||||
m_Venom = reader.ReadItem() as ChampionSkullBrazier;
|
||||
m_Pain = reader.ReadItem() as ChampionSkullBrazier;
|
||||
m_Greed = reader.ReadItem() as ChampionSkullBrazier;
|
||||
m_Death = reader.ReadItem() as ChampionSkullBrazier;
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Power = reader.ReadItem() as ChampionSkullBrazier;
|
||||
m_Enlightenment = reader.ReadItem() as ChampionSkullBrazier;
|
||||
m_Venom = reader.ReadItem() as ChampionSkullBrazier;
|
||||
m_Pain = reader.ReadItem() as ChampionSkullBrazier;
|
||||
m_Greed = reader.ReadItem() as ChampionSkullBrazier;
|
||||
m_Death = reader.ReadItem() as ChampionSkullBrazier;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
namespace Server.Engines.CannedEvil
|
||||
{
|
||||
public enum ChampionSkullType
|
||||
{
|
||||
Power,
|
||||
Enlightenment,
|
||||
Venom,
|
||||
Pain,
|
||||
Greed,
|
||||
Death
|
||||
}
|
||||
public enum ChampionSkullType
|
||||
{
|
||||
Power,
|
||||
Enlightenment,
|
||||
Venom,
|
||||
Pain,
|
||||
Greed,
|
||||
Death
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -3,115 +3,131 @@ using Server.Mobiles;
|
|||
|
||||
namespace Server.Engines.CannedEvil
|
||||
{
|
||||
public enum ChampionSpawnType
|
||||
{
|
||||
Abyss,
|
||||
Arachnid,
|
||||
ColdBlood,
|
||||
ForestLord,
|
||||
VerminHorde,
|
||||
UnholyTerror,
|
||||
SleepingDragon,
|
||||
Glade,
|
||||
Pestilence
|
||||
}
|
||||
public enum ChampionSpawnType
|
||||
{
|
||||
Abyss,
|
||||
Arachnid,
|
||||
ColdBlood,
|
||||
ForestLord,
|
||||
VerminHorde,
|
||||
UnholyTerror,
|
||||
SleepingDragon,
|
||||
Glade,
|
||||
Pestilence
|
||||
}
|
||||
|
||||
public class ChampionSpawnInfo
|
||||
{
|
||||
public string Name { get; }
|
||||
public class ChampionSpawnInfo
|
||||
{
|
||||
public ChampionSpawnInfo(string name, Type champion, string[] levelNames, Type[][] spawnTypes)
|
||||
{
|
||||
Name = name;
|
||||
Champion = champion;
|
||||
LevelNames = levelNames;
|
||||
SpawnTypes = spawnTypes;
|
||||
}
|
||||
|
||||
public Type Champion { get; }
|
||||
public string Name{ get; }
|
||||
|
||||
public Type[][] SpawnTypes { get; }
|
||||
public Type Champion{ get; }
|
||||
|
||||
public string[] LevelNames { get; }
|
||||
public Type[][] SpawnTypes{ get; }
|
||||
|
||||
public ChampionSpawnInfo( string name, Type champion, string[] levelNames, Type[][] spawnTypes )
|
||||
{
|
||||
Name = name;
|
||||
Champion = champion;
|
||||
LevelNames = levelNames;
|
||||
SpawnTypes = spawnTypes;
|
||||
}
|
||||
public string[] LevelNames{ get; }
|
||||
|
||||
public static ChampionSpawnInfo[] Table { get; } =
|
||||
{
|
||||
new ChampionSpawnInfo( "Abyss", typeof( Semidar ), new[]{ "Foe", "Assassin", "Conqueror" }, new[] // Abyss
|
||||
{ // Abyss
|
||||
new[]{ typeof( GreaterMongbat ), typeof( Imp ) }, // Level 1
|
||||
new[]{ typeof( Gargoyle ), typeof( Harpy ) }, // Level 2
|
||||
new[]{ typeof( FireGargoyle ), typeof( StoneGargoyle ) }, // Level 3
|
||||
new[]{ typeof( Daemon ), typeof( Succubus ) } // Level 4
|
||||
} ),
|
||||
new ChampionSpawnInfo( "Arachnid", typeof( Mephitis ), new[]{ "Bane", "Killer", "Vanquisher" }, new[] // Arachnid
|
||||
{ // Arachnid
|
||||
new[]{ typeof( Scorpion ), typeof( GiantSpider ) }, // Level 1
|
||||
new[]{ typeof( TerathanDrone ), typeof( TerathanWarrior ) }, // Level 2
|
||||
new[]{ typeof( DreadSpider ), typeof( TerathanMatriarch ) }, // Level 3
|
||||
new[]{ typeof( PoisonElemental ), typeof( TerathanAvenger ) } // Level 4
|
||||
} ),
|
||||
new ChampionSpawnInfo( "Cold Blood", typeof( Rikktor ), new[]{ "Blight", "Slayer", "Destroyer" }, new[] // Cold Blood
|
||||
{ // Cold Blood
|
||||
new[]{ typeof( Lizardman ), typeof( Snake ) }, // Level 1
|
||||
new[]{ typeof( LavaLizard ), typeof( OphidianWarrior ) }, // Level 2
|
||||
new[]{ typeof( Drake ), typeof( OphidianArchmage ) }, // Level 3
|
||||
new[]{ typeof( Dragon ), typeof( OphidianKnight ) } // Level 4
|
||||
} ),
|
||||
new ChampionSpawnInfo( "Forest Lord", typeof( LordOaks ), new[]{ "Enemy", "Curse", "Slaughterer" }, new[] // Forest Lord
|
||||
{ // Forest Lord
|
||||
new[]{ typeof( Pixie ), typeof( ShadowWisp ) }, // Level 1
|
||||
new[]{ typeof( Kirin ), typeof( Wisp ) }, // Level 2
|
||||
new[]{ typeof( Centaur ), typeof( Unicorn ) }, // Level 3
|
||||
new[]{ typeof( EtherealWarrior ), typeof( SerpentineDragon ) } // Level 4
|
||||
} ),
|
||||
new ChampionSpawnInfo( "Vermin Horde", typeof( Barracoon ), new[]{ "Adversary", "Subjugator", "Eradicator" }, new[] // Vermin Horde
|
||||
{ // Vermin Horde
|
||||
new[]{ typeof( GiantRat ), typeof( Slime ) }, // Level 1
|
||||
new[]{ typeof( DireWolf ), typeof( Ratman ) }, // Level 2
|
||||
new[]{ typeof( HellHound ), typeof( RatmanMage ) }, // Level 3
|
||||
new[]{ typeof( RatmanArcher ), typeof( SilverSerpent ) } // Level 4
|
||||
} ),
|
||||
new ChampionSpawnInfo( "Unholy Terror", typeof( Neira ), new[]{ "Scourge", "Punisher", "Nemesis" }, new[] // Unholy Terror
|
||||
{ // Unholy Terror
|
||||
(Core.AOS ?
|
||||
new[]{ typeof( Bogle ), typeof( Ghoul ), typeof( Shade ), typeof( Spectre ), typeof( Wraith ) } // Level 1 (Pre-AoS)
|
||||
: new[]{ typeof( Ghoul ), typeof( Shade ), typeof( Spectre ), typeof( Wraith ) } ), // Level 1
|
||||
public static ChampionSpawnInfo[] Table{ get; } =
|
||||
{
|
||||
new ChampionSpawnInfo("Abyss", typeof(Semidar), new[] { "Foe", "Assassin", "Conqueror" }, new[] // Abyss
|
||||
{
|
||||
// Abyss
|
||||
new[] { typeof(GreaterMongbat), typeof(Imp) }, // Level 1
|
||||
new[] { typeof(Gargoyle), typeof(Harpy) }, // Level 2
|
||||
new[] { typeof(FireGargoyle), typeof(StoneGargoyle) }, // Level 3
|
||||
new[] { typeof(Daemon), typeof(Succubus) } // Level 4
|
||||
}),
|
||||
new ChampionSpawnInfo("Arachnid", typeof(Mephitis), new[] { "Bane", "Killer", "Vanquisher" }, new[] // Arachnid
|
||||
{
|
||||
// Arachnid
|
||||
new[] { typeof(Scorpion), typeof(GiantSpider) }, // Level 1
|
||||
new[] { typeof(TerathanDrone), typeof(TerathanWarrior) }, // Level 2
|
||||
new[] { typeof(DreadSpider), typeof(TerathanMatriarch) }, // Level 3
|
||||
new[] { typeof(PoisonElemental), typeof(TerathanAvenger) } // Level 4
|
||||
}),
|
||||
new ChampionSpawnInfo("Cold Blood", typeof(Rikktor), new[] { "Blight", "Slayer", "Destroyer" },
|
||||
new[] // Cold Blood
|
||||
{
|
||||
// Cold Blood
|
||||
new[] { typeof(Lizardman), typeof(Snake) }, // Level 1
|
||||
new[] { typeof(LavaLizard), typeof(OphidianWarrior) }, // Level 2
|
||||
new[] { typeof(Drake), typeof(OphidianArchmage) }, // Level 3
|
||||
new[] { typeof(Dragon), typeof(OphidianKnight) } // Level 4
|
||||
}),
|
||||
new ChampionSpawnInfo("Forest Lord", typeof(LordOaks), new[] { "Enemy", "Curse", "Slaughterer" },
|
||||
new[] // Forest Lord
|
||||
{
|
||||
// Forest Lord
|
||||
new[] { typeof(Pixie), typeof(ShadowWisp) }, // Level 1
|
||||
new[] { typeof(Kirin), typeof(Wisp) }, // Level 2
|
||||
new[] { typeof(Centaur), typeof(Unicorn) }, // Level 3
|
||||
new[] { typeof(EtherealWarrior), typeof(SerpentineDragon) } // Level 4
|
||||
}),
|
||||
new ChampionSpawnInfo("Vermin Horde", typeof(Barracoon), new[] { "Adversary", "Subjugator", "Eradicator" },
|
||||
new[] // Vermin Horde
|
||||
{
|
||||
// Vermin Horde
|
||||
new[] { typeof(GiantRat), typeof(Slime) }, // Level 1
|
||||
new[] { typeof(DireWolf), typeof(Ratman) }, // Level 2
|
||||
new[] { typeof(HellHound), typeof(RatmanMage) }, // Level 3
|
||||
new[] { typeof(RatmanArcher), typeof(SilverSerpent) } // Level 4
|
||||
}),
|
||||
new ChampionSpawnInfo("Unholy Terror", typeof(Neira), new[] { "Scourge", "Punisher", "Nemesis" },
|
||||
new[] // Unholy Terror
|
||||
{
|
||||
// Unholy Terror
|
||||
Core.AOS
|
||||
? new[]
|
||||
{
|
||||
typeof(Bogle), typeof(Ghoul), typeof(Shade), typeof(Spectre), typeof(Wraith)
|
||||
} // Level 1 (Pre-AoS)
|
||||
: new[] { typeof(Ghoul), typeof(Shade), typeof(Spectre), typeof(Wraith) }, // Level 1
|
||||
|
||||
new[]{ typeof( BoneMagi ), typeof( Mummy ), typeof( SkeletalMage ) }, // Level 2
|
||||
new[]{ typeof( BoneKnight ), typeof( Lich ), typeof( SkeletalKnight ) }, // Level 3
|
||||
new[]{ typeof( LichLord ), typeof( RottingCorpse ) } // Level 4
|
||||
} ),
|
||||
new ChampionSpawnInfo( "Sleeping Dragon", typeof( Serado ), new[]{ "Rival", "Challenger", "Antagonist" } , new[]
|
||||
{ // Unholy Terror
|
||||
new[]{ typeof( DeathwatchBeetleHatchling ), typeof( Lizardman ) },
|
||||
new[]{ typeof( DeathwatchBeetle ), typeof( Kappa ) },
|
||||
new[]{ typeof( LesserHiryu ), typeof( RevenantLion ) },
|
||||
new[]{ typeof( Hiryu ), typeof( Oni ) }
|
||||
} ),
|
||||
new ChampionSpawnInfo( "Glade", typeof( Twaulo ), new[]{ "Banisher", "Enforcer", "Eradicator" } , new[]
|
||||
{ // Glade
|
||||
new[]{ typeof( Pixie ), typeof( ShadowWisp ) },
|
||||
new[]{ typeof( Centaur ), typeof( MLDryad ) },
|
||||
new[]{ typeof( Satyr ), typeof( CuSidhe ) },
|
||||
new[]{ typeof( FeralTreefellow ), typeof( RagingGrizzlyBear ) }
|
||||
} ),
|
||||
new ChampionSpawnInfo( "The Corrupt", typeof( Ilhenir ), new[]{ "Cleanser", "Expunger", "Depurator" } , new[]
|
||||
{ // Unholy Terror
|
||||
new[]{ typeof( PlagueSpawn ), typeof( Bogling ) },
|
||||
new[]{ typeof( PlagueBeast ), typeof( BogThing ) },
|
||||
new[]{ typeof( PlagueBeastLord ), typeof( InterredGrizzle ) },
|
||||
new[]{ typeof( FetidEssence ), typeof( PestilentBandage ) }
|
||||
} )
|
||||
};
|
||||
new[] { typeof(BoneMagi), typeof(Mummy), typeof(SkeletalMage) }, // Level 2
|
||||
new[] { typeof(BoneKnight), typeof(Lich), typeof(SkeletalKnight) }, // Level 3
|
||||
new[] { typeof(LichLord), typeof(RottingCorpse) } // Level 4
|
||||
}),
|
||||
new ChampionSpawnInfo("Sleeping Dragon", typeof(Serado), new[] { "Rival", "Challenger", "Antagonist" }, new[]
|
||||
{
|
||||
// Unholy Terror
|
||||
new[] { typeof(DeathwatchBeetleHatchling), typeof(Lizardman) },
|
||||
new[] { typeof(DeathwatchBeetle), typeof(Kappa) },
|
||||
new[] { typeof(LesserHiryu), typeof(RevenantLion) },
|
||||
new[] { typeof(Hiryu), typeof(Oni) }
|
||||
}),
|
||||
new ChampionSpawnInfo("Glade", typeof(Twaulo), new[] { "Banisher", "Enforcer", "Eradicator" }, new[]
|
||||
{
|
||||
// Glade
|
||||
new[] { typeof(Pixie), typeof(ShadowWisp) },
|
||||
new[] { typeof(Centaur), typeof(MLDryad) },
|
||||
new[] { typeof(Satyr), typeof(CuSidhe) },
|
||||
new[] { typeof(FeralTreefellow), typeof(RagingGrizzlyBear) }
|
||||
}),
|
||||
new ChampionSpawnInfo("The Corrupt", typeof(Ilhenir), new[] { "Cleanser", "Expunger", "Depurator" }, new[]
|
||||
{
|
||||
// Unholy Terror
|
||||
new[] { typeof(PlagueSpawn), typeof(Bogling) },
|
||||
new[] { typeof(PlagueBeast), typeof(BogThing) },
|
||||
new[] { typeof(PlagueBeastLord), typeof(InterredGrizzle) },
|
||||
new[] { typeof(FetidEssence), typeof(PestilentBandage) }
|
||||
})
|
||||
};
|
||||
|
||||
public static ChampionSpawnInfo GetInfo( ChampionSpawnType type )
|
||||
{
|
||||
int v = (int)type;
|
||||
public static ChampionSpawnInfo GetInfo(ChampionSpawnType type)
|
||||
{
|
||||
int v = (int)type;
|
||||
|
||||
if ( v < 0 || v >= Table.Length )
|
||||
v = 0;
|
||||
if (v < 0 || v >= Table.Length)
|
||||
v = 0;
|
||||
|
||||
return Table[v];
|
||||
}
|
||||
}
|
||||
}
|
||||
return Table[v];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +1,56 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class HarrowerGate : Moongate
|
||||
{
|
||||
private Mobile m_Harrower;
|
||||
public class HarrowerGate : Moongate
|
||||
{
|
||||
private Mobile m_Harrower;
|
||||
|
||||
public override int LabelNumber => 1049498; // dark moongate
|
||||
public HarrowerGate(Mobile harrower, Point3D loc, Map map, Point3D targLoc, Map targMap) : base(targLoc, targMap)
|
||||
{
|
||||
m_Harrower = harrower;
|
||||
|
||||
public HarrowerGate( Mobile harrower, Point3D loc, Map map, Point3D targLoc, Map targMap ) : base( targLoc, targMap )
|
||||
{
|
||||
m_Harrower = harrower;
|
||||
Dispellable = false;
|
||||
ItemID = 0x1FD4;
|
||||
Light = LightType.Circle300;
|
||||
|
||||
Dispellable = false;
|
||||
ItemID = 0x1FD4;
|
||||
Light = LightType.Circle300;
|
||||
MoveToWorld(loc, map);
|
||||
}
|
||||
|
||||
MoveToWorld( loc, map );
|
||||
}
|
||||
public HarrowerGate(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public HarrowerGate( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
public override int LabelNumber => 1049498; // dark moongate
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write( m_Harrower );
|
||||
}
|
||||
writer.Write(m_Harrower);
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Harrower = reader.ReadMobile();
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Harrower = reader.ReadMobile();
|
||||
|
||||
if ( m_Harrower == null )
|
||||
Delete();
|
||||
if (m_Harrower == null)
|
||||
Delete();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( Light != LightType.Circle300 )
|
||||
Light = LightType.Circle300;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Light != LightType.Circle300)
|
||||
Light = LightType.Circle300;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,19 +2,19 @@ using System;
|
|||
|
||||
namespace Server.Engines.CannedEvil
|
||||
{
|
||||
public class RestartTimer : Timer
|
||||
{
|
||||
private ChampionSpawn m_Spawn;
|
||||
public class RestartTimer : Timer
|
||||
{
|
||||
private ChampionSpawn m_Spawn;
|
||||
|
||||
public RestartTimer( ChampionSpawn spawn, TimeSpan delay ) : base( delay )
|
||||
{
|
||||
m_Spawn = spawn;
|
||||
Priority = TimerPriority.FiveSeconds;
|
||||
}
|
||||
public RestartTimer(ChampionSpawn spawn, TimeSpan delay) : base(delay)
|
||||
{
|
||||
m_Spawn = spawn;
|
||||
Priority = TimerPriority.FiveSeconds;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Spawn.EndRestart();
|
||||
}
|
||||
}
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Spawn.EndRestart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,19 +2,19 @@ using System;
|
|||
|
||||
namespace Server.Engines.CannedEvil
|
||||
{
|
||||
public class SliceTimer : Timer
|
||||
{
|
||||
private ChampionSpawn m_Spawn;
|
||||
public class SliceTimer : Timer
|
||||
{
|
||||
private ChampionSpawn m_Spawn;
|
||||
|
||||
public SliceTimer( ChampionSpawn spawn ) : base( TimeSpan.FromSeconds( 1.0 ), TimeSpan.FromSeconds( 1.0 ) )
|
||||
{
|
||||
m_Spawn = spawn;
|
||||
Priority = TimerPriority.OneSecond;
|
||||
}
|
||||
public SliceTimer(ChampionSpawn spawn) : base(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0))
|
||||
{
|
||||
m_Spawn = spawn;
|
||||
Priority = TimerPriority.OneSecond;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Spawn.OnSlice();
|
||||
}
|
||||
}
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Spawn.OnSlice();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,103 +2,103 @@ using System;
|
|||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class StarRoomGate : Moongate
|
||||
{
|
||||
private bool m_Decays;
|
||||
private DateTime m_DecayTime;
|
||||
private Timer m_Timer;
|
||||
public class StarRoomGate : Moongate
|
||||
{
|
||||
private bool m_Decays;
|
||||
private DateTime m_DecayTime;
|
||||
private Timer m_Timer;
|
||||
|
||||
public override int LabelNumber => 1049498; // dark moongate
|
||||
[Constructible]
|
||||
public StarRoomGate() : this(false)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public StarRoomGate() : this( false )
|
||||
{
|
||||
}
|
||||
[Constructible]
|
||||
public StarRoomGate(bool decays, Point3D loc, Map map) : this(decays)
|
||||
{
|
||||
MoveToWorld(loc, map);
|
||||
Effects.PlaySound(loc, map, 0x20E);
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public StarRoomGate( bool decays, Point3D loc, Map map ) : this( decays )
|
||||
{
|
||||
MoveToWorld( loc, map );
|
||||
Effects.PlaySound( loc, map, 0x20E );
|
||||
}
|
||||
[Constructible]
|
||||
public StarRoomGate(bool decays) : base(new Point3D(5143, 1774, 0), Map.Felucca)
|
||||
{
|
||||
Dispellable = false;
|
||||
ItemID = 0x1FD4;
|
||||
|
||||
[Constructible]
|
||||
public StarRoomGate( bool decays ) : base( new Point3D( 5143, 1774, 0 ), Map.Felucca )
|
||||
{
|
||||
Dispellable = false;
|
||||
ItemID = 0x1FD4;
|
||||
if (decays)
|
||||
{
|
||||
m_Decays = true;
|
||||
m_DecayTime = DateTime.UtcNow + TimeSpan.FromMinutes(2.0);
|
||||
|
||||
if ( decays )
|
||||
{
|
||||
m_Decays = true;
|
||||
m_DecayTime = DateTime.UtcNow + TimeSpan.FromMinutes( 2.0 );
|
||||
m_Timer = new InternalTimer(this, m_DecayTime);
|
||||
m_Timer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
m_Timer = new InternalTimer( this, m_DecayTime );
|
||||
m_Timer.Start();
|
||||
}
|
||||
}
|
||||
public StarRoomGate(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public StarRoomGate( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
public override int LabelNumber => 1049498; // dark moongate
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
m_Timer?.Stop();
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
m_Timer?.Stop();
|
||||
|
||||
base.OnAfterDelete();
|
||||
}
|
||||
base.OnAfterDelete();
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write( m_Decays );
|
||||
writer.Write(m_Decays);
|
||||
|
||||
if ( m_Decays )
|
||||
writer.WriteDeltaTime( m_DecayTime );
|
||||
}
|
||||
if (m_Decays)
|
||||
writer.WriteDeltaTime(m_DecayTime);
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Decays = reader.ReadBool();
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Decays = reader.ReadBool();
|
||||
|
||||
if ( m_Decays )
|
||||
{
|
||||
m_DecayTime = reader.ReadDeltaTime();
|
||||
if (m_Decays)
|
||||
{
|
||||
m_DecayTime = reader.ReadDeltaTime();
|
||||
|
||||
m_Timer = new InternalTimer( this, m_DecayTime );
|
||||
m_Timer.Start();
|
||||
}
|
||||
m_Timer = new InternalTimer(this, m_DecayTime);
|
||||
m_Timer.Start();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private Item m_Item;
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private Item m_Item;
|
||||
|
||||
public InternalTimer( Item item, DateTime end ) : base( end - DateTime.UtcNow )
|
||||
{
|
||||
m_Item = item;
|
||||
}
|
||||
public InternalTimer(Item item, DateTime end) : base(end - DateTime.UtcNow)
|
||||
{
|
||||
m_Item = item;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Item.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Item.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue