feat: Moves gumps out of the core (#1916)
> [!Important] > **Developer Note** > This code change will **completely move gumps out of the core** ### Summary - Adds `GetGumps()` convenience which exposes methods to Find/Close/Send multiple gumps. This helper is a performance improvement by eliminating the Dictionary<Player, List> lookup for gumps.
This commit is contained in:
parent
40d99f6d1c
commit
8282b00ca2
246 changed files with 1722 additions and 1383 deletions
|
|
@ -307,9 +307,10 @@ public class AddonGenerator
|
|||
private const int GreenHue = 0x40;
|
||||
private readonly PickerState _state;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public InternalGump(Mobile m, PickerState state) : base(100, 50)
|
||||
{
|
||||
m.CloseGump<InternalGump>();
|
||||
_state = state;
|
||||
MakeGump();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -524,11 +524,11 @@ namespace Server.Commands.Generic
|
|||
if (match.Length < 3)
|
||||
{
|
||||
e.Mobile.SendMessage("Invalid search string.");
|
||||
e.Mobile.SendGump(new AddGump(e.Mobile, match, 0, Type.EmptyTypes, false));
|
||||
e.Mobile.SendGump(new AddGump(match, 0, Type.EmptyTypes, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Mobile.SendGump(new AddGump(e.Mobile, match, 0, AddGump.Match(match), true));
|
||||
e.Mobile.SendGump(new AddGump(match, 0, AddGump.Match(match), true));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -290,18 +290,20 @@ public static class HelpInfo
|
|||
public override void OnResponse(NetState sender, in RelayInfo info)
|
||||
{
|
||||
var m = sender.Mobile;
|
||||
var gumps = m.GetGumps();
|
||||
|
||||
switch (info.ButtonID)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m.CloseGump<CommandInfoGump>();
|
||||
gumps.Close<CommandInfoGump>();
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (_page > 0)
|
||||
{
|
||||
m.SendGump(new CommandListGump(_page - 1, m, _list));
|
||||
gumps.Send(new CommandListGump(_page - 1, m, _list));
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -310,7 +312,7 @@ public static class HelpInfo
|
|||
{
|
||||
if ((_page + 1) * EntriesPerPage < SortedHelpInfo.Count)
|
||||
{
|
||||
m.SendGump(new CommandListGump(_page + 1, m, _list));
|
||||
gumps.Send(new CommandListGump(_page + 1, m, _list));
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -325,13 +327,13 @@ public static class HelpInfo
|
|||
|
||||
if (m.AccessLevel >= c.AccessLevel)
|
||||
{
|
||||
m.SendGump(new CommandInfoGump(c));
|
||||
m.SendGump(new CommandListGump(_page, m, _list));
|
||||
gumps.Send(new CommandInfoGump(c));
|
||||
gumps.Send(new CommandListGump(_page, m, _list));
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendMessage("You no longer have access to that command.");
|
||||
m.SendGump(new CommandListGump(_page, m, null));
|
||||
gumps.Send(new CommandListGump(_page, m, null));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,14 +14,14 @@ public class AddGump : DynamicGump
|
|||
private readonly string _searchString;
|
||||
private readonly bool _explicitSearch;
|
||||
|
||||
public AddGump(Mobile from, string searchString, int page, Type[] searchResults, bool explicitSearch) : base(50, 50)
|
||||
public override bool Singleton => true;
|
||||
|
||||
public AddGump(string searchString, int page, Type[] searchResults, bool explicitSearch) : base(50, 50)
|
||||
{
|
||||
_searchString = searchString;
|
||||
_searchResults = searchResults;
|
||||
_explicitSearch = explicitSearch;
|
||||
_page = page;
|
||||
|
||||
from.CloseGump<AddGump>();
|
||||
}
|
||||
|
||||
protected override void BuildLayout(ref DynamicGumpBuilder builder) {
|
||||
|
|
@ -120,7 +120,7 @@ public class AddGump : DynamicGump
|
|||
explicitSearch = true;
|
||||
}
|
||||
|
||||
e.Mobile.SendGump(new AddGump(e.Mobile, val, 0, types, explicitSearch));
|
||||
e.Mobile.SendGump(new AddGump(val, 0, types, explicitSearch));
|
||||
}
|
||||
|
||||
private static void Match(string match, Type[] types, HashSet<Type> results)
|
||||
|
|
@ -212,11 +212,11 @@ public class AddGump : DynamicGump
|
|||
if (match.Length < 3)
|
||||
{
|
||||
from.SendMessage("Invalid search string.");
|
||||
from.SendGump(new AddGump(from, match, _page, _searchResults, false));
|
||||
from.SendGump(new AddGump(match, _page, _searchResults, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendGump(new AddGump(from, match, 0, Match(match), true));
|
||||
from.SendGump(new AddGump(match, 0, Match(match), true));
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -225,7 +225,7 @@ public class AddGump : DynamicGump
|
|||
{
|
||||
if (_page > 0)
|
||||
{
|
||||
from.SendGump(new AddGump(from, _searchString, _page - 1, _searchResults, true));
|
||||
from.SendGump(new AddGump(_searchString, _page - 1, _searchResults, true));
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -234,7 +234,7 @@ public class AddGump : DynamicGump
|
|||
{
|
||||
if ((_page + 1) * 10 < _searchResults.Length)
|
||||
{
|
||||
from.SendGump(new AddGump(from, _searchString, _page + 1, _searchResults, true));
|
||||
from.SendGump(new AddGump(_searchString, _page + 1, _searchResults, true));
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -307,7 +307,7 @@ public class AddGump : DynamicGump
|
|||
{
|
||||
if (cancelType == TargetCancelType.Canceled)
|
||||
{
|
||||
from.SendGump(new AddGump(from, m_SearchString, m_Page, m_SearchResults, true));
|
||||
from.SendGump(new AddGump(m_SearchString, m_Page, m_SearchResults, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,14 +34,14 @@ namespace Server.Gumps
|
|||
private readonly Mobile m_Owner;
|
||||
private int m_Page;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
|||
30
Projects/UOContent/Diagnostics/GumpProfile.cs
Normal file
30
Projects/UOContent/Diagnostics/GumpProfile.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Diagnostics;
|
||||
|
||||
public class GumpProfile : BaseProfile
|
||||
{
|
||||
private static readonly Dictionary<Type, GumpProfile> _profiles = new();
|
||||
|
||||
public GumpProfile(Type type) : base(type.FullName)
|
||||
{
|
||||
}
|
||||
|
||||
public static IEnumerable<GumpProfile> Profiles => _profiles.Values;
|
||||
|
||||
public static GumpProfile Acquire(Type type)
|
||||
{
|
||||
if (!Core.Profiling)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!_profiles.TryGetValue(type, out var prof))
|
||||
{
|
||||
_profiles.Add(type, prof = new GumpProfile(type));
|
||||
}
|
||||
|
||||
return prof;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
using Server.Gumps;
|
||||
|
||||
namespace Server.Engines.AdvancedSearch;
|
||||
|
||||
public static class AdvancedSearchCommand
|
||||
|
|
@ -14,7 +16,6 @@ public static class AdvancedSearchCommand
|
|||
{
|
||||
var from = e.Mobile;
|
||||
|
||||
from.CloseGump<AdvancedSearchGump>();
|
||||
from.SendGump(new AdvancedSearchGump(from));
|
||||
from.SendGump(new AdvancedSearchGump(from), true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ using Server.Network;
|
|||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class BOBFilterGump : Gump
|
||||
public sealed class BOBFilterGump : DynamicGump
|
||||
{
|
||||
private const int LabelColor = 0x7FFF;
|
||||
|
||||
private static readonly int[,] m_MaterialFilters =
|
||||
private static readonly int[,] _materialFilters =
|
||||
{
|
||||
{ 1044067, 1 }, // Blacksmithy
|
||||
{ 1062226, 3 }, // Iron
|
||||
|
|
@ -30,21 +30,21 @@ namespace Server.Engines.BulkOrders
|
|||
{ 1062238, 16 } // Barbed
|
||||
};
|
||||
|
||||
private static readonly int[,] m_TypeFilters =
|
||||
private static readonly int[,] _typeFilters =
|
||||
{
|
||||
{ 1062229, 0 }, // All
|
||||
{ 1062224, 1 }, // Small
|
||||
{ 1062225, 2 } // Large
|
||||
};
|
||||
|
||||
private static readonly int[,] m_QualityFilters =
|
||||
private static readonly int[,] _qualityFilters =
|
||||
{
|
||||
{ 1062229, 0 }, // All
|
||||
{ 1011542, 1 }, // Normal
|
||||
{ 1060636, 2 } // Exceptional
|
||||
};
|
||||
|
||||
private static readonly int[,] m_AmountFilters =
|
||||
private static readonly int[,] _amountFilters =
|
||||
{
|
||||
{ 1062229, 0 }, // All
|
||||
{ 1049706, 1 }, // 10
|
||||
|
|
@ -52,74 +52,77 @@ namespace Server.Engines.BulkOrders
|
|||
{ 1062239, 3 } // 20
|
||||
};
|
||||
|
||||
private static readonly int[][,] m_Filters =
|
||||
private static readonly int[][,] _filters =
|
||||
{
|
||||
m_TypeFilters,
|
||||
m_QualityFilters,
|
||||
m_MaterialFilters,
|
||||
m_AmountFilters
|
||||
_typeFilters,
|
||||
_qualityFilters,
|
||||
_materialFilters,
|
||||
_amountFilters
|
||||
};
|
||||
|
||||
private static readonly int[] m_XOffsets_Type = { 0, 75, 170 };
|
||||
private static readonly int[] m_XOffsets_Quality = { 0, 75, 170 };
|
||||
private static readonly int[] m_XOffsets_Amount = { 0, 75, 180, 275 };
|
||||
private static readonly int[] m_XOffsets_Material = { 0, 105, 210, 305, 390, 485 };
|
||||
private static readonly int[] _xOffsets_Type = [0, 75, 170];
|
||||
private static readonly int[] _xOffsets_Quality = [0, 75, 170];
|
||||
private static readonly int[] _xOffsets_Amount = [0, 75, 180, 275];
|
||||
private static readonly int[] _xOffsets_Material = [0, 105, 210, 305, 390, 485];
|
||||
|
||||
private static readonly int[] m_XWidths_Small = { 50, 50, 70, 50 };
|
||||
private static readonly int[] m_XWidths_Large = { 80, 50, 50, 50, 50, 50 };
|
||||
private readonly BulkOrderBook m_Book;
|
||||
private readonly PlayerMobile m_From;
|
||||
private static readonly int[] _xWidths_Small = [50, 50, 70, 50];
|
||||
private static readonly int[] _xWidths_Large = [80, 50, 50, 50, 50, 50];
|
||||
|
||||
private readonly BulkOrderBook _book;
|
||||
private readonly PlayerMobile _from;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public BOBFilterGump(PlayerMobile from, BulkOrderBook book) : base(12, 24)
|
||||
{
|
||||
from.CloseGump<BOBGump>();
|
||||
from.CloseGump<BOBFilterGump>();
|
||||
|
||||
m_From = from;
|
||||
m_Book = book;
|
||||
|
||||
var f = from.UseOwnFilter ? from.BOBFilter : book.Filter;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(10, 10, 600, 439, 5054);
|
||||
|
||||
AddImageTiled(18, 20, 583, 420, 2624);
|
||||
AddAlphaRegion(18, 20, 583, 420);
|
||||
|
||||
AddImage(5, 5, 10460);
|
||||
AddImage(585, 5, 10460);
|
||||
AddImage(5, 424, 10460);
|
||||
AddImage(585, 424, 10460);
|
||||
|
||||
AddHtmlLocalized(270, 32, 200, 32, 1062223, LabelColor); // Filter Preference
|
||||
|
||||
AddHtmlLocalized(26, 64, 120, 32, 1062228, LabelColor); // Bulk Order Type
|
||||
AddFilterList(25, 96, m_XOffsets_Type, 40, m_TypeFilters, m_XWidths_Small, f.Type, 0);
|
||||
|
||||
AddHtmlLocalized(320, 64, 50, 32, 1062215, LabelColor); // Quality
|
||||
AddFilterList(320, 96, m_XOffsets_Quality, 40, m_QualityFilters, m_XWidths_Small, f.Quality, 1);
|
||||
|
||||
AddHtmlLocalized(26, 160, 120, 32, 1062232, LabelColor); // Material Type
|
||||
AddFilterList(25, 192, m_XOffsets_Material, 40, m_MaterialFilters, m_XWidths_Large, f.Material, 2);
|
||||
|
||||
AddHtmlLocalized(26, 320, 120, 32, 1062217, LabelColor); // Amount
|
||||
AddFilterList(25, 352, m_XOffsets_Amount, 40, m_AmountFilters, m_XWidths_Small, f.Quantity, 3);
|
||||
|
||||
AddHtmlLocalized(75, 416, 120, 32, 1062477, from.UseOwnFilter ? LabelColor : 16927); // Set Book Filter
|
||||
AddButton(40, 416, 4005, 4007, 1);
|
||||
|
||||
AddHtmlLocalized(235, 416, 120, 32, 1062478, from.UseOwnFilter ? 16927 : LabelColor); // Set Your Filter
|
||||
AddButton(200, 416, 4005, 4007, 2);
|
||||
|
||||
AddHtmlLocalized(405, 416, 120, 32, 1062231, LabelColor); // Clear Filter
|
||||
AddButton(370, 416, 4005, 4007, 3);
|
||||
|
||||
AddHtmlLocalized(540, 416, 50, 32, 1011046, LabelColor); // APPLY
|
||||
AddButton(505, 416, 4017, 4018, 0);
|
||||
_from = from;
|
||||
_book = book;
|
||||
}
|
||||
|
||||
private void AddFilterList(
|
||||
protected override void BuildLayout(ref DynamicGumpBuilder builder)
|
||||
{
|
||||
var f = _from.UseOwnFilter ? _from.BOBFilter : _book.Filter;
|
||||
|
||||
builder.AddPage();
|
||||
|
||||
builder.AddBackground(10, 10, 600, 439, 5054);
|
||||
|
||||
builder.AddImageTiled(18, 20, 583, 420, 2624);
|
||||
builder.AddAlphaRegion(18, 20, 583, 420);
|
||||
|
||||
builder.AddImage(5, 5, 10460);
|
||||
builder.AddImage(585, 5, 10460);
|
||||
builder.AddImage(5, 424, 10460);
|
||||
builder.AddImage(585, 424, 10460);
|
||||
|
||||
builder.AddHtmlLocalized(270, 32, 200, 32, 1062223, LabelColor); // Filter Preference
|
||||
|
||||
builder.AddHtmlLocalized(26, 64, 120, 32, 1062228, LabelColor); // Bulk Order Type
|
||||
AddFilterList(ref builder, 25, 96, _xOffsets_Type, 40, _typeFilters, _xWidths_Small, f.Type, 0);
|
||||
|
||||
builder.AddHtmlLocalized(320, 64, 50, 32, 1062215, LabelColor); // Quality
|
||||
AddFilterList(ref builder, 320, 96, _xOffsets_Quality, 40, _qualityFilters, _xWidths_Small, f.Quality, 1);
|
||||
|
||||
builder.AddHtmlLocalized(26, 160, 120, 32, 1062232, LabelColor); // Material Type
|
||||
AddFilterList(ref builder, 25, 192, _xOffsets_Material, 40, _materialFilters, _xWidths_Large, f.Material, 2);
|
||||
|
||||
builder.AddHtmlLocalized(26, 320, 120, 32, 1062217, LabelColor); // Amount
|
||||
AddFilterList(ref builder, 25, 352, _xOffsets_Amount, 40, _amountFilters, _xWidths_Small, f.Quantity, 3);
|
||||
|
||||
builder.AddHtmlLocalized(75, 416, 120, 32, 1062477, _from.UseOwnFilter ? LabelColor : 16927); // Set Book Filter
|
||||
builder.AddButton(40, 416, 4005, 4007, 1);
|
||||
|
||||
builder.AddHtmlLocalized(235, 416, 120, 32, 1062478, _from.UseOwnFilter ? 16927 : LabelColor); // Set Your Filter
|
||||
builder.AddButton(200, 416, 4005, 4007, 2);
|
||||
|
||||
builder.AddHtmlLocalized(405, 416, 120, 32, 1062231, LabelColor); // Clear Filter
|
||||
builder.AddButton(370, 416, 4005, 4007, 3);
|
||||
|
||||
builder.AddHtmlLocalized(540, 416, 50, 32, 1011046, LabelColor); // APPLY
|
||||
builder.AddButton(505, 416, 4017, 4018, 0);
|
||||
}
|
||||
|
||||
private void AddFilterList(ref DynamicGumpBuilder builder,
|
||||
int x, int y, int[] xOffsets, int yOffset, int[,] filters, int[] xWidths, int filterValue,
|
||||
int filterIndex
|
||||
)
|
||||
|
|
@ -136,7 +139,7 @@ namespace Server.Engines.BulkOrders
|
|||
var isSelected = filters[i, 1] == filterValue ||
|
||||
i % xOffsets.Length == 0 && filterValue == 0;
|
||||
|
||||
AddHtmlLocalized(
|
||||
builder.AddHtmlLocalized(
|
||||
x + 35 + xOffsets[i % xOffsets.Length],
|
||||
y + i / xOffsets.Length * yOffset,
|
||||
xWidths[i % xOffsets.Length],
|
||||
|
|
@ -144,7 +147,8 @@ namespace Server.Engines.BulkOrders
|
|||
number,
|
||||
isSelected ? 16927 : LabelColor
|
||||
);
|
||||
AddButton(
|
||||
|
||||
builder.AddButton(
|
||||
x + xOffsets[i % xOffsets.Length],
|
||||
y + i / xOffsets.Length * yOffset,
|
||||
4005,
|
||||
|
|
@ -156,7 +160,7 @@ namespace Server.Engines.BulkOrders
|
|||
|
||||
public override void OnResponse(NetState sender, in RelayInfo info)
|
||||
{
|
||||
var f = m_From.UseOwnFilter ? m_From.BOBFilter : m_Book.Filter;
|
||||
var f = _from.UseOwnFilter ? _from.BOBFilter : _book.Filter;
|
||||
|
||||
var index = info.ButtonID;
|
||||
|
||||
|
|
@ -164,28 +168,28 @@ namespace Server.Engines.BulkOrders
|
|||
{
|
||||
case 0: // Apply
|
||||
{
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book));
|
||||
_from.SendGump(new BOBGump(_from, _book));
|
||||
|
||||
break;
|
||||
}
|
||||
case 1: // Set Book Filter
|
||||
{
|
||||
m_From.UseOwnFilter = false;
|
||||
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
|
||||
_from.UseOwnFilter = false;
|
||||
_from.SendGump(new BOBFilterGump(_from, _book));
|
||||
|
||||
break;
|
||||
}
|
||||
case 2: // Set Your Filter
|
||||
{
|
||||
m_From.UseOwnFilter = true;
|
||||
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
|
||||
_from.UseOwnFilter = true;
|
||||
_from.SendGump(new BOBFilterGump(_from, _book));
|
||||
|
||||
break;
|
||||
}
|
||||
case 3: // Clear Filter
|
||||
{
|
||||
f.Clear();
|
||||
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
|
||||
_from.SendGump(new BOBFilterGump(_from, _book));
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -196,9 +200,9 @@ namespace Server.Engines.BulkOrders
|
|||
var type = index % 4;
|
||||
index /= 4;
|
||||
|
||||
if (type >= 0 && type < m_Filters.Length)
|
||||
if (type >= 0 && type < _filters.Length)
|
||||
{
|
||||
var filters = m_Filters[type];
|
||||
var filters = _filters[type];
|
||||
|
||||
if (index >= 0 && index < filters.GetLength(0))
|
||||
{
|
||||
|
|
@ -223,7 +227,7 @@ namespace Server.Engines.BulkOrders
|
|||
break;
|
||||
}
|
||||
|
||||
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
|
||||
_from.SendGump(new BOBFilterGump(_from, _book));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,20 +11,19 @@ namespace Server.Engines.BulkOrders
|
|||
public class BOBGump : Gump
|
||||
{
|
||||
private const int LabelColor = 0x7FFF;
|
||||
private readonly BulkOrderBook m_Book;
|
||||
private readonly PlayerMobile m_From;
|
||||
private readonly List<IBOBEntry> m_List;
|
||||
private readonly BulkOrderBook _book;
|
||||
private readonly PlayerMobile _from;
|
||||
private readonly List<IBOBEntry> _list;
|
||||
|
||||
private int m_Page;
|
||||
private int _page;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public BOBGump(PlayerMobile from, BulkOrderBook book, int page = 0, List<IBOBEntry> list = null) : base(12, 24)
|
||||
{
|
||||
from.CloseGump<BOBGump>();
|
||||
from.CloseGump<BOBFilterGump>();
|
||||
|
||||
m_From = from;
|
||||
m_Book = book;
|
||||
m_Page = page;
|
||||
_from = from;
|
||||
_book = book;
|
||||
_page = page;
|
||||
|
||||
if (list == null)
|
||||
{
|
||||
|
|
@ -41,7 +40,7 @@ namespace Server.Engines.BulkOrders
|
|||
}
|
||||
}
|
||||
|
||||
m_List = list;
|
||||
_list = list;
|
||||
|
||||
var index = GetIndexForPage(page);
|
||||
var count = GetCountForIndex(index);
|
||||
|
|
@ -313,7 +312,7 @@ namespace Server.Engines.BulkOrders
|
|||
Type itemType
|
||||
)
|
||||
{
|
||||
var f = m_From.UseOwnFilter ? m_From.BOBFilter : m_Book.Filter;
|
||||
var f = _from.UseOwnFilter ? _from.BOBFilter : _book.Filter;
|
||||
|
||||
if (f.IsDefault)
|
||||
{
|
||||
|
|
@ -394,7 +393,7 @@ namespace Server.Engines.BulkOrders
|
|||
var slots = 0;
|
||||
var count = 0;
|
||||
|
||||
var list = m_List;
|
||||
var list = _list;
|
||||
|
||||
for (var i = index; i >= 0 && i < list.Count; ++i)
|
||||
{
|
||||
|
|
@ -429,7 +428,7 @@ namespace Server.Engines.BulkOrders
|
|||
var page = 0;
|
||||
int i;
|
||||
|
||||
var list = m_List;
|
||||
var list = _list;
|
||||
for (i = 0; i < index && i < list.Count; i++)
|
||||
{
|
||||
var entry = list[i];
|
||||
|
|
@ -525,6 +524,13 @@ namespace Server.Engines.BulkOrders
|
|||
return "Invalid";
|
||||
}
|
||||
|
||||
public override void SendTo(NetState ns)
|
||||
{
|
||||
ns.CloseGump<BOBFilterGump>();
|
||||
|
||||
base.SendTo(ns);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, in RelayInfo info)
|
||||
{
|
||||
var index = info.ButtonID;
|
||||
|
|
@ -537,34 +543,34 @@ namespace Server.Engines.BulkOrders
|
|||
}
|
||||
case 1: // Set Filter
|
||||
{
|
||||
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
|
||||
_from.SendGump(new BOBFilterGump(_from, _book));
|
||||
|
||||
break;
|
||||
}
|
||||
case 2: // Previous page
|
||||
{
|
||||
if (m_Page > 0)
|
||||
if (_page > 0)
|
||||
{
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page - 1, m_List));
|
||||
_from.SendGump(new BOBGump(_from, _book, _page - 1, _list));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
case 3: // Next page
|
||||
{
|
||||
if (GetIndexForPage(m_Page + 1) < m_List.Count)
|
||||
if (GetIndexForPage(_page + 1) < _list.Count)
|
||||
{
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page + 1, m_List));
|
||||
_from.SendGump(new BOBGump(_from, _book, _page + 1, _list));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 4: // Price all
|
||||
{
|
||||
if (m_Book.IsChildOf(m_From.Backpack))
|
||||
if (_book.IsChildOf(_from.Backpack))
|
||||
{
|
||||
m_From.Prompt = new SetPricePrompt(m_Book, null, m_Page, m_List);
|
||||
m_From.SendMessage("Type in a price for all deeds in the book:");
|
||||
_from.Prompt = new SetPricePrompt(_book, null, _page, _list);
|
||||
_from.SendMessage("Type in a price for all deeds in the book:");
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -576,28 +582,28 @@ namespace Server.Engines.BulkOrders
|
|||
var type = index % 2;
|
||||
index /= 2;
|
||||
|
||||
if (index < 0 || index >= m_List.Count)
|
||||
if (index < 0 || index >= _list.Count)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var bobEntry = m_List[index];
|
||||
var bobEntry = _list[index];
|
||||
|
||||
if (!m_Book.Entries.Contains(bobEntry))
|
||||
if (!_book.Entries.Contains(bobEntry))
|
||||
{
|
||||
m_From.SendLocalizedMessage(1062382); // The deed selected is not available.
|
||||
_from.SendLocalizedMessage(1062382); // The deed selected is not available.
|
||||
break;
|
||||
}
|
||||
|
||||
if (type == 0) // Drop
|
||||
{
|
||||
if (m_Book.IsChildOf(m_From.Backpack))
|
||||
if (_book.IsChildOf(_from.Backpack))
|
||||
{
|
||||
var item = bobEntry.Reconstruct();
|
||||
|
||||
var pack = m_From.Backpack;
|
||||
var pack = _from.Backpack;
|
||||
if (pack?.CheckHold(
|
||||
m_From,
|
||||
_from,
|
||||
item,
|
||||
true,
|
||||
true,
|
||||
|
|
@ -605,37 +611,37 @@ namespace Server.Engines.BulkOrders
|
|||
item.PileWeight + item.TotalWeight
|
||||
) != true)
|
||||
{
|
||||
m_From.SendLocalizedMessage(503204); // You do not have room in your backpack for this
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page));
|
||||
_from.SendLocalizedMessage(503204); // You do not have room in your backpack for this
|
||||
_from.SendGump(new BOBGump(_from, _book, _page));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_Book.IsChildOf(m_From.Backpack))
|
||||
if (_book.IsChildOf(_from.Backpack))
|
||||
{
|
||||
var sizeOfDroppedBod = bobEntry is BOBLargeEntry entry ? entry.Entries.Length : 1;
|
||||
|
||||
m_From.AddToBackpack(item);
|
||||
_from.AddToBackpack(item);
|
||||
|
||||
// The bulk order deed has been placed in your backpack.
|
||||
m_From.SendLocalizedMessage(1045152);
|
||||
_from.SendLocalizedMessage(1045152);
|
||||
|
||||
m_Book.Entries.Remove(bobEntry);
|
||||
m_Book.InvalidateProperties();
|
||||
_book.Entries.Remove(bobEntry);
|
||||
_book.InvalidateProperties();
|
||||
|
||||
if (m_Book.Entries.Count / 5 < m_Book.ItemCount)
|
||||
if (_book.Entries.Count / 5 < _book.ItemCount)
|
||||
{
|
||||
m_Book.ItemCount--;
|
||||
m_Book.InvalidateItems();
|
||||
_book.ItemCount--;
|
||||
_book.InvalidateItems();
|
||||
}
|
||||
|
||||
if (m_Book.Entries.Count > 0)
|
||||
if (_book.Entries.Count > 0)
|
||||
{
|
||||
m_Page = GetPageForIndex(index, sizeOfDroppedBod);
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page));
|
||||
_page = GetPageForIndex(index, sizeOfDroppedBod);
|
||||
_from.SendGump(new BOBGump(_from, _book, _page));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendLocalizedMessage(1062381); // The book is empty.
|
||||
_from.SendLocalizedMessage(1062381); // The book is empty.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -643,14 +649,14 @@ namespace Server.Engines.BulkOrders
|
|||
}
|
||||
else // Set Price | Buy
|
||||
{
|
||||
if (m_Book.IsChildOf(m_From.Backpack))
|
||||
if (_book.IsChildOf(_from.Backpack))
|
||||
{
|
||||
m_From.Prompt = new SetPricePrompt(m_Book, bobEntry, m_Page, m_List);
|
||||
m_From.SendLocalizedMessage(1062383); // Type in a price for the deed:
|
||||
_from.Prompt = new SetPricePrompt(_book, bobEntry, _page, _list);
|
||||
_from.SendLocalizedMessage(1062383); // Type in a price for the deed:
|
||||
}
|
||||
else if (m_Book.RootParent is PlayerVendor pv)
|
||||
else if (_book.RootParent is PlayerVendor pv)
|
||||
{
|
||||
var vi = pv.GetVendorItem(m_Book);
|
||||
var vi = pv.GetVendorItem(_book);
|
||||
|
||||
if (vi?.IsForSale != false)
|
||||
{
|
||||
|
|
@ -662,18 +668,18 @@ namespace Server.Engines.BulkOrders
|
|||
|
||||
if (price == 0)
|
||||
{
|
||||
m_From.SendLocalizedMessage(1062382); // The deed selected is not available.
|
||||
_from.SendLocalizedMessage(1062382); // The deed selected is not available.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_Book.Entries.Count > 0)
|
||||
if (_book.Entries.Count > 0)
|
||||
{
|
||||
m_Page = GetPageForIndex(index, sizeOfDroppedBod);
|
||||
m_From.SendGump(new BODBuyGump(m_From, m_Book, bobEntry, m_Page, price));
|
||||
_page = GetPageForIndex(index, sizeOfDroppedBod);
|
||||
_from.SendGump(new BODBuyGump(_from, _book, bobEntry, _page, price));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendLocalizedMessage(1062381); // The book is emptz
|
||||
_from.SendLocalizedMessage(1062381); // The book is emptz
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using ModernUO.Serialization;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.BulkOrders
|
||||
|
|
|
|||
|
|
@ -8,14 +8,13 @@ namespace Server.Engines.BulkOrders
|
|||
private readonly LargeBOD m_Deed;
|
||||
private readonly Mobile m_From;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public LargeBODAcceptGump(Mobile from, LargeBOD deed) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Deed = deed;
|
||||
|
||||
m_From.CloseGump<LargeBODAcceptGump>();
|
||||
m_From.CloseGump<SmallBODAcceptGump>();
|
||||
|
||||
var entries = deed.Entries;
|
||||
|
||||
AddPage(0);
|
||||
|
|
|
|||
|
|
@ -8,14 +8,13 @@ namespace Server.Engines.BulkOrders
|
|||
private readonly LargeBOD m_Deed;
|
||||
private readonly Mobile m_From;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public LargeBODGump(Mobile from, LargeBOD deed) : base(25, 25)
|
||||
{
|
||||
m_From = from;
|
||||
m_Deed = deed;
|
||||
|
||||
m_From.CloseGump<LargeBODGump>();
|
||||
m_From.CloseGump<SmallBODGump>();
|
||||
|
||||
var entries = deed.Entries;
|
||||
|
||||
AddPage(0);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,14 +8,13 @@ namespace Server.Engines.BulkOrders
|
|||
private readonly SmallBOD m_Deed;
|
||||
private readonly Mobile m_From;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public SmallBODAcceptGump(Mobile from, SmallBOD deed) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Deed = deed;
|
||||
|
||||
m_From.CloseGump<LargeBODAcceptGump>();
|
||||
m_From.CloseGump<SmallBODAcceptGump>();
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(25, 10, 430, 264, 5054);
|
||||
|
|
|
|||
|
|
@ -8,14 +8,13 @@ namespace Server.Engines.BulkOrders
|
|||
private readonly SmallBOD m_Deed;
|
||||
private readonly Mobile m_From;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public SmallBODGump(Mobile from, SmallBOD deed) : base(25, 25)
|
||||
{
|
||||
m_From = from;
|
||||
m_Deed = deed;
|
||||
|
||||
m_From.CloseGump<LargeBODGump>();
|
||||
m_From.CloseGump<SmallBODGump>();
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(50, 10, 455, 260, 5054);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
private bool m_Active = true;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public AcceptDuelGump(Mobile challenger, Mobile challenged, DuelContext context, Participant p, int slot) : base(
|
||||
50,
|
||||
50
|
||||
|
|
@ -33,8 +35,6 @@ namespace Server.Engines.ConPVP
|
|||
m_Participant = p;
|
||||
m_Slot = slot;
|
||||
|
||||
challenged.CloseGump<AcceptDuelGump>();
|
||||
|
||||
Closable = false;
|
||||
|
||||
AddPage(0);
|
||||
|
|
@ -244,23 +244,18 @@ namespace Server.Engines.ConPVP
|
|||
m_Challenger.SendMessage($"{m_Challenged.Name} has accepted the request.");
|
||||
m_Challenged.SendMessage($"You have accepted the request from {m_Challenger.Name}.");
|
||||
|
||||
var ns = m_Challenger.NetState;
|
||||
|
||||
if (ns != null)
|
||||
foreach (var g in m_Challenger.GetAllGumps())
|
||||
{
|
||||
foreach (var g in ns.Gumps)
|
||||
if (g is ParticipantGump pg && pg.Participant == m_Participant)
|
||||
{
|
||||
if (g is ParticipantGump pg && pg.Participant == m_Participant)
|
||||
{
|
||||
m_Challenger.SendGump(new ParticipantGump(m_Challenger, m_Context, m_Participant));
|
||||
break;
|
||||
}
|
||||
m_Challenger.SendGump(new ParticipantGump(m_Challenger, m_Context, m_Participant));
|
||||
break;
|
||||
}
|
||||
|
||||
if (g is DuelContextGump dcg && dcg.Context == m_Context)
|
||||
{
|
||||
m_Challenger.SendGump(new DuelContextGump(m_Challenger, m_Context));
|
||||
break;
|
||||
}
|
||||
if (g is DuelContextGump dcg && dcg.Context == m_Context)
|
||||
{
|
||||
m_Challenger.SendGump(new DuelContextGump(m_Challenger, m_Context));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,9 +135,9 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
string title = move switch
|
||||
{
|
||||
NinjaMove => "Bushido",
|
||||
NinjaMove => "Bushido",
|
||||
SamuraiMove => "Ninjitsu",
|
||||
_ => null
|
||||
_ => null
|
||||
};
|
||||
|
||||
if (title == null || name == null || Ruleset.GetOption(title, name))
|
||||
|
|
@ -199,15 +199,15 @@ namespace Server.Engines.ConPVP
|
|||
case MagerySpell magerySpell:
|
||||
title = magerySpell.Circle switch
|
||||
{
|
||||
SpellCircle.First => "1st Circle",
|
||||
SpellCircle.Second => "2nd Circle",
|
||||
SpellCircle.Third => "3rd Circle",
|
||||
SpellCircle.Fourth => "4th Circle",
|
||||
SpellCircle.Fifth => "5th Circle",
|
||||
SpellCircle.Sixth => "6th Circle",
|
||||
SpellCircle.First => "1st Circle",
|
||||
SpellCircle.Second => "2nd Circle",
|
||||
SpellCircle.Third => "3rd Circle",
|
||||
SpellCircle.Fourth => "4th Circle",
|
||||
SpellCircle.Fifth => "5th Circle",
|
||||
SpellCircle.Sixth => "6th Circle",
|
||||
SpellCircle.Seventh => "7th Circle",
|
||||
SpellCircle.Eighth => "8th Circle",
|
||||
_ => null
|
||||
SpellCircle.Eighth => "8th Circle",
|
||||
_ => null
|
||||
};
|
||||
|
||||
option = magerySpell.Name;
|
||||
|
|
@ -1431,7 +1431,6 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
if (prefs != null)
|
||||
{
|
||||
e.Mobile.CloseGump<PreferencesGump>();
|
||||
e.Mobile.SendGump(new PreferencesGump(e.Mobile, prefs));
|
||||
}
|
||||
}
|
||||
|
|
@ -1542,23 +1541,18 @@ namespace Server.Engines.ConPVP
|
|||
p.Nullify(pl);
|
||||
pm.DuelPlayer = null;
|
||||
|
||||
var ns = init.NetState;
|
||||
|
||||
if (ns != null)
|
||||
foreach (var g in init.GetAllGumps())
|
||||
{
|
||||
foreach (var g in ns.Gumps)
|
||||
if (g is ParticipantGump pg && pg.Participant == p)
|
||||
{
|
||||
if (g is ParticipantGump pg && pg.Participant == p)
|
||||
{
|
||||
init.SendGump(new ParticipantGump(init, dc, p));
|
||||
break;
|
||||
}
|
||||
init.SendGump(new ParticipantGump(init, dc, p));
|
||||
break;
|
||||
}
|
||||
|
||||
if (g is DuelContextGump dcg && dcg.Context == dc)
|
||||
{
|
||||
init.SendGump(new DuelContextGump(init, dc));
|
||||
break;
|
||||
}
|
||||
if (g is DuelContextGump dcg && dcg.Context == dc)
|
||||
{
|
||||
init.SendGump(new DuelContextGump(init, dc));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1580,34 +1574,29 @@ namespace Server.Engines.ConPVP
|
|||
p.Nullify(pl);
|
||||
pm.DuelPlayer = null;
|
||||
|
||||
var ns = init.NetState;
|
||||
var send = true;
|
||||
|
||||
if (ns != null)
|
||||
foreach (var g in init.GetAllGumps())
|
||||
{
|
||||
var send = true;
|
||||
|
||||
foreach (var g in ns.Gumps)
|
||||
if (g is ParticipantGump pg && pg.Participant == p)
|
||||
{
|
||||
if (g is ParticipantGump pg && pg.Participant == p)
|
||||
{
|
||||
init.SendGump(new ParticipantGump(init, dc, p));
|
||||
send = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (g is DuelContextGump dcg && dcg.Context == dc)
|
||||
{
|
||||
init.SendGump(new DuelContextGump(init, dc));
|
||||
send = false;
|
||||
break;
|
||||
}
|
||||
init.SendGump(new ParticipantGump(init, dc, p));
|
||||
send = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (send)
|
||||
if (g is DuelContextGump dcg && dcg.Context == dc)
|
||||
{
|
||||
init.SendGump(new DuelContextGump(init, dc));
|
||||
send = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (send)
|
||||
{
|
||||
init.SendGump(new DuelContextGump(init, dc));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1629,34 +1618,29 @@ namespace Server.Engines.ConPVP
|
|||
p.Nullify(pl);
|
||||
pm.DuelPlayer = null;
|
||||
|
||||
var ns = init.NetState;
|
||||
var send = true;
|
||||
|
||||
if (ns != null)
|
||||
foreach (var g in init.GetAllGumps())
|
||||
{
|
||||
var send = true;
|
||||
|
||||
foreach (var g in ns.Gumps)
|
||||
if (g is ParticipantGump pg && pg.Participant == p)
|
||||
{
|
||||
if (g is ParticipantGump pg && pg.Participant == p)
|
||||
{
|
||||
init.SendGump(new ParticipantGump(init, dc, p));
|
||||
send = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (g is DuelContextGump dcg && dcg.Context == dc)
|
||||
{
|
||||
init.SendGump(new DuelContextGump(init, dc));
|
||||
send = false;
|
||||
break;
|
||||
}
|
||||
init.SendGump(new ParticipantGump(init, dc, p));
|
||||
send = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (send)
|
||||
if (g is DuelContextGump dcg && dcg.Context == dc)
|
||||
{
|
||||
init.SendGump(new DuelContextGump(init, dc));
|
||||
send = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (send)
|
||||
{
|
||||
init.SendGump(new DuelContextGump(init, dc));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1714,13 +1698,15 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public void CloseAllGumps(DuelPlayer pl)
|
||||
{
|
||||
pl.Mobile.CloseGump<BeginGump>();
|
||||
pl.Mobile.CloseGump<DuelContextGump>();
|
||||
pl.Mobile.CloseGump<ParticipantGump>();
|
||||
pl.Mobile.CloseGump<PickRulesetGump>();
|
||||
pl.Mobile.CloseGump<ReadyGump>();
|
||||
pl.Mobile.CloseGump<ReadyUpGump>();
|
||||
pl.Mobile.CloseGump<RulesetGump>();
|
||||
var gumps = pl.Mobile.GetGumps();
|
||||
|
||||
gumps.Close<BeginGump>();
|
||||
gumps.Close<DuelContextGump>();
|
||||
gumps.Close<ParticipantGump>();
|
||||
gumps.Close<PickRulesetGump>();
|
||||
gumps.Close<ReadyGump>();
|
||||
gumps.Close<ReadyUpGump>();
|
||||
gumps.Close<RulesetGump>();
|
||||
}
|
||||
|
||||
public void CloseAllGumps()
|
||||
|
|
@ -1799,9 +1785,11 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
|
||||
// Close all of them?
|
||||
mob.CloseGump<DuelContextGump>();
|
||||
mob.CloseGump<ReadyUpGump>();
|
||||
mob.CloseGump<ReadyGump>();
|
||||
var gumps = mob.GetGumps();
|
||||
|
||||
gumps.Close<DuelContextGump>();
|
||||
gumps.Close<ReadyUpGump>();
|
||||
gumps.Close<ReadyGump>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2194,10 +2182,12 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
if (count == 10)
|
||||
{
|
||||
mob.CloseGump<ReadyGump>();
|
||||
mob.CloseGump<ReadyUpGump>();
|
||||
mob.CloseGump<BeginGump>();
|
||||
mob.SendGump(new BeginGump(count));
|
||||
var gumps = mob.GetGumps();
|
||||
|
||||
gumps.Close<ReadyGump>();
|
||||
gumps.Close<ReadyUpGump>();
|
||||
gumps.Close<BeginGump>();
|
||||
gumps.Send(new BeginGump(count));
|
||||
}
|
||||
|
||||
mob.Frozen = true;
|
||||
|
|
@ -2256,8 +2246,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
if (mob != null && m_Tournament == null)
|
||||
{
|
||||
mob.CloseGump<ReadyUpGump>();
|
||||
mob.SendGump(new ReadyUpGump(mob, this));
|
||||
mob.SendGump(new ReadyUpGump(mob, this), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2512,8 +2501,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
if (m_Tournament == null)
|
||||
{
|
||||
mob.CloseGump<ReadyGump>();
|
||||
mob.SendGump(new ReadyGump(mob, this, count));
|
||||
mob.SendGump(new ReadyGump(mob, this, count), true);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1057,7 +1057,6 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
if (m_TeamInfo?.Game != null)
|
||||
{
|
||||
from.CloseGump<BRBoardGump>();
|
||||
from.SendGump(new BRBoardGump(from, m_TeamInfo.Game));
|
||||
}
|
||||
}
|
||||
|
|
@ -1082,7 +1081,7 @@ namespace Server.Engines.ConPVP
|
|||
private const int LabelColor32 = 0xFFFFFF;
|
||||
private const int BlackColor32 = 0x000000;
|
||||
|
||||
// private BRGame m_Game;
|
||||
public override bool Singleton => true;
|
||||
|
||||
public BRBoardGump(Mobile mob, BRGame game, BRTeamInfo section = null) : base(60, 60)
|
||||
{
|
||||
|
|
@ -1719,7 +1718,6 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
}
|
||||
|
||||
mob.CloseGump<BRBoardGump>();
|
||||
mob.SendGump(new BRBoardGump(mob, this));
|
||||
|
||||
m_Context.Requip(mob, corpse);
|
||||
|
|
@ -1918,7 +1916,6 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
if (dp?.Mobile != null)
|
||||
{
|
||||
dp.Mobile.CloseGump<BRBoardGump>();
|
||||
dp.Mobile.SendGump(new BRBoardGump(dp.Mobile, this));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
if (m_TeamInfo?.Game != null)
|
||||
{
|
||||
from.CloseGump<CTFBoardGump>();
|
||||
from.SendGump(new CTFBoardGump(from, m_TeamInfo.Game));
|
||||
}
|
||||
}
|
||||
|
|
@ -56,6 +55,8 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
private CTFGame m_Game;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public CTFBoardGump(Mobile mob, CTFGame game, CTFTeamInfo section = null)
|
||||
: base(60, 60)
|
||||
{
|
||||
|
|
@ -1059,7 +1060,6 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
}
|
||||
|
||||
mob.CloseGump<CTFBoardGump>();
|
||||
mob.SendGump(new CTFBoardGump(mob, this));
|
||||
|
||||
m_Context.Requip(mob, corpse);
|
||||
|
|
@ -1258,7 +1258,6 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
if (dp?.Mobile != null)
|
||||
{
|
||||
dp.Mobile.CloseGump<CTFBoardGump>();
|
||||
dp.Mobile.SendGump(new CTFBoardGump(dp.Mobile, this));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
if (m_TeamInfo?.Game != null)
|
||||
{
|
||||
from.CloseGump<DDBoardGump>();
|
||||
from.SendGump(new DDBoardGump(from, m_TeamInfo.Game));
|
||||
}
|
||||
}
|
||||
|
|
@ -52,7 +51,7 @@ namespace Server.Engines.ConPVP
|
|||
private const int LabelColor32 = 0xFFFFFF;
|
||||
private const int BlackColor32 = 0x000000;
|
||||
|
||||
// private DDGame m_Game;
|
||||
public override bool Singleton => true;
|
||||
|
||||
public DDBoardGump(Mobile mob, DDGame game, DDTeamInfo section = null)
|
||||
: base(60, 60)
|
||||
|
|
@ -605,7 +604,6 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
}
|
||||
|
||||
mob.CloseGump<DDBoardGump>();
|
||||
mob.SendGump(new DDBoardGump(mob, this));
|
||||
|
||||
m_Context.Requip(mob, corpse);
|
||||
|
|
@ -820,7 +818,6 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
if (dp?.Mobile != null)
|
||||
{
|
||||
dp.Mobile.CloseGump<DDBoardGump>();
|
||||
dp.Mobile.SendGump(new DDBoardGump(dp.Mobile, this));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -311,7 +311,6 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
if (m_Game != null)
|
||||
{
|
||||
from.CloseGump<KHBoardGump>();
|
||||
from.SendGump(new KHBoardGump(from, m_Game));
|
||||
}
|
||||
else
|
||||
|
|
@ -353,6 +352,8 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
private KHGame m_Game;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public KHBoardGump(Mobile mob, KHGame game)
|
||||
: base(60, 60)
|
||||
{
|
||||
|
|
@ -989,7 +990,6 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
}
|
||||
|
||||
mob.CloseGump<KHBoardGump>();
|
||||
mob.SendGump(new KHBoardGump(mob, this));
|
||||
|
||||
m_Context.Requip(mob, corpse);
|
||||
|
|
@ -1199,7 +1199,6 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
if (dp?.Mobile != null)
|
||||
{
|
||||
dp.Mobile.CloseGump<KHBoardGump>();
|
||||
dp.Mobile.SendGump(new KHBoardGump(dp.Mobile, this));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ namespace Server.Engines.ConPVP
|
|||
return false;
|
||||
}
|
||||
|
||||
from.CloseGump<ArenaGump>();
|
||||
from.SendGump(new ArenaGump(from, this));
|
||||
|
||||
if (!from.Hidden || from.AccessLevel == AccessLevel.Player)
|
||||
|
|
@ -84,6 +83,8 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
private int m_ColumnX = 12;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public ArenaGump(Mobile from, ArenasMoongate gate) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ namespace Server.Engines.ConPVP
|
|||
private readonly Mobile m_Registrar;
|
||||
private readonly Tournament m_Tournament;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public ConfirmSignupGump(Mobile from, Mobile registrar, Tournament tourney, List<Mobile> players) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
|
|
@ -26,10 +28,11 @@ namespace Server.Engines.ConPVP
|
|||
m_Tournament = tourney;
|
||||
m_Players = players;
|
||||
|
||||
m_From.CloseGump<AcceptTeamGump>();
|
||||
m_From.CloseGump<AcceptDuelGump>();
|
||||
m_From.CloseGump<DuelContextGump>();
|
||||
m_From.CloseGump<ConfirmSignupGump>();
|
||||
var gumps = m_From.GetGumps();
|
||||
|
||||
gumps.Close<AcceptTeamGump>();
|
||||
gumps.Close<AcceptDuelGump>();
|
||||
gumps.Close<DuelContextGump>();
|
||||
|
||||
var ruleset = tourney.Ruleset;
|
||||
var basedef = ruleset.Base;
|
||||
|
|
|
|||
|
|
@ -5,14 +5,17 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
public class DuelContextGump : Gump
|
||||
{
|
||||
public override bool Singleton => true;
|
||||
|
||||
public DuelContextGump(Mobile from, DuelContext context) : base(50, 50)
|
||||
{
|
||||
From = from;
|
||||
Context = context;
|
||||
|
||||
from.CloseGump<RulesetGump>();
|
||||
from.CloseGump<DuelContextGump>();
|
||||
from.CloseGump<ParticipantGump>();
|
||||
var gumps = from.GetGumps();
|
||||
|
||||
gumps.Close<RulesetGump>();
|
||||
gumps.Close<ParticipantGump>();
|
||||
|
||||
var count = context.Participants.Count;
|
||||
|
||||
|
|
|
|||
|
|
@ -52,8 +52,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
if (ladder != null)
|
||||
{
|
||||
from.CloseGump<LadderGump>();
|
||||
from.SendGump(new LadderGump(ladder));
|
||||
from.SendGump(new LadderGump(ladder), true);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -7,15 +7,18 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
public class ParticipantGump : Gump
|
||||
{
|
||||
public override bool Singleton => true;
|
||||
|
||||
public ParticipantGump(Mobile from, DuelContext context, Participant p) : base(50, 50)
|
||||
{
|
||||
From = from;
|
||||
Context = context;
|
||||
Participant = p;
|
||||
|
||||
from.CloseGump<RulesetGump>();
|
||||
from.CloseGump<DuelContextGump>();
|
||||
from.CloseGump<ParticipantGump>();
|
||||
var gumps = from.GetGumps();
|
||||
|
||||
gumps.Close<RulesetGump>();
|
||||
gumps.Close<DuelContextGump>();
|
||||
|
||||
var count = p.Players.Length;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ namespace Server.Engines.ConPVP
|
|||
private readonly bool m_ReadOnly;
|
||||
private readonly Ruleset m_Ruleset;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public RulesetGump(Mobile from, Ruleset ruleset, RulesetLayout page, DuelContext duelContext, bool readOnly = false)
|
||||
: base(readOnly ? 310 : 50, 50)
|
||||
{
|
||||
|
|
@ -23,9 +25,10 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
Draggable = !readOnly;
|
||||
|
||||
from.CloseGump<RulesetGump>();
|
||||
from.CloseGump<DuelContextGump>();
|
||||
from.CloseGump<ParticipantGump>();
|
||||
var gumps = from.GetGumps();
|
||||
|
||||
gumps.Close<DuelContextGump>();
|
||||
gumps.Close<ParticipantGump>();
|
||||
|
||||
var depthCounter = page;
|
||||
|
||||
|
|
|
|||
|
|
@ -179,6 +179,8 @@ namespace Server.Engines.ConPVP
|
|||
private readonly PreferencesEntry m_Entry;
|
||||
private int m_ColumnX = 12;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public PreferencesGump(Mobile from, Preferences prefs) : base(50, 50)
|
||||
{
|
||||
m_Entry = prefs.Find(from);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
using Server.Gumps;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class TournamentBracketItem : Item
|
||||
|
|
@ -26,8 +28,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
if (tourney != null)
|
||||
{
|
||||
from.CloseGump<TournamentBracketGump>();
|
||||
from.SendGump(new TournamentBracketGump(from, tourney, TourneyBracketGumpType.Index));
|
||||
from.SendGump(new TournamentBracketGump(from, tourney, TourneyBracketGumpType.Index), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,9 +66,11 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster && Tournament != null)
|
||||
{
|
||||
from.CloseGump<PickRulesetGump>();
|
||||
from.CloseGump<RulesetGump>();
|
||||
from.SendGump(new PickRulesetGump(from, null, Tournament.Ruleset));
|
||||
var gumps = from.GetGumps();
|
||||
|
||||
gumps.Close<RulesetGump>();
|
||||
gumps.Close<PickRulesetGump>();
|
||||
gumps.Send(new PickRulesetGump(from, null, Tournament.Ruleset));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.Factions;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
|
|
@ -146,7 +147,6 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
else if (!tourney.HasParticipant(from))
|
||||
{
|
||||
from.CloseGump<ConfirmSignupGump>();
|
||||
from.SendGump(new ConfirmSignupGump(from, Registrar, tourney, new List<Mobile> { from }));
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ public class CraftGump : DynamicGump
|
|||
private readonly BaseTool _tool;
|
||||
private readonly TextDefinition _notice;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public CraftGump(
|
||||
Mobile from, CraftSystem craftSystem, BaseTool tool, TextDefinition notice, CraftPage page = CraftPage.None
|
||||
) : base(40, 40)
|
||||
|
|
@ -419,7 +421,6 @@ public class CraftGump : DynamicGump
|
|||
|
||||
public override void SendTo(NetState ns)
|
||||
{
|
||||
_from.CloseGump<CraftGump>();
|
||||
_from.CloseGump<CraftGumpItem>();
|
||||
|
||||
base.SendTo(ns);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ namespace Server.Engines.Craft
|
|||
|
||||
private bool m_ShowExceptionalChance;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public CraftGumpItem(Mobile from, CraftSystem craftSystem, CraftItem craftItem, BaseTool tool) : base(40, 40)
|
||||
{
|
||||
m_From = from;
|
||||
|
|
@ -34,9 +36,6 @@ namespace Server.Engines.Craft
|
|||
m_CraftItem = craftItem;
|
||||
m_Tool = tool;
|
||||
|
||||
from.CloseGump<CraftGump>();
|
||||
from.CloseGump<CraftGumpItem>();
|
||||
|
||||
AddPage(0);
|
||||
AddBackground(0, 0, 530, 417, 5054);
|
||||
AddImageTiled(10, 10, 510, 22, 2624);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using Server.Commands;
|
||||
using Server.Factions;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Logging;
|
||||
using Server.Mobiles;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Targeting;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,13 +14,13 @@ namespace Server.Engines.Craft
|
|||
private readonly BaseTool m_Tool;
|
||||
private readonly Type m_TypeRes;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public QueryMakersMarkGump(
|
||||
int quality, Mobile from, CraftItem craftItem, CraftSystem craftSystem, Type typeRes,
|
||||
BaseTool tool
|
||||
) : base(100, 200)
|
||||
{
|
||||
from.CloseGump<QueryMakersMarkGump>();
|
||||
|
||||
m_Quality = quality;
|
||||
m_From = from;
|
||||
m_CraftItem = craftItem;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Server.Ethics;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Targeting;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using Server.Factions;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Targeting;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using Server.Commands.Generic;
|
|||
using Server.Engines.ConPVP;
|
||||
using Server.Ethics;
|
||||
using Server.Guilds;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Prompts;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Factions;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Factions;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Factions;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Factions;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using ModernUO.Serialization;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ public sealed class HelpGump : DynamicGump
|
|||
{
|
||||
private readonly Mobile _from;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public HelpGump(Mobile from) : base(0, 0) => _from = from;
|
||||
|
||||
protected override void BuildLayout(ref DynamicGumpBuilder builder)
|
||||
|
|
@ -206,12 +208,6 @@ public sealed class HelpGump : DynamicGump
|
|||
builder.AddHtmlLocalized(180, y + 150, 335, 40, 1001015); // NO - I meant to ask for help with another matter.
|
||||
}
|
||||
|
||||
public override void SendTo(NetState ns)
|
||||
{
|
||||
_from.CloseGump<HelpGump>();
|
||||
base.SendTo(ns);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void AddOption(
|
||||
ref DynamicGumpBuilder builder, int y, int buttonId, int localizedName, GumpButtonType type = GumpButtonType.Reply,
|
||||
|
|
@ -237,12 +233,9 @@ public sealed class HelpGump : DynamicGump
|
|||
|
||||
public static void HelpRequest(Mobile m)
|
||||
{
|
||||
foreach (var gump in m.NetState.Gumps)
|
||||
if (m.HasGump<HelpGump>())
|
||||
{
|
||||
if (gump is HelpGump)
|
||||
{
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PageQueue.CheckAllowedToPage(m))
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ public sealed class PagePromptGump : StaticGump<PagePromptGump>
|
|||
private readonly Mobile _from;
|
||||
private readonly PageType _type;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public PagePromptGump(Mobile from, PageType type) : base(0, 0)
|
||||
{
|
||||
_from = from;
|
||||
|
|
@ -31,12 +33,6 @@ public sealed class PagePromptGump : StaticGump<PagePromptGump>
|
|||
builder. AddButton(405, 355, 2073, 2072, 0); // Cancel
|
||||
}
|
||||
|
||||
public override void SendTo(NetState ns)
|
||||
{
|
||||
_from.CloseGump<PagePromptGump>();
|
||||
base.SendTo(ns);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, in RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 0)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Misc;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
|
|
|||
|
|
@ -118,9 +118,7 @@ namespace Server.Engines.Help
|
|||
{
|
||||
if (PageQueue.List.IndexOf(m_List[info.ButtonID - 1]) >= 0)
|
||||
{
|
||||
var g = new PageEntryGump(state.Mobile, m_List[info.ButtonID - 1]);
|
||||
|
||||
g.SendTo(state);
|
||||
state.SendGump(new PageEntryGump(state.Mobile, m_List[info.ButtonID - 1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -224,13 +222,13 @@ namespace Server.Engines.Help
|
|||
private readonly Mobile m_From;
|
||||
private readonly PredefinedResponse m_Response;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public PredefGump(Mobile from, PredefinedResponse response) : base(30, 30)
|
||||
{
|
||||
m_From = from;
|
||||
m_Response = response;
|
||||
|
||||
from.CloseGump<PredefGump>();
|
||||
|
||||
var canEdit = from.AccessLevel >= AccessLevel.GameMaster;
|
||||
|
||||
AddPage(0);
|
||||
|
|
@ -593,9 +591,7 @@ namespace Server.Engines.Help
|
|||
|
||||
public void Resend(NetState state)
|
||||
{
|
||||
var g = new PageEntryGump(m_Mobile, m_Entry);
|
||||
|
||||
g.SendTo(state);
|
||||
state.SendGump(new PageEntryGump(m_Mobile, m_Entry));
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, in RelayInfo info)
|
||||
|
|
@ -613,9 +609,7 @@ namespace Server.Engines.Help
|
|||
{
|
||||
if (m_Entry.Handler != state.Mobile)
|
||||
{
|
||||
var g = new PageQueueGump();
|
||||
|
||||
g.SendTo(state);
|
||||
state.SendGump(new PageQueueGump());
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -722,10 +716,7 @@ namespace Server.Engines.Help
|
|||
PageQueue.Remove(m_Entry);
|
||||
|
||||
state.Mobile.SendMessage("You delete the page.");
|
||||
|
||||
var g = new PageQueueGump();
|
||||
|
||||
g.SendTo(state);
|
||||
state.SendGump(new PageQueueGump());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -764,10 +755,7 @@ namespace Server.Engines.Help
|
|||
m_Entry.Handler = null;
|
||||
|
||||
state.Mobile.SendMessage("You mark the page as handled, and remove it from the queue.");
|
||||
|
||||
var g = new PageQueueGump();
|
||||
|
||||
g.SendTo(state);
|
||||
state.SendGump(new PageQueueGump());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -290,9 +290,11 @@ namespace Server.Items
|
|||
);
|
||||
}
|
||||
|
||||
from.CloseGump<PuzzleGump>();
|
||||
from.CloseGump<StatusGump>();
|
||||
from.SendGump(new PuzzleGump(from, this, solution, 0));
|
||||
var gumps = from.GetGumps();
|
||||
|
||||
gumps.Close<StatusGump>();
|
||||
gumps.Close<PuzzleGump>();
|
||||
gumps.Send(new PuzzleGump(from, this, solution, 0));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -268,12 +268,13 @@ namespace Server.Engines.MLQuests.Gumps
|
|||
*/
|
||||
public static void CloseOtherGumps(PlayerMobile pm)
|
||||
{
|
||||
pm.CloseGump<InfoNPCGump>();
|
||||
pm.CloseGump<QuestRewardGump>();
|
||||
pm.CloseGump<QuestConversationGump>();
|
||||
pm.CloseGump<QuestReportBackGump>();
|
||||
// pm.CloseGump( typeof( UnknownGump807 ) );
|
||||
pm.CloseGump<QuestCancelConfirmGump>();
|
||||
var gumps = pm.GetGumps();
|
||||
|
||||
gumps.Close<InfoNPCGump>();
|
||||
gumps.Close<QuestRewardGump>();
|
||||
gumps.Close<QuestConversationGump>();
|
||||
gumps.Close<QuestReportBackGump>();
|
||||
gumps.Close<QuestCancelConfirmGump>();
|
||||
}
|
||||
|
||||
private struct ButtonInfo
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ namespace Server.Engines.MLQuests.Gumps
|
|||
private readonly bool m_CloseGumps;
|
||||
private readonly MLQuestInstance m_Instance;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public QuestLogDetailedGump(MLQuestInstance instance, bool closeGumps = true)
|
||||
: base(1046026) // Quest Log
|
||||
{
|
||||
|
|
@ -20,7 +22,6 @@ namespace Server.Engines.MLQuests.Gumps
|
|||
if (closeGumps)
|
||||
{
|
||||
CloseOtherGumps(pm);
|
||||
pm.CloseGump<QuestLogDetailedGump>();
|
||||
}
|
||||
|
||||
SetTitle(quest.Title);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ namespace Server.Engines.MLQuests.Gumps
|
|||
private readonly bool m_CloseGumps;
|
||||
private readonly PlayerMobile m_Owner;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public QuestLogGump(PlayerMobile pm, bool closeGumps = true)
|
||||
: base(1046026) // Quest Log
|
||||
{
|
||||
|
|
@ -17,7 +19,6 @@ namespace Server.Engines.MLQuests.Gumps
|
|||
|
||||
if (closeGumps)
|
||||
{
|
||||
pm.CloseGump<QuestLogGump>();
|
||||
pm.CloseGump<QuestLogDetailedGump>();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ namespace Server.Engines.MLQuests.Gumps
|
|||
private readonly MLQuest m_Quest;
|
||||
private readonly IQuestGiver m_Quester;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public QuestOfferGump(MLQuest quest, IQuestGiver quester, PlayerMobile pm)
|
||||
: base(1049010) // Quest Offer
|
||||
{
|
||||
|
|
@ -16,7 +18,6 @@ namespace Server.Engines.MLQuests.Gumps
|
|||
m_Quester = quester;
|
||||
|
||||
CloseOtherGumps(pm);
|
||||
pm.CloseGump<QuestOfferGump>();
|
||||
|
||||
SetTitle(quest.Title);
|
||||
RegisterButton(ButtonPosition.Left, ButtonGraphic.Accept, 1);
|
||||
|
|
|
|||
|
|
@ -27,11 +27,11 @@ namespace Server.Engines.MLQuests.Gumps
|
|||
private readonly IRaceChanger m_Owner;
|
||||
private readonly Race m_Race;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public RaceChangeConfirmGump(IRaceChanger owner, PlayerMobile from, Race targetRace)
|
||||
: base(50, 50)
|
||||
{
|
||||
from.CloseGump<RaceChangeConfirmGump>();
|
||||
|
||||
m_Owner = owner;
|
||||
m_From = from;
|
||||
m_Race = targetRace;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using Server.Engines.MLQuests.Gumps;
|
|||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.MLQuests
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using Server.Engines.MLQuests.Gumps;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.MLQuests
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using ModernUO.Serialization;
|
||||
using Server.Engines.MLQuests.Definitions;
|
||||
using Server.Engines.MLQuests.Gumps;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Server.Gumps;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Engines.Plants
|
||||
|
|
@ -21,12 +22,7 @@ namespace Server.Engines.Plants
|
|||
if (!m_Plant.Deleted && m_Plant.PlantStatus < PlantStatus.DecorativePlant &&
|
||||
from.InRange(m_Plant.GetWorldLocation(), 3) && m_Plant.IsUsableBy(from))
|
||||
{
|
||||
if (from.HasGump<MainPlantGump>())
|
||||
{
|
||||
from.CloseGump<MainPlantGump>();
|
||||
}
|
||||
|
||||
from.SendGump(new MainPlantGump(m_Plant));
|
||||
from.SendGump(new MainPlantGump(m_Plant), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Server.Gumps;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Engines.Plants
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ public partial class Impresario : BaseQuester
|
|||
|
||||
if (obj.IsInRightTheater())
|
||||
{
|
||||
player.CloseGump<SheetMusicOfferGump>();
|
||||
player.SendGump(new SheetMusicOfferGump());
|
||||
}
|
||||
else
|
||||
|
|
@ -68,6 +67,8 @@ public partial class Impresario : BaseQuester
|
|||
|
||||
public class SheetMusicOfferGump : BaseQuestGump
|
||||
{
|
||||
public override bool Singleton => true;
|
||||
|
||||
public SheetMusicOfferGump() : base(75, 25)
|
||||
{
|
||||
Closable = false;
|
||||
|
|
|
|||
|
|
@ -130,6 +130,8 @@ namespace Server.Engines.Quests
|
|||
{
|
||||
private readonly QuestSystem m_System;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public QuestLogUpdatedGump(QuestSystem system) : base(3, 30)
|
||||
{
|
||||
m_System = system;
|
||||
|
|
|
|||
|
|
@ -264,7 +264,6 @@ namespace Server.Engines.Quests
|
|||
|
||||
public virtual void ShowQuestLogUpdated()
|
||||
{
|
||||
From.CloseGump<QuestLogUpdatedGump>();
|
||||
From.SendGump(new QuestLogUpdatedGump(this));
|
||||
}
|
||||
|
||||
|
|
@ -272,18 +271,19 @@ namespace Server.Engines.Quests
|
|||
{
|
||||
if (Objectives.Count > 0)
|
||||
{
|
||||
From.CloseGump<QuestItemInfoGump>();
|
||||
From.CloseGump<QuestLogUpdatedGump>();
|
||||
From.CloseGump<QuestObjectivesGump>();
|
||||
From.CloseGump<QuestConversationsGump>();
|
||||
var gumps = From.GetGumps();
|
||||
gumps.Close<QuestItemInfoGump>();
|
||||
gumps.Close<QuestLogUpdatedGump>();
|
||||
gumps.Close<QuestConversationsGump>();
|
||||
gumps.Close<QuestObjectivesGump>();
|
||||
|
||||
From.SendGump(new QuestObjectivesGump(Objectives));
|
||||
gumps.Send(new QuestObjectivesGump(Objectives));
|
||||
|
||||
var last = Objectives[^1];
|
||||
|
||||
if (last.Info != null)
|
||||
{
|
||||
From.SendGump(new QuestItemInfoGump(last.Info));
|
||||
gumps.Send(new QuestItemInfoGump(last.Info));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -292,11 +292,13 @@ namespace Server.Engines.Quests
|
|||
{
|
||||
if (Conversations.Count > 0)
|
||||
{
|
||||
From.CloseGump<QuestItemInfoGump>();
|
||||
From.CloseGump<QuestObjectivesGump>();
|
||||
From.CloseGump<QuestConversationsGump>();
|
||||
var gumps = From.GetGumps();
|
||||
|
||||
From.SendGump(new QuestConversationsGump(Conversations));
|
||||
gumps.Close<QuestItemInfoGump>();
|
||||
gumps.Close<QuestObjectivesGump>();
|
||||
gumps.Close<QuestConversationsGump>();
|
||||
|
||||
gumps.Send(new QuestConversationsGump(Conversations));
|
||||
|
||||
var last = Conversations[^1];
|
||||
|
||||
|
|
@ -389,10 +391,10 @@ namespace Server.Engines.Quests
|
|||
Conversations.Add(conv);
|
||||
}
|
||||
|
||||
From.CloseGump<QuestItemInfoGump>();
|
||||
From.CloseGump<QuestObjectivesGump>();
|
||||
From.CloseGump<QuestConversationsGump>();
|
||||
From.SendGump(conv.Logged ? new QuestConversationsGump(Conversations) : new QuestConversationsGump(conv));
|
||||
var gumps = From.GetGumps();
|
||||
gumps.Close<QuestItemInfoGump>();
|
||||
gumps.Close<QuestObjectivesGump>();
|
||||
gumps.Send(conv.Logged ? new QuestConversationsGump(Conversations) : new QuestConversationsGump(conv));
|
||||
|
||||
if (conv.Info != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -186,7 +186,6 @@ public partial class Mardoth : BaseQuester
|
|||
m.PlaySound(0x214);
|
||||
m.FixedEffect(0x376A, 10, 16);
|
||||
|
||||
m.CloseGump<ResurrectGump>();
|
||||
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -203,7 +203,6 @@ public partial class Emino : BaseQuester
|
|||
m.PlaySound(0x214);
|
||||
m.FixedEffect(0x376A, 10, 16);
|
||||
|
||||
m.CloseGump<ResurrectGump>();
|
||||
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,6 @@ public partial class Zoel : BaseQuester
|
|||
m.PlaySound(0x214);
|
||||
m.FixedEffect(0x376A, 10, 16);
|
||||
|
||||
m.CloseGump<ResurrectGump>();
|
||||
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using Server.Gumps;
|
||||
using Server.Regions;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -220,7 +220,6 @@ public partial class Chyloth : BaseQuester
|
|||
AngryAt = null;
|
||||
}
|
||||
|
||||
member.CloseGump<ChylothPartyGump>();
|
||||
member.SendGump(new ChylothPartyGump(from, member));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,7 +130,6 @@ public partial class Schmendrick : BaseQuester
|
|||
m.PlaySound(0x214);
|
||||
m.FixedEffect(0x376A, 10, 16);
|
||||
|
||||
m.CloseGump<ResurrectGump>();
|
||||
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -391,7 +391,6 @@ public partial class Uzeraan : BaseQuester
|
|||
m.PlaySound(0x214);
|
||||
m.FixedEffect(0x376A, 10, 16);
|
||||
|
||||
m.CloseGump<ResurrectGump>();
|
||||
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using System.Reflection;
|
|||
using System.Text.Json;
|
||||
using ModernUO.Serialization;
|
||||
using Server.Commands;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Json;
|
||||
using Server.Mobiles;
|
||||
|
|
|
|||
|
|
@ -291,6 +291,8 @@ namespace Server.Mobiles
|
|||
{
|
||||
if (m.Alive && m is PlayerMobile pm)
|
||||
{
|
||||
var gumps = pm.GetGumps();
|
||||
|
||||
if (pm.Alive && (Z - pm.Z).Abs() < 16 && InRange(m, 3) && !InRange(oldLocation, 3))
|
||||
{
|
||||
if (pm.ToTItemsTurnedIn >= TreasuresOfTokuno.ItemsPerReward)
|
||||
|
|
@ -298,11 +300,11 @@ namespace Server.Mobiles
|
|||
// Congratulations! You have turned in enough minor treasures to earn a greater reward.
|
||||
SayTo(pm, 1070980);
|
||||
|
||||
pm.CloseGump<ToTTurnInGump>(); // Sanity
|
||||
gumps.Close<ToTTurnInGump>(); // Sanity
|
||||
|
||||
if (!pm.HasGump<ToTRedeemGump>())
|
||||
{
|
||||
pm.SendGump(new ToTRedeemGump(this, false));
|
||||
gumps.Send(new ToTRedeemGump(this, false));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -325,7 +327,7 @@ namespace Server.Mobiles
|
|||
|
||||
if (buttons?.Count > 0 && !pm.HasGump<ToTTurnInGump>())
|
||||
{
|
||||
pm.SendGump(new ToTTurnInGump(this, buttons));
|
||||
gumps.Send(new ToTTurnInGump(this, buttons));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -334,8 +336,8 @@ namespace Server.Mobiles
|
|||
|
||||
if (!InRange(m, leaveRange) && InRange(oldLocation, leaveRange))
|
||||
{
|
||||
pm.CloseGump<ToTRedeemGump>();
|
||||
pm.CloseGump<ToTTurnInGump>();
|
||||
gumps.Close<ToTRedeemGump>();
|
||||
gumps.Close<ToTTurnInGump>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -412,16 +414,18 @@ namespace Server.Gumps
|
|||
|
||||
item.Delete();
|
||||
|
||||
var gumps = pm.GetGumps();
|
||||
|
||||
if (++pm.ToTItemsTurnedIn >= TreasuresOfTokuno.ItemsPerReward)
|
||||
{
|
||||
// Congratulations! You have turned in enough minor treasures to earn a greater reward.
|
||||
m_Collector.SayTo(pm, 1070980);
|
||||
|
||||
pm.CloseGump<ToTTurnInGump>(); // Sanity
|
||||
gumps.Close<ToTTurnInGump>(); // Sanity
|
||||
|
||||
if (!pm.HasGump<ToTRedeemGump>())
|
||||
if (!gumps.Has<ToTRedeemGump>())
|
||||
{
|
||||
pm.SendGump(new ToTRedeemGump(m_Collector, false));
|
||||
gumps.Send(new ToTRedeemGump(m_Collector, false));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -434,11 +438,11 @@ namespace Server.Gumps
|
|||
|
||||
var buttons = FindRedeemableItems(pm);
|
||||
|
||||
pm.CloseGump<ToTTurnInGump>(); // Sanity
|
||||
gumps.Close<ToTTurnInGump>(); // Sanity
|
||||
|
||||
if (buttons?.Count > 0)
|
||||
{
|
||||
pm.SendGump(new ToTTurnInGump(m_Collector, buttons));
|
||||
gumps.Send(new ToTTurnInGump(m_Collector, buttons));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -594,9 +598,7 @@ namespace Server.Gumps
|
|||
if (t.Type == typeof(PigmentsOfTokuno)) // Special case of course.
|
||||
{
|
||||
pm.CloseGump<ToTTurnInGump>(); // Sanity
|
||||
pm.CloseGump<ToTRedeemGump>();
|
||||
|
||||
pm.SendGump(new ToTRedeemGump(m_Collector, true));
|
||||
pm.SendGump(new ToTRedeemGump(m_Collector, true), true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -591,8 +591,7 @@ public class CharacterStatueTarget : Target
|
|||
_maker.Delete();
|
||||
statue.Sculpt(from);
|
||||
|
||||
from.CloseGump<CharacterStatueGump>();
|
||||
from.SendGump(new CharacterStatueGump(_maker, statue, from));
|
||||
from.SendGump(new CharacterStatueGump(_maker, statue, from), true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ namespace Server.Engines.VeteranRewards
|
|||
{
|
||||
private readonly Mobile m_From;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public RewardChoiceGump(Mobile from) : base(0, 0)
|
||||
{
|
||||
m_From = from;
|
||||
|
||||
from.CloseGump<RewardChoiceGump>();
|
||||
|
||||
RenderBackground();
|
||||
RenderCategories();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ namespace Server.Engines.VeteranRewards
|
|||
private readonly RewardEntry m_Entry;
|
||||
private readonly Mobile m_From;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public RewardConfirmGump(Mobile from, RewardEntry entry) : base(0, 0)
|
||||
{
|
||||
m_From = from;
|
||||
m_Entry = entry;
|
||||
|
||||
from.CloseGump<RewardConfirmGump>();
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(10, 10, 500, 300, 2600);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ namespace Server.Gumps
|
|||
{
|
||||
private readonly IAddon m_Addon;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public RewardDemolitionGump(IAddon addon, int question) : base(150, 50)
|
||||
{
|
||||
m_Addon = addon;
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ namespace Server.Engines.VeteranRewards
|
|||
{
|
||||
private readonly Mobile m_From;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public RewardNoticeGump(Mobile from) : base(0, 0)
|
||||
{
|
||||
m_From = from;
|
||||
|
||||
from.CloseGump<RewardNoticeGump>();
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(10, 10, 500, 135, 2600);
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ namespace Server.Gumps
|
|||
private readonly IRewardOption m_Option;
|
||||
private readonly RewardOptionList m_Options = new();
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public RewardOptionGump(IRewardOption option, int title = 0) : base(60, 36)
|
||||
{
|
||||
m_Option = option;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using Server.Accounting;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@ public static class SacrificeVirtue
|
|||
* We need to wait for them to accept the gump or they can just use
|
||||
* Sacrifice and cancel to have items in their backpack for free.
|
||||
*/
|
||||
from.CloseGump<ResurrectGump>();
|
||||
from.SendGump(new ResurrectGump(from, fromSacrifice: true));
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ public class VirtueGump : Gump
|
|||
}
|
||||
else if (beholder.Map == beheld.Map && beholder.InRange(beheld, 12))
|
||||
{
|
||||
beholder.CloseGump<VirtueGump>();
|
||||
beholder.SendGump(new VirtueGump(beholder, beheld));
|
||||
beholder.SendGump(new VirtueGump(beholder, beheld), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,13 +74,13 @@ namespace Server.Gumps
|
|||
private readonly AdminGumpPage m_PageType;
|
||||
private readonly object m_State;
|
||||
|
||||
public override bool Singleton => true;
|
||||
|
||||
public AdminGump(
|
||||
Mobile from, AdminGumpPage pageType, int listPage = 0, List<object> list = null, string notice = null,
|
||||
object state = null
|
||||
) : base(50, 40)
|
||||
{
|
||||
from.CloseGump<AdminGump>();
|
||||
|
||||
m_From = from;
|
||||
m_PageType = pageType;
|
||||
m_ListPage = listPage;
|
||||
|
|
|
|||
89
Projects/UOContent/Gumps/Base/BaseGump.cs
Normal file
89
Projects/UOContent/Gumps/Base/BaseGump.cs
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2024 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: BaseGump.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using Server.Network;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public abstract class BaseGump
|
||||
{
|
||||
private static readonly byte[] _packetBuffer = GC.AllocateUninitializedArray<byte>(0x10000);
|
||||
private static Serial nextSerial = (Serial)1;
|
||||
|
||||
public int TypeID { get; protected set; }
|
||||
public Serial Serial { get; protected set; }
|
||||
|
||||
public abstract int Switches { get; }
|
||||
public abstract int TextEntries { get; }
|
||||
|
||||
public int X { get; set; }
|
||||
public int Y { get; set; }
|
||||
|
||||
/**
|
||||
* If true, only one instance of this gump can be open at a time per player.
|
||||
*/
|
||||
public virtual bool Singleton => false;
|
||||
|
||||
public BaseGump(int x, int y) : this()
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
public BaseGump()
|
||||
{
|
||||
Serial = nextSerial++;
|
||||
TypeID = GetTypeId(GetType());
|
||||
}
|
||||
|
||||
public virtual void SendTo(NetState ns)
|
||||
{
|
||||
var writer = new SpanWriter(_packetBuffer);
|
||||
Compile(ref writer);
|
||||
|
||||
ns.Send(writer.Span);
|
||||
|
||||
writer.Dispose();
|
||||
}
|
||||
|
||||
public abstract void Compile(ref SpanWriter writer);
|
||||
|
||||
public virtual void OnResponse(NetState sender, in RelayInfo info)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnServerClose(NetState owner)
|
||||
{
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int GetTypeId(Type type)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
// To use the original .NET Framework deterministic hash code (with really terrible performance)
|
||||
// change the next line to use HashUtility.GetNetFrameworkHashCode
|
||||
var hash = (int)HashUtility.ComputeHash32(type?.FullName);
|
||||
|
||||
const int primeMulti = 0x108B76F1;
|
||||
|
||||
// Virtue Gump
|
||||
return hash == 461 ? hash * primeMulti : hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
62
Projects/UOContent/Gumps/Base/DynamicGump.cs
Normal file
62
Projects/UOContent/Gumps/Base/DynamicGump.cs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2024 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: DynamicGump.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System.Buffers;
|
||||
using System.IO;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public abstract class DynamicGump : BaseGump
|
||||
{
|
||||
private int _switches;
|
||||
private int _textEntries;
|
||||
|
||||
public override int Switches => _switches;
|
||||
public override int TextEntries => _textEntries;
|
||||
|
||||
public DynamicGump(int x, int y) : base(x, y)
|
||||
{
|
||||
}
|
||||
|
||||
protected abstract void BuildLayout(ref DynamicGumpBuilder builder);
|
||||
|
||||
public override void Compile(ref SpanWriter writer)
|
||||
{
|
||||
writer.Write((byte)0xDD); // Packet ID
|
||||
writer.Seek(2, SeekOrigin.Current);
|
||||
|
||||
writer.Write(Serial);
|
||||
writer.Write(TypeID);
|
||||
writer.Write(X);
|
||||
writer.Write(Y);
|
||||
|
||||
DynamicGumpBuilder gumpBuilder = new DynamicGumpBuilder();
|
||||
BuildLayout(ref gumpBuilder);
|
||||
gumpBuilder.FinalizeLayout();
|
||||
|
||||
_switches = gumpBuilder.Switches;
|
||||
_textEntries = gumpBuilder.TextEntries;
|
||||
|
||||
OutgoingGumpPackets.WritePacked(gumpBuilder.LayoutData, ref writer);
|
||||
|
||||
writer.Write(gumpBuilder._stringsCount);
|
||||
OutgoingGumpPackets.WritePacked(gumpBuilder.StringsData, ref writer);
|
||||
|
||||
gumpBuilder.Dispose();
|
||||
|
||||
writer.WritePacketLength();
|
||||
}
|
||||
}
|
||||
404
Projects/UOContent/Gumps/Base/DynamicGumpBuilder.cs
Normal file
404
Projects/UOContent/Gumps/Base/DynamicGumpBuilder.cs
Normal file
|
|
@ -0,0 +1,404 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2024 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: DynamicGumpBuilder.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Server.Buffers;
|
||||
using Server.Text;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public ref struct DynamicGumpBuilder
|
||||
{
|
||||
private static readonly byte[] _staticStringsBuffer = GC.AllocateUninitializedArray<byte>(0x80000);
|
||||
|
||||
private byte[] _stringsBuffer;
|
||||
private int _stringBytesWritten;
|
||||
internal int _stringsCount;
|
||||
private GumpLayoutBuilder _gumpBuilder;
|
||||
|
||||
public ReadOnlySpan<byte> LayoutData => _gumpBuilder.LayoutData;
|
||||
|
||||
public ReadOnlySpan<byte> StringsData => _stringsBuffer.AsSpan(0, _stringBytesWritten);
|
||||
|
||||
public int Switches => _gumpBuilder._switches;
|
||||
public int TextEntries => _gumpBuilder._textEntries;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public DynamicGumpBuilder()
|
||||
{
|
||||
_stringsBuffer = _staticStringsBuffer;
|
||||
_gumpBuilder = new GumpLayoutBuilder();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetNoClose() => _gumpBuilder.SetNoClose();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetNoMove() => _gumpBuilder.SetNoMove();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetNoResize() => _gumpBuilder.SetNoResize();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetNoDispose() => _gumpBuilder.SetNoDispose();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddAlphaRegion(int x, int y, int width, int height) =>
|
||||
_gumpBuilder.AddAlphaRegion(x, y, width, height);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddBackground(int x, int y, int width, int height, int gumpID) =>
|
||||
_gumpBuilder.AddBackground(x, y, width, height, gumpID);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddButton(
|
||||
int x, int y, int normalID, int pressedId, int buttonId, GumpButtonType type = GumpButtonType.Reply, int param = 0
|
||||
) => _gumpBuilder.AddButton(x, y, normalID, pressedId, buttonId, type, param);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddCheckbox(int x, int y, int inactiveID, int activeID, bool selected, int switchId) =>
|
||||
_gumpBuilder.AddCheckbox(x, y, inactiveID, activeID, selected, switchId);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddGroup(int groupId) => _gumpBuilder.AddGroup(groupId);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddHtml(
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
ReadOnlySpan<char> text,
|
||||
bool background = false,
|
||||
bool scrollbar = false
|
||||
)
|
||||
{
|
||||
WriteInternalizedString(text);
|
||||
_gumpBuilder.AddHtml(x, y, width, height, _stringsCount++, background, scrollbar);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddHtml(
|
||||
int x, int y, int width, int height, ref RawInterpolatedStringHandler handler,
|
||||
bool background = false, bool scrollbar = false
|
||||
)
|
||||
{
|
||||
AddHtml(x, y, width, height, handler.Text, background, scrollbar);
|
||||
handler.Clear();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddHtml(
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int color,
|
||||
ReadOnlySpan<char> text,
|
||||
bool background = false,
|
||||
bool scrollbar = false
|
||||
)
|
||||
{
|
||||
var handler = text.Color(color);
|
||||
AddHtml(x, y, width, height, ref handler, background, scrollbar);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddHtml(
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int color,
|
||||
ref RawInterpolatedStringHandler handler,
|
||||
bool background = false,
|
||||
bool scrollbar = false
|
||||
)
|
||||
{
|
||||
AddHtml(x, y, width, height, color, handler.Text, background, scrollbar);
|
||||
handler.Clear();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddHtmlCentered(
|
||||
int x, int y, int width, int height, ReadOnlySpan<char> text, bool background = false, bool scrollbar = false
|
||||
)
|
||||
{
|
||||
var handler = text.Center();
|
||||
AddHtml(x, y, width, height, ref handler, background, scrollbar);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddHtmlCentered(
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
ref RawInterpolatedStringHandler handler,
|
||||
bool background = false,
|
||||
bool scrollbar = false
|
||||
)
|
||||
{
|
||||
AddHtmlCentered(x, y, width, height, handler.Text, background, scrollbar);
|
||||
handler.Clear();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddHtmlCentered(
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int color,
|
||||
ReadOnlySpan<char> text,
|
||||
bool background = false,
|
||||
bool scrollbar = false
|
||||
)
|
||||
{
|
||||
var handler = text.Center(color);
|
||||
AddHtml(x, y, width, height, ref handler, background, scrollbar);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddHtmlCentered(
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int color,
|
||||
ref RawInterpolatedStringHandler handler,
|
||||
bool background = false,
|
||||
bool scrollbar = false
|
||||
)
|
||||
{
|
||||
AddHtmlCentered(x, y, width, height, color, handler.Text, background, scrollbar);
|
||||
handler.Clear();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddHtmlLocalized(
|
||||
int x, int y, int width, int height, int number, bool background = false, bool scrollbar = false
|
||||
) => _gumpBuilder.AddHtmlLocalized(x, y, width, height, number, background, scrollbar);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddHtmlLocalized(
|
||||
int x, int y, int width, int height, int number, int color, bool background = false, bool scrollbar = false
|
||||
) => _gumpBuilder.AddHtmlLocalized(x, y, width, height, number, color, background, scrollbar);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddHtmlLocalized(
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int number,
|
||||
ReadOnlySpan<char> args,
|
||||
int color,
|
||||
bool background = false,
|
||||
bool scrollbar = false
|
||||
) => _gumpBuilder.AddHtmlLocalized(x, y, width, height, number, args, color, background, scrollbar);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddHtmlLocalized(
|
||||
int x, int y, int width, int height, int number, ref RawInterpolatedStringHandler handler, int color,
|
||||
bool background = false, bool scrollbar = false
|
||||
) => _gumpBuilder.AddHtmlLocalized(x, y, width, height, number, ref handler, color, background, scrollbar);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddImage(int x, int y, int gumpId, int hue = 0, ReadOnlySpan<char> cls = default) =>
|
||||
_gumpBuilder.AddImage(x, y, gumpId, hue, cls);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddImage(int x, int y, int gumpId, ref RawInterpolatedStringHandler handler) =>
|
||||
_gumpBuilder.AddImage(x, y, gumpId, ref handler);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddImage(int x, int y, int gumpId, int hue, ref RawInterpolatedStringHandler handler) =>
|
||||
_gumpBuilder.AddImage(x, y, gumpId, hue, ref handler);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddImageTiledButton(
|
||||
int x,
|
||||
int y,
|
||||
int normalId,
|
||||
int pressedId,
|
||||
int buttonId,
|
||||
GumpButtonType type,
|
||||
int param,
|
||||
int itemId,
|
||||
int hue,
|
||||
int width,
|
||||
int height,
|
||||
int localizedTooltip = -1
|
||||
) => _gumpBuilder.AddImageTiledButton(
|
||||
x, y, normalId, pressedId, buttonId, type, param, itemId, hue, width, height, localizedTooltip
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddImageTiled(int x, int y, int width, int height, int gumpId) =>
|
||||
_gumpBuilder.AddImageTiled(x, y, width, height, gumpId);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddItem(int x, int y, int itemId, int hue = 0) => _gumpBuilder.AddItem(x, y, itemId, hue);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddItemProperty(Serial serial) => _gumpBuilder.AddItemProperty(serial);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddLabel(int x, int y, int hue, ReadOnlySpan<char> text)
|
||||
{
|
||||
WriteInternalizedString(text);
|
||||
_gumpBuilder.AddLabel(x, y, hue, _stringsCount++);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddLabel(int x, int y, int hue, ref RawInterpolatedStringHandler handler)
|
||||
{
|
||||
AddLabel(x, y, hue, handler.Text);
|
||||
handler.Clear();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddLabelCropped(int x, int y, int width, int height, int hue, ReadOnlySpan<char> text)
|
||||
{
|
||||
WriteInternalizedString(text);
|
||||
_gumpBuilder.AddLabelCropped(x, y, width, height, hue, _stringsCount++);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddLabelCropped(int x, int y, int width, int height, int hue, ref RawInterpolatedStringHandler handler)
|
||||
{
|
||||
AddLabelCropped(x, y, width, height, hue, handler.Text);
|
||||
handler.Clear();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddGumpIdOverride(int gumpId) => _gumpBuilder.AddGumpIdOverride(gumpId);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddPage(int page = 0) => _gumpBuilder.AddPage(page);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddRadio(int x, int y, int inactiveId, int activeId, bool selected, int switchId) =>
|
||||
_gumpBuilder.AddRadio(x, y, inactiveId, activeId, selected, switchId);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddSpriteImage(int x, int y, int gumpId, int width, int height, int sx, int sy) =>
|
||||
_gumpBuilder.AddSpriteImage(x, y, gumpId, width, height, sx, sy);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddTextEntry(
|
||||
int x, int y, int width, int height, int hue, int entryId, ReadOnlySpan<char> initialText = default
|
||||
)
|
||||
{
|
||||
WriteInternalizedString(initialText);
|
||||
_gumpBuilder.AddTextEntry(x, y, width, height, hue, entryId, _stringsCount++);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddTextEntry(
|
||||
int x, int y, int width, int height, int hue, int entryId, ref RawInterpolatedStringHandler handler
|
||||
)
|
||||
{
|
||||
AddTextEntry(x, y, width, height, hue, entryId, handler.Text);
|
||||
handler.Clear();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddTextEntryLimited(
|
||||
int x, int y, int width, int height, int hue, int entryId, ReadOnlySpan<char> initialText = default, int size = 0
|
||||
)
|
||||
{
|
||||
WriteInternalizedString(initialText);
|
||||
_gumpBuilder.AddTextEntryLimited(x, y, width, height, hue, entryId, _stringsCount++, size);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddTextEntryLimited(
|
||||
int x, int y, int width, int height, int hue, int entryId, ref RawInterpolatedStringHandler handler, int size = 0
|
||||
)
|
||||
{
|
||||
AddTextEntryLimited(x, y, width, height, hue, entryId, handler.Text, size);
|
||||
handler.Clear();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddTooltip(int number) => _gumpBuilder.AddTooltip(number);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddTooltip(int number, ReadOnlySpan<char> args) => _gumpBuilder.AddTooltip(number, args);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddTooltip(int number, ref RawInterpolatedStringHandler handler)
|
||||
{
|
||||
_gumpBuilder.AddTooltip(number, handler.Text);
|
||||
handler.Clear();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void FinalizeLayout() => _gumpBuilder.FinalizeLayout();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void WriteInternalizedString(ReadOnlySpan<char> text)
|
||||
{
|
||||
if (text.Length > ushort.MaxValue)
|
||||
{
|
||||
text = text[..ushort.MaxValue];
|
||||
}
|
||||
|
||||
GrowStringsBufferIfNeeded(2 + text.Length * 2);
|
||||
BinaryPrimitives.WriteUInt16BigEndian(_stringsBuffer.AsSpan(_stringBytesWritten), (ushort)text.Length);
|
||||
|
||||
_stringBytesWritten += 2;
|
||||
_stringBytesWritten += text.GetBytesBigUni(_stringsBuffer.AsSpan(_stringBytesWritten));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void GrowStringsBufferIfNeeded(int needed)
|
||||
{
|
||||
if (needed + _stringBytesWritten <= _stringsBuffer.Length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var newSize = Math.Max(_stringBytesWritten + needed, _stringsBuffer.Length * 2);
|
||||
byte[] poolArray = STArrayPool<byte>.Shared.Rent(newSize);
|
||||
|
||||
_stringsBuffer.AsSpan(0, _stringBytesWritten).CopyTo(poolArray);
|
||||
|
||||
byte[] toReturn = _stringsBuffer;
|
||||
_stringsBuffer = poolArray;
|
||||
|
||||
if (toReturn != null && toReturn != _staticStringsBuffer)
|
||||
{
|
||||
STArrayPool<byte>.Shared.Return(toReturn);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Dispose()
|
||||
{
|
||||
_gumpBuilder.Dispose();
|
||||
|
||||
if (_stringsBuffer != _staticStringsBuffer)
|
||||
{
|
||||
STArrayPool<byte>.Shared.Return(_stringsBuffer);
|
||||
}
|
||||
|
||||
this = default;
|
||||
}
|
||||
}
|
||||
77
Projects/UOContent/Gumps/Base/Grid/Grid.cs
Normal file
77
Projects/UOContent/Gumps/Base/Grid/Grid.cs
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2023 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: Grid.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public enum GridHues
|
||||
{
|
||||
White = 2049, // Change to 0x480 if you have old hues.mul
|
||||
Black = 0,
|
||||
}
|
||||
|
||||
public static class GridColors
|
||||
{
|
||||
public const string Gold = "#ffc959";
|
||||
public const string White = "#ffffff";
|
||||
public const string Blue = "#1D63DC";
|
||||
public const string LightBlue = "#7799EE";
|
||||
public const string Green = "#80E732";
|
||||
public const string Orange = "#F28B00";
|
||||
public const string Purple = "#F3ACF6";
|
||||
public const string Red = "#B52B2D";
|
||||
public const string LightGreen = "#E6FFC0";
|
||||
public const string Yellow = "#FFFFBB";
|
||||
}
|
||||
|
||||
public class ListItem
|
||||
{
|
||||
public int X { get; set; }
|
||||
public int Y { get; set; }
|
||||
public int Index { get; set; }
|
||||
public Col[] Cols { get; set; }
|
||||
}
|
||||
|
||||
public class Col
|
||||
{
|
||||
public int X { get; set; }
|
||||
public int Width { get; set; }
|
||||
public int HCenter => X + Width / 2;
|
||||
public int HEnd => X + Width;
|
||||
}
|
||||
|
||||
public class Row
|
||||
{
|
||||
public int Y { get; set; }
|
||||
public int Height { get; set; }
|
||||
public int VCenter => Y + Height / 2;
|
||||
public int VEnd => Y + Height;
|
||||
}
|
||||
|
||||
public class Grid
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Height { get; set; }
|
||||
public int Width { get; set; }
|
||||
public List<Col> Columns { get; set; } = new();
|
||||
public List<Row> Rows { get; set; } = new();
|
||||
}
|
||||
|
||||
public class Swap
|
||||
{
|
||||
public int Index { get; set; }
|
||||
public int Size { get; set; }
|
||||
}
|
||||
525
Projects/UOContent/Gumps/Base/Grid/GumpGrid.cs
Normal file
525
Projects/UOContent/Gumps/Base/Grid/GumpGrid.cs
Normal file
|
|
@ -0,0 +1,525 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2023 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: GumpGrid.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Collections;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public class GumpGrid : Gump
|
||||
{
|
||||
private Dictionary<string, Grid> _grids = new();
|
||||
|
||||
public GumpGrid(int x, int y) : base(x, y)
|
||||
{
|
||||
}
|
||||
|
||||
private void AddColumn(string name, int x, int width)
|
||||
{
|
||||
_grids[name].Columns.Add(new Col { X = x, Width = width, });
|
||||
}
|
||||
|
||||
private void AddRow(string name, int y, int height)
|
||||
{
|
||||
_grids[name].Rows.Add(new Row { Y = y, Height = height });
|
||||
}
|
||||
|
||||
private void InitColumn(string name, int column, int w, int x)
|
||||
{
|
||||
var width = w / column;
|
||||
for (int i = 0; i < column; i++)
|
||||
{
|
||||
AddColumn(name, i * width + x, width);
|
||||
}
|
||||
}
|
||||
|
||||
private void InitRow(string name, int row, int h, int y)
|
||||
{
|
||||
var height = h / row;
|
||||
for (int i = 0; i < row; i++)
|
||||
{
|
||||
AddRow(name, i * height + y, height);
|
||||
}
|
||||
}
|
||||
|
||||
private static Swap Exist(ref PooledRefList<Swap> list, int index)
|
||||
{
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
var item = list[i];
|
||||
if (item.Index == index)
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int CalculateCustom(int column, int len, string[] sizes, ref PooledRefList<Swap> list)
|
||||
{
|
||||
var cropSize = 0;
|
||||
|
||||
for (int i = 0; i < column; i++)
|
||||
{
|
||||
if (sizes[i] == "*")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//percent
|
||||
var percent = sizes[i].RemoveOrdinal("*");
|
||||
var size = sizes[i] != percent ? len / 100 * int.Parse(percent) : int.Parse(percent);
|
||||
|
||||
list.Add(new Swap { Index = i, Size = size });
|
||||
cropSize += size;
|
||||
}
|
||||
|
||||
return cropSize;
|
||||
}
|
||||
private void InitCustomSizeRow(string name, int height, int row, string[] sizes, int y)
|
||||
{
|
||||
var list = PooledRefList<Swap>.Create();
|
||||
var cropHeight = CalculateCustom(row, height, sizes, ref list);
|
||||
var Height = height - cropHeight;
|
||||
var factor = row - list.Count;
|
||||
for (int i = 0; i < row; i++)
|
||||
{
|
||||
var swap = Exist(ref list, i);
|
||||
if (swap != null)
|
||||
{
|
||||
var size = swap.Size;
|
||||
if (i == 0)
|
||||
{
|
||||
AddRow(name, y, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
var col = _grids[name].Rows[i - 1];
|
||||
AddRow(name, col.Height + col.Y + y, size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var size = Height / factor;
|
||||
if (i == 0)
|
||||
{
|
||||
AddRow(name, y, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
var col = _grids[name].Rows[i - 1];
|
||||
AddRow(name, col.Height + col.Y + y, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list.Dispose();
|
||||
}
|
||||
|
||||
private void InitCustomSizeColumn(string name, int width, int column, string[] sizes, int x)
|
||||
{
|
||||
var list = PooledRefList<Swap>.Create();
|
||||
var cropWidth = CalculateCustom(column, width, sizes, ref list);
|
||||
var Width = width - cropWidth;
|
||||
var factor = column - list.Count;
|
||||
|
||||
for (int i = 0; i < column; i++)
|
||||
{
|
||||
var swap = Exist(ref list, i);
|
||||
if (swap != null)
|
||||
{
|
||||
var size = swap.Size;
|
||||
if (i == 0)
|
||||
{
|
||||
AddColumn(name, x, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
var col = _grids[name].Columns[i - 1];
|
||||
AddColumn(name, col.Width + col.X + x, size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var size = Width / factor;
|
||||
if (i == 0)
|
||||
{
|
||||
AddColumn(name, x, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
var col = _grids[name].Columns[i - 1];
|
||||
AddColumn(name, col.Width + col.X + x, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Grid SubGrid(
|
||||
string name,
|
||||
string destGridName,
|
||||
int columnStart,
|
||||
int rowStart,
|
||||
int createColumnsCount,
|
||||
int createRowsCount,
|
||||
int columnSpan = 0,
|
||||
int rowSpan = 0,
|
||||
string createColumnSize = "",
|
||||
string createRowSize = "",
|
||||
int marginX = 0,
|
||||
int marginY = 0
|
||||
)
|
||||
{
|
||||
if (CalculateCord(
|
||||
destGridName,
|
||||
columnStart,
|
||||
rowStart,
|
||||
columnSpan,
|
||||
rowSpan,
|
||||
out var x,
|
||||
out var y,
|
||||
out var width,
|
||||
out var height
|
||||
))
|
||||
{
|
||||
Grid(
|
||||
name,
|
||||
width,
|
||||
height,
|
||||
createColumnsCount,
|
||||
createRowsCount,
|
||||
createColumnSize,
|
||||
createRowSize,
|
||||
x + marginX,
|
||||
y + marginY
|
||||
);
|
||||
}
|
||||
|
||||
return CreateGrid(name, 0, 0);
|
||||
}
|
||||
|
||||
public Grid CreateGrid(string name, int width, int height)
|
||||
{
|
||||
if (!_grids.TryGetValue(name, out var grid))
|
||||
{
|
||||
grid = new Grid { Name = name, Width = width, Height = height };
|
||||
_grids.Add(name, grid);
|
||||
}
|
||||
|
||||
return grid;
|
||||
}
|
||||
|
||||
public Grid Grid(
|
||||
string name,
|
||||
int width,
|
||||
int height,
|
||||
int columns,
|
||||
int rows,
|
||||
string columnSize = "",
|
||||
string rowSize = "",
|
||||
int x = 0,
|
||||
int y = 0
|
||||
)
|
||||
{
|
||||
if (columns < 1)
|
||||
{
|
||||
throw new Exception(nameof(columns));
|
||||
}
|
||||
|
||||
if (rows < 1)
|
||||
{
|
||||
throw new Exception(nameof(columns));
|
||||
}
|
||||
|
||||
var Grid = CreateGrid(name, width, height);
|
||||
|
||||
if (columnSize.Length > 0)
|
||||
{
|
||||
var buffer = columnSize.Split(' ');
|
||||
if (buffer.Length == columns)
|
||||
{
|
||||
InitCustomSizeColumn(name, width, columns, buffer, x);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(nameof(columnSize));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InitColumn(name, columns, width, x);
|
||||
}
|
||||
|
||||
if (rowSize.Length > 0)
|
||||
{
|
||||
var buffer = rowSize.Split(' ');
|
||||
if (buffer.Length == rows)
|
||||
{
|
||||
InitCustomSizeRow(name, height, rows, buffer, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(nameof(rowSize));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InitRow(name, rows, height, y);
|
||||
}
|
||||
|
||||
return Grid;
|
||||
}
|
||||
|
||||
public bool CalculateCord(
|
||||
string name,
|
||||
int column,
|
||||
int row,
|
||||
int columnSpan,
|
||||
int rowSpan,
|
||||
out int x,
|
||||
out int y,
|
||||
out int width,
|
||||
out int height
|
||||
)
|
||||
{
|
||||
x = 0; y = 0; width = 0; height = 0;
|
||||
if (_grids.TryGetValue(name, out var grid))
|
||||
{
|
||||
var count = columnSpan == 0 ? column + 1 : row + columnSpan;
|
||||
for (int i = column; i < count; i++)
|
||||
{
|
||||
if (i >= grid.Columns.Count)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var dcol = grid.Columns[i];
|
||||
if (i == column)
|
||||
{
|
||||
x = dcol.X;
|
||||
}
|
||||
|
||||
width += dcol.Width;
|
||||
}
|
||||
|
||||
count = rowSpan == 0 ? row + 1 : row + rowSpan;
|
||||
for (int i = row; i < count; i++)
|
||||
{
|
||||
if (i >= grid.Rows.Count)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var drow = grid.Rows[i];
|
||||
if (i == row)
|
||||
{
|
||||
y = drow.Y;
|
||||
}
|
||||
|
||||
height += drow.Height;
|
||||
}
|
||||
|
||||
if (width == 0)
|
||||
{
|
||||
width = grid.Width;
|
||||
}
|
||||
|
||||
if (height == 0)
|
||||
{
|
||||
height = grid.Height;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public class ListView
|
||||
{
|
||||
public int LineCount { get; }
|
||||
public int ItemsCount { get; }
|
||||
public ListItem[] Items { get; }
|
||||
public ListItem Header { get; }
|
||||
public int Page { get; }
|
||||
public int TotalPages { get; }
|
||||
public int ColHeight { get; }
|
||||
public bool CanNext { get; }
|
||||
public bool CanBack { get; }
|
||||
public int ColsCount { get; }
|
||||
|
||||
public ListView(
|
||||
int itemsCount,
|
||||
int columns,
|
||||
int heightPerItem,
|
||||
int page,
|
||||
int x,
|
||||
int y,
|
||||
int height,
|
||||
int pageItemCount,
|
||||
int[] ColWidth,
|
||||
int marginX = 0,
|
||||
int marginY = 0,
|
||||
int headerHeight = 0
|
||||
)
|
||||
{
|
||||
ItemsCount = itemsCount;
|
||||
var itemsPerPageCount = pageItemCount == 0 ? (height - marginY) / heightPerItem : pageItemCount;
|
||||
LineCount = itemsPerPageCount;
|
||||
|
||||
if (itemsCount > 0)
|
||||
{
|
||||
TotalPages = itemsCount / itemsPerPageCount;
|
||||
if (itemsCount % itemsPerPageCount == 0)
|
||||
{
|
||||
TotalPages--;
|
||||
}
|
||||
}
|
||||
|
||||
Page = page > TotalPages ? TotalPages : page;
|
||||
ColsCount = columns;
|
||||
ColHeight = heightPerItem;
|
||||
|
||||
var index = Page * itemsPerPageCount > 0 ? Page * itemsPerPageCount : 0;
|
||||
var nowPageItems = index + itemsPerPageCount;
|
||||
|
||||
if (index > 0)
|
||||
{
|
||||
CanBack = true;
|
||||
}
|
||||
|
||||
if (nowPageItems < itemsCount)
|
||||
{
|
||||
CanNext = true;
|
||||
}
|
||||
|
||||
if (nowPageItems > itemsCount)
|
||||
{
|
||||
itemsPerPageCount = Page > 0 ? itemsCount - Page * itemsPerPageCount : itemsCount;
|
||||
}
|
||||
|
||||
//header
|
||||
Header = new ListItem
|
||||
{
|
||||
X = x,
|
||||
Y = y + marginY,
|
||||
Index = -1,
|
||||
Cols = new Col[columns],
|
||||
};
|
||||
|
||||
var length = x + marginX;
|
||||
for (int col = 0; col < columns; col++)
|
||||
{
|
||||
Header.Cols[col] = new Col();
|
||||
Header.Cols[col].Width = ColWidth[col];
|
||||
Header.Cols[col].X = length;
|
||||
length += ColWidth[col];
|
||||
}
|
||||
|
||||
Items = new ListItem[itemsPerPageCount];
|
||||
|
||||
for (int i = 0; i < itemsPerPageCount; i++)
|
||||
{
|
||||
Items[i] = new ListItem
|
||||
{
|
||||
X = x,
|
||||
Y = y + i * heightPerItem + marginY + headerHeight,
|
||||
Index = index + i,
|
||||
Cols = Header.Cols
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ListView AddListView(
|
||||
string name,
|
||||
int column,
|
||||
int row,
|
||||
int itemsCount,
|
||||
int page,
|
||||
int heightPerItem,
|
||||
int createColumn,
|
||||
int columnSpan = 0,
|
||||
int rowSpan = 0,
|
||||
int width = 0,
|
||||
int height = 0,
|
||||
int pageItemCount = 0,
|
||||
int marginX = 0,
|
||||
int marginY = 0,
|
||||
int headerHeight = 0,
|
||||
string colSize = ""
|
||||
)
|
||||
{
|
||||
if (CalculateCord(name, column, row, columnSpan, rowSpan, out var x, out var y, out var w, out var h))
|
||||
{
|
||||
w = width > 0 ? width : w;
|
||||
h = height > 0 ? height : h;
|
||||
|
||||
int[] colWidth = new int[createColumn];
|
||||
|
||||
if (colSize == string.Empty)
|
||||
{
|
||||
for (int i = 0; i < createColumn; i++)
|
||||
{
|
||||
colWidth[i] = w / createColumn;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var buffer = colSize.Split(' ');
|
||||
|
||||
if (buffer.Length > 0)
|
||||
{
|
||||
const string listName = "listView";
|
||||
_grids.Add(listName, new Grid());
|
||||
|
||||
if (createColumn < buffer.Length)
|
||||
{
|
||||
Array.Resize(ref buffer, createColumn);
|
||||
}
|
||||
|
||||
InitCustomSizeColumn(listName, w, createColumn, buffer, x);
|
||||
var cols = _grids[listName].Columns;
|
||||
for (var i = 0; i < createColumn; i++)
|
||||
{
|
||||
colWidth[i] = cols[i].Width;
|
||||
}
|
||||
|
||||
_grids.Remove(listName);
|
||||
}
|
||||
}
|
||||
|
||||
return new ListView(
|
||||
itemsCount,
|
||||
createColumn,
|
||||
heightPerItem,
|
||||
page,
|
||||
x,
|
||||
y,
|
||||
h,
|
||||
pageItemCount,
|
||||
colWidth,
|
||||
marginX,
|
||||
marginY,
|
||||
headerHeight
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
27
Projects/UOContent/Gumps/Base/GumpFlags.cs
Normal file
27
Projects/UOContent/Gumps/Base/GumpFlags.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2023 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: GumpFlags.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
[Flags]
|
||||
public enum GumpFlags
|
||||
{
|
||||
NoDispose = 0x1,
|
||||
NoResize = 0x2,
|
||||
NoMove = 0x4,
|
||||
NoClose = 0x8
|
||||
}
|
||||
642
Projects/UOContent/Gumps/Base/GumpLayoutBuilder.cs
Normal file
642
Projects/UOContent/Gumps/Base/GumpLayoutBuilder.cs
Normal file
|
|
@ -0,0 +1,642 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2024 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: GumpLayoutBuilder.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Server.Buffers;
|
||||
using Server.Text;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public ref struct GumpLayoutBuilder
|
||||
{
|
||||
private static readonly byte[] _staticLayoutBuffer = GC.AllocateUninitializedArray<byte>(0x80000);
|
||||
|
||||
private byte[] _layoutBuffer;
|
||||
private int _bytesWritten;
|
||||
|
||||
internal GumpFlags _flags;
|
||||
internal int _switches;
|
||||
internal int _textEntries;
|
||||
|
||||
internal Span<byte> LayoutData => _layoutBuffer.AsSpan(0, _bytesWritten);
|
||||
|
||||
// This struct uses static fields and is therefore not thread safe!
|
||||
// Do not instantiate/process multiple gumps at the same time!
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public GumpLayoutBuilder() => _layoutBuffer = _staticLayoutBuffer;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetNoClose()
|
||||
{
|
||||
if ((_flags & GumpFlags.NoClose) == 0)
|
||||
{
|
||||
GrowIfNeeded(11);
|
||||
Write("{ noclose }"u8);
|
||||
_flags |= GumpFlags.NoClose;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetNoMove()
|
||||
{
|
||||
if ((_flags & GumpFlags.NoMove) == 0)
|
||||
{
|
||||
GrowIfNeeded(10);
|
||||
Write("{ nomove }"u8);
|
||||
_flags |= GumpFlags.NoMove;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetNoResize()
|
||||
{
|
||||
if ((_flags & GumpFlags.NoResize) == 0)
|
||||
{
|
||||
GrowIfNeeded(12);
|
||||
Write("{ noresize }"u8);
|
||||
_flags |= GumpFlags.NoResize;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetNoDispose()
|
||||
{
|
||||
if ((_flags & GumpFlags.NoDispose) == 0)
|
||||
{
|
||||
GrowIfNeeded(13);
|
||||
Write("{ nodispose }"u8);
|
||||
_flags |= GumpFlags.NoDispose;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddAlphaRegion(int x, int y, int width, int height)
|
||||
{
|
||||
GrowIfNeeded(8 + 12 + 36);
|
||||
WriteStart("checkertrans"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(width);
|
||||
WriteValue(height);
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
public void AddBackground(int x, int y, int width, int height, int gumpId)
|
||||
{
|
||||
GrowIfNeeded(9 + 9 + 45);
|
||||
WriteStart("resizepic"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(gumpId);
|
||||
WriteValue(width);
|
||||
WriteValue(height);
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
public void AddButton(
|
||||
int x, int y, int normalId, int pressedId, int buttonId, GumpButtonType type = GumpButtonType.Reply, int param = 0
|
||||
)
|
||||
{
|
||||
GrowIfNeeded(11 + 6 + 54 + 2);
|
||||
WriteStart("button"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(normalId);
|
||||
WriteValue(pressedId);
|
||||
WriteValue(type == GumpButtonType.Reply);
|
||||
WriteValue(param);
|
||||
WriteValue(buttonId);
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
public void AddCheckbox(int x, int y, int inactiveId, int activeId, bool selected, int switchId)
|
||||
{
|
||||
GrowIfNeeded(10 + 8 + 45 + 2);
|
||||
WriteStart("checkbox"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(inactiveId);
|
||||
WriteValue(activeId);
|
||||
WriteValue(selected);
|
||||
WriteValue(switchId);
|
||||
WriteEnd();
|
||||
|
||||
_switches++;
|
||||
}
|
||||
|
||||
public void AddGroup(int groupId)
|
||||
{
|
||||
if (groupId == 1)
|
||||
{
|
||||
GrowIfNeeded(11);
|
||||
Write("{ group 1 }"u8);
|
||||
return;
|
||||
}
|
||||
|
||||
GrowIfNeeded(5 + 7 + 9);
|
||||
WriteStart("group"u8);
|
||||
WriteValue(groupId);
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
public int AddHtmlPlaceholder(int x, int y, int width, int height,
|
||||
bool background = false, bool scrollbar = false)
|
||||
{
|
||||
GrowIfNeeded(11 + 8 + 36 + 10);
|
||||
WriteStart("htmlgump"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(width);
|
||||
WriteValue(height);
|
||||
var position = _bytesWritten;
|
||||
Write(" "u8);
|
||||
WriteValue(background);
|
||||
WriteValue(scrollbar);
|
||||
WriteEnd();
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
public void AddHtml(int x, int y, int width, int height, int text,
|
||||
bool background = false, bool scrollbar = false)
|
||||
{
|
||||
GrowIfNeeded(11 + 8 + 45 + 4);
|
||||
WriteStart("htmlgump"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(width);
|
||||
WriteValue(height);
|
||||
WriteValue(text);
|
||||
WriteValue(background);
|
||||
WriteValue(scrollbar);
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
public void AddHtmlLocalized(
|
||||
int x, int y, int width, int height, int number, bool background = false, bool scrollbar = false
|
||||
)
|
||||
{
|
||||
GrowIfNeeded(11 + 11 + 45 + 4);
|
||||
WriteStart("xmfhtmlgump"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(width);
|
||||
WriteValue(height);
|
||||
WriteValue(number);
|
||||
WriteValue(background);
|
||||
WriteValue(scrollbar);
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
public void AddHtmlLocalized(
|
||||
int x, int y, int width, int height, int number, int color, bool background = false, bool scrollbar = false
|
||||
)
|
||||
{
|
||||
GrowIfNeeded(12 + 16 + 45 + 5 + 4);
|
||||
WriteStart("xmfhtmlgumpcolor"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(width);
|
||||
WriteValue(height);
|
||||
WriteValue(number);
|
||||
WriteValue(background);
|
||||
WriteValue(scrollbar);
|
||||
WriteValue(color);
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
public void AddHtmlLocalized(int x, int y, int width, int height, int number, ReadOnlySpan<char> args, int color,
|
||||
bool background = false, bool scrollbar = false)
|
||||
{
|
||||
GrowIfNeeded(12 + 10 + 45 + 5 + 4 + (args.Length > 0 ? 3 + args.Length : 0));
|
||||
WriteStart("xmfhtmltok"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(width);
|
||||
WriteValue(height);
|
||||
WriteValue(background);
|
||||
WriteValue(scrollbar);
|
||||
WriteValue(color);
|
||||
WriteValue(number);
|
||||
|
||||
if (args.Length > 0)
|
||||
{
|
||||
Write("@"u8);
|
||||
WriteValue(args);
|
||||
Write("@ "u8);
|
||||
}
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddHtmlLocalized(
|
||||
int x, int y, int width, int height, int number, ref RawInterpolatedStringHandler handler, int color,
|
||||
bool background = false, bool scrollbar = false
|
||||
)
|
||||
{
|
||||
AddHtmlLocalized(x, y, width, height, number, handler.Text, color, background, scrollbar);
|
||||
|
||||
// Dispose of the handler
|
||||
handler.Clear();
|
||||
}
|
||||
|
||||
public void AddImage(int x, int y, int gumpId, int hue = 0, ReadOnlySpan<char> cls = default)
|
||||
{
|
||||
GrowIfNeeded(7 + 7 + 36 + (hue != 0 ? 14 : 0) + (cls.Length > 0 ? 7 + cls.Length : 0));
|
||||
WriteStart("gumppic"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(gumpId);
|
||||
|
||||
if (hue != 0)
|
||||
{
|
||||
Write("hue="u8);
|
||||
WriteValue(hue);
|
||||
Write(" "u8);
|
||||
}
|
||||
|
||||
if (!cls.IsEmpty)
|
||||
{
|
||||
Write("class="u8);
|
||||
WriteValue(cls);
|
||||
Write(" "u8);
|
||||
}
|
||||
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddImage(int x, int y, int gumpId, ref RawInterpolatedStringHandler handler)
|
||||
{
|
||||
AddImage(x, y, gumpId, 0, handler.Text);
|
||||
handler.Clear();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AddImage(int x, int y, int gumpId, int hue, ref RawInterpolatedStringHandler handler)
|
||||
{
|
||||
AddImage(x, y, gumpId, hue, handler.Text);
|
||||
handler.Clear();
|
||||
}
|
||||
|
||||
public void AddImageTiledButton(int x, int y, int normalId, int pressedId, int buttonId, GumpButtonType type, int param,
|
||||
int itemId, int hue, int width, int height, int localizedTooltip = -1)
|
||||
{
|
||||
GrowIfNeeded(15 + 13 + 90 + 2);
|
||||
WriteStart("buttontileart"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(normalId);
|
||||
WriteValue(pressedId);
|
||||
WriteValue(type == GumpButtonType.Reply);
|
||||
WriteValue(param);
|
||||
WriteValue(buttonId);
|
||||
WriteValue(itemId);
|
||||
WriteValue(hue);
|
||||
WriteValue(width);
|
||||
WriteValue(height);
|
||||
WriteEnd();
|
||||
|
||||
if (localizedTooltip <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AddTooltip(localizedTooltip);
|
||||
}
|
||||
|
||||
public void AddImageTiled(int x, int y, int width, int height, int gumpId)
|
||||
{
|
||||
GrowIfNeeded(9 + 12 + 45);
|
||||
WriteStart("gumppictiled"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(width);
|
||||
WriteValue(height);
|
||||
WriteValue(gumpId);
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
public void AddItem(int x, int y, int itemId, int hue = 0)
|
||||
{
|
||||
GrowIfNeeded(7 + 36 + (hue != 0 ? 20 : 7));
|
||||
WriteStart(hue == 0 ? "tilepic"u8 : "tilepichue"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(itemId);
|
||||
|
||||
if (hue != 0)
|
||||
{
|
||||
WriteValue(hue);
|
||||
}
|
||||
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
public void AddItemProperty(Serial serial)
|
||||
{
|
||||
GrowIfNeeded(5 + 12 + 9);
|
||||
WriteStart("itemproperty"u8);
|
||||
WriteValue(serial.Value);
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
public int AddLabelPlaceholder(int x, int y, int hue)
|
||||
{
|
||||
GrowIfNeeded(8 + 4 + 27 + 6);
|
||||
WriteStart("text"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(hue);
|
||||
var position = _bytesWritten;
|
||||
Write(" "u8);
|
||||
WriteEnd();
|
||||
return position;
|
||||
}
|
||||
|
||||
public void AddLabel(int x, int y, int hue, int text)
|
||||
{
|
||||
GrowIfNeeded(8 + 4 + 36 + 6);
|
||||
WriteStart("text"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(hue);
|
||||
WriteValue(text);
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
public int AddLabelCroppedPlaceholder(int x, int y, int width, int height, int hue)
|
||||
{
|
||||
GrowIfNeeded(10 + 11 + 45 + 6);
|
||||
WriteStart("croppedtext"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(width);
|
||||
WriteValue(height);
|
||||
WriteValue(hue);
|
||||
var position = _bytesWritten;
|
||||
Write(" "u8);
|
||||
WriteEnd();
|
||||
return position;
|
||||
}
|
||||
|
||||
public void AddLabelCropped(int x, int y, int width, int height, int hue, int text)
|
||||
{
|
||||
GrowIfNeeded(10 + 11 + 54 + 6);
|
||||
WriteStart("croppedtext"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(width);
|
||||
WriteValue(height);
|
||||
WriteValue(hue);
|
||||
WriteValue(text);
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
public void AddGumpIdOverride(int gumpId)
|
||||
{
|
||||
GrowIfNeeded(5 + 10 + 9);
|
||||
WriteStart("mastergump"u8);
|
||||
WriteValue(gumpId);
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
public void AddPage(int page = 0)
|
||||
{
|
||||
if (page == 0)
|
||||
{
|
||||
GrowIfNeeded(10);
|
||||
Write("{ page 0 }"u8);
|
||||
return;
|
||||
}
|
||||
|
||||
GrowIfNeeded(5 + 4 + 9);
|
||||
WriteStart("page"u8);
|
||||
WriteValue(page);
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
public void AddRadio(int x, int y, int inactiveId, int activeId, bool selected, int switchId)
|
||||
{
|
||||
GrowIfNeeded(10 + 5 + 45 + 2);
|
||||
WriteStart("radio"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(inactiveId);
|
||||
WriteValue(activeId);
|
||||
WriteValue(selected);
|
||||
WriteValue(switchId);
|
||||
WriteEnd();
|
||||
|
||||
_switches++;
|
||||
}
|
||||
|
||||
public void AddSpriteImage(int x, int y, int gumpId, int width, int height, int sx, int sy)
|
||||
{
|
||||
GrowIfNeeded(11 + 8 + 63);
|
||||
WriteStart("picinpic"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(gumpId);
|
||||
WriteValue(width);
|
||||
WriteValue(height);
|
||||
WriteValue(sx);
|
||||
WriteValue(sy);
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
public int AddTextEntryPlaceholder(
|
||||
int x, int y, int width, int height, int hue, int entryId
|
||||
)
|
||||
{
|
||||
GrowIfNeeded(11 + 9 + 54 + 6);
|
||||
WriteStart("textentry"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(width);
|
||||
WriteValue(height);
|
||||
WriteValue(hue);
|
||||
WriteValue(entryId);
|
||||
var position = _bytesWritten;
|
||||
Write(" "u8);
|
||||
WriteEnd();
|
||||
|
||||
_textEntries++;
|
||||
return position;
|
||||
}
|
||||
|
||||
public void AddTextEntry(
|
||||
int x, int y, int width, int height, int hue, int entryId, int initialText
|
||||
)
|
||||
{
|
||||
GrowIfNeeded(11 + 9 + 63 + 6);
|
||||
WriteStart("textentry"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(width);
|
||||
WriteValue(height);
|
||||
WriteValue(hue);
|
||||
WriteValue(entryId);
|
||||
WriteValue(initialText);
|
||||
WriteEnd();
|
||||
|
||||
_textEntries++;
|
||||
}
|
||||
|
||||
public int AddTextEntryLimitedPlaceholder(
|
||||
int x, int y, int width, int height, int hue, int entryId, int size = 0
|
||||
)
|
||||
{
|
||||
GrowIfNeeded(12 + 16 + 63 + 6);
|
||||
WriteStart("textentrylimited"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(width);
|
||||
WriteValue(height);
|
||||
WriteValue(hue);
|
||||
WriteValue(entryId);
|
||||
var position = _bytesWritten;
|
||||
Write(" "u8);
|
||||
WriteValue(size);
|
||||
WriteEnd();
|
||||
|
||||
_textEntries++;
|
||||
return position;
|
||||
}
|
||||
|
||||
public void AddTextEntryLimited(
|
||||
int x, int y, int width, int height, int hue, int entryId, int initialText, int size = 0
|
||||
)
|
||||
{
|
||||
GrowIfNeeded(12 + 16 + 72);
|
||||
WriteStart("textentrylimited"u8);
|
||||
WriteValue(x);
|
||||
WriteValue(y);
|
||||
WriteValue(width);
|
||||
WriteValue(height);
|
||||
WriteValue(hue);
|
||||
WriteValue(entryId);
|
||||
WriteValue(initialText);
|
||||
WriteValue(size);
|
||||
WriteEnd();
|
||||
|
||||
_textEntries++;
|
||||
}
|
||||
|
||||
public void AddTooltip(int number)
|
||||
{
|
||||
GrowIfNeeded(5 + 7 + 9);
|
||||
WriteStart("tooltip"u8);
|
||||
WriteValue(number);
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
public void AddTooltip(int number, ReadOnlySpan<char> args)
|
||||
{
|
||||
GrowIfNeeded(5 + 7 + 9 + (args.Length > 0 ? 3 + args.Length : 0));
|
||||
WriteStart("tooltip"u8);
|
||||
WriteValue(number);
|
||||
|
||||
if (args.Length > 0)
|
||||
{
|
||||
Write("@"u8);
|
||||
WriteValue(args);
|
||||
Write("@ "u8);
|
||||
}
|
||||
WriteEnd();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void WriteStart(ReadOnlySpan<byte> value)
|
||||
{
|
||||
Write("{ "u8);
|
||||
Write(value);
|
||||
Write(" "u8);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void WriteEnd() => Write("}"u8);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void WriteValue(bool value) => Write(value ? "1 "u8 : "0 "u8);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void WriteValue(ReadOnlySpan<char> value)
|
||||
{
|
||||
if (!value.IsEmpty)
|
||||
{
|
||||
_bytesWritten += value.GetBytesAscii(_layoutBuffer.AsSpan(_bytesWritten));
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void WriteValue<T>(T value, ReadOnlySpan<char> format = default) where T : IUtf8SpanFormattable
|
||||
{
|
||||
if (!value.TryFormat(_layoutBuffer.AsSpan(_bytesWritten), out int bytesWritten, format, null))
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to format '{value}' with the given format '{format}'");
|
||||
}
|
||||
|
||||
_bytesWritten += bytesWritten;
|
||||
Write(" "u8);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void Write(ReadOnlySpan<byte> span)
|
||||
{
|
||||
span.CopyTo(_layoutBuffer.AsSpan(_bytesWritten));
|
||||
_bytesWritten += span.Length;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal void FinalizeLayout()
|
||||
{
|
||||
GrowIfNeeded(1);
|
||||
_layoutBuffer[_bytesWritten++] = 0;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void GrowIfNeeded(int count)
|
||||
{
|
||||
if (_bytesWritten + count <= _layoutBuffer.Length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var newSize = Math.Max(_bytesWritten + count, _layoutBuffer.Length * 2);
|
||||
byte[] poolArray = STArrayPool<byte>.Shared.Rent(newSize);
|
||||
|
||||
_layoutBuffer.AsSpan(0, _bytesWritten).CopyTo(poolArray);
|
||||
|
||||
byte[] toReturn = _layoutBuffer;
|
||||
_layoutBuffer = poolArray;
|
||||
|
||||
if (toReturn != _staticLayoutBuffer)
|
||||
{
|
||||
STArrayPool<byte>.Shared.Return(toReturn);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Dispose()
|
||||
{
|
||||
if (_layoutBuffer != _staticLayoutBuffer)
|
||||
{
|
||||
STArrayPool<byte>.Shared.Return(_layoutBuffer);
|
||||
}
|
||||
|
||||
this = default;
|
||||
}
|
||||
}
|
||||
129
Projects/UOContent/Gumps/Base/GumpStringsBuilder.cs
Normal file
129
Projects/UOContent/Gumps/Base/GumpStringsBuilder.cs
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2024 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: GumpStringsBuilder.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Server.Buffers;
|
||||
using Server.Text;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public ref struct GumpStringsBuilder
|
||||
{
|
||||
private static readonly byte[] _staticStringsBuffer = GC.AllocateUninitializedArray<byte>(0x80000);
|
||||
private static readonly Dictionary<ulong, int> _hashes = new();
|
||||
|
||||
private readonly bool _finalizeLayout;
|
||||
private byte[] _stringsBuffer;
|
||||
private int _stringBytesWritten;
|
||||
internal int _stringsCount;
|
||||
|
||||
internal ReadOnlySpan<byte> StringsBuffer => _stringsBuffer.AsSpan(0, _stringBytesWritten);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public GumpStringsBuilder(bool finalizeLayout)
|
||||
{
|
||||
_finalizeLayout = finalizeLayout;
|
||||
_stringsBuffer = _staticStringsBuffer;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void GrowStringsBufferIfNeeded(int needed)
|
||||
{
|
||||
var newLength = needed + _stringBytesWritten;
|
||||
if (newLength <= _stringsBuffer.Length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var newSize = Math.Max(newLength, _stringsBuffer.Length * 2);
|
||||
byte[] poolArray = STArrayPool<byte>.Shared.Rent(newSize);
|
||||
|
||||
_stringsBuffer.AsSpan(0, _stringBytesWritten).CopyTo(poolArray);
|
||||
|
||||
byte[] toReturn = _stringsBuffer;
|
||||
_stringsBuffer = poolArray;
|
||||
|
||||
if (toReturn != _staticStringsBuffer)
|
||||
{
|
||||
STArrayPool<byte>.Shared.Return(toReturn);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetStringSlot(ReadOnlySpan<char> slotKey, ref RawInterpolatedStringHandler handler)
|
||||
{
|
||||
SetStringSlot(slotKey, handler.Text);
|
||||
handler.Clear();
|
||||
}
|
||||
|
||||
public void SetStringSlot(ReadOnlySpan<char> slotKey, ReadOnlySpan<char> text)
|
||||
{
|
||||
var hash = HashUtility.ComputeHash64(slotKey);
|
||||
|
||||
if (text.Length > ushort.MaxValue)
|
||||
{
|
||||
text = text[..ushort.MaxValue];
|
||||
}
|
||||
|
||||
GrowStringsBufferIfNeeded(2 + text.Length * 2);
|
||||
BinaryPrimitives.WriteUInt16BigEndian(_stringsBuffer.AsSpan(_stringBytesWritten), (ushort)text.Length);
|
||||
_stringBytesWritten += 2;
|
||||
|
||||
if (text.Length > 0)
|
||||
{
|
||||
_stringBytesWritten += text.GetBytesBigUni(_stringsBuffer.AsSpan(_stringBytesWritten));
|
||||
}
|
||||
|
||||
if (_finalizeLayout)
|
||||
{
|
||||
_hashes[hash] = _stringsCount;
|
||||
}
|
||||
|
||||
_stringsCount++;
|
||||
}
|
||||
|
||||
public void FinalizeStrings(ref StaticGumpBuilder builder)
|
||||
{
|
||||
var startingIndex = builder._stringsCount;
|
||||
|
||||
var stringSlotOffsets = builder.StringSlotOffsets;
|
||||
for (var i = 0; i < stringSlotOffsets.Length; i++)
|
||||
{
|
||||
var (hash, offset) = stringSlotOffsets[i];
|
||||
|
||||
if (hash != 0 && _hashes.TryGetValue(hash, out var index))
|
||||
{
|
||||
builder.WriteSlotIndex(offset, index + startingIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Dispose()
|
||||
{
|
||||
if (_finalizeLayout)
|
||||
{
|
||||
_hashes.Clear();
|
||||
}
|
||||
|
||||
if (_stringsBuffer != _staticStringsBuffer)
|
||||
{
|
||||
STArrayPool<byte>.Shared.Return(_stringsBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
198
Projects/UOContent/Gumps/Base/GumpSystem.IncomingPackets.cs
Normal file
198
Projects/UOContent/Gumps/Base/GumpSystem.IncomingPackets.cs
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2023 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: IncomingGumpPackets.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using Server.Diagnostics;
|
||||
using Server.Engines.Virtues;
|
||||
using Server.Exceptions;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Buffers.Binary;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public static partial class GumpSystem
|
||||
{
|
||||
public static void DisplayGumpResponse(NetState state, SpanReader reader)
|
||||
{
|
||||
var serial = (Serial)reader.ReadUInt32();
|
||||
var typeId = reader.ReadInt32();
|
||||
var buttonId = reader.ReadInt32();
|
||||
|
||||
BaseGump baseGump = null;
|
||||
|
||||
foreach (var g in GetAll(state))
|
||||
{
|
||||
if (g.Serial != serial || g.TypeID != typeId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
baseGump = g;
|
||||
break;
|
||||
}
|
||||
|
||||
if (baseGump != null)
|
||||
{
|
||||
if (baseGump is Gump gump)
|
||||
{
|
||||
var buttonExists = buttonId == 0; // 0 is always 'close'
|
||||
|
||||
if (!buttonExists)
|
||||
{
|
||||
foreach (var e in gump.Entries)
|
||||
{
|
||||
if ((e as GumpButton)?.ButtonID == buttonId)
|
||||
{
|
||||
buttonExists = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((e as GumpImageTileButton)?.ButtonID == buttonId)
|
||||
{
|
||||
buttonExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!buttonExists)
|
||||
{
|
||||
state.LogInfo("Invalid gump response, disconnecting...");
|
||||
var exception = new InvalidGumpResponseException($"Button {buttonId} doesn't exist");
|
||||
exception.SetStackTrace(new StackTrace());
|
||||
NetState.TraceException(exception);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var switchCount = reader.ReadInt32();
|
||||
|
||||
if (switchCount < 0 || switchCount > baseGump.Switches)
|
||||
{
|
||||
state.LogInfo("Invalid gump response, disconnecting...");
|
||||
var exception = new InvalidGumpResponseException($"Bad switch count {switchCount}");
|
||||
exception.SetStackTrace(new StackTrace());
|
||||
NetState.TraceException(exception);
|
||||
return;
|
||||
}
|
||||
|
||||
int switchByteCount = switchCount * 4;
|
||||
|
||||
// Read all the integers
|
||||
ReadOnlySpan<int> switchBlock =
|
||||
MemoryMarshal.Cast<byte, int>(reader.Buffer.Slice(reader.Position, switchByteCount));
|
||||
|
||||
reader.Seek(switchByteCount, SeekOrigin.Current);
|
||||
|
||||
scoped ReadOnlySpan<int> switches;
|
||||
|
||||
// Swap the endianness if necessary
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
Span<int> reversedSwitches = stackalloc int[switchCount];
|
||||
BinaryPrimitives.ReverseEndianness(switchBlock, reversedSwitches);
|
||||
switches = reversedSwitches;
|
||||
}
|
||||
else
|
||||
{
|
||||
switches = switchBlock;
|
||||
}
|
||||
|
||||
var textCount = reader.ReadInt32();
|
||||
if (textCount < 0 || textCount > baseGump.TextEntries)
|
||||
{
|
||||
state.LogInfo("Invalid gump response, disconnecting...");
|
||||
var exception = new InvalidGumpResponseException($"Bad text entry count {textCount}");
|
||||
exception.SetStackTrace(new StackTrace());
|
||||
NetState.TraceException(exception);
|
||||
return;
|
||||
}
|
||||
|
||||
Span<ushort> textIds = stackalloc ushort[textCount];
|
||||
Span<Range> textFields = stackalloc Range[textCount];
|
||||
|
||||
var textOffset = reader.Position;
|
||||
for (var i = 0; i < textCount; i++)
|
||||
{
|
||||
var textId = reader.ReadUInt16();
|
||||
var textLength = reader.ReadUInt16();
|
||||
|
||||
if (textLength > 239)
|
||||
{
|
||||
state.LogInfo("Invalid gump response, disconnecting...");
|
||||
var exception = new InvalidGumpResponseException($"Text entry {i} is too long ({textLength})");
|
||||
exception.SetStackTrace(new StackTrace());
|
||||
NetState.TraceException(exception);
|
||||
return;
|
||||
}
|
||||
|
||||
textIds[i] = textId;
|
||||
var offset = reader.Position - textOffset;
|
||||
var length = textLength * 2;
|
||||
textFields[i] = offset..(offset + length);
|
||||
reader.Seek(length, SeekOrigin.Current);
|
||||
}
|
||||
|
||||
var textBlock = reader.Buffer.Slice(textOffset, reader.Position - textOffset);
|
||||
|
||||
Remove(state, baseGump);
|
||||
|
||||
var prof = GumpProfile.Acquire(baseGump.GetType());
|
||||
|
||||
prof?.Start();
|
||||
|
||||
var relayInfo = new RelayInfo(
|
||||
buttonId,
|
||||
switches,
|
||||
textIds,
|
||||
textFields,
|
||||
textBlock
|
||||
);
|
||||
baseGump.OnResponse(state, relayInfo);
|
||||
|
||||
prof?.Finish();
|
||||
}
|
||||
|
||||
if (typeId == 461)
|
||||
{
|
||||
// Virtue gump
|
||||
var switchCount = reader.Remaining >= 4 ? reader.ReadInt32() : 0;
|
||||
|
||||
if (buttonId == 1 && switchCount > 0)
|
||||
{
|
||||
var beheld = World.FindEntity<PlayerMobile>((Serial)reader.ReadUInt32());
|
||||
|
||||
if (beheld != null)
|
||||
{
|
||||
VirtueGump.RequestVirtueGump((PlayerMobile)state.Mobile, beheld);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var beheld = World.FindMobile(serial);
|
||||
|
||||
if (beheld != null)
|
||||
{
|
||||
VirtueGump.RequestVirtueItem((PlayerMobile)state.Mobile, beheld, buttonId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
289
Projects/UOContent/Gumps/Base/GumpSystem.cs
Normal file
289
Projects/UOContent/Gumps/Base/GumpSystem.cs
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2023 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: GumpSystem.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using Server.Gumps.Base;
|
||||
using Server.Logging;
|
||||
using Server.Network;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public static partial class GumpSystem
|
||||
{
|
||||
private const int GumpCap = 512;
|
||||
private const int InitialCapacity = 4;
|
||||
|
||||
private static readonly Dictionary<NetState, List<BaseGump>> _gumps = [];
|
||||
private static readonly ILogger _logger = LogFactory.GetLogger(typeof(GumpSystem));
|
||||
|
||||
public static unsafe void Configure()
|
||||
{
|
||||
IncomingPackets.Register(0xB1, 0, true, &DisplayGumpResponse);
|
||||
|
||||
EventSink.Disconnected += EventSink_Disconnected;
|
||||
}
|
||||
|
||||
private static void EventSink_Disconnected(Mobile m)
|
||||
{
|
||||
if (m.NetState != null && _gumps.Remove(m.NetState, out var gumps))
|
||||
{
|
||||
gumps.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<BaseGump> GetAll(NetState ns) =>
|
||||
_gumps.TryGetValue(ns, out var gumps) ? CollectionsMarshal.AsSpan(gumps) : [];
|
||||
|
||||
private static T Find<T>(NetState ns) where T : BaseGump
|
||||
{
|
||||
if (ns == null || !_gumps.TryGetValue(ns, out var gumps))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var gumpsSpan = CollectionsMarshal.AsSpan(gumps);
|
||||
for (int i = 0; i < gumpsSpan.Length; i++)
|
||||
{
|
||||
if (gumpsSpan[i] is T tGump)
|
||||
{
|
||||
return tGump;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void Add(NetState ns, BaseGump gump)
|
||||
{
|
||||
if (ns == null || gump == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_gumps.TryGetValue(ns, out var gumps))
|
||||
{
|
||||
gumps = new List<BaseGump>(InitialCapacity);
|
||||
_gumps.Add(ns, gumps);
|
||||
}
|
||||
|
||||
if (gumps.Count < GumpCap)
|
||||
{
|
||||
gumps.Add(gump);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Information("Exceeded gump cap, disconnecting...");
|
||||
ns.Disconnect("Exceeded gump cap.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void Remove(NetState ns, BaseGump gump)
|
||||
{
|
||||
if (_gumps.TryGetValue(ns, out var gumps))
|
||||
{
|
||||
for (int i = 0; i < gumps.Count; i++)
|
||||
{
|
||||
if (gumps[i] == gump)
|
||||
{
|
||||
gumps.RemoveAt(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool Remove<T>(NetState ns, out T gump) where T : BaseGump
|
||||
{
|
||||
if (ns != null && _gumps.TryGetValue(ns, out var gumps))
|
||||
{
|
||||
var gumpsSpan = CollectionsMarshal.AsSpan(gumps);
|
||||
for (int i = 0; i < gumpsSpan.Length; i++)
|
||||
{
|
||||
if (gumpsSpan[i] is T tGump)
|
||||
{
|
||||
gumps.RemoveAt(i);
|
||||
gump = tGump;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gump = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void Send(NetState ns, BaseGump gump, bool singleton)
|
||||
{
|
||||
if (ns.CannotSendPackets()) // Handles ns null check too
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ref List<BaseGump> list = ref CollectionsMarshal.GetValueRefOrAddDefault(_gumps, ns, out bool exists);
|
||||
|
||||
if (exists)
|
||||
{
|
||||
bool replaced = false;
|
||||
|
||||
if (singleton || gump.Singleton)
|
||||
{
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
BaseGump old = list[i];
|
||||
|
||||
if (old.TypeID == gump.TypeID)
|
||||
{
|
||||
ns.SendCloseGump(old.TypeID, 0);
|
||||
old.OnServerClose(ns);
|
||||
|
||||
list[i] = gump;
|
||||
replaced = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!replaced)
|
||||
{
|
||||
list.Add(gump);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
list = [gump];
|
||||
}
|
||||
|
||||
gump.SendTo(ns);
|
||||
}
|
||||
|
||||
private static bool Close<T>(NetState ns) where T : BaseGump
|
||||
{
|
||||
if (Remove<T>(ns, out var gump))
|
||||
{
|
||||
ns.SendCloseGump(gump.TypeID, 0);
|
||||
gump.OnServerClose(ns);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static readonly List<BaseGump> _emptyList = [];
|
||||
|
||||
private static NetStateGumps Get(NetState ns)
|
||||
{
|
||||
if (ns == null)
|
||||
{
|
||||
return new NetStateGumps(_emptyList, null);
|
||||
}
|
||||
|
||||
ref List<BaseGump> list = ref CollectionsMarshal.GetValueRefOrAddDefault(_gumps, ns, out bool exists);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
list = [];
|
||||
}
|
||||
|
||||
return new NetStateGumps(list, ns);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool HasGump<T>([DisallowNull] this Mobile m) where T : BaseGump
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(m);
|
||||
return Find<T>(m.NetState) != null;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static T FindGump<T>([DisallowNull] this Mobile m) where T : BaseGump
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(m);
|
||||
return Find<T>(m.NetState);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool CloseGump<T>([DisallowNull] this Mobile m) where T : BaseGump
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(m);
|
||||
return Close<T>(m.NetState);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void SendGump([DisallowNull] this Mobile m, BaseGump g, bool singleton = false)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(m);
|
||||
Send(m.NetState, g, singleton);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ReadOnlySpan<BaseGump> GetAllGumps([DisallowNull] this Mobile m)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(m);
|
||||
return GetAll(m.NetState);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static NetStateGumps GetGumps([DisallowNull] this Mobile m)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(m);
|
||||
return Get(m.NetState);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool HasGump<T>([DisallowNull] this NetState ns) where T : BaseGump
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(ns);
|
||||
return Find<T>(ns) != null;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void SendGump([DisallowNull] this NetState ns, BaseGump g, bool singleton = false)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(ns);
|
||||
Send(ns, g, singleton);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool CloseGump<T>([DisallowNull] this NetState ns) where T : BaseGump
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(ns);
|
||||
return Close<T>(ns);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ReadOnlySpan<BaseGump> GetAllGumps([DisallowNull] this NetState ns)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(ns);
|
||||
return GetAll(ns);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void AddGump([DisallowNull] this NetState ns, BaseGump gump)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(ns);
|
||||
Add(ns, gump);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static NetStateGumps GetGumps([DisallowNull] this NetState ns)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(ns);
|
||||
return Get(ns);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2023 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: InvalidGumpResponseException.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public class InvalidGumpResponseException : Exception
|
||||
{
|
||||
public InvalidGumpResponseException(string reason) : base(reason)
|
||||
{
|
||||
}
|
||||
}
|
||||
324
Projects/UOContent/Gumps/Base/Legacy/Gump.cs
Normal file
324
Projects/UOContent/Gumps/Base/Legacy/Gump.cs
Normal file
|
|
@ -0,0 +1,324 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2024 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: Gump.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using Server.Collections;
|
||||
using Server.Network;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public class Gump : BaseGump
|
||||
{
|
||||
private static readonly byte[] _layoutBuffer = GC.AllocateUninitializedArray<byte>(0x20000);
|
||||
private static readonly byte[] _stringsBuffer = GC.AllocateUninitializedArray<byte>(0x20000);
|
||||
private static readonly OrderedSet<string> _stringsList = new();
|
||||
|
||||
private int _switches;
|
||||
private int _textEntries;
|
||||
|
||||
public Gump(int x, int y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
|
||||
Entries = [];
|
||||
Strings = [];
|
||||
}
|
||||
|
||||
public List<string> Strings { get; }
|
||||
|
||||
public List<GumpEntry> Entries { get; }
|
||||
|
||||
public bool Disposable { get; set; } = true;
|
||||
|
||||
public bool Resizable { get; set; } = true;
|
||||
|
||||
public bool Draggable { get; set; } = true;
|
||||
|
||||
public bool Closable { get; set; } = true;
|
||||
|
||||
public override int Switches => _switches;
|
||||
|
||||
public override int TextEntries => _textEntries;
|
||||
|
||||
public void AddPage(int page)
|
||||
{
|
||||
Add(new GumpPage(page));
|
||||
}
|
||||
|
||||
public void AddAlphaRegion(int x, int y, int width, int height)
|
||||
{
|
||||
Add(new GumpAlphaRegion(x, y, width, height));
|
||||
}
|
||||
|
||||
public void AddBackground(int x, int y, int width, int height, int gumpID)
|
||||
{
|
||||
Add(new GumpBackground(x, y, width, height, gumpID));
|
||||
}
|
||||
|
||||
public void AddButton(
|
||||
int x, int y, int normalID, int pressedID, int buttonID,
|
||||
GumpButtonType type = GumpButtonType.Reply, int param = 0
|
||||
)
|
||||
{
|
||||
Add(new GumpButton(x, y, normalID, pressedID, buttonID, type, param));
|
||||
}
|
||||
|
||||
public void AddCheck(int x, int y, int inactiveID, int activeID, bool initialState, int switchID)
|
||||
{
|
||||
Add(new GumpCheck(x, y, inactiveID, activeID, initialState, switchID));
|
||||
}
|
||||
|
||||
public void AddGroup(int group)
|
||||
{
|
||||
Add(new GumpGroup(group));
|
||||
}
|
||||
|
||||
public void AddTooltip(int number, string args = null)
|
||||
{
|
||||
Add(new GumpTooltip(number, args));
|
||||
}
|
||||
|
||||
public void AddHtml(
|
||||
int x, int y, int width, int height, string text, bool background = false, bool scrollbar = false
|
||||
)
|
||||
{
|
||||
Add(new GumpHtml(x, y, width, height, text, background, scrollbar));
|
||||
}
|
||||
|
||||
public void AddHtmlLocalized(
|
||||
int x, int y, int width, int height, int number, bool background = false,
|
||||
bool scrollbar = false
|
||||
)
|
||||
{
|
||||
Add(new GumpHtmlLocalized(x, y, width, height, number, background, scrollbar));
|
||||
}
|
||||
|
||||
public void AddHtmlLocalized(
|
||||
int x, int y, int width, int height, int number, int color, bool background = false,
|
||||
bool scrollbar = false
|
||||
)
|
||||
{
|
||||
Add(new GumpHtmlLocalized(x, y, width, height, number, color, background, scrollbar));
|
||||
}
|
||||
|
||||
public void AddHtmlLocalized(
|
||||
int x, int y, int width, int height, int number, string args, int color,
|
||||
bool background = false, bool scrollbar = false
|
||||
)
|
||||
{
|
||||
Add(new GumpHtmlLocalized(x, y, width, height, number, args, color, background, scrollbar));
|
||||
}
|
||||
|
||||
public void AddImage(int x, int y, int gumpID, int hue = 0)
|
||||
{
|
||||
Add(new GumpImage(x, y, gumpID, hue));
|
||||
}
|
||||
|
||||
public void AddImageTiled(int x, int y, int width, int height, int gumpID)
|
||||
{
|
||||
Add(new GumpImageTiled(x, y, width, height, gumpID));
|
||||
}
|
||||
|
||||
public void AddImageTiledButton(
|
||||
int x, int y, int normalID, int pressedID, int buttonID, GumpButtonType type,
|
||||
int param, int itemID, int hue, int width, int height
|
||||
)
|
||||
{
|
||||
Add(
|
||||
new GumpImageTileButton(
|
||||
x,
|
||||
y,
|
||||
normalID,
|
||||
pressedID,
|
||||
buttonID,
|
||||
type,
|
||||
param,
|
||||
itemID,
|
||||
hue,
|
||||
width,
|
||||
height
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public void AddItem(int x, int y, int itemID, int hue = 0)
|
||||
{
|
||||
Add(new GumpItem(x, y, itemID, hue));
|
||||
}
|
||||
|
||||
public void AddLabel(int x, int y, int hue, string text)
|
||||
{
|
||||
Add(new GumpLabel(x, y, hue, text));
|
||||
}
|
||||
|
||||
public void AddLabelHtml(int x, int y, int width, int height, string text, string hue, int size = 4, bool center = true)
|
||||
{
|
||||
AddHtml(x, y, width, height, center ? text.Center(hue, size) : text.Color(hue, size));
|
||||
}
|
||||
|
||||
public void AddLabelCropped(int x, int y, int width, int height, int hue, string text)
|
||||
{
|
||||
Add(new GumpLabelCropped(x, y, width, height, hue, text));
|
||||
}
|
||||
|
||||
public void AddRadio(int x, int y, int inactiveID, int activeID, bool initialState, int switchID)
|
||||
{
|
||||
Add(new GumpRadio(x, y, inactiveID, activeID, initialState, switchID));
|
||||
}
|
||||
|
||||
public void AddTextEntry(int x, int y, int width, int height, int hue, int entryID, string initialText)
|
||||
{
|
||||
Add(new GumpTextEntry(x, y, width, height, hue, entryID, initialText));
|
||||
}
|
||||
|
||||
public void AddTextEntry(int x, int y, int width, int height, int hue, int entryID, string initialText, int size)
|
||||
{
|
||||
Add(new GumpTextEntryLimited(x, y, width, height, hue, entryID, initialText, size));
|
||||
}
|
||||
|
||||
public void AddItemProperty(Serial serial)
|
||||
{
|
||||
Add(new GumpItemProperty(serial));
|
||||
}
|
||||
|
||||
public void AddSpriteImage(int x, int y, int gumpID, int width, int height, int sx, int sy)
|
||||
{
|
||||
Add(new GumpSpriteImage(x, y, gumpID, width, height, sx, sy));
|
||||
}
|
||||
|
||||
public void AddECHandleInput()
|
||||
{
|
||||
Add(new GumpECHandleInput());
|
||||
}
|
||||
|
||||
public void AddGumpIDOverride(int gumpID)
|
||||
{
|
||||
Add(new GumpMasterGump(gumpID));
|
||||
}
|
||||
|
||||
public void Add(GumpEntry g)
|
||||
{
|
||||
if (g.Parent != this)
|
||||
{
|
||||
g.Parent = this;
|
||||
}
|
||||
else if (!Entries.Contains(g))
|
||||
{
|
||||
Entries.Add(g);
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove(GumpEntry g)
|
||||
{
|
||||
if (g == null || !Entries.Contains(g))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Entries.Remove(g);
|
||||
g.Parent = null;
|
||||
}
|
||||
|
||||
public int Intern(string value)
|
||||
{
|
||||
var indexOf = Strings.IndexOf(value);
|
||||
|
||||
if (indexOf >= 0)
|
||||
{
|
||||
return indexOf;
|
||||
}
|
||||
|
||||
Strings.Add(value);
|
||||
return Strings.Count - 1;
|
||||
}
|
||||
|
||||
public override void Compile(ref SpanWriter writer)
|
||||
{
|
||||
_textEntries = 0;
|
||||
_switches = 0;
|
||||
|
||||
var layoutWriter = new SpanWriter(_layoutBuffer);
|
||||
|
||||
if (!Draggable)
|
||||
{
|
||||
layoutWriter.Write("{ nomove }"u8);
|
||||
}
|
||||
|
||||
if (!Closable)
|
||||
{
|
||||
layoutWriter.Write("{ noclose }"u8);
|
||||
}
|
||||
|
||||
if (!Disposable)
|
||||
{
|
||||
layoutWriter.Write("{ nodispose }"u8);
|
||||
}
|
||||
|
||||
if (!Resizable)
|
||||
{
|
||||
layoutWriter.Write("{ noresize }"u8);
|
||||
}
|
||||
|
||||
foreach (var entry in Entries)
|
||||
{
|
||||
entry.AppendTo(ref layoutWriter, _stringsList, ref _textEntries, ref _switches);
|
||||
}
|
||||
|
||||
var stringsWriter = new SpanWriter(_stringsBuffer);
|
||||
|
||||
foreach (var str in _stringsList)
|
||||
{
|
||||
var s = str ?? "";
|
||||
stringsWriter.Write((ushort)s.Length);
|
||||
stringsWriter.WriteBigUni(s);
|
||||
}
|
||||
|
||||
writer.Write((byte)0xDD); // Packet ID
|
||||
writer.Seek(2, SeekOrigin.Current);
|
||||
|
||||
writer.Write(Serial);
|
||||
writer.Write(TypeID);
|
||||
writer.Write(X);
|
||||
writer.Write(Y);
|
||||
|
||||
layoutWriter.Write((byte)0); // Layout text terminator
|
||||
OutgoingGumpPackets.WritePacked(layoutWriter.Span, ref writer);
|
||||
|
||||
writer.Write(_stringsList.Count);
|
||||
OutgoingGumpPackets.WritePacked(stringsWriter.Span, ref writer);
|
||||
|
||||
writer.WritePacketLength();
|
||||
|
||||
layoutWriter.Dispose(); // Just in case
|
||||
stringsWriter.Dispose(); // Just in case
|
||||
|
||||
if (_stringsList.Count > 0)
|
||||
{
|
||||
_stringsList.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
protected void Reset()
|
||||
{
|
||||
_switches = 0;
|
||||
_textEntries = 0;
|
||||
Entries.Clear();
|
||||
Strings.Clear();
|
||||
}
|
||||
}
|
||||
43
Projects/UOContent/Gumps/Base/Legacy/GumpAlphaRegion.cs
Normal file
43
Projects/UOContent/Gumps/Base/Legacy/GumpAlphaRegion.cs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2024 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: GumpAlphaRegion.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System.Buffers;
|
||||
using Server.Collections;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public class GumpAlphaRegion : GumpEntry
|
||||
{
|
||||
public GumpAlphaRegion(int x, int y, int width, int height)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
public int X { get; set; }
|
||||
|
||||
public int Y { get; set; }
|
||||
|
||||
public int Width { get; set; }
|
||||
|
||||
public int Height { get; set; }
|
||||
|
||||
public override void AppendTo(ref SpanWriter writer, OrderedSet<string> strings, ref int entries, ref int switches)
|
||||
{
|
||||
writer.WriteAscii($"{{ checkertrans {X} {Y} {Width} {Height} }}");
|
||||
}
|
||||
}
|
||||
46
Projects/UOContent/Gumps/Base/Legacy/GumpBackground.cs
Normal file
46
Projects/UOContent/Gumps/Base/Legacy/GumpBackground.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2024 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: GumpBackground.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System.Buffers;
|
||||
using Server.Collections;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public class GumpBackground : GumpEntry
|
||||
{
|
||||
public GumpBackground(int x, int y, int width, int height, int gumpID)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Width = width;
|
||||
Height = height;
|
||||
GumpID = gumpID;
|
||||
}
|
||||
|
||||
public int X { get; set; }
|
||||
|
||||
public int Y { get; set; }
|
||||
|
||||
public int Width { get; set; }
|
||||
|
||||
public int Height { get; set; }
|
||||
|
||||
public int GumpID { get; set; }
|
||||
|
||||
public override void AppendTo(ref SpanWriter writer, OrderedSet<string> strings, ref int entries, ref int switches)
|
||||
{
|
||||
writer.WriteAscii($"{{ resizepic {X} {Y} {GumpID} {Width} {Height} }}");
|
||||
}
|
||||
}
|
||||
61
Projects/UOContent/Gumps/Base/Legacy/GumpButton.cs
Normal file
61
Projects/UOContent/Gumps/Base/Legacy/GumpButton.cs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2024 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: GumpButton.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System.Buffers;
|
||||
using Server.Collections;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public enum GumpButtonType
|
||||
{
|
||||
Page = 0,
|
||||
Reply = 1
|
||||
}
|
||||
|
||||
public class GumpButton : GumpEntry
|
||||
{
|
||||
public GumpButton(
|
||||
int x, int y, int normalID, int pressedID, int buttonID,
|
||||
GumpButtonType type = GumpButtonType.Reply, int param = 0
|
||||
)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
NormalID = normalID;
|
||||
PressedID = pressedID;
|
||||
ButtonID = buttonID;
|
||||
Type = type;
|
||||
Param = param;
|
||||
}
|
||||
|
||||
public int X { get; set; }
|
||||
|
||||
public int Y { get; set; }
|
||||
|
||||
public int NormalID { get; set; }
|
||||
|
||||
public int PressedID { get; set; }
|
||||
|
||||
public int ButtonID { get; set; }
|
||||
|
||||
public GumpButtonType Type { get; set; }
|
||||
|
||||
public int Param { get; set; }
|
||||
|
||||
public override void AppendTo(ref SpanWriter writer, OrderedSet<string> strings, ref int entries, ref int switches)
|
||||
{
|
||||
writer.WriteAscii($"{{ button {X} {Y} {NormalID} {PressedID} {(int)Type} {Param} {ButtonID} }}");
|
||||
}
|
||||
}
|
||||
51
Projects/UOContent/Gumps/Base/Legacy/GumpCheck.cs
Normal file
51
Projects/UOContent/Gumps/Base/Legacy/GumpCheck.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2024 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: GumpCheck.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System.Buffers;
|
||||
using Server.Collections;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public class GumpCheck : GumpEntry
|
||||
{
|
||||
public GumpCheck(int x, int y, int inactiveID, int activeID, bool initialState, int switchID)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
InactiveID = inactiveID;
|
||||
ActiveID = activeID;
|
||||
InitialState = initialState;
|
||||
SwitchID = switchID;
|
||||
}
|
||||
|
||||
public int X { get; set; }
|
||||
|
||||
public int Y { get; set; }
|
||||
|
||||
public int InactiveID { get; set; }
|
||||
|
||||
public int ActiveID { get; set; }
|
||||
|
||||
public bool InitialState { get; set; }
|
||||
|
||||
public int SwitchID { get; set; }
|
||||
|
||||
public override void AppendTo(ref SpanWriter writer, OrderedSet<string> strings, ref int entries, ref int switches)
|
||||
{
|
||||
var initialState = InitialState ? "1" : "0";
|
||||
writer.WriteAscii($"{{ checkbox {X} {Y} {InactiveID} {ActiveID} {initialState} {SwitchID} }}");
|
||||
switches++;
|
||||
}
|
||||
}
|
||||
27
Projects/UOContent/Gumps/Base/Legacy/GumpECHandleInput.cs
Normal file
27
Projects/UOContent/Gumps/Base/Legacy/GumpECHandleInput.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2024 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: GumpECHandleInput.cs *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System.Buffers;
|
||||
using Server.Collections;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public class GumpECHandleInput : GumpEntry
|
||||
{
|
||||
public override void AppendTo(ref SpanWriter writer, OrderedSet<string> strings, ref int entries, ref int switches)
|
||||
{
|
||||
writer.Write("{ echandleinput }"u8);
|
||||
}
|
||||
}
|
||||
27
Projects/UOContent/Gumps/Base/Legacy/GumpEntry.cs
Normal file
27
Projects/UOContent/Gumps/Base/Legacy/GumpEntry.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
using System.Buffers;
|
||||
using Server.Collections;
|
||||
|
||||
namespace Server.Gumps;
|
||||
|
||||
public abstract class GumpEntry
|
||||
{
|
||||
private Gump m_Parent;
|
||||
|
||||
public Gump Parent
|
||||
{
|
||||
get => m_Parent;
|
||||
set
|
||||
{
|
||||
if (m_Parent != value)
|
||||
{
|
||||
m_Parent?.Remove(this);
|
||||
|
||||
m_Parent = value;
|
||||
|
||||
m_Parent?.Add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void AppendTo(ref SpanWriter writer, OrderedSet<string> strings, ref int entries, ref int switches);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue