Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
485
Scripts/SubSystem/Pet Shrink/ConfigParser.cs
Normal file
485
Scripts/SubSystem/Pet Shrink/ConfigParser.cs
Normal file
@@ -0,0 +1,485 @@
|
||||
#region AuthorHeader
|
||||
//
|
||||
// ConfigParser version 1.2 - utilities version 2.0, by Xanthos
|
||||
//
|
||||
// Provides for parsing of xml files containing values to be used to set C# variables during
|
||||
// initialization of a module. This code will throw exceptions if the data does not match
|
||||
// the expected type or number of elements (in the case of arrays) so that the problem can
|
||||
// be corrected to avoid potentially catastrophic runtime errors.
|
||||
// If the config file does not exist or cannot be read it will simply output an error to the
|
||||
// console and continue. In other words - it's ok not to provide a config file.
|
||||
//
|
||||
#endregion AuthorHeader
|
||||
#undef HALT_ON_ERRORS
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using Server;
|
||||
|
||||
namespace Xanthos.Utilities
|
||||
{
|
||||
public class ConfigParser
|
||||
{
|
||||
public static Element GetConfig( string filename, string tag )
|
||||
{
|
||||
Element element = GetConfig( filename );
|
||||
|
||||
if ( element != null )
|
||||
element = GetConfig( element, tag );
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public static Element GetConfig( string filename )
|
||||
{
|
||||
XmlTextReader reader = null;
|
||||
Element element = null;
|
||||
DOMParser parser;
|
||||
|
||||
try
|
||||
{
|
||||
Console.WriteLine( "Xanthos.Utilities.ConfigParser attempting to load {0}...", filename );
|
||||
reader = new XmlTextReader( filename );
|
||||
parser = new DOMParser();
|
||||
element = parser.Parse( reader );
|
||||
Console.WriteLine( "Xanthos.Utilities.ConfigParser success!" );
|
||||
|
||||
}
|
||||
catch ( Exception exc )
|
||||
{
|
||||
// Fail gracefully only on errors reading the file
|
||||
if ( !( exc is System.IO.IOException ))
|
||||
throw;
|
||||
|
||||
Console.WriteLine( "Xanthos.Utilities.ConfigParser failed." );
|
||||
}
|
||||
|
||||
if ( null != reader )
|
||||
reader.Close();
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public static Element GetConfig( Element element, string tag )
|
||||
{
|
||||
if ( element.ChildElements.Count > 0 )
|
||||
{
|
||||
foreach( Element child in element.ChildElements )
|
||||
{
|
||||
if ( child.TagName == tag )
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class DOMParser
|
||||
{
|
||||
private Stack m_Elements;
|
||||
private Element m_CurrentElement;
|
||||
private Element m_RootElement;
|
||||
|
||||
public DOMParser()
|
||||
{
|
||||
m_Elements = new Stack();
|
||||
m_CurrentElement = null;
|
||||
m_RootElement = null;
|
||||
}
|
||||
|
||||
public Element Parse( XmlTextReader reader )
|
||||
{
|
||||
Element element = null;
|
||||
|
||||
while ( !reader.EOF )
|
||||
{
|
||||
reader.Read();
|
||||
switch ( reader.NodeType )
|
||||
{
|
||||
case XmlNodeType.Element :
|
||||
element = new Element( reader.LocalName );
|
||||
m_CurrentElement = element;
|
||||
if ( m_Elements.Count == 0 )
|
||||
{
|
||||
m_RootElement = element;
|
||||
m_Elements.Push( element );
|
||||
}
|
||||
else
|
||||
{
|
||||
Element parent = (Element)m_Elements.Peek();
|
||||
parent.ChildElements.Add( element );
|
||||
|
||||
if ( reader.IsEmptyElement )
|
||||
break;
|
||||
else
|
||||
m_Elements.Push( element );
|
||||
}
|
||||
if ( reader.HasAttributes )
|
||||
{
|
||||
while( reader.MoveToNextAttribute() )
|
||||
{
|
||||
m_CurrentElement.setAttribute( reader.Name, reader.Value );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XmlNodeType.Attribute :
|
||||
element.setAttribute( reader.Name, reader.Value );
|
||||
break;
|
||||
case XmlNodeType.EndElement :
|
||||
m_Elements.Pop();
|
||||
break;
|
||||
case XmlNodeType.Text :
|
||||
m_CurrentElement.Text = reader.Value;
|
||||
break;
|
||||
case XmlNodeType.CDATA :
|
||||
m_CurrentElement.Text = reader.Value;
|
||||
break;
|
||||
default :
|
||||
// ignore
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m_RootElement;
|
||||
}
|
||||
}
|
||||
|
||||
public class Elements : CollectionBase
|
||||
{
|
||||
public Elements()
|
||||
{
|
||||
}
|
||||
|
||||
public void Add( Element element )
|
||||
{
|
||||
List.Add( element );
|
||||
}
|
||||
|
||||
public Element this[ int index ]
|
||||
{
|
||||
get { return (Element)List[index]; }
|
||||
}
|
||||
}
|
||||
|
||||
public class Element
|
||||
{
|
||||
private String m_TagName;
|
||||
private String m_Text;
|
||||
private StringDictionary m_Attributes;
|
||||
private Elements m_ChildElements;
|
||||
|
||||
public Element( String tagName )
|
||||
{
|
||||
m_TagName = tagName;
|
||||
m_Attributes = new StringDictionary();
|
||||
m_ChildElements = new Elements();
|
||||
m_Text = "";
|
||||
}
|
||||
|
||||
public String TagName
|
||||
{
|
||||
get { return m_TagName; }
|
||||
set { m_TagName = value; }
|
||||
}
|
||||
|
||||
public string Text
|
||||
{
|
||||
get { return m_Text; }
|
||||
set { m_Text = value; }
|
||||
}
|
||||
|
||||
public Elements ChildElements
|
||||
{
|
||||
get { return m_ChildElements; }
|
||||
}
|
||||
|
||||
public StringDictionary Attributes
|
||||
{
|
||||
get { return m_Attributes; }
|
||||
}
|
||||
|
||||
public String Attribute( String name )
|
||||
{
|
||||
return (String)m_Attributes[name];
|
||||
}
|
||||
|
||||
public void setAttribute( String name, String value )
|
||||
{
|
||||
m_Attributes.Add( name, value );
|
||||
}
|
||||
|
||||
#region Xml to data type conversions
|
||||
|
||||
public bool GetBoolValue( out bool val )
|
||||
{
|
||||
val = false;
|
||||
|
||||
try
|
||||
{
|
||||
if ( null != m_Text && "" != m_Text )
|
||||
{
|
||||
val = bool.Parse( m_Text );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch ( Exception exc ) { HandleError( exc ); }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool GetDoubleValue( out double val )
|
||||
{
|
||||
val = 0;
|
||||
|
||||
try
|
||||
{
|
||||
if ( null != m_Text && "" != m_Text )
|
||||
{
|
||||
val = double.Parse( m_Text );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch ( Exception exc ) { HandleError( exc ); }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool GetIntValue( out int val )
|
||||
{
|
||||
val = 0;
|
||||
|
||||
try
|
||||
{
|
||||
if ( null != m_Text && "" != m_Text )
|
||||
{
|
||||
val = Int32.Parse( m_Text );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch ( Exception exc ) { HandleError( exc ); }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool GetAccessLevelValue( out AccessLevel val )
|
||||
{
|
||||
val = AccessLevel.Player;
|
||||
try
|
||||
{
|
||||
val = (AccessLevel)AccessLevel.Parse( typeof(Server.AccessLevel), m_Text, true );
|
||||
}
|
||||
catch ( Exception exc ) { HandleError( exc ); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool GetMapValue( out Map val )
|
||||
{
|
||||
val = null;
|
||||
try
|
||||
{
|
||||
val = Map.Parse( m_Text );
|
||||
|
||||
if ( null == val )
|
||||
throw new ArgumentException( "Map expected" );
|
||||
}
|
||||
catch ( Exception exc ) { HandleError( exc ); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool GetTypeValue( out Type val )
|
||||
{
|
||||
val = null;
|
||||
try
|
||||
{
|
||||
val = Type.GetType( m_Text );
|
||||
|
||||
if ( null == val )
|
||||
throw new ArgumentException( "Type expected" );
|
||||
}
|
||||
catch ( Exception exc ) { HandleError( exc ); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool GetPoint3DValue( out Point3D val )
|
||||
{
|
||||
val = new Point3D();
|
||||
int elementsExpected = 3;
|
||||
|
||||
try
|
||||
{
|
||||
if ( null == ChildElements )
|
||||
return false;
|
||||
|
||||
if ( elementsExpected != ChildElements.Count )
|
||||
throw new System.IndexOutOfRangeException( elementsExpected + " elements were expected" );
|
||||
|
||||
int temp;
|
||||
|
||||
if ( ChildElements[ 0 ].GetIntValue( out temp ))
|
||||
val.X = temp;
|
||||
else
|
||||
throw new System.ArrayTypeMismatchException( "Int expected" );
|
||||
|
||||
if ( ChildElements[ 1 ].GetIntValue( out temp ))
|
||||
val.Y = temp;
|
||||
else
|
||||
throw new System.ArrayTypeMismatchException( "Int expected" );
|
||||
|
||||
if ( ChildElements[ 2 ].GetIntValue( out temp ))
|
||||
val.Z = temp;
|
||||
else
|
||||
throw new System.ArrayTypeMismatchException( "Int expected" );
|
||||
}
|
||||
catch ( Exception exc ) { HandleError( exc ); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public bool GetArray( out bool[] val )
|
||||
{
|
||||
return GetArray( 0, out val );
|
||||
}
|
||||
|
||||
public bool GetArray( int elementsExpected, out bool[] val )
|
||||
{
|
||||
val = null;
|
||||
|
||||
if ( null == ChildElements )
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
if ( elementsExpected > 0 && elementsExpected != ChildElements.Count )
|
||||
throw new System.IndexOutOfRangeException( elementsExpected + " elements were expected" );
|
||||
|
||||
bool[] array = new bool[ ChildElements.Count ];
|
||||
bool temp;
|
||||
|
||||
for ( int i = 0; i < ChildElements.Count; i++ )
|
||||
{
|
||||
if ( ChildElements[ i ].GetBoolValue( out temp ))
|
||||
array[ i ] = temp;
|
||||
else
|
||||
throw new System.ArrayTypeMismatchException( "Bool expected" );
|
||||
}
|
||||
val = array;
|
||||
}
|
||||
catch ( Exception exc ) { HandleError( exc ); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool GetArray( out int[] val )
|
||||
{
|
||||
return GetArray( 0, out val );
|
||||
}
|
||||
|
||||
public bool GetArray( int elementsExpected, out int[] val )
|
||||
{
|
||||
val = null;
|
||||
|
||||
if ( null == ChildElements )
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
if ( elementsExpected > 0 && elementsExpected != ChildElements.Count )
|
||||
throw new System.IndexOutOfRangeException( elementsExpected + " elements were expected" );
|
||||
|
||||
int[] array = new int[ ChildElements.Count ];
|
||||
int temp;
|
||||
|
||||
for ( int i = 0; i < ChildElements.Count; i++ )
|
||||
{
|
||||
if ( ChildElements[ i ].GetIntValue( out temp ))
|
||||
array[ i ] = temp;
|
||||
else
|
||||
throw new System.ArrayTypeMismatchException( "Int expected" );
|
||||
}
|
||||
val = array;
|
||||
}
|
||||
catch ( Exception exc ) { HandleError( exc ); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool GetArray( out Type[] val )
|
||||
{
|
||||
return GetArray( 0, out val );
|
||||
}
|
||||
|
||||
public bool GetArray( int elementsExpected, out Type[] val )
|
||||
{
|
||||
val = null;
|
||||
|
||||
if ( null == ChildElements )
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
if ( elementsExpected > 0 && elementsExpected != ChildElements.Count )
|
||||
throw new System.IndexOutOfRangeException( elementsExpected + " elements were expected" );
|
||||
|
||||
Type[] array = new Type[ ChildElements.Count ];
|
||||
|
||||
for ( int i = 0; i < ChildElements.Count; i++ )
|
||||
{
|
||||
array[ i ] = Type.GetType( ChildElements[ i ].Text );
|
||||
}
|
||||
val = array;
|
||||
}
|
||||
catch ( Exception exc ) { HandleError( exc ); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool GetArray( out string[] val )
|
||||
{
|
||||
return GetArray( 0, out val );
|
||||
}
|
||||
|
||||
public bool GetArray( int elementsExpected, out string[] val )
|
||||
{
|
||||
val = null;
|
||||
|
||||
if ( null == ChildElements )
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
if ( elementsExpected > 0 && elementsExpected != ChildElements.Count )
|
||||
throw new System.IndexOutOfRangeException( elementsExpected + " elements were expected" );
|
||||
|
||||
string[] array = new string[ ChildElements.Count ];
|
||||
|
||||
for ( int i = 0; i < ChildElements.Count; i++ )
|
||||
{
|
||||
if ( null != ChildElements[ i ].Text )
|
||||
array[ i ] = ChildElements[ i ].Text;
|
||||
else
|
||||
throw new System.ArrayTypeMismatchException( "String expected" );
|
||||
}
|
||||
val = array;
|
||||
}
|
||||
catch ( Exception exc ) { HandleError( exc ); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void HandleError( Exception exc )
|
||||
{
|
||||
Console.WriteLine( "\nXanthos.Utilities.ConfigParser error:\n{0}\nElement: <{1}>{2}</{1}>\n", exc.Message, TagName, Text );
|
||||
#if HALT_ON_ERRORS
|
||||
throw exc;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
143
Scripts/SubSystem/Pet Shrink/Misc.cs
Normal file
143
Scripts/SubSystem/Pet Shrink/Misc.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
#region AuthorHeader
|
||||
//
|
||||
// Misc version 2.0 - utilities version 2.0, by Xanthos
|
||||
//
|
||||
//
|
||||
#endregion AuthorHeader
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Security;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
using Server.Commands;
|
||||
|
||||
namespace Xanthos.Utilities
|
||||
{
|
||||
public class Misc
|
||||
{
|
||||
/// <summary>
|
||||
/// The hues used for gumps in the systems
|
||||
/// </summary>
|
||||
public static int kLabelHue = 0x480;
|
||||
public static int kGreenHue = 0x40;
|
||||
public static int kRedHue = 0x20;
|
||||
|
||||
public static bool IsArtifact( Item item )
|
||||
{
|
||||
if ( null == item )
|
||||
return false;
|
||||
|
||||
Type t = item.GetType();
|
||||
PropertyInfo prop = null;
|
||||
|
||||
try { prop = t.GetProperty( "ArtifactRarity" ); }
|
||||
catch {}
|
||||
|
||||
if ( null == prop || (int)(prop.GetValue( item, null )) <= 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IsPlayerConstructed( Item item )
|
||||
{
|
||||
if ( null == item )
|
||||
return false;
|
||||
|
||||
Type t = item.GetType();
|
||||
PropertyInfo prop = null;
|
||||
|
||||
try { prop = t.GetProperty( "PlayerConstructed" ); }
|
||||
catch {}
|
||||
|
||||
if ( null == prop || true != (bool)(prop.GetValue( item, null )))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Puts spaces before type name inner-caps
|
||||
//
|
||||
public static string GetFriendlyClassName( string typeName )
|
||||
{
|
||||
for ( int index = 1; index < typeName.Length; index++ )
|
||||
{
|
||||
if ( char.IsUpper( typeName, index ) )
|
||||
{
|
||||
typeName.Insert( index++, " " );
|
||||
}
|
||||
}
|
||||
|
||||
return typeName;
|
||||
}
|
||||
|
||||
public static object InvokeParameterlessMethod( object target, string method )
|
||||
{
|
||||
object result = null;
|
||||
|
||||
try
|
||||
{
|
||||
Type objectType = target.GetType();
|
||||
MethodInfo methodInfo = objectType.GetMethod( method );
|
||||
|
||||
result = methodInfo.Invoke( target, null );
|
||||
}
|
||||
catch ( SecurityException exc )
|
||||
{
|
||||
Console.WriteLine( "SecurityException: " + exc.Message );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void SendCommandDetails( Mobile player, string command )
|
||||
{
|
||||
SendCommandDescription( player, command );
|
||||
SendCommandUsage( player, command );
|
||||
}
|
||||
|
||||
public static void SendCommandUsage( Mobile player, string command )
|
||||
{
|
||||
string message;
|
||||
CommandEntry entry = CommandSystem.Entries[ command ];
|
||||
|
||||
if ( null != entry )
|
||||
{
|
||||
MethodInfo mi = entry.Handler.Method;
|
||||
|
||||
object[] attrs = mi.GetCustomAttributes( typeof( UsageAttribute ), false );
|
||||
|
||||
UsageAttribute usage = attrs.Length > 0 ? attrs[ 0 ] as UsageAttribute : null;
|
||||
|
||||
message = "Format: " + ( null == usage ? " - no usage" : usage.Usage );
|
||||
}
|
||||
else
|
||||
message = command + " - unknown command";
|
||||
|
||||
player.SendMessage( kRedHue, message );
|
||||
}
|
||||
|
||||
public static void SendCommandDescription( Mobile player, string command )
|
||||
{
|
||||
string message;
|
||||
CommandEntry entry = CommandSystem.Entries[ command ];
|
||||
|
||||
if ( null != entry )
|
||||
{
|
||||
MethodInfo mi = entry.Handler.Method;
|
||||
|
||||
object[] attrs = mi.GetCustomAttributes( typeof( DescriptionAttribute ), false );
|
||||
|
||||
DescriptionAttribute desc = attrs.Length > 0 ? attrs[ 0 ] as DescriptionAttribute : null;
|
||||
|
||||
message = command + ": " + ( null == desc ? " - no description" : desc.Description );
|
||||
}
|
||||
else
|
||||
message = command + " - unknown command";
|
||||
|
||||
player.SendMessage( kRedHue, message );
|
||||
}
|
||||
}
|
||||
}
|
||||
325
Scripts/SubSystem/Pet Shrink/NewHitchingPost.cs
Normal file
325
Scripts/SubSystem/Pet Shrink/NewHitchingPost.cs
Normal file
@@ -0,0 +1,325 @@
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
using System.Linq;
|
||||
|
||||
using Xanthos.Interfaces;
|
||||
|
||||
namespace Xanthos.ShrinkSystem
|
||||
{
|
||||
[Flipable(0x14E8, 0x14E7)]
|
||||
public class NewHitchingPost : AddonComponent, IShrinkTool
|
||||
{
|
||||
private int m_ShrinkCharges;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ShrinkCharges
|
||||
{
|
||||
get { return m_ShrinkCharges; }
|
||||
set
|
||||
{
|
||||
m_ShrinkCharges = value;
|
||||
|
||||
if (m_ShrinkCharges == 0 && Addon == null && World.Loaded)
|
||||
Delete();
|
||||
else
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
bool IShrinkTool.DeleteWhenEmpty { get => World.Loaded && Addon == null; set { } }
|
||||
|
||||
protected virtual bool DeleteIfUnlinked => false;
|
||||
|
||||
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
|
||||
|
||||
[Constructable]
|
||||
public NewHitchingPost()
|
||||
: this(0x14E7)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public NewHitchingPost(int itemID)
|
||||
: this(itemID, ShrinkConfig.ShrinkCharges)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public NewHitchingPost(int itemID, int charges)
|
||||
: base(itemID)
|
||||
{
|
||||
m_ShrinkCharges = charges;
|
||||
}
|
||||
|
||||
public NewHitchingPost(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void AddNameProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.AddNameProperties(list);
|
||||
|
||||
if (m_ShrinkCharges >= 0)
|
||||
list.Add(1060658, "Charges\t{0}", m_ShrinkCharges.ToString());
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (Movable && !IsChildOf(from.Backpack))
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
else
|
||||
ShrinkTarget.Begin(from, this);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(m_ShrinkCharges);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.ReadInt();
|
||||
|
||||
m_ShrinkCharges = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
#region Addons
|
||||
|
||||
public class NewHitchingPostEastAddon : BaseAddon
|
||||
{
|
||||
private int m_ShrinkCharges;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ShrinkCharges => Deleted ? m_ShrinkCharges : Components.OfType<IShrinkTool>().Sum(c => c.ShrinkCharges);
|
||||
|
||||
public override BaseAddonDeed Deed => new NewHitchingPostEastDeed(ShrinkCharges);
|
||||
|
||||
public override bool RetainDeedHue => true;
|
||||
|
||||
[Constructable]
|
||||
public NewHitchingPostEastAddon()
|
||||
: this(ShrinkConfig.ShrinkCharges)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public NewHitchingPostEastAddon(int charges)
|
||||
{
|
||||
AddComponent(new NewHitchingPost(0x14E7, m_ShrinkCharges = charges), 0, 0, 0);
|
||||
}
|
||||
|
||||
public NewHitchingPostEastAddon(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void OnChop(Mobile from)
|
||||
{
|
||||
m_ShrinkCharges = ShrinkCharges;
|
||||
|
||||
//base.OnChop(from, tool);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class NewHitchingPostSouthAddon : BaseAddon
|
||||
{
|
||||
private int m_ShrinkCharges;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ShrinkCharges => Deleted ? m_ShrinkCharges : Components.OfType<IShrinkTool>().Sum(c => c.ShrinkCharges);
|
||||
|
||||
public override BaseAddonDeed Deed => new NewHitchingPostSouthDeed(ShrinkCharges);
|
||||
|
||||
public override bool RetainDeedHue => true;
|
||||
|
||||
[Constructable]
|
||||
public NewHitchingPostSouthAddon()
|
||||
: this(ShrinkConfig.ShrinkCharges)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public NewHitchingPostSouthAddon(int charges)
|
||||
{
|
||||
AddComponent(new NewHitchingPost(0x14E8, m_ShrinkCharges = charges), 0, 0, 0);
|
||||
}
|
||||
|
||||
public NewHitchingPostSouthAddon(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void OnChop(Mobile from)
|
||||
{
|
||||
m_ShrinkCharges = ShrinkCharges;
|
||||
|
||||
//base.OnChop(from, tool);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Deeds
|
||||
|
||||
public class NewHitchingPostEastDeed : BaseAddonDeed
|
||||
{
|
||||
private int m_ShrinkCharges;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ShrinkCharges
|
||||
{
|
||||
get { return m_ShrinkCharges; }
|
||||
set
|
||||
{
|
||||
m_ShrinkCharges = value;
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override BaseAddon Addon => new NewHitchingPostEastAddon(m_ShrinkCharges);
|
||||
|
||||
[Constructable]
|
||||
public NewHitchingPostEastDeed()
|
||||
: this(ShrinkConfig.ShrinkCharges)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public NewHitchingPostEastDeed(int charges)
|
||||
{
|
||||
m_ShrinkCharges = charges;
|
||||
|
||||
Name = "Hitching Post (East)";
|
||||
}
|
||||
|
||||
public NewHitchingPostEastDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void AddNameProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.AddNameProperties(list);
|
||||
|
||||
if (m_ShrinkCharges >= 0)
|
||||
list.Add(1060658, "Charges\t{0}", m_ShrinkCharges.ToString());
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1);
|
||||
|
||||
writer.Write(m_ShrinkCharges);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var v = reader.ReadInt();
|
||||
|
||||
m_ShrinkCharges = reader.ReadInt();
|
||||
|
||||
//if (v > 0 && Insensitive.Contains(Tooltip1, "Charges"))
|
||||
// Tooltip1 = null;
|
||||
}
|
||||
}
|
||||
|
||||
public class NewHitchingPostSouthDeed : BaseAddonDeed
|
||||
{
|
||||
private int m_ShrinkCharges;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ShrinkCharges
|
||||
{
|
||||
get { return m_ShrinkCharges; }
|
||||
set
|
||||
{
|
||||
m_ShrinkCharges = value;
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override BaseAddon Addon => new NewHitchingPostSouthAddon(m_ShrinkCharges);
|
||||
|
||||
[Constructable]
|
||||
public NewHitchingPostSouthDeed()
|
||||
: this(ShrinkConfig.ShrinkCharges)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public NewHitchingPostSouthDeed(int charges)
|
||||
{
|
||||
m_ShrinkCharges = charges;
|
||||
|
||||
Name = "Hitching Post (South)";
|
||||
}
|
||||
|
||||
public NewHitchingPostSouthDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void AddNameProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.AddNameProperties(list);
|
||||
|
||||
if (m_ShrinkCharges >= 0)
|
||||
list.Add(1060658, "Charges\t{0}", m_ShrinkCharges.ToString());
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1);
|
||||
|
||||
writer.Write(m_ShrinkCharges);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var v = reader.ReadInt();
|
||||
|
||||
m_ShrinkCharges = reader.ReadInt();
|
||||
|
||||
//if (v > 0 && Insensitive.Contains(Tooltip1, "Charges"))
|
||||
// Tooltip1 = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
87
Scripts/SubSystem/Pet Shrink/PetLeash.cs
Normal file
87
Scripts/SubSystem/Pet Shrink/PetLeash.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using Server;
|
||||
|
||||
using Xanthos.Interfaces;
|
||||
|
||||
namespace Xanthos.ShrinkSystem
|
||||
{
|
||||
public class PetLeash : Item, IShrinkTool
|
||||
{
|
||||
private int m_ShrinkCharges;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ShrinkCharges
|
||||
{
|
||||
get { return m_ShrinkCharges; }
|
||||
set
|
||||
{
|
||||
m_ShrinkCharges = value;
|
||||
|
||||
if (m_ShrinkCharges == 0 && DeleteWhenEmpty)
|
||||
Delete();
|
||||
else
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool DeleteWhenEmpty { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public PetLeash()
|
||||
: this(ShrinkConfig.ShrinkCharges)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public PetLeash(int charges)
|
||||
: base(0x1374)
|
||||
{
|
||||
ShrinkCharges = charges;
|
||||
|
||||
Name = "Pet Leash";
|
||||
DeleteWhenEmpty = true;
|
||||
Weight = 1.0;
|
||||
|
||||
LootType = ShrinkConfig.BlessedLeash ? LootType.Blessed : LootType.Regular;
|
||||
}
|
||||
|
||||
public PetLeash(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void AddNameProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.AddNameProperties(list);
|
||||
|
||||
if (ShrinkCharges >= 0)
|
||||
list.Add(1060658, "Charges\t{0}", ShrinkCharges.ToString());
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
else
|
||||
ShrinkTarget.Begin(from, this);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1);
|
||||
|
||||
writer.Write(DeleteWhenEmpty);
|
||||
writer.Write(ShrinkCharges);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var v = reader.ReadInt();
|
||||
|
||||
DeleteWhenEmpty = v >= 1 && reader.ReadBool();
|
||||
ShrinkCharges = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
207
Scripts/SubSystem/Pet Shrink/Replace.cs
Normal file
207
Scripts/SubSystem/Pet Shrink/Replace.cs
Normal file
@@ -0,0 +1,207 @@
|
||||
#region AuthorHeader
|
||||
//
|
||||
// Replace version 1.0 - utilities version 2.0, by Xanthos
|
||||
//
|
||||
//
|
||||
#endregion AuthorHeader
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using Server.Prompts;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using Server.Commands;
|
||||
using Server.Commands.Generic;
|
||||
|
||||
namespace Xanthos.Utilities
|
||||
{
|
||||
public class PickReplacementTarget : Target
|
||||
{
|
||||
private Item m_ItemToReplace;
|
||||
private bool m_CopyDeep;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandHandlers.Register( "ReplaceItem", AccessLevel.GameMaster, new CommandEventHandler( ReplaceItem_OnCommand ) );
|
||||
// CommandHandlers.Register( "UpgradeShrinkSystem", AccessLevel.GameMaster, new CommandEventHandler( UpgradeShrinkSystem ) );
|
||||
}
|
||||
|
||||
public PickReplacementTarget( object o, bool copyDeep ) : base( -1, false, TargetFlags.None )
|
||||
{
|
||||
m_ItemToReplace = o as Item;
|
||||
m_CopyDeep = copyDeep;
|
||||
}
|
||||
|
||||
[Usage( "ReplaceItem [-d]" )]
|
||||
[Description( "Replaces an item with another copying properties of the replaced to the replacement." )]
|
||||
private static void ReplaceItem_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
bool copyDeep = false;
|
||||
|
||||
if ( e.Length == 1 && e.GetString( 0 ).Equals( "-d" ))
|
||||
copyDeep = true;
|
||||
|
||||
e.Mobile.Target = new ReplaceItemTarget( copyDeep );
|
||||
e.Mobile.SendMessage( "Choose an Item to replace." );
|
||||
}
|
||||
|
||||
[Usage( "UpdateShrinkSystem" )]
|
||||
[Description( "Updates the Items in the shrink system." )]
|
||||
public static void UpgradeShrinkSystem( CommandEventArgs e )
|
||||
{
|
||||
// ReplaceType( "Xanthos.ShrinkSystem.PetLeash", "Xanthos.Evo.PetLeash", false );
|
||||
// ReplaceType( "Xanthos.ShrinkSystem.HitchingPost", "Xanthos.Evo.HitchingPost", false );
|
||||
// ReplaceType( "Xanthos.ShrinkSystem.ShrinkItem", "Xanthos.Evo.ShrinkItem", true );
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object replacement )
|
||||
{
|
||||
if ( !( replacement is Item ))
|
||||
from.SendMessage( "You cannot use that as a replacement!" );
|
||||
else
|
||||
ReplaceItem( replacement as Item, m_ItemToReplace, m_CopyDeep );
|
||||
}
|
||||
|
||||
private static void CopyPropertiesShallow( Item dest, Item src )
|
||||
{
|
||||
dest.IsLockedDown = src.IsLockedDown;
|
||||
dest.IsSecure = src.IsSecure;
|
||||
dest.Movable = src.Movable;
|
||||
dest.Insured = src.Insured;
|
||||
dest.LootType = src.LootType;
|
||||
dest.BlessedFor = src.BlessedFor;
|
||||
dest.Name = src.Name;
|
||||
}
|
||||
|
||||
private static void CopyProperties( Item dest, Item src )
|
||||
{
|
||||
Dupe.CopyProperties(src, dest);
|
||||
|
||||
// Must do this due to a bug in impl of Newbied, which comes after loottype
|
||||
// in the props list, overwriting loottype.
|
||||
dest.LootType = src.LootType;
|
||||
}
|
||||
|
||||
//
|
||||
// Search through all of the Items for those with Type oldTypeName
|
||||
// and create Items of newTypeName passing the two Items to ReplaceItem()
|
||||
//
|
||||
private static void ReplaceType( string newTypeName, string oldTypeName, bool copyDeep )
|
||||
{
|
||||
Type oldType = null;
|
||||
Type newType = null;
|
||||
|
||||
try
|
||||
{
|
||||
oldType = Type.GetType( oldTypeName );
|
||||
newType = Type.GetType( newTypeName );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
Console.WriteLine( "Exception getting types {0}", e.Message );
|
||||
}
|
||||
|
||||
if ( oldType == null )
|
||||
Console.WriteLine( "No class {0} installed", oldTypeName );
|
||||
else if ( newType == null )
|
||||
Console.WriteLine( "No class {0} installed", newTypeName );
|
||||
else
|
||||
{
|
||||
Type[] types = new Type[0];
|
||||
ConstructorInfo ci = newType.GetConstructor( types );
|
||||
|
||||
if ( ci != null )
|
||||
{
|
||||
ArrayList array = new ArrayList();
|
||||
|
||||
Console.WriteLine( "Looking for {0}s", oldTypeName );
|
||||
foreach( Item item in World.Items.Values )
|
||||
{
|
||||
if ( item.GetType() == oldType )
|
||||
array.Add( item );
|
||||
}
|
||||
|
||||
Console.WriteLine( "Found {0} {1}s - replacing with {2}s", array.Count, oldTypeName, newTypeName );
|
||||
|
||||
for ( int j = 0; j < array.Count; j++ )
|
||||
{
|
||||
Item item = array[j] as Item;
|
||||
|
||||
if ( item != null && item.GetType() == oldType )
|
||||
{
|
||||
Object obj = ci.Invoke( null );
|
||||
|
||||
if ( obj == null )
|
||||
continue;
|
||||
|
||||
ReplaceItem( (Item)obj, item, copyDeep ); // This does the actual work of replacement
|
||||
}
|
||||
}
|
||||
Console.WriteLine( "Replaced {0} {1} with {2}", array.Count, oldTypeName, newTypeName );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Given two Items, copies the properties of the first to the second
|
||||
// then places the second one where the first is and deletes the first.
|
||||
//
|
||||
public static void ReplaceItem( Item replacement, Item itemToReplace, bool copyDeep )
|
||||
{
|
||||
Container pack;
|
||||
|
||||
if ( null != itemToReplace && !itemToReplace.Deleted )
|
||||
{
|
||||
if ( copyDeep )
|
||||
CopyProperties( replacement, itemToReplace );
|
||||
else
|
||||
CopyPropertiesShallow( replacement, itemToReplace );
|
||||
|
||||
if ( itemToReplace.Parent is Container )
|
||||
pack = (Container)itemToReplace.Parent;
|
||||
else if ( itemToReplace.Parent is Mobile )
|
||||
pack = ((Mobile)itemToReplace.Parent).Backpack;
|
||||
else
|
||||
pack = null;
|
||||
|
||||
replacement.Internalize();
|
||||
|
||||
if ( pack != null )
|
||||
pack.DropItem( replacement );
|
||||
else
|
||||
replacement.MoveToWorld( itemToReplace.Location, itemToReplace.Map );
|
||||
|
||||
itemToReplace.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ReplaceItemTarget : Target
|
||||
{
|
||||
bool m_CopyDeep;
|
||||
|
||||
public ReplaceItemTarget( bool copyDeep ) : base( -1, false, TargetFlags.None )
|
||||
{
|
||||
m_CopyDeep = copyDeep;
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object o )
|
||||
{
|
||||
if ( o is Item )
|
||||
{
|
||||
from.Target = new PickReplacementTarget( o, m_CopyDeep );
|
||||
from.SendMessage( "Choose a replacement." );
|
||||
}
|
||||
else
|
||||
from.SendMessage( "You cannot replace that!" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
96
Scripts/SubSystem/Pet Shrink/Shrink.cs
Normal file
96
Scripts/SubSystem/Pet Shrink/Shrink.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using Server;
|
||||
using Server.Commands;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Xanthos.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// This interface is implemented by clients of ShrinkTarget allowing the ShrinkTarget
|
||||
/// to adjust the charges of tools without requiring they have the same base class.
|
||||
/// </summary>
|
||||
public interface IShrinkTool : IEntity
|
||||
{
|
||||
bool DeleteWhenEmpty { get; set; }
|
||||
int ShrinkCharges { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used by the auction system to validate the pet referred to by a shrink item.
|
||||
/// </summary>
|
||||
public interface IShrinkItem : IEntity
|
||||
{
|
||||
BaseCreature ShrunkenPet { get; }
|
||||
}
|
||||
}
|
||||
|
||||
namespace Xanthos.ShrinkSystem
|
||||
{
|
||||
public class Shrink
|
||||
{
|
||||
public static bool LockDown { get; set; }
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
EventSink.WorldSave += e => Persistence.Serialize("Saves/Misc/ShrinkCommands.bin", Serialize);
|
||||
EventSink.WorldLoad += () => Persistence.Deserialize("Saves/Misc/ShrinkCommands.bin", Deserialize);
|
||||
}
|
||||
|
||||
private static void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(LockDown);
|
||||
}
|
||||
|
||||
private static void Deserialize(GenericReader reader)
|
||||
{
|
||||
reader.ReadInt();
|
||||
|
||||
LockDown = reader.ReadBool();
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandHandlers.Register("Shrink", AccessLevel.GameMaster, Shrink_OnCommand);
|
||||
CommandHandlers.Register("ShrinkLockDown", AccessLevel.Administrator, ShrinkLockDown_OnCommand);
|
||||
CommandHandlers.Register("ShrinkRelease", AccessLevel.Administrator, ShrinkRelease_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("Shrink")]
|
||||
[Description("Shrinks a creature.")]
|
||||
private static void Shrink_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
ShrinkTarget.Begin(e.Mobile, null);
|
||||
}
|
||||
|
||||
[Usage("ShrinkLockDown")]
|
||||
[Description("Disables all shrinkitems in the world.")]
|
||||
private static void ShrinkLockDown_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
SetLockDown(true);
|
||||
}
|
||||
|
||||
[Usage("ShrinkRelease")]
|
||||
[Description("Re-enables all disabled shrink items in the world.")]
|
||||
private static void ShrinkRelease_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
SetLockDown(false);
|
||||
}
|
||||
|
||||
private static void SetLockDown(bool lockDown)
|
||||
{
|
||||
LockDown = lockDown;
|
||||
|
||||
if (LockDown)
|
||||
{
|
||||
World.Broadcast(0x22, true, "A server wide pet shrink lockout has initiated.");
|
||||
World.Broadcast(0x22, true, "All shrunken pets will remain in their state until further notice.");
|
||||
}
|
||||
else
|
||||
{
|
||||
World.Broadcast(0x35, true, "The server wide pet shrink lockout has been lifted.");
|
||||
World.Broadcast(0x35, true, "You may once again unshrink pets.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
89
Scripts/SubSystem/Pet Shrink/ShrinkConfig.cs
Normal file
89
Scripts/SubSystem/Pet Shrink/ShrinkConfig.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
#region AuthorHeader
|
||||
//
|
||||
// Shrink System version 2.1, by Xanthos
|
||||
//
|
||||
//
|
||||
#endregion AuthorHeader
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using Xanthos.Utilities;
|
||||
|
||||
namespace Xanthos.ShrinkSystem
|
||||
{
|
||||
// This file is for configuration of the Shrink System. It is advised
|
||||
// that you DO NOT edit this file, instead place ShrinkConfig.xml in the
|
||||
// RunUO/Data directory and modify the values there to configure the system
|
||||
// without changing code. This allows you to take updates to the system
|
||||
// without losing your specific configuration settings.
|
||||
|
||||
public class ShrinkConfig
|
||||
{
|
||||
public enum BlessStatus
|
||||
{
|
||||
All, // All shrink items are blessed
|
||||
BondedOnly, // Only shrink items for bonded pets are blessed
|
||||
None // No shrink items are blessed
|
||||
}
|
||||
|
||||
public static bool PetAsStatuette = true; // Deed or statuette form
|
||||
public static bool AllowLocking = false; // Allow players to lock the shrunken pet or not
|
||||
public static bool ShowPetDetails = true; // Show stats and skills on the properties of the shrunken pet
|
||||
public static double ShrunkenWeight = 10.0;
|
||||
public static bool BlessedLeash = false;
|
||||
public static BlessStatus LootStatus = BlessStatus.All; // How the shruken pet should be as loot
|
||||
public static double TamingRequired = 0; // set to zero for no skill requirement to use shrink tools
|
||||
public static int ShrinkCharges = 100; // set to -1 for infinite uses
|
||||
|
||||
private const string kConfigFile = @"Data/ShrinkConfig.xml";
|
||||
private const string kConfigName = "ShrinkSystem";
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Element element = ConfigParser.GetConfig( kConfigFile, kConfigName );
|
||||
|
||||
if ( null == element || element.ChildElements.Count <= 0 )
|
||||
return;
|
||||
|
||||
double tempDouble;
|
||||
bool tempBool;
|
||||
int tempInt;
|
||||
|
||||
foreach( Element child in element.ChildElements )
|
||||
{
|
||||
if ( child.TagName == "PetAsStatuette" && child.GetBoolValue( out tempBool ))
|
||||
PetAsStatuette = tempBool;
|
||||
|
||||
else if ( child.TagName == "AllowLocking" && child.GetBoolValue( out tempBool ))
|
||||
AllowLocking = tempBool;
|
||||
|
||||
else if ( child.TagName == "ShowPetDetails" && child.GetBoolValue( out tempBool ))
|
||||
ShowPetDetails = tempBool;
|
||||
|
||||
else if ( child.TagName == "ShrunkenWeight" && child.GetDoubleValue( out tempDouble ))
|
||||
ShrunkenWeight = tempDouble;
|
||||
|
||||
else if ( child.TagName == "BlessedLeash" && child.GetBoolValue( out tempBool ))
|
||||
BlessedLeash = tempBool;
|
||||
|
||||
else if ( child.TagName == "LootStatus" && null != child.Text && "" != child.Text )
|
||||
{
|
||||
if ( "BlessStatus.All" == child.Text )
|
||||
LootStatus = BlessStatus.All;
|
||||
else if ( "BlessStatus.BondedOnly" == child.Text )
|
||||
LootStatus = BlessStatus.BondedOnly;
|
||||
else if ( "BlessStatus.None" == child.Text )
|
||||
LootStatus = BlessStatus.None;
|
||||
}
|
||||
else if ( child.TagName == "TamingRequired" && child.GetIntValue( out tempInt ))
|
||||
TamingRequired = tempInt;
|
||||
|
||||
else if ( child.TagName == "ShrinkCharges" && child.GetIntValue( out tempInt ))
|
||||
ShrinkCharges = tempInt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
458
Scripts/SubSystem/Pet Shrink/ShrinkItem.cs
Normal file
458
Scripts/SubSystem/Pet Shrink/ShrinkItem.cs
Normal file
@@ -0,0 +1,458 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.ContextMenus;
|
||||
using Server.Spells;
|
||||
|
||||
using Xanthos.Utilities;
|
||||
using Xanthos.Interfaces;
|
||||
|
||||
namespace Xanthos.ShrinkSystem
|
||||
{
|
||||
public class ShrinkItem : Item, IShrinkItem
|
||||
{
|
||||
// Persisted
|
||||
private bool m_IsStatuette;
|
||||
private bool m_Locked;
|
||||
|
||||
private Mobile m_Owner;
|
||||
private BaseCreature m_Pet;
|
||||
|
||||
// Not persisted; lazy loaded.
|
||||
private bool m_PropsLoaded;
|
||||
|
||||
private string m_Breed;
|
||||
private string m_Gender;
|
||||
|
||||
private bool m_IsBonded;
|
||||
|
||||
private int m_RawStr;
|
||||
private int m_RawDex;
|
||||
private int m_RawInt;
|
||||
|
||||
private double m_Wrestling;
|
||||
private double m_Tactics;
|
||||
private double m_Anatomy;
|
||||
private double m_Poisoning;
|
||||
private double m_Magery;
|
||||
private double m_EvalInt;
|
||||
private double m_MagicResist;
|
||||
private double m_Meditation;
|
||||
private double m_Archery;
|
||||
private double m_Fencing;
|
||||
private double m_Macing;
|
||||
private double m_Swords;
|
||||
private double m_Parry;
|
||||
|
||||
private bool m_IgnoreLockDown; // Is only ever changed by staff
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool IsStatuette
|
||||
{
|
||||
get { return m_IsStatuette; }
|
||||
set
|
||||
{
|
||||
m_IsStatuette = value;
|
||||
|
||||
if (m_Pet == null)
|
||||
ItemID = 0xFAA;
|
||||
else if (m_IsStatuette)
|
||||
ItemID = ShrinkTable.Lookup(m_Pet);
|
||||
else
|
||||
ItemID = 0x0E2D;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool IgnoreLockDown
|
||||
{
|
||||
get { return m_IgnoreLockDown; }
|
||||
set
|
||||
{
|
||||
m_IgnoreLockDown = value;
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Locked
|
||||
{
|
||||
get { return m_Locked; }
|
||||
set
|
||||
{
|
||||
m_Locked = value;
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Mobile Owner
|
||||
{
|
||||
get { return m_Owner; }
|
||||
set
|
||||
{
|
||||
m_Owner = value;
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public BaseCreature ShrunkenPet
|
||||
{
|
||||
get { return m_Pet; }
|
||||
set
|
||||
{
|
||||
m_Pet = value;
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[Hue, CommandProperty(AccessLevel.GameMaster)]
|
||||
public override int Hue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Pet != null)
|
||||
return m_Pet.Hue;
|
||||
|
||||
return base.Hue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (m_Pet != null)
|
||||
{
|
||||
m_Pet.Hue = value;
|
||||
|
||||
ReleaseWorldPackets();
|
||||
|
||||
Delta(ItemDelta.Update);
|
||||
}
|
||||
else
|
||||
base.Hue = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Hue, CommandProperty(AccessLevel.Decorator)]
|
||||
//public override int HueMod
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// if (m_Pet != null)
|
||||
// return m_Pet.HueMod;
|
||||
|
||||
// return base.HueMod;
|
||||
// }
|
||||
// set
|
||||
// {
|
||||
// if (m_Pet != null)
|
||||
// {
|
||||
// m_Pet.HueMod = value;
|
||||
|
||||
// ReleaseWorldPackets();
|
||||
|
||||
// Delta(ItemDelta.Update);
|
||||
// }
|
||||
// else
|
||||
// base.HueMod = value;
|
||||
// }
|
||||
//}
|
||||
|
||||
public override string DefaultName => m_Pet != null ? $"{Utility.FixHtml(m_Pet.Name)} on a leash" : "a leashed pet";
|
||||
|
||||
public ShrinkItem()
|
||||
: base()
|
||||
{ }
|
||||
|
||||
public ShrinkItem(BaseCreature pet)
|
||||
: this()
|
||||
{
|
||||
ShrinkPet(pet);
|
||||
|
||||
IsStatuette = ShrinkConfig.PetAsStatuette;
|
||||
|
||||
Weight = ShrinkConfig.ShrunkenWeight;
|
||||
|
||||
base.Hue = 2732;
|
||||
}
|
||||
|
||||
public ShrinkItem(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!m_PropsLoaded)
|
||||
PreloadProperties();
|
||||
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Pet == null || m_Pet.Deleted || ItemID == 0xFAA)
|
||||
{
|
||||
from.SendMessage("Due to unforseen circumstances your pet is lost forever.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Locked && m_Owner != from)
|
||||
{
|
||||
from.SendMessage("This is locked and only the owner can claim this pet while locked.");
|
||||
from.SendMessage("This item is now being returned to its owner.");
|
||||
|
||||
m_Owner.AddToBackpack(this);
|
||||
m_Owner.SendMessage("Your pet {0} has been returned to you because it was locked and {1} was trying to claim it.", m_Breed, from.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (from.Followers + m_Pet.ControlSlots > from.FollowersMax)
|
||||
{
|
||||
from.SendMessage("You have to many followers to claim this pet.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (SpellHelper.CheckCombat(from))
|
||||
{
|
||||
from.SendMessage("You cannot reclaim your pet while you are fighting.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Shrink.LockDown && !m_IgnoreLockDown)
|
||||
{
|
||||
from.SendMessage(54, "The server is under shrink item lockdown. You cannot unshrink your pet at this time.");
|
||||
return;
|
||||
}
|
||||
|
||||
// if (from.AccessLevel < AccessLevel.GameMaster && m_Pet.RequiresDomination && from.Karma >= 0)
|
||||
// {
|
||||
// from.SendMessage("You cannot unshrink a dominated creature until you have negative karma.");
|
||||
// return;
|
||||
// }
|
||||
|
||||
//if (from.AccessLevel < AccessLevel.GameMaster && m_Pet.RequiresCleric && from.Karma <= 0)
|
||||
//{
|
||||
// from.SendMessage("You cannot unshrink a holy creature until you have positive karma.");
|
||||
// return;
|
||||
//}
|
||||
|
||||
if (!m_Pet.CanBeControlledBy(from))
|
||||
{
|
||||
from.SendMessage("You do not have the required skills to control this pet.");
|
||||
return;
|
||||
}
|
||||
|
||||
UnshrinkPet(from);
|
||||
}
|
||||
|
||||
private void ShrinkPet(BaseCreature pet)
|
||||
{
|
||||
m_Pet = pet;
|
||||
m_Owner = pet.ControlMaster;
|
||||
|
||||
if (ShrinkConfig.LootStatus == ShrinkConfig.BlessStatus.All || (m_Pet.IsBonded && ShrinkConfig.LootStatus == ShrinkConfig.BlessStatus.BondedOnly))
|
||||
LootType = LootType.Blessed;
|
||||
else
|
||||
LootType = LootType.Regular;
|
||||
|
||||
m_Pet.Internalize();
|
||||
m_Pet.SetControlMaster(null);
|
||||
|
||||
if (m_Pet.Loyalty < BaseCreature.MaxLoyalty * 0.60)
|
||||
m_Pet.Loyalty = (int)Math.Ceiling(BaseCreature.MaxLoyalty * 0.60);
|
||||
|
||||
m_Pet.ControlOrder = OrderType.Stay;
|
||||
m_Pet.SummonMaster = null;
|
||||
m_Pet.IsStabled = true;
|
||||
}
|
||||
|
||||
private void UnshrinkPet(Mobile from)
|
||||
{
|
||||
if (m_Pet.Loyalty < BaseCreature.MaxLoyalty * 0.60)
|
||||
m_Pet.Loyalty = (int)Math.Ceiling(BaseCreature.MaxLoyalty * 0.60);
|
||||
|
||||
m_Pet.SetControlMaster(from);
|
||||
|
||||
m_Pet.IsStabled = false;
|
||||
|
||||
m_Pet.MoveToWorld(from.Location, from.Map);
|
||||
|
||||
if (m_Owner != from)
|
||||
m_Pet.IsBonded = false;
|
||||
|
||||
m_Pet = null;
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public void OnPetSummoned()
|
||||
{
|
||||
// Summoning ball was used so dispose of the shrink item
|
||||
m_Pet = null;
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
// Don't orphan pets on the internal map
|
||||
m_Pet?.Delete();
|
||||
|
||||
base.Delete();
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
|
||||
if ((ShrinkConfig.AllowLocking || m_Locked) && from.Alive && m_Owner == from)
|
||||
{
|
||||
if (!m_Locked)
|
||||
list.Add(new LockShrinkItem(from, this));
|
||||
else
|
||||
list.Add(new UnLockShrinkItem(from, this));
|
||||
}
|
||||
}
|
||||
|
||||
public override void AddNameProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.AddNameProperties(list);
|
||||
|
||||
if (m_Pet == null || m_Pet.Deleted)
|
||||
return;
|
||||
|
||||
if (!m_PropsLoaded)
|
||||
PreloadProperties();
|
||||
|
||||
if (m_IsBonded && ShrinkConfig.BlessStatus.None == ShrinkConfig.LootStatus) // Only show bonded when the item is not blessed
|
||||
list.Add(1049608);
|
||||
|
||||
if (ShrinkConfig.AllowLocking || m_Locked) // Only show lock status when locking enabled or already locked
|
||||
list.Add(1049644, m_Locked ? "Locked" : "Unlocked");
|
||||
|
||||
if (ShrinkConfig.ShowPetDetails)
|
||||
{
|
||||
list.Add(1061640, m_Owner?.Name ?? "nobody (WILD)"); // Owner: ~1_OWNER~
|
||||
|
||||
list.Add(1060658, "Info\tBreed: {0} Gender: {1}", m_Breed, m_Gender);
|
||||
list.Add(1060659, "Stats\tStrength {0}, Dexterity {1}, Intelligence {2}", m_RawStr, m_RawDex, m_RawInt);
|
||||
|
||||
if (m_Wrestling != 0 || m_Tactics != 0 || m_Anatomy != 0 || m_Poisoning != 0)
|
||||
list.Add(1060660, "Combat Skills\tWrestling {0}, Tactics {1}, Anatomy {2}, Poisoning {3}", m_Wrestling, m_Tactics, m_Anatomy, m_Poisoning);
|
||||
|
||||
if (m_Magery != 0 || m_EvalInt != 0 || m_MagicResist != 0 || m_Meditation != 0)
|
||||
list.Add(1060661, "Magic Skills\tMagery {0}, Eval Intel {1}, Magic Resist {2}, Meditation {3}", m_Magery, m_EvalInt, m_MagicResist, m_Meditation);
|
||||
|
||||
if (m_Archery != 0 || m_Fencing != 0 || m_Macing != 0 || m_Parry != 0 || m_Swords != 0)
|
||||
list.Add(1060662, "Weapon Skills\tArchery {0}, Fencing {1}, Macing {2}, Parry {3}, Swords {4}", m_Archery, m_Fencing, m_Macing, m_Parry, m_Swords);
|
||||
}
|
||||
}
|
||||
|
||||
private void PreloadProperties()
|
||||
{
|
||||
if (m_Pet == null)
|
||||
return;
|
||||
|
||||
m_IsBonded = m_Pet.IsBonded;
|
||||
|
||||
m_Gender = m_Pet.Female ? "Female" : "Male";
|
||||
m_Breed = Misc.GetFriendlyClassName(m_Pet.GetType().Name);
|
||||
|
||||
m_RawStr = m_Pet.RawStr;
|
||||
m_RawDex = m_Pet.RawDex;
|
||||
m_RawInt = m_Pet.RawInt;
|
||||
|
||||
m_Wrestling = m_Pet.Skills[SkillName.Wrestling].Base;
|
||||
m_Tactics = m_Pet.Skills[SkillName.Tactics].Base;
|
||||
m_Anatomy = m_Pet.Skills[SkillName.Anatomy].Base;
|
||||
m_Poisoning = m_Pet.Skills[SkillName.Poisoning].Base;
|
||||
m_Magery = m_Pet.Skills[SkillName.Magery].Base;
|
||||
m_EvalInt = m_Pet.Skills[SkillName.EvalInt].Base;
|
||||
m_MagicResist = m_Pet.Skills[SkillName.MagicResist].Base;
|
||||
m_Meditation = m_Pet.Skills[SkillName.Meditation].Base;
|
||||
m_Parry = m_Pet.Skills[SkillName.Parry].Base;
|
||||
m_Archery = m_Pet.Skills[SkillName.Archery].Base;
|
||||
m_Fencing = m_Pet.Skills[SkillName.Fencing].Base;
|
||||
m_Swords = m_Pet.Skills[SkillName.Swords].Base;
|
||||
m_Macing = m_Pet.Skills[SkillName.Macing].Base;
|
||||
|
||||
m_PropsLoaded = true;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
|
||||
writer.Write(m_IsStatuette);
|
||||
writer.Write(m_Locked);
|
||||
writer.Write(m_Owner);
|
||||
writer.Write(m_Pet);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var v = reader.ReadInt();
|
||||
|
||||
m_IsStatuette = reader.ReadBool();
|
||||
m_Locked = reader.ReadBool();
|
||||
m_Owner = reader.ReadMobile<PlayerMobile>();
|
||||
m_Pet = reader.ReadMobile<BaseCreature>();
|
||||
|
||||
if (m_Pet != null)
|
||||
m_Pet.IsStabled = true;
|
||||
|
||||
if (v < 1)
|
||||
Name = null;
|
||||
}
|
||||
}
|
||||
|
||||
public class LockShrinkItem : ContextMenuEntry
|
||||
{
|
||||
private readonly Mobile m_From;
|
||||
private readonly ShrinkItem m_ShrinkItem;
|
||||
|
||||
public LockShrinkItem(Mobile from, ShrinkItem shrink)
|
||||
: base(2029, 5)
|
||||
{
|
||||
m_From = from;
|
||||
m_ShrinkItem = shrink;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
m_ShrinkItem.Locked = true;
|
||||
|
||||
m_From.SendMessage(38, "You have locked this shrunken pet so only you can reclaim it.");
|
||||
}
|
||||
}
|
||||
|
||||
public class UnLockShrinkItem : ContextMenuEntry
|
||||
{
|
||||
private readonly Mobile m_From;
|
||||
private readonly ShrinkItem m_ShrinkItem;
|
||||
|
||||
public UnLockShrinkItem(Mobile from, ShrinkItem shrink)
|
||||
: base(2033, 5)
|
||||
{
|
||||
m_From = from;
|
||||
m_ShrinkItem = shrink;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
m_ShrinkItem.Locked = false;
|
||||
|
||||
m_From.SendMessage(38, "You have unlocked this shrunken pet, now anyone can reclaim it as theirs.");
|
||||
}
|
||||
}
|
||||
}
|
||||
220
Scripts/SubSystem/Pet Shrink/ShrinkTarget.cs
Normal file
220
Scripts/SubSystem/Pet Shrink/ShrinkTarget.cs
Normal file
@@ -0,0 +1,220 @@
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Regions;
|
||||
using Server.Spells;
|
||||
using System.Linq;
|
||||
using Xanthos.Interfaces;
|
||||
|
||||
namespace Xanthos.ShrinkSystem
|
||||
{
|
||||
public static class ShrinkTarget
|
||||
{
|
||||
public static void Begin(Mobile from, IShrinkTool tool)
|
||||
{
|
||||
var staff = from.AccessLevel >= AccessLevel.GameMaster;
|
||||
|
||||
if (!staff)
|
||||
{
|
||||
if (tool != null)
|
||||
{
|
||||
if (from.Skills[SkillName.AnimalTaming].Value < ShrinkConfig.TamingRequired)
|
||||
{
|
||||
from.SendMessage("You must have at least " + ShrinkConfig.TamingRequired + " animal taming to use that.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (tool.ShrinkCharges == 0)
|
||||
{
|
||||
if (tool.DeleteWhenEmpty)
|
||||
tool.Delete();
|
||||
else
|
||||
from.SendMessage("That does not have enough charges remaining to shrink a pet.");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
from.SendMessage("Target the pet you wish to shrink...");
|
||||
from.BeginTarget(-1, false, 0, End, tool);
|
||||
}
|
||||
|
||||
private static void End(Mobile from, object target, IShrinkTool tool)
|
||||
{
|
||||
End(from, target as BaseCreature, tool);
|
||||
}
|
||||
|
||||
public static void End(Mobile from, BaseCreature pet, IShrinkTool tool)
|
||||
{
|
||||
if (!Validate(from, pet, true))
|
||||
return;
|
||||
|
||||
var staff = from.AccessLevel >= AccessLevel.GameMaster;
|
||||
|
||||
if (!staff)
|
||||
{
|
||||
if (tool != null)
|
||||
{
|
||||
if (from.Skills[SkillName.AnimalTaming].Value < ShrinkConfig.TamingRequired)
|
||||
{
|
||||
from.SendMessage("You must have at least " + ShrinkConfig.TamingRequired + " animal taming to use that.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (tool.ShrinkCharges == 0)
|
||||
{
|
||||
if (tool.DeleteWhenEmpty)
|
||||
tool.Delete();
|
||||
else
|
||||
from.SendMessage("That does not have enough charges remaining to shrink a pet.");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pet.ControlMaster != from && !pet.Controlled)
|
||||
{
|
||||
if (pet.Spawner is SpawnEntry se && se.UnlinkOnTaming)
|
||||
{
|
||||
pet.Spawner.Remove(pet);
|
||||
pet.Spawner = null;
|
||||
}
|
||||
|
||||
pet.CurrentWayPoint = null;
|
||||
pet.ControlMaster = from;
|
||||
pet.Controlled = true;
|
||||
pet.ControlTarget = null;
|
||||
pet.ControlOrder = OrderType.Come;
|
||||
pet.Guild = null;
|
||||
|
||||
pet.Delta(MobileDelta.Noto);
|
||||
}
|
||||
|
||||
var p1 = new Entity(Serial.Zero, new Point3D(from.X, from.Y, from.Z), from.Map);
|
||||
var p2 = new Entity(Serial.Zero, new Point3D(from.X, from.Y, from.Z + 50), from.Map);
|
||||
|
||||
Effects.SendMovingParticles(p2, p1, ShrinkTable.Lookup(pet), 1, 0, true, false, 0, 3, 1153, 1, 0, EffectLayer.Head, 0x100);
|
||||
|
||||
from.PlaySound(492);
|
||||
from.AddToBackpack(new ShrinkItem(pet));
|
||||
|
||||
if (!staff && tool != null && tool.ShrinkCharges > 0 && --tool.ShrinkCharges == 0 && tool.DeleteWhenEmpty && !tool.Deleted)
|
||||
tool.Delete();
|
||||
}
|
||||
|
||||
public static bool Validate(Mobile from, BaseCreature pet, bool message)
|
||||
{
|
||||
var staff = from.AccessLevel >= AccessLevel.GameMaster;
|
||||
|
||||
if (pet == null || pet.Deleted)
|
||||
{
|
||||
if (message)
|
||||
from.SendMessage("You cannot shrink that!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pet == from)
|
||||
{
|
||||
if (message)
|
||||
from.SendMessage("You cannot shrink yourself!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SpellHelper.CheckCombat(from))
|
||||
{
|
||||
if (message)
|
||||
from.SendMessage("You cannot shrink your pet while you are fighting.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pet is BaseTalismanSummon)
|
||||
{
|
||||
if (message)
|
||||
from.SendMessage("You cannot shrink a summoned creature!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pet.Summoned)
|
||||
{
|
||||
if (message)
|
||||
from.SendMessage("You cannot shrink a summoned creature!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pet.IsDeadPet)
|
||||
{
|
||||
if (message)
|
||||
from.SendMessage("You cannot shrink the dead!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pet.Allured)
|
||||
{
|
||||
if (message)
|
||||
from.SendMessage("You cannot shrink an allured creature!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pet.BodyMod != 0)
|
||||
{
|
||||
if (message)
|
||||
from.SendMessage("You cannot shrink your pet while it is polymorphed.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!staff)
|
||||
{
|
||||
if (pet.Combatant != null && pet.InRange(pet.Combatant, 12) && pet.Map == pet.Combatant.Map)
|
||||
{
|
||||
if (message)
|
||||
from.SendMessage("Your pet is fighting; you cannot shrink it yet.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!pet.Controlled)
|
||||
{
|
||||
if (message)
|
||||
from.SendMessage("You cannot not shrink wild creatures.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pet.ControlMaster != from)
|
||||
{
|
||||
if (message)
|
||||
from.SendMessage("That is not your pet.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pet.Loyalty < BaseCreature.MaxLoyalty * 0.60)
|
||||
{
|
||||
if (message)
|
||||
from.SendMessage("Your pet loyalty rating must be happy or greater to be shrunk.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pet.Backpack != null && pet.Backpack.Items.Count(o => o.Movable && o.Visible && o.IsStandardLoot()) > 0)
|
||||
{
|
||||
if (message)
|
||||
from.SendMessage("You must unload this pet's pack before it can be shrunk.");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
368
Scripts/SubSystem/Pet Shrink/findMobs.cs
Normal file
368
Scripts/SubSystem/Pet Shrink/findMobs.cs
Normal file
@@ -0,0 +1,368 @@
|
||||
#region AuthorHeader
|
||||
//
|
||||
// FindMobs version 1.5 - utilities version 2.0, by Xanthos
|
||||
// based on the GoByName utility by unknown
|
||||
//
|
||||
#endregion AuthorHeaderusing System;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using Server.Accounting;
|
||||
using Server.Gumps;
|
||||
using Server.Commands;
|
||||
|
||||
namespace Xanthos.Utilities
|
||||
{
|
||||
public class FindMobsGump : Gump
|
||||
{
|
||||
public const string kCommandName = "FindMobs";
|
||||
public const int kGumpOffsetX = 30;
|
||||
public const int kGumpOffsetY = 30;
|
||||
|
||||
public const int kTextHue = 0;
|
||||
public const int kTextOffsetX = 2;
|
||||
public const int kButtonWidth = 20;
|
||||
public const int kOffsetSize = 1;
|
||||
public const int kEntryHeight = 20;
|
||||
public const int kBorderSize = 10;
|
||||
|
||||
public const int kOffsetGumpID = 0x0052; // Pure black
|
||||
public const int kHeaderGumpID = 0x0E14; // Dark navy blue, textured
|
||||
public const int kEntryGumpID = 0x0BBC; // Light offwhite, textured
|
||||
public const int kBackGumpID = 0x13BE; // Gray slate/stoney
|
||||
public const int kButtonGumpID = 0x0E14; // Dark navy blue, textured
|
||||
|
||||
public const int kGoOffsetX = 2;
|
||||
public const int kGoOffsetY = 2;
|
||||
public const int kGoButtonID1 = 0x15E1; // Arrow pointing right
|
||||
public const int kGoButtonID2 = 0x15E5; // " pressed
|
||||
|
||||
public const int kBringOffsetX = 1;
|
||||
public const int kBringOffsetY = 1;
|
||||
public const int kBringButtonID1 = 0x15E3; // 'X' Button
|
||||
public const int kBringButtonID2 = 0x15E7; // " pressed
|
||||
|
||||
public const int kPrevWidth = 20;
|
||||
public const int kPrevOffsetX = 2;
|
||||
public const int kPrevOffsetY = 2;
|
||||
public const int kPrevButtonID1 = 0x15E3; // Arrow pointing left
|
||||
public const int kPrevButtonID2 = 0x15E7; // " pressed
|
||||
|
||||
public const int kNextWidth = 20;
|
||||
public const int kNextOffsetX = 2;
|
||||
public const int kNextOffsetY = 2;
|
||||
public const int kNextButtonID1 = 0x15E1; // Arrow pointing right
|
||||
public const int kNextButtonID2 = 0x15E5; // " pressed
|
||||
|
||||
private const int kMiniGumpButtonID = 7107;
|
||||
private const int kGreenHue = 0x40;
|
||||
private const int kRedHue = 0x20;
|
||||
|
||||
private const int kPrevLabelOffsetX = kPrevWidth + 1;
|
||||
private const int kPrevLabelOffsetY = 0;
|
||||
|
||||
private const int kNextLabelOffsetX = -29;
|
||||
private const int kNextLabelOffsetY = 0;
|
||||
|
||||
private const int kEntryWidth = 500;
|
||||
private const int kEntryCount = 15;
|
||||
|
||||
private const int kTotalWidth = kOffsetSize + kEntryWidth + kOffsetSize + (kButtonWidth * 2) + kOffsetSize;
|
||||
private const int kTotalHeight = kOffsetSize + ((kEntryHeight + kOffsetSize) * (kEntryCount + 2));
|
||||
|
||||
private const int kBackWidth = kBorderSize + kTotalWidth + kBorderSize;
|
||||
private const int kBackHeight = kBorderSize + kTotalHeight + kBorderSize;
|
||||
|
||||
private static bool s_PrevLabel = false;
|
||||
private static bool s_NextLabel = false;
|
||||
|
||||
private string m_SearchValue;
|
||||
private int m_Options;
|
||||
private Mobile m_Owner;
|
||||
private ArrayList m_Names;
|
||||
private int m_Page;
|
||||
private string m_Args;
|
||||
private bool m_MiniGump;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( kCommandName, AccessLevel.GameMaster, new CommandEventHandler( Find_OnCommand ) );
|
||||
}
|
||||
|
||||
[Usage( kCommandName + " [-i] [-p|-t] <name>" )]
|
||||
[Description( "Finds all mobiles by name, -p for players, -t searches by mobiles type name, -i specifies the internal map" )]
|
||||
private static void Find_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
string str;
|
||||
|
||||
try
|
||||
{
|
||||
int options = GetOptions( e, out str );
|
||||
e.Mobile.SendGump( new FindMobsGump( e.Mobile, str, options ) );
|
||||
}
|
||||
catch
|
||||
{
|
||||
Misc.SendCommandDetails( e.Mobile, kCommandName );
|
||||
}
|
||||
}
|
||||
|
||||
public enum FindOptions
|
||||
{
|
||||
None = 0x00,
|
||||
Player = 0x01,
|
||||
Internal = 0x02,
|
||||
Type = 0x04,
|
||||
}
|
||||
|
||||
private static int GetOptions( CommandEventArgs e, out string searchValue )
|
||||
{
|
||||
int options = (int)FindOptions.None;
|
||||
|
||||
searchValue = "";
|
||||
|
||||
for ( int i = 0; i < e.Length; i++ )
|
||||
{
|
||||
string str = e.GetString( i ).ToLower();
|
||||
|
||||
if ( str.Equals( "-?" ) )
|
||||
throw new Exception();
|
||||
|
||||
else if ( str.Equals( "-i" ) )
|
||||
options |= (int)FindOptions.Internal;
|
||||
|
||||
else if ( str.Equals( "-p" ) )
|
||||
{
|
||||
options |= (int)FindOptions.Player;
|
||||
options &= ~( (int)FindOptions.Type ); // mutually exclusive, turn off the bit
|
||||
}
|
||||
else if ( str.Equals( "-t" ) )
|
||||
{
|
||||
options |= (int)FindOptions.Type;
|
||||
options &= ~( (int)FindOptions.Player ); // mutually exclusive, turn off the bit
|
||||
}
|
||||
else
|
||||
searchValue = str;
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
public FindMobsGump( Mobile owner, string searchValue, int options ) : this( owner, BuildList( owner, searchValue, options ), 0, searchValue, options, false )
|
||||
{
|
||||
m_SearchValue = searchValue;
|
||||
m_Options = options;
|
||||
m_MiniGump = false;
|
||||
GenerateArgString();
|
||||
}
|
||||
|
||||
public FindMobsGump( Mobile owner, ArrayList list, int page, string searchValue, int options, bool miniGump ) : base( kGumpOffsetX, kGumpOffsetY )
|
||||
{
|
||||
m_Owner = owner;
|
||||
m_Names = list;
|
||||
m_SearchValue = searchValue;
|
||||
m_Options = options;
|
||||
m_MiniGump = miniGump;
|
||||
owner.CloseGump( typeof( FindMobsGump ) );
|
||||
GenerateArgString();
|
||||
Initialize( page );
|
||||
}
|
||||
|
||||
public static ArrayList BuildList( Mobile owner, string searchValue, int options )
|
||||
{
|
||||
ArrayList list = new ArrayList();
|
||||
|
||||
bool searchInternal = ((options & (int)FindOptions.Internal) == (int)FindOptions.Internal);
|
||||
bool findPlayers = ((options & (int)FindOptions.Player) == (int)FindOptions.Player);
|
||||
bool findTypes = ((options & (int)FindOptions.Type) == (int)FindOptions.Type);
|
||||
|
||||
foreach ( Mobile mob in World.Mobiles.Values )
|
||||
{
|
||||
if ( searchInternal != (Map.Internal == mob.Map) )
|
||||
continue;
|
||||
else if ( findPlayers && !(mob is PlayerMobile) )
|
||||
continue;
|
||||
|
||||
if ( findTypes && searchValue != "" && mob.GetType().Name.ToLower().StartsWith( searchValue ) )
|
||||
list.Add( mob );
|
||||
if ( !findTypes && (searchValue == "" || mob.Name.ToLower().StartsWith( searchValue )) )
|
||||
list.Add( mob );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void GenerateArgString()
|
||||
{
|
||||
bool m_SearchInternal = ( ( m_Options & (int)FindOptions.Internal ) == (int)FindOptions.Internal );
|
||||
bool m_FindPlayers = ( ( m_Options & (int)FindOptions.Player ) == (int)FindOptions.Player );
|
||||
bool m_FindTypes = ( ( m_Options & (int)FindOptions.Type ) == (int)FindOptions.Type );
|
||||
|
||||
if ( m_SearchValue == "" )
|
||||
m_Args = "all ";
|
||||
|
||||
m_Args += m_FindPlayers ? "players" : "mobiles";
|
||||
m_Args += m_SearchInternal ? " (internal)" : "";
|
||||
|
||||
if ( m_SearchValue != "" )
|
||||
{
|
||||
m_Args += m_FindTypes ? " of type " : " named ";
|
||||
m_Args += m_SearchValue;
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialize( int page )
|
||||
{
|
||||
m_Page = page;
|
||||
|
||||
int count = m_Names.Count - ( page * kEntryCount );
|
||||
|
||||
if ( count < 0 )
|
||||
count = 0;
|
||||
else if ( count > kEntryCount )
|
||||
count = kEntryCount;
|
||||
|
||||
if ( m_MiniGump )
|
||||
{
|
||||
AddPage( 0 );
|
||||
AddBackground( 0, 0, 40, 40, kBackGumpID );
|
||||
AddItem( 10, 10, kMiniGumpButtonID, kGreenHue );
|
||||
}
|
||||
else
|
||||
{
|
||||
int kTotalHeight = kOffsetSize + ( ( kEntryHeight + kOffsetSize ) * ( count + 2 ) );
|
||||
int x = kBorderSize + kOffsetSize;
|
||||
int y = kBorderSize + kOffsetSize;
|
||||
int emptyWidth = kEntryWidth;
|
||||
|
||||
AddPage( 0 );
|
||||
|
||||
AddBackground( 0, 0, kBackWidth, kBorderSize + kTotalHeight + kBorderSize, kBackGumpID );
|
||||
AddImageTiled( kBorderSize, kBorderSize, kTotalWidth, kTotalHeight, kOffsetGumpID );
|
||||
AddImageTiled( x, y, emptyWidth, kEntryHeight, kEntryGumpID );
|
||||
AddLabel( x + kTextOffsetX, y, kTextHue, string.Format( "Page {0} of {1} ({2}) - Matches for: {3}", page + 1, ( m_Names.Count + kEntryCount - 1 ) / kEntryCount, m_Names.Count, m_Args ) );
|
||||
|
||||
x += emptyWidth + kOffsetSize;
|
||||
|
||||
AddImageTiled( x, y, kPrevWidth, kEntryHeight, kHeaderGumpID );
|
||||
|
||||
if ( page > 0 )
|
||||
{
|
||||
AddButton( x + kPrevOffsetX, y + kPrevOffsetY, kPrevButtonID1, kPrevButtonID2, 1, GumpButtonType.Reply, 0 );
|
||||
|
||||
if ( s_PrevLabel )
|
||||
AddLabel( x + kPrevLabelOffsetX, y + kPrevLabelOffsetY, kTextHue, "Previous" );
|
||||
}
|
||||
|
||||
x += kPrevWidth + kOffsetSize;
|
||||
|
||||
AddImageTiled( x, y, kNextWidth, kEntryHeight, kHeaderGumpID );
|
||||
|
||||
if ( ( page + 1 ) * kEntryCount < m_Names.Count )
|
||||
{
|
||||
AddButton( x + kNextOffsetX, y + kNextOffsetY, kNextButtonID1, kNextButtonID2, 2, GumpButtonType.Reply, 1 );
|
||||
|
||||
if ( s_NextLabel )
|
||||
AddLabel( x + kNextLabelOffsetX, y + kNextLabelOffsetY, kTextHue, "Next" );
|
||||
}
|
||||
|
||||
for ( int i = 0, index = page * kEntryCount; i < kEntryCount && index < m_Names.Count; ++i, ++index )
|
||||
{
|
||||
x = kBorderSize + kOffsetSize;
|
||||
y += kEntryHeight + kOffsetSize;
|
||||
|
||||
Mobile item = (Mobile)m_Names[ index ];
|
||||
|
||||
AddImageTiled( x, y, kEntryWidth, kEntryHeight, kEntryGumpID );
|
||||
AddLabelCropped( x + kTextOffsetX, y, kEntryWidth - kTextOffsetX, kEntryHeight, 0x58,
|
||||
item.Deleted ? "(deleted)" : ( string.Format( "{0} : {1} : {2} {3}", item.Name, item is PlayerMobile ? ( (Account)item.Account ).Username : "Null", item.Map, item.Location ) ) );
|
||||
|
||||
if ( !item.Deleted )
|
||||
{
|
||||
x += kEntryWidth + kOffsetSize;
|
||||
AddImageTiled( x, y, kButtonWidth, kEntryHeight, kButtonGumpID );
|
||||
AddButton( x + kBringOffsetX, y + kBringOffsetY, kBringButtonID1, kBringButtonID2, i + 4, GumpButtonType.Reply, 0 );
|
||||
|
||||
x += kButtonWidth + kOffsetSize;
|
||||
AddImageTiled( x, y, kButtonWidth, kEntryHeight, kButtonGumpID );
|
||||
AddButton( x + kGoOffsetX, y + kGoOffsetY, kGoButtonID1, kGoButtonID2, i + 1004, GumpButtonType.Reply, 0 );
|
||||
}
|
||||
}
|
||||
// AddItem( kBackWidth - 55, ((kEntryHeight + kOffsetSize) * (count + 1)) + 15, kMiniGumpButtonID, kRedHue );
|
||||
// AddButton( kBackWidth - 55, ( ( kEntryHeight + kOffsetSize ) * ( count + 1 ) ) + 15, 0, 0, 3, GumpButtonType.Reply, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse( NetState state, RelayInfo info )
|
||||
{
|
||||
Mobile from = state.Mobile;
|
||||
|
||||
switch ( info.ButtonID )
|
||||
{
|
||||
case 0: // Close
|
||||
{
|
||||
return;
|
||||
}
|
||||
case 1: // Previous
|
||||
{
|
||||
if ( m_Page > 0 )
|
||||
from.SendGump( new FindMobsGump( from, m_Names, m_Page - 1, m_SearchValue, m_Options, false ) );
|
||||
|
||||
break;
|
||||
}
|
||||
case 2: // Next
|
||||
{
|
||||
if ( ( m_Page + 1 ) * kEntryCount < m_Names.Count )
|
||||
from.SendGump( new FindMobsGump( from, m_Names, m_Page + 1, m_SearchValue, m_Options, false ) );
|
||||
|
||||
break;
|
||||
}
|
||||
case 3: // MiniGump toggle
|
||||
{
|
||||
from.SendGump( new FindMobsGump( from, m_Names, m_Page, m_SearchValue, m_Options, !m_MiniGump ) );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
int index = (m_Page * kEntryCount) + (info.ButtonID - 4);
|
||||
bool bringing = index < 1000;
|
||||
if ( !bringing )
|
||||
index -= 1000;
|
||||
|
||||
if ( index >= 0 && index < m_Names.Count )
|
||||
{
|
||||
Mobile sought = (Mobile)m_Names[index];
|
||||
|
||||
if ( sought.Deleted )
|
||||
{
|
||||
from.SendMessage( "That mobile no longer exists." );
|
||||
from.SendGump( new FindMobsGump( from, m_Names, m_Page, m_SearchValue, m_Options, false ) );
|
||||
}
|
||||
else if ( bringing )
|
||||
{
|
||||
from.SendMessage( "Bringing {0} to you.", sought.Name );
|
||||
sought.Map = from.Map;
|
||||
sought.SetLocation( from.Location, true );
|
||||
from.SendGump( new FindMobsGump( from, m_Names, m_Page, m_SearchValue, m_Options, false ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage( "Going to {0}.", sought.Name );
|
||||
if ( sought.Map == Map.Internal)
|
||||
{
|
||||
from.Map = sought.LogoutMap;
|
||||
}
|
||||
else
|
||||
{
|
||||
from.Map = sought.Map;
|
||||
}
|
||||
from.SetLocation( sought.Location, true );
|
||||
from.SendGump( new FindMobsGump( from, m_Names, m_Page, m_SearchValue, m_Options, false ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user