Overwrite

Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
Unstable Kitsune
2023-11-28 23:20:26 -05:00
parent 3cd54811de
commit b918192e4e
11608 changed files with 2644205 additions and 47 deletions

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

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

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

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

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

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

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

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

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

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