servuo/Scripts/Commands/Dupe.cs
TrueUO b73897e554
Cleanup (#4848)
- Cleanup of various double calls and simplified code where possible.

Co-authored-by: TrueUO <knight.daniel.r@gmail.com>
2020-09-16 07:43:44 -07:00

360 lines
11 KiB
C#

#region References
using Server.Items;
using Server.Targeting;
using System;
using System.Linq;
#endregion
namespace Server.Commands
{
public class Dupe
{
public static void Initialize()
{
CommandSystem.Register("Dupe", AccessLevel.GameMaster, Dupe_OnCommand);
CommandSystem.Register("DupeInBag", AccessLevel.GameMaster, DupeInBag_OnCommand);
}
[Usage("Dupe [amount]")]
[Description("Dupes a targeted item.")]
private static void Dupe_OnCommand(CommandEventArgs e)
{
int amount = 1;
if (e.Length > 0)
{
amount = e.GetInt32(0);
}
e.Mobile.Target = new DupeTarget(false, Math.Max(1, amount));
e.Mobile.SendMessage("What do you wish to dupe?");
}
[Usage("DupeInBag <count>")]
[Description("Dupes an item at it's current location (count) number of times.")]
private static void DupeInBag_OnCommand(CommandEventArgs e)
{
int amount = 1;
if (e.Length > 0)
{
amount = e.GetInt32(0);
}
e.Mobile.Target = new DupeTarget(true, Math.Max(1, amount));
e.Mobile.SendMessage("What do you wish to dupe?");
}
private class DupeTarget : Target
{
private readonly bool _InBag;
private readonly int _Amount;
public DupeTarget(bool inbag, int amount)
: base(15, false, TargetFlags.None)
{
_InBag = inbag;
_Amount = amount;
}
protected override void OnTarget(Mobile m, object targ)
{
bool done = false;
if (!(targ is Item))
{
m.SendMessage("You can only dupe items.");
return;
}
CommandLogging.WriteLine(
m,
"{0} {1} duping {2} (inBag={3}; amount={4})",
m.AccessLevel,
CommandLogging.Format(m),
CommandLogging.Format(targ),
_InBag,
_Amount);
Item item = (Item)targ;
Container pack;
if (_InBag)
{
if (item.Parent is Container)
{
pack = (Container)item.Parent;
}
else if (item.Parent is Mobile)
{
pack = ((Mobile)item.Parent).Backpack;
}
else
{
pack = null;
}
}
else
{
pack = m.Backpack;
}
Type t = item.GetType();
object[] a = t.GetCustomAttributes(typeof(ConstructableAttribute), false);
if (a.OfType<ConstructableAttribute>().Any(ca => ca.AccessLevel > m.AccessLevel))
{
return;
}
try
{
m.SendMessage("Duping {0}...", _Amount);
bool noCtor = false;
for (int i = 0; i < _Amount; i++)
{
Item o;
try
{
o = Activator.CreateInstance(t, true) as Item;
}
catch
{
o = null;
}
if (o == null)
{
noCtor = true;
break;
}
CopyProperties(item, o);
o.Parent = null;
item.OnAfterDuped(o);
if (item is Container && o is Container)
{
m.SendMessage("Duping Container Children...");
DupeChildren(m, (Container)item, (Container)o);
}
if (pack != null)
{
pack.DropItem(o);
}
else
{
o.MoveToWorld(m.Location, m.Map);
}
o.UpdateTotals();
o.InvalidateProperties();
o.Delta(ItemDelta.Update);
CommandLogging.WriteLine(
m,
"{0} {1} duped {2} creating {3}",
m.AccessLevel,
CommandLogging.Format(m),
CommandLogging.Format(item),
CommandLogging.Format(o));
}
if (!noCtor)
{
m.SendMessage("Done");
done = true;
}
}
catch (Exception e)
{
Diagnostics.ExceptionLogging.LogException(e);
m.SendMessage("Error");
return;
}
if (!done)
{
m.SendMessage("Unable to dupe. Item must have a 0 parameter constructor.");
}
else
{
item.Delta(ItemDelta.Update);
}
}
}
public static Item DupeItem(Item item)
{
return DupeItem(null, item);
}
public static Item DupeItem(Mobile m, Item item)
{
try
{
Type t = item.GetType();
if (m != null)
{
object[] a = t.GetCustomAttributes(typeof(ConstructableAttribute), false);
if (a.OfType<ConstructableAttribute>().Any(ca => ca.AccessLevel > m.AccessLevel))
{
return null;
}
}
Item o;
try
{
o = Activator.CreateInstance(t, true) as Item;
}
catch
{
o = null;
}
if (o == null)
{
return null;
}
CopyProperties(item, o);
o.Parent = null;
item.OnAfterDuped(o);
if (item is Container && o is Container)
{
DupeChildren(m, (Container)item, (Container)o);
}
if (m != null)
{
o.MoveToWorld(m.Location, m.Map);
o.UpdateTotals();
o.InvalidateProperties();
o.Delta(ItemDelta.Update);
CommandLogging.WriteLine(m, "{0} {1} duped {2} creating {3}", m.AccessLevel, CommandLogging.Format(m),
CommandLogging.Format(item), CommandLogging.Format(o));
}
item.Delta(ItemDelta.Update);
return o;
}
catch (Exception e)
{
Diagnostics.ExceptionLogging.LogException(e);
return null;
}
}
public static void DupeChildren(Container src, Container dest)
{
DupeChildren(null, src, dest);
}
public static void DupeChildren(Mobile m, Container src, Container dest)
{
foreach (Item item in src.Items)
{
try
{
Type t = item.GetType();
if (m != null)
{
object[] a = t.GetCustomAttributes(typeof(ConstructableAttribute), false);
if (a.OfType<ConstructableAttribute>().Any(ca => ca.AccessLevel > m.AccessLevel))
{
continue;
}
}
Item o;
try
{
o = Activator.CreateInstance(t, true) as Item;
}
catch
{
o = null;
}
if (o == null)
{
continue;
}
CopyProperties(item, o);
o.Parent = null;
item.OnAfterDuped(o);
if (item is Container && o is Container)
{
DupeChildren(m, (Container)item, (Container)o);
}
dest.DropItem(o);
o.Location = item.Location;
o.UpdateTotals();
o.InvalidateProperties();
o.Delta(ItemDelta.Update);
CommandLogging.WriteLine(
m,
"{0} {1} duped {2} creating {3}",
m.AccessLevel,
CommandLogging.Format(m),
CommandLogging.Format(item),
CommandLogging.Format(o));
item.Delta(ItemDelta.Update);
}
catch (Exception e)
{
Diagnostics.ExceptionLogging.LogException(e);
}
}
}
public static void CopyProperties(object src, object dest)
{
System.Reflection.PropertyInfo[] props = src.GetType().GetProperties();
foreach (System.Reflection.PropertyInfo p in props)
{
try
{
if (p.CanRead && p.CanWrite)
{
p.SetValue(dest, p.GetValue(src, null), null);
}
}
catch (Exception e)
{
Diagnostics.ExceptionLogging.LogException(e);
}
}
}
}
}