Updates Data to JSON (#159)

This commit is contained in:
Kamron Batman 2020-06-19 13:53:18 -07:00 • committed by GitHub
parent d2f7e08de4
commit 1246a135f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
61 changed files with 18005 additions and 9152 deletions

View file

@ -0,0 +1,248 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Server.Network;
using Server.Targeting;
namespace Server.Gumps
{
public class AddGump : Gump
{
private static readonly Type typeofItem = typeof(Item);
private static readonly Type typeofMobile = typeof(Mobile);
private readonly int m_Page;
private readonly Type[] m_SearchResults;
private readonly string m_SearchString;
public AddGump(Mobile from, string searchString, int page, Type[] searchResults, bool explicitSearch) : base(50, 50)
{
m_SearchString = searchString;
m_SearchResults = searchResults;
m_Page = page;
from.CloseGump<AddGump>();
AddPage(0);
AddBackground(0, 0, 420, 280, 5054);
AddImageTiled(10, 10, 400, 20, 2624);
AddAlphaRegion(10, 10, 400, 20);
AddImageTiled(41, 11, 184, 18, 0xBBC);
AddImageTiled(42, 12, 182, 16, 2624);
AddAlphaRegion(42, 12, 182, 16);
AddButton(10, 9, 4011, 4013, 1);
AddTextEntry(44, 10, 180, 20, 0x480, 0, searchString);
AddHtmlLocalized(230, 10, 100, 20, 3010005, 0x7FFF);
AddImageTiled(10, 40, 400, 200, 2624);
AddAlphaRegion(10, 40, 400, 200);
if (searchResults.Length > 0)
for (int i = page * 10; i < (page + 1) * 10 && i < searchResults.Length; ++i)
{
int index = i % 10;
AddLabel(44, 39 + index * 20, 0x480, searchResults[i].Name);
AddButton(10, 39 + index * 20, 4023, 4025, 4 + i);
}
else
AddLabel(15, 44, 0x480, explicitSearch ? "Nothing matched your search terms." : "No results to display.");
AddImageTiled(10, 250, 400, 20, 2624);
AddAlphaRegion(10, 250, 400, 20);
if (m_Page > 0)
AddButton(10, 249, 4014, 4016, 2);
else
AddImage(10, 249, 4014);
AddHtmlLocalized(44, 250, 170, 20, 1061028, m_Page > 0 ? 0x7FFF : 0x5EF7); // Previous page
if ((m_Page + 1) * 10 < searchResults.Length)
AddButton(210, 249, 4005, 4007, 3);
else
AddImage(210, 249, 4005);
AddHtmlLocalized(244, 250, 170, 20, 1061027, (m_Page + 1) * 10 < searchResults.Length ? 0x7FFF : 0x5EF7); // Next page
}
public static void Initialize()
{
CommandSystem.Register("AddMenu", AccessLevel.GameMaster, AddMenu_OnCommand);
}
[Usage("AddMenu [searchString]")]
[Description(
"Opens an add menu, with an optional initial search string. This menu allows you to search for Items or Mobiles and add them interactively.")]
private static void AddMenu_OnCommand(CommandEventArgs e)
{
string val = e.ArgString.Trim();
Type[] types;
bool explicitSearch = false;
if (val.Length == 0)
{
types = Type.EmptyTypes;
}
else if (val.Length < 3)
{
e.Mobile.SendMessage("Invalid search string.");
types = Type.EmptyTypes;
}
else
{
types = Match(val).ToArray();
explicitSearch = true;
}
e.Mobile.SendGump(new AddGump(e.Mobile, val, 0, types, explicitSearch));
}
private static void Match(string match, Type[] types, List<Type> results)
{
if (match.Length == 0)
return;
match = match.ToLower();
for (int i = 0; i < types.Length; ++i)
{
Type t = types[i];
if ((typeofMobile.IsAssignableFrom(t) || typeofItem.IsAssignableFrom(t)) &&
t.Name.ToLower().IndexOf(match) >= 0 && !results.Contains(t))
{
ConstructorInfo[] ctors = t.GetConstructors();
for (int j = 0; j < ctors.Length; ++j)
if (ctors[j].GetParameters().Length == 0 &&
ctors[j].IsDefined(typeof(ConstructibleAttribute), false))
{
results.Add(t);
break;
}
}
}
}
public static List<Type> Match(string match)
{
List<Type> results = new List<Type>();
Type[] types;
Assembly[] asms = AssemblyHandler.Assemblies;
for (int i = 0; i < asms.Length; ++i)
{
types = AssemblyHandler.GetTypeCache(asms[i]).Types.ToArray();
Match(match, types, results);
}
types = AssemblyHandler.GetTypeCache(Core.Assembly).Types.ToArray();
Match(match, types, results);
results.Sort(new TypeNameComparer());
return results;
}
public override void OnResponse(NetState sender, RelayInfo info)
{
Mobile from = sender.Mobile;
switch (info.ButtonID)
{
case 1: // Search
{
TextRelay te = info.GetTextEntry(0);
string match = te?.Text.Trim() ?? "";
if (match.Length < 3)
{
from.SendMessage("Invalid search string.");
from.SendGump(new AddGump(from, match, m_Page, m_SearchResults, false));
}
else
{
from.SendGump(new AddGump(from, match, 0, Match(match).ToArray(), true));
}
break;
}
case 2: // Previous page
{
if (m_Page > 0)
from.SendGump(new AddGump(from, m_SearchString, m_Page - 1, m_SearchResults, true));
break;
}
case 3: // Next page
{
if ((m_Page + 1) * 10 < m_SearchResults.Length)
from.SendGump(new AddGump(from, m_SearchString, m_Page + 1, m_SearchResults, true));
break;
}
default:
{
int index = info.ButtonID - 4;
if (index >= 0 && index < m_SearchResults.Length)
{
from.SendMessage("Where do you wish to place this object? <ESC> to cancel.");
from.Target = new InternalTarget(m_SearchResults[index], m_SearchResults, m_SearchString, m_Page);
}
break;
}
}
}
private class TypeNameComparer : IComparer<Type>
{
public int Compare(Type x, Type y) => x.Name.CompareTo(y.Name);
}
public class InternalTarget : Target
{
private readonly int m_Page;
private readonly Type[] m_SearchResults;
private readonly string m_SearchString;
private readonly Type m_Type;
public InternalTarget(Type type, Type[] searchResults, string searchString, int page) : base(-1, true,
TargetFlags.None)
{
m_Type = type;
m_SearchResults = searchResults;
m_SearchString = searchString;
m_Page = page;
}
protected override void OnTarget(Mobile from, object o)
{
if (o is IPoint3D p)
{
if (p is Item item)
p = item.GetWorldTop();
else if (p is Mobile m)
p = m.Location;
Commands.Add.Invoke(from, new Point3D(p), new Point3D(p), new[] { m_Type.Name });
from.Target = new InternalTarget(m_Type, m_SearchResults, m_SearchString, m_Page);
}
}
protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType)
{
if (cancelType == TargetCancelType.Canceled)
from.SendGump(new AddGump(from, m_SearchString, m_Page, m_SearchResults, true));
}
}
}
}

View file

@ -0,0 +1,28 @@
using Server.Gumps;
namespace Server.Commands
{
public class CAGCategory : CAGNode
{
private static CAGCategory m_Root;
public CAGCategory(string title, CAGCategory parent = null)
{
Title = title;
Parent = parent;
}
public override string Title { get; }
public CAGNode[] Nodes { get; set; }
public CAGCategory Parent { get; }
public static CAGCategory Root => m_Root ??= CAGLoader.Load();
public override void OnClick(Mobile from, int page)
{
from.SendGump(new CategorizedAddGump(from, this));
}
}
}

View file

@ -0,0 +1,68 @@
using System.Collections.Generic;
using System.IO;
using System.Text.Json.Serialization;
using Server.Json;
namespace Server.Commands
{
public static class CAGLoader
{
public static CAGCategory Load()
{
var root = new CAGCategory("Add Menu");
var path = Path.Combine(Core.BaseDirectory, "Data/objects.json");
List<CAGJson> list = JsonConfig.Deserialize<List<CAGJson>>(path);
// Not an optimized solution
foreach (var cag in list)
{
var parent = root;
// Navigate through the dot notation categories until we find the last one
var categories = cag.Category.Split(".");
for (int i = 0; i < categories.Length; i++)
{
var category = categories[i];
var oldParent = parent;
for (int j = 0; j < parent.Nodes.Length; j++)
{
var node = parent.Nodes[i];
if (category == node.Title && node is CAGCategory cat)
{
parent = cat;
break;
}
}
if (parent == oldParent)
parent = new CAGCategory(category, parent);
}
// Set the objects associated with the child most node
parent.Nodes = new CAGNode[cag.Objects.Length];
for (int i = 0; i < cag.Objects.Length; i++)
{
var obj = cag.Objects[i];
obj.Parent = parent;
parent.Nodes[i] = obj;
}
}
return root;
}
}
public class CAGJson
{
public CAGJson()
{
}
[JsonPropertyName("category")]
public string Category { get; set; }
[JsonPropertyName("objects")]
public CAGObject[] Objects { get; set; }
}
}

View file

@ -0,0 +1,8 @@
namespace Server.Commands
{
public abstract class CAGNode
{
public abstract string Title { get; }
public abstract void OnClick(Mobile from, int page);
}
}

View file

@ -0,0 +1,40 @@
using System;
using System.Text.Json.Serialization;
using Server.Gumps;
namespace Server.Commands
{
public class CAGObject : CAGNode
{
public CAGObject()
{
}
[JsonPropertyName("type")]
public Type Type { get; set; }
[JsonPropertyName("gfx")]
public int ItemID { get; set; }
[JsonPropertyName("hue")]
public int? Hue { get; set; }
public CAGCategory Parent { get; set; }
public override string Title => Type == null ? "bad type" : Type.Name;
public override void OnClick(Mobile from, int page)
{
if (Type == null)
{
from.SendMessage("That is an invalid type name.");
}
else
{
CommandSystem.Handle(from, $"{CommandSystem.Prefix}Add {Type.Name}");
from.SendGump(new CategorizedAddGump(from, Parent, page));
}
}
}
}

View file

@ -1,15 +1,15 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml;
using Server.Items;
using Server.Json;
using Server.Utilities;
namespace Server.Commands
{
public class Categorization
public static class Categorization
{
private static CategoryEntry m_RootItems, m_RootMobiles;
@ -50,95 +50,87 @@ namespace Server.Commands
{
CategoryEntry root = new CategoryEntry(null, "Add Menu", new[] { Items, Mobiles });
Export(root, "Data/objects.xml", "Objects");
List<CategoryEntry> ceList = new List<CategoryEntry>();
ceList.AddRange(root.SubCategories);
Export(ceList, "Data/objects.json");
e.Mobile.SendMessage("Categorization menu rebuilt.");
}
public static void Export(CategoryEntry ce, string fileName, string title)
public static void Export(List<CategoryEntry> ceList, string fileName)
{
XmlTextWriter xml = new XmlTextWriter(fileName, Encoding.UTF8);
List<CAGJson> list = new List<CAGJson>();
foreach (var ce in ceList)
RecurseExport(list, ce, null);
xml.Indentation = 1;
xml.IndentChar = '\t';
xml.Formatting = Formatting.Indented;
xml.WriteStartDocument(true);
RecurseExport(xml, ce);
xml.Flush();
xml.Close();
JsonConfig.Serialize(fileName, list);
}
public static void RecurseExport(XmlTextWriter xml, CategoryEntry ce)
public static void RecurseExport(List<CAGJson> list, CategoryEntry ce, string category)
{
xml.WriteStartElement("category");
category = string.IsNullOrWhiteSpace(category) ? ce.Title : $"{category}{ce.Title}";
xml.WriteAttributeString("title", ce.Title);
if (ce.Matched.Count > 0)
list.Add(new CAGJson
{
Category = category,
Objects = ce.Matched.Select(cte =>
{
if (cte.Object is Item item)
{
int itemID = item.ItemID;
if (item is BaseAddon addon && addon.Components.Count == 1)
itemID = addon.Components[0].ItemID;
if (itemID > TileData.MaxItemValue)
itemID = 1;
int? hue = item.Hue & 0x7FFF;
if ((hue & 0x4000) != 0)
hue = 0;
return new CAGObject
{
Type = cte.Type,
ItemID = itemID,
Hue = hue == 0 ? null : hue
};
}
if (cte.Object is Mobile m)
{
int itemID = ShrinkTable.Lookup(m, 1);
int? hue = m.Hue & 0x7FFF;
if ((hue & 0x4000) != 0)
hue = 0;
return new CAGObject
{
Type = cte.Type,
ItemID = itemID,
Hue = hue == 0 ? null : hue
};
}
throw new InvalidCastException($"Categorization Type Entry: {cte.Type.Name} is not a valid type.");
}).ToArray()
});
List<CategoryEntry> subCats = new List<CategoryEntry>(ce.SubCategories);
subCats.Sort(new CategorySorter());
for (int i = 0; i < subCats.Count; ++i)
RecurseExport(xml, subCats[i]);
ce.Matched.Sort(new CategoryTypeSorter());
for (int i = 0; i < ce.Matched.Count; ++i)
for (int i = 0; i < subCats.Count; i++)
{
CategoryTypeEntry cte = ce.Matched[i];
xml.WriteStartElement("object");
xml.WriteAttributeString("type", cte.Type.ToString());
if (cte.Object is Item item)
{
int itemID = item.ItemID;
if (item is BaseAddon addon && addon.Components.Count == 1)
itemID = addon.Components[0].ItemID;
if (itemID > TileData.MaxItemValue)
itemID = 1;
xml.WriteAttributeString("gfx", XmlConvert.ToString(itemID));
int hue = item.Hue & 0x7FFF;
if ((hue & 0x4000) != 0)
hue = 0;
if (hue != 0)
xml.WriteAttributeString("hue", XmlConvert.ToString(hue));
item.Delete();
}
else if (cte.Object is Mobile mob)
{
int itemID = ShrinkTable.Lookup(mob, 1);
xml.WriteAttributeString("gfx", XmlConvert.ToString(itemID));
int hue = mob.Hue & 0x7FFF;
if ((hue & 0x4000) != 0)
hue = 0;
if (hue != 0)
xml.WriteAttributeString("hue", XmlConvert.ToString(hue));
mob.Delete();
}
xml.WriteEndElement();
var subCat = subCats[i];
RecurseExport(list, subCat, category);
}
xml.WriteEndElement();
}
public static void Load()
{
List<Type> types = new List<Type>();
@ -156,17 +148,15 @@ namespace Server.Commands
{
CategoryLine[] lines = CategoryLine.Load(config);
if (lines.Length > 0)
{
int index = 0;
CategoryEntry root = new CategoryEntry(null, lines, ref index);
if (lines.Length <= 0) return new CategoryEntry();
Fill(root, types);
int index = 0;
CategoryEntry root = new CategoryEntry(null, lines, ref index);
return root;
}
Fill(root, types);
return root;
return new CategoryEntry();
}
private static bool IsConstructible(Type type)
@ -240,13 +230,12 @@ namespace Server.Commands
string a = x?.Title;
string b = y?.Title;
if (a == null && b == null)
return 0;
if (a == null)
return 1;
return a.CompareTo(b);
return a switch
{
null when b == null => 0,
null => 1,
_ => a.CompareTo(b)
};
}
}
@ -257,13 +246,12 @@ namespace Server.Commands
string a = x?.Type.Name;
string b = y?.Type.Name;
if (a == null && b == null)
return 0;
if (a == null)
return 1;
return a.CompareTo(b);
return a switch
{
null when b == null => 0,
null => 1,
_ => a.CompareTo(b)
};
}
}

View file

@ -0,0 +1,252 @@
using System;
using Server.Commands;
using Server.Network;
namespace Server.Gumps
{
public class CategorizedAddGump : Gump
{
public static bool OldStyle = PropsConfig.OldStyle;
public static readonly int EntryHeight = 24; // PropsConfig.EntryHeight;
public static readonly int OffsetSize = PropsConfig.OffsetSize;
public static readonly int BorderSize = PropsConfig.BorderSize;
public static readonly int GumpOffsetX = PropsConfig.GumpOffsetX;
public static readonly int GumpOffsetY = PropsConfig.GumpOffsetY;
public static readonly int TextHue = PropsConfig.TextHue;
public static readonly int TextOffsetX = PropsConfig.TextOffsetX;
public static readonly int OffsetGumpID = PropsConfig.OffsetGumpID;
public static readonly int HeaderGumpID = PropsConfig.HeaderGumpID;
public static readonly int EntryGumpID = PropsConfig.EntryGumpID;
public static readonly int BackGumpID = PropsConfig.BackGumpID;
public static readonly int SetGumpID = PropsConfig.SetGumpID;
public static readonly int SetWidth = PropsConfig.SetWidth;
public static readonly int SetOffsetX = PropsConfig.SetOffsetX,
SetOffsetY = PropsConfig.SetOffsetY + (EntryHeight - 20) / 2 / 2;
public static readonly int SetButtonID1 = PropsConfig.SetButtonID1;
public static readonly int SetButtonID2 = PropsConfig.SetButtonID2;
public static readonly int PrevWidth = PropsConfig.PrevWidth;
public static readonly int PrevOffsetX = PropsConfig.PrevOffsetX,
PrevOffsetY = PropsConfig.PrevOffsetY + (EntryHeight - 20) / 2 / 2;
public static readonly int PrevButtonID1 = PropsConfig.PrevButtonID1;
public static readonly int PrevButtonID2 = PropsConfig.PrevButtonID2;
public static readonly int NextWidth = PropsConfig.NextWidth;
public static readonly int NextOffsetX = PropsConfig.NextOffsetX,
NextOffsetY = PropsConfig.NextOffsetY + (EntryHeight - 20) / 2 / 2;
public static readonly int NextButtonID1 = PropsConfig.NextButtonID1;
public static readonly int NextButtonID2 = PropsConfig.NextButtonID2;
private static readonly bool PrevLabel = false;
private static readonly bool NextLabel = false;
private static readonly int PrevLabelOffsetX = PrevWidth + 1;
private static readonly int PrevLabelOffsetY = 0;
private static readonly int NextLabelOffsetX = -29;
private static readonly int NextLabelOffsetY = 0;
private static readonly int EntryWidth = 180;
private static readonly int EntryCount = 15;
private static readonly int TotalWidth = OffsetSize + EntryWidth + OffsetSize + SetWidth + OffsetSize;
private static readonly int TotalHeight = OffsetSize + (EntryHeight + OffsetSize) * (EntryCount + 1);
private static readonly int BackWidth = BorderSize + TotalWidth + BorderSize;
private static readonly int BackHeight = BorderSize + TotalHeight + BorderSize;
private readonly CAGCategory m_Category;
private readonly Mobile m_Owner;
private int m_Page;
public CategorizedAddGump(Mobile owner) : this(owner, CAGCategory.Root)
{
}
public CategorizedAddGump(Mobile owner, CAGCategory category, int page = 0) : base(GumpOffsetX, GumpOffsetY)
{
owner.CloseGump<WhoGump>();
m_Owner = owner;
m_Category = category;
Initialize(page);
}
public void Initialize(int page)
{
m_Page = page;
CAGNode[] nodes = m_Category.Nodes;
int count = nodes.Length - page * EntryCount;
if (count < 0)
count = 0;
else if (count > EntryCount)
count = EntryCount;
int totalHeight = OffsetSize + (EntryHeight + OffsetSize) * (count + 1);
AddPage(0);
AddBackground(0, 0, BackWidth, BorderSize + totalHeight + BorderSize, BackGumpID);
AddImageTiled(BorderSize, BorderSize, TotalWidth - (OldStyle ? SetWidth + OffsetSize : 0), totalHeight,
OffsetGumpID);
int x = BorderSize + OffsetSize;
int y = BorderSize + OffsetSize;
if (OldStyle)
AddImageTiled(x, y, TotalWidth - OffsetSize * 3 - SetWidth, EntryHeight, HeaderGumpID);
else
AddImageTiled(x, y, PrevWidth, EntryHeight, HeaderGumpID);
if (m_Category.Parent != null)
{
AddButton(x + PrevOffsetX, y + PrevOffsetY, PrevButtonID1, PrevButtonID2, 1);
if (PrevLabel)
AddLabel(x + PrevLabelOffsetX, y + PrevLabelOffsetY, TextHue, "Previous");
}
x += PrevWidth + OffsetSize;
int emptyWidth = TotalWidth - PrevWidth * 2 - NextWidth - OffsetSize * 5 -
(OldStyle ? SetWidth + OffsetSize : 0);
if (!OldStyle)
AddImageTiled(x - (OldStyle ? OffsetSize : 0), y, emptyWidth + (OldStyle ? OffsetSize * 2 : 0), EntryHeight,
EntryGumpID);
AddHtml(x + TextOffsetX, y + (EntryHeight - 20) / 2, emptyWidth - TextOffsetX, EntryHeight,
$"<center>{m_Category.Title}</center>");
x += emptyWidth + OffsetSize;
if (OldStyle)
AddImageTiled(x, y, TotalWidth - OffsetSize * 3 - SetWidth, EntryHeight, HeaderGumpID);
else
AddImageTiled(x, y, PrevWidth, EntryHeight, HeaderGumpID);
if (page > 0)
{
AddButton(x + PrevOffsetX, y + PrevOffsetY, PrevButtonID1, PrevButtonID2, 2);
if (PrevLabel)
AddLabel(x + PrevLabelOffsetX, y + PrevLabelOffsetY, TextHue, "Previous");
}
x += PrevWidth + OffsetSize;
if (!OldStyle)
AddImageTiled(x, y, NextWidth, EntryHeight, HeaderGumpID);
if ((page + 1) * EntryCount < nodes.Length)
{
AddButton(x + NextOffsetX, y + NextOffsetY, NextButtonID1, NextButtonID2, 3, GumpButtonType.Reply, 1);
if (NextLabel)
AddLabel(x + NextLabelOffsetX, y + NextLabelOffsetY, TextHue, "Next");
}
for (int i = 0, index = page * EntryCount; i < EntryCount && index < nodes.Length; ++i, ++index)
{
x = BorderSize + OffsetSize;
y += EntryHeight + OffsetSize;
CAGNode node = nodes[index];
AddImageTiled(x, y, EntryWidth, EntryHeight, EntryGumpID);
AddLabelCropped(x + TextOffsetX, y + (EntryHeight - 20) / 2, EntryWidth - TextOffsetX, EntryHeight, TextHue,
node.Title);
x += EntryWidth + OffsetSize;
if (SetGumpID != 0)
AddImageTiled(x, y, SetWidth, EntryHeight, SetGumpID);
AddButton(x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, i + 4);
if (node is CAGObject obj)
{
int itemID = obj.ItemID;
Rectangle2D bounds = ItemBounds.Table[itemID];
if (itemID != 1 && bounds.Height < EntryHeight * 2)
{
if (bounds.Height < EntryHeight)
AddItem(x - OffsetSize - 22 - i % 2 * 44 - bounds.Width / 2 - bounds.X,
y + EntryHeight / 2 - bounds.Height / 2 - bounds.Y, itemID);
else
AddItem(x - OffsetSize - 22 - i % 2 * 44 - bounds.Width / 2 - bounds.X,
y + EntryHeight - 1 - bounds.Height - bounds.Y, itemID);
}
}
}
}
public override void OnResponse(NetState state, RelayInfo info)
{
Mobile from = m_Owner;
switch (info.ButtonID)
{
case 0: // Closed
{
return;
}
case 1: // Up
{
if (m_Category.Parent != null)
{
int index = Array.IndexOf(m_Category.Parent.Nodes, m_Category) / EntryCount;
if (index < 0)
index = 0;
from.SendGump(new CategorizedAddGump(from, m_Category.Parent, index));
}
break;
}
case 2: // Previous
{
if (m_Page > 0)
from.SendGump(new CategorizedAddGump(from, m_Category, m_Page - 1));
break;
}
case 3: // Next
{
if ((m_Page + 1) * EntryCount < m_Category.Nodes.Length)
from.SendGump(new CategorizedAddGump(from, m_Category, m_Page + 1));
break;
}
default:
{
int index = m_Page * EntryCount + (info.ButtonID - 4);
if (index >= 0 && index < m_Category.Nodes.Length)
m_Category.Nodes[index].OnClick(from, m_Page);
break;
}
}
}
}
}

View file

@ -11,7 +11,7 @@ using Server.Utilities;
namespace Server.Commands
{
public class DecorateMag
public static class DecorateMag
{
private static Mobile m_Mobile;
private static int m_Count;

View file

@ -5,30 +5,28 @@ using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using Server.Items;
using Server.Json;
namespace Server.Commands
{
public struct Location
{
[JsonPropertyName("point"), JsonConverter(typeof(Point3DConverter))]
public Point3D Pos { get; set; }
[JsonPropertyName("map"), JsonConverter(typeof(MapConverter))]
public Map Map { get; set; }
public override string ToString() => $"({Map.Name}:{Pos.X},{Pos.Y},{Pos.Z})";
public override int GetHashCode() => ToString().GetHashCode();
}
public struct TeleporterDefinition
{
[JsonPropertyName("source")]
public Location Source { get; set; }
[JsonPropertyName("destination")]
public Location Destination { get; set; }
[JsonPropertyName("src")]
public WorldLocation Source { get; set; }
[JsonPropertyName("dst")]
public WorldLocation Destination { get; set; }
[JsonPropertyName("back")]
public bool Back { get; set; }
public override string ToString() => $"{{{Source},{Destination},{Back}}}";
public override int GetHashCode() => ToString().GetHashCode();
public bool Equals(TeleporterDefinition other) =>
Source.Equals(other.Source) && Destination.Equals(other.Destination) && Back == other.Back;
public override bool Equals(object obj) => obj is TeleporterDefinition other && Equals(other);
public override int GetHashCode() => HashCode.Combine(Source, Destination, Back);
}
public static class GenTeleporter
@ -124,11 +122,11 @@ namespace Server.Commands
private static bool IsWithinZ(int delta) => delta >= -12 && delta <= 12;
public static int DeleteTeleporters(Location location)
public static int DeleteTeleporters(WorldLocation worldLocation)
{
IPooledEnumerable<Teleporter> eable = location.Map.GetItemsInRange<Teleporter>(location.Pos, 0);
IPooledEnumerable<Teleporter> eable = worldLocation.Map.GetItemsInRange<Teleporter>(worldLocation, 0);
var items = eable
.Where(x => !(x is KeywordTeleporter || x is SkillTeleporter) && IsWithinZ(x.Z - location.Pos.Z));
.Where(x => !(x is KeywordTeleporter || x is SkillTeleporter) && IsWithinZ(x.Z - worldLocation.Z));
int count = 0;
foreach (var item in items)
{
@ -143,11 +141,11 @@ namespace Server.Commands
{
DelCount += DeleteTeleporters(telDef.Source);
Count++;
new Teleporter(telDef.Destination.Pos, telDef.Destination.Map).MoveToWorld(telDef.Source.Pos, telDef.Source.Map);
new Teleporter(telDef.Destination, telDef.Destination.Map).MoveToWorld(telDef.Source, telDef.Source.Map);
if (!telDef.Back) return;
DelCount += DeleteTeleporters(telDef.Destination);
Count++;
new Teleporter(telDef.Source.Pos, telDef.Source.Map).MoveToWorld(telDef.Destination.Pos, telDef.Destination.Map);
new Teleporter(telDef.Source, telDef.Source.Map).MoveToWorld(telDef.Destination, telDef.Destination.Map);
}
}
}