Updates Data to JSON (#159)
This commit is contained in:
parent
d2f7e08de4
commit
1246a135f7
61 changed files with 18005 additions and 9152 deletions
|
|
@ -1,248 +0,0 @@
|
|||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,386 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Gumps
|
||||
{
|
||||
public abstract class CAGNode
|
||||
{
|
||||
public abstract string Caption { get; }
|
||||
public abstract void OnClick(Mobile from, int page);
|
||||
}
|
||||
|
||||
public class CAGObject : CAGNode
|
||||
{
|
||||
public CAGObject(CAGCategory parent, XmlTextReader xml)
|
||||
{
|
||||
Parent = parent;
|
||||
|
||||
if (xml.MoveToAttribute("type"))
|
||||
Type = AssemblyHandler.FindFirstTypeForName(xml.Value, false);
|
||||
|
||||
if (xml.MoveToAttribute("gfx"))
|
||||
ItemID = XmlConvert.ToInt32(xml.Value);
|
||||
|
||||
if (xml.MoveToAttribute("hue"))
|
||||
Hue = XmlConvert.ToInt32(xml.Value);
|
||||
}
|
||||
|
||||
public Type Type { get; }
|
||||
|
||||
public int ItemID { get; }
|
||||
|
||||
public int Hue { get; }
|
||||
|
||||
public CAGCategory Parent { get; }
|
||||
|
||||
public override string Caption => 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CAGCategory : CAGNode
|
||||
{
|
||||
private static CAGCategory m_Root;
|
||||
|
||||
private CAGCategory()
|
||||
{
|
||||
Title = "no data";
|
||||
Nodes = Array.Empty<CAGNode>();
|
||||
}
|
||||
|
||||
public CAGCategory(CAGCategory parent, XmlTextReader xml)
|
||||
{
|
||||
Parent = parent;
|
||||
|
||||
if (xml.MoveToAttribute("title"))
|
||||
Title = xml.Value;
|
||||
else
|
||||
Title = "empty";
|
||||
|
||||
if (Title == "Docked")
|
||||
Title = "Docked 2";
|
||||
|
||||
if (xml.IsEmptyElement)
|
||||
{
|
||||
Nodes = Array.Empty<CAGNode>();
|
||||
}
|
||||
else
|
||||
{
|
||||
List<CAGNode> nodes = new List<CAGNode>();
|
||||
|
||||
while (xml.Read() && xml.NodeType != XmlNodeType.EndElement)
|
||||
if (xml.NodeType == XmlNodeType.Element && xml.Name == "object")
|
||||
{
|
||||
nodes.Add(new CAGObject(this, xml));
|
||||
}
|
||||
else if (xml.NodeType == XmlNodeType.Element && xml.Name == "category")
|
||||
{
|
||||
if (!xml.IsEmptyElement)
|
||||
nodes.Add(new CAGCategory(this, xml));
|
||||
}
|
||||
else
|
||||
{
|
||||
xml.Skip();
|
||||
}
|
||||
|
||||
Nodes = nodes.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public string Title { get; }
|
||||
|
||||
public CAGNode[] Nodes { get; }
|
||||
|
||||
public CAGCategory Parent { get; }
|
||||
|
||||
public override string Caption => Title;
|
||||
|
||||
public static CAGCategory Root => m_Root ?? (m_Root = Load("Data/objects.xml"));
|
||||
|
||||
public override void OnClick(Mobile from, int page)
|
||||
{
|
||||
from.SendGump(new CategorizedAddGump(from, this));
|
||||
}
|
||||
|
||||
public static CAGCategory Load(string path)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
XmlTextReader xml = new XmlTextReader(path) { WhitespaceHandling = WhitespaceHandling.None };
|
||||
|
||||
while (xml.Read())
|
||||
if (xml.Name == "category" && xml.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
CAGCategory cat = new CAGCategory(null, xml);
|
||||
|
||||
xml.Close();
|
||||
|
||||
return cat;
|
||||
}
|
||||
}
|
||||
|
||||
return new CAGCategory();
|
||||
}
|
||||
}
|
||||
|
||||
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.Caption}</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.Caption);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
using System.Xml;
|
||||
|
||||
namespace Server.Gumps
|
||||
{
|
||||
public class ChildNode : IGoNode
|
||||
{
|
||||
public ChildNode(XmlTextReader xml, ParentNode parent)
|
||||
{
|
||||
Parent = parent;
|
||||
|
||||
Parse(xml);
|
||||
}
|
||||
|
||||
public ParentNode Parent { get; }
|
||||
|
||||
public string Name { get; private set; }
|
||||
|
||||
public Point3D Location { get; private set; }
|
||||
|
||||
private void Parse(XmlTextReader xml)
|
||||
{
|
||||
Name = xml.MoveToAttribute("name") ? xml.Value : "empty";
|
||||
|
||||
int x = 0, y = 0, z = 0;
|
||||
|
||||
if (xml.MoveToAttribute("x"))
|
||||
x = Utility.ToInt32(xml.Value);
|
||||
|
||||
if (xml.MoveToAttribute("y"))
|
||||
y = Utility.ToInt32(xml.Value);
|
||||
|
||||
if (xml.MoveToAttribute("z"))
|
||||
z = Utility.ToInt32(xml.Value);
|
||||
|
||||
Location = new Point3D(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
18
Projects/UOContent/Gumps/Go/GoCategory.cs
Normal file
18
Projects/UOContent/Gumps/Go/GoCategory.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Gumps
|
||||
{
|
||||
public class GoCategory
|
||||
{
|
||||
public GoCategory Parent { get; set; }
|
||||
|
||||
[JsonPropertyName("locations")]
|
||||
public GoLocation[] Locations { get; set; }
|
||||
|
||||
[JsonPropertyName("categories")]
|
||||
public GoCategory[] Categories { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -4,11 +4,12 @@ namespace Server.Gumps
|
|||
{
|
||||
public class GoGump : Gump
|
||||
{
|
||||
public static readonly LocationTree Felucca = new LocationTree("felucca.xml", Map.Felucca);
|
||||
public static readonly LocationTree Trammel = new LocationTree("trammel.xml", Map.Trammel);
|
||||
public static readonly LocationTree Ilshenar = new LocationTree("ilshenar.xml", Map.Ilshenar);
|
||||
public static readonly LocationTree Malas = new LocationTree("malas.xml", Map.Malas);
|
||||
public static readonly LocationTree Tokuno = new LocationTree("tokuno.xml", Map.Tokuno);
|
||||
private static LocationTree Felucca;
|
||||
private static LocationTree Trammel;
|
||||
private static LocationTree Ilshenar;
|
||||
private static LocationTree Malas;
|
||||
private static LocationTree Tokuno;
|
||||
private static LocationTree TerMur;
|
||||
|
||||
public static bool OldStyle = PropsConfig.OldStyle;
|
||||
|
||||
|
|
@ -61,16 +62,43 @@ namespace Server.Gumps
|
|||
|
||||
private static readonly int BackWidth = BorderSize + TotalWidth + BorderSize;
|
||||
private static readonly int BackHeight = BorderSize + TotalHeight + BorderSize;
|
||||
private readonly ParentNode m_Node;
|
||||
private readonly GoCategory m_Node;
|
||||
private readonly int m_Page;
|
||||
|
||||
private readonly LocationTree m_Tree;
|
||||
|
||||
private GoGump(int page, Mobile from, LocationTree tree, ParentNode node) : base(50, 50)
|
||||
public static void DisplayTo(Mobile from)
|
||||
{
|
||||
LocationTree tree;
|
||||
|
||||
if (from.Map == Map.Ilshenar)
|
||||
tree = Ilshenar ??= new LocationTree("ilshenar", Map.Ilshenar);
|
||||
else if (from.Map == Map.Felucca)
|
||||
tree = Felucca ??= new LocationTree("felucca", Map.Felucca);
|
||||
else if (from.Map == Map.Trammel)
|
||||
tree = Trammel ??= new LocationTree("trammel", Map.Trammel);
|
||||
else if (from.Map == Map.Malas)
|
||||
tree = Malas ??= new LocationTree("malas", Map.Malas);
|
||||
else if (from.Map == Map.Tokuno)
|
||||
tree = Tokuno ??= new LocationTree("tokuno", Map.Tokuno);
|
||||
else
|
||||
tree = TerMur ??= new LocationTree("termur", Map.TerMur);
|
||||
|
||||
if (!tree.LastBranch.TryGetValue(from, out GoCategory branch))
|
||||
branch = tree.Root;
|
||||
|
||||
if (branch != null)
|
||||
from.SendGump(new GoGump(0, from, tree, branch));
|
||||
}
|
||||
|
||||
private GoGump(int page, Mobile from, LocationTree tree, GoCategory node) : base(50, 50)
|
||||
{
|
||||
from.CloseGump<GoGump>();
|
||||
|
||||
tree.LastBranch[from] = node;
|
||||
if (node == tree.Root)
|
||||
tree.LastBranch.Remove(from);
|
||||
else
|
||||
tree.LastBranch[from] = node;
|
||||
|
||||
m_Page = page;
|
||||
m_Tree = tree;
|
||||
|
|
@ -79,7 +107,7 @@ namespace Server.Gumps
|
|||
int x = BorderSize + OffsetSize;
|
||||
int y = BorderSize + OffsetSize;
|
||||
|
||||
int count = node.Children.Length - page * EntryCount;
|
||||
int count = node.Categories.Length + node.Locations.Length - page * EntryCount;
|
||||
|
||||
if (count < 0)
|
||||
count = 0;
|
||||
|
|
@ -138,7 +166,7 @@ namespace Server.Gumps
|
|||
if (!OldStyle)
|
||||
AddImageTiled(x, y, NextWidth, EntryHeight, HeaderGumpID);
|
||||
|
||||
if ((page + 1) * EntryCount < node.Children.Length)
|
||||
if ((page + 1) * EntryCount < node.Categories.Length + node.Locations.Length)
|
||||
{
|
||||
AddButton(x + NextOffsetX, y + NextOffsetY, NextButtonID1, NextButtonID2, 3, GumpButtonType.Reply, 1);
|
||||
|
||||
|
|
@ -146,13 +174,14 @@ namespace Server.Gumps
|
|||
AddLabel(x + NextLabelOffsetX, y + NextLabelOffsetY, TextHue, "Next");
|
||||
}
|
||||
|
||||
for (int i = 0, index = page * EntryCount; i < EntryCount && index < node.Children.Length; ++i, ++index)
|
||||
int totalEntryCount = node.Categories.Length + node.Locations.Length;
|
||||
|
||||
for (int i = 0, index = page * EntryCount; i < EntryCount && index < totalEntryCount; ++i, ++index)
|
||||
{
|
||||
x = BorderSize + OffsetSize;
|
||||
y += EntryHeight + OffsetSize;
|
||||
|
||||
IGoNode child = node.Children[index];
|
||||
string name = child.Name;
|
||||
string name = index >= node.Categories.Length ? node.Locations[index].Name : node.Categories[index].Name;
|
||||
|
||||
AddImageTiled(x, y, EntryWidth, EntryHeight, EntryGumpID);
|
||||
AddLabelCropped(x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, name);
|
||||
|
|
@ -166,28 +195,6 @@ namespace Server.Gumps
|
|||
}
|
||||
}
|
||||
|
||||
public static void DisplayTo(Mobile from)
|
||||
{
|
||||
LocationTree tree;
|
||||
|
||||
if (from.Map == Map.Ilshenar)
|
||||
tree = Ilshenar;
|
||||
else if (from.Map == Map.Felucca)
|
||||
tree = Felucca;
|
||||
else if (from.Map == Map.Trammel)
|
||||
tree = Trammel;
|
||||
else if (from.Map == Map.Malas)
|
||||
tree = Malas;
|
||||
else
|
||||
tree = Tokuno;
|
||||
|
||||
if (!tree.LastBranch.TryGetValue(from, out ParentNode branch))
|
||||
branch = tree.Root;
|
||||
|
||||
if (branch != null)
|
||||
from.SendGump(new GoGump(0, from, tree, branch));
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
{
|
||||
Mobile from = state.Mobile;
|
||||
|
|
@ -210,7 +217,7 @@ namespace Server.Gumps
|
|||
}
|
||||
case 3:
|
||||
{
|
||||
if ((m_Page + 1) * EntryCount < m_Node.Children.Length)
|
||||
if ((m_Page + 1) * EntryCount < m_Node.Categories.Length + m_Node.Locations.Length)
|
||||
from.SendGump(new GoGump(m_Page + 1, from, m_Tree, m_Node));
|
||||
|
||||
break;
|
||||
|
|
@ -219,14 +226,18 @@ namespace Server.Gumps
|
|||
{
|
||||
int index = info.ButtonID - 4;
|
||||
|
||||
if (index >= 0 && index < m_Node.Children.Length)
|
||||
{
|
||||
IGoNode o = m_Node.Children[index];
|
||||
if (index < 0)
|
||||
break;
|
||||
|
||||
if (o is ParentNode node)
|
||||
from.SendGump(new GoGump(0, from, m_Tree, node));
|
||||
else
|
||||
from.MoveToWorld(((ChildNode)o).Location, m_Tree.Map);
|
||||
if (index < m_Node.Categories.Length)
|
||||
{
|
||||
from.SendGump(new GoGump(0, from, m_Tree, m_Node.Categories[index]));
|
||||
}
|
||||
else
|
||||
{
|
||||
index -= m_Node.Categories.Length;
|
||||
if (index < m_Node.Locations.Length)
|
||||
from.MoveToWorld(m_Node.Locations[index].Location, m_Tree.Map);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
|||
15
Projects/UOContent/Gumps/Go/GoLocation.cs
Normal file
15
Projects/UOContent/Gumps/Go/GoLocation.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Gumps
|
||||
{
|
||||
public class GoLocation
|
||||
{
|
||||
public GoCategory Parent { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonPropertyName("location")]
|
||||
public Point3D Location { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using Server.Json;
|
||||
|
||||
namespace Server.Gumps
|
||||
{
|
||||
|
|
@ -8,34 +9,50 @@ namespace Server.Gumps
|
|||
{
|
||||
public LocationTree(string fileName, Map map)
|
||||
{
|
||||
LastBranch = new Dictionary<Mobile, ParentNode>();
|
||||
LastBranch = new Dictionary<Mobile, GoCategory>();
|
||||
Map = map;
|
||||
|
||||
string path = Path.Combine("Data/Locations/", fileName);
|
||||
string path = Path.Combine($"Data/Locations/{fileName}.json");
|
||||
|
||||
if (File.Exists(path))
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
XmlTextReader xml = new XmlTextReader(new StreamReader(path)) { WhitespaceHandling = WhitespaceHandling.None };
|
||||
Console.WriteLine("Go Locations: {0} does not exist", path);
|
||||
return;
|
||||
}
|
||||
|
||||
Root = Parse(xml);
|
||||
|
||||
xml.Close();
|
||||
try
|
||||
{
|
||||
Root = JsonConfig.Deserialize<GoCategory>(path);
|
||||
SetParents(Root);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("Go Locations: Error in deserializing {0}", path);
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<Mobile, ParentNode> LastBranch { get; }
|
||||
public Dictionary<Mobile, GoCategory> LastBranch { get; }
|
||||
|
||||
public Map Map { get; }
|
||||
|
||||
public ParentNode Root { get; }
|
||||
public GoCategory Root { get; }
|
||||
|
||||
private ParentNode Parse(XmlTextReader xml)
|
||||
private static void SetParents(GoCategory parent)
|
||||
{
|
||||
xml.Read();
|
||||
xml.Read();
|
||||
xml.Read();
|
||||
// Deserialization may leave these null
|
||||
parent.Categories ??= Array.Empty<GoCategory>();
|
||||
parent.Locations ??= Array.Empty<GoLocation>();
|
||||
|
||||
return new ParentNode(xml, null);
|
||||
for (int i = 0; i < parent.Categories.Length; i++)
|
||||
{
|
||||
GoCategory category = parent.Categories[i];
|
||||
category.Parent = parent;
|
||||
SetParents(category);
|
||||
}
|
||||
|
||||
for (int j = 0; j < parent.Locations.Length; j++)
|
||||
parent.Locations[j].Parent = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace Server.Gumps
|
||||
{
|
||||
public interface IGoNode
|
||||
{
|
||||
ParentNode Parent { get; }
|
||||
string Name { get; }
|
||||
}
|
||||
|
||||
public class ParentNode : IGoNode
|
||||
{
|
||||
public ParentNode(XmlTextReader xml, ParentNode parent)
|
||||
{
|
||||
Parent = parent;
|
||||
|
||||
Parse(xml);
|
||||
}
|
||||
|
||||
public ParentNode Parent { get; }
|
||||
|
||||
public IGoNode[] Children { get; private set; }
|
||||
|
||||
public string Name { get; private set; }
|
||||
|
||||
private void Parse(XmlTextReader xml)
|
||||
{
|
||||
Name = xml.MoveToAttribute("name") ? xml.Value : "empty";
|
||||
|
||||
if (xml.IsEmptyElement)
|
||||
Children = Array.Empty<IGoNode>();
|
||||
else
|
||||
{
|
||||
List<IGoNode> children = new List<IGoNode>();
|
||||
|
||||
while (xml.Read() && (xml.NodeType == XmlNodeType.Element || xml.NodeType == XmlNodeType.Comment))
|
||||
{
|
||||
if (xml.NodeType == XmlNodeType.Comment)
|
||||
continue;
|
||||
|
||||
if (xml.Name == "child")
|
||||
children.Add(new ChildNode(xml, this));
|
||||
else
|
||||
children.Add(new ParentNode(xml, this));
|
||||
}
|
||||
|
||||
Children = children.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue