perf: Migrates New Guild System gumps from legacy Gump. (#2422)

## Summary

Migrates the eight concrete New Guild System gumps (CreateGuild, GuildInfo,
GuildMemberInfo, GuildRoster, GuildDiplomacy, WarDeclaration,
GuildAdvancedSearch, GuildInvitationRequest) and three abstract bases
(BaseGuildGump, BaseGuildListGump, OtherGuildInfo) from the legacy `Gump`
class to `DynamicGump`. Layout work moves from constructor-side `AddX(...)`
calls into `BuildLayout(ref DynamicGumpBuilder builder)` — the abstract
`BaseGuildGump` now provides a `BuildContent` callout for shared
tab-strip chrome, and `BaseGuildListGump<T>` adds another
`BuildListExtras` hook so subclasses can paint highlighted titles after
the filter/sort/pagination chrome.

The headline win is the **self-refresh pattern** on the list gumps and
diplomacy advanced search. Previously each filter/sort/back/forward
click allocated a brand new gump via `GetResentGump`. After migration,
those handlers mutate `_filter`, `_startNumber`, `_comparer`, `_ascending`,
or `_display` on the existing gump and call `from.SendGump(this)`,
letting the singleton path in `NetStateGumps.Send` swap in the same
instance with the new layout. The original list is preserved separately
from the per-render filtered/sorted `_displayList`, so refreshes pick up
the latest state without losing the source list.

All guild gumps deal with per-instance dynamic strings (guild names,
member names, war declarations, alliance names), which would defeat
`StaticGump<T>` caching per the cliloc rule, so every concrete subclass
migrates to `DynamicGump`. `AllianceRosterGump` (in `Misc/Guild.cs`)
is a `GuildDiplomacyGump` subclass and inherits the new behavior; its
unused override and stored alliance reference were dropped along with
the now-obsolete `GetResentGump` abstract.
This commit is contained in:
Kamron Batman 2026-05-03 00:09:22 -07:00 • committed by GitHub
parent 598c3c125c
commit 9c2ac2b8ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 642 additions and 689 deletions

View file

@ -6,39 +6,49 @@ using Server.Network;
namespace Server.Guilds
{
public abstract class BaseGuildGump : Gump
public abstract class BaseGuildGump : DynamicGump
{
public override bool Singleton => true;
public BaseGuildGump(PlayerMobile pm, Guild g, int x = 10, int y = 10) : base(x, y)
protected BaseGuildGump(PlayerMobile pm, Guild g, int x = 10, int y = 10) : base(x, y)
{
guild = g;
player = pm;
Guild = g;
Player = pm;
}
protected Guild guild { get; }
protected Guild Guild { get; }
protected PlayerMobile player { get; }
protected PlayerMobile Player { get; }
// There's prolly a way to have all the vars set of inherited classes before something is called in the Ctor... but... I can't think of it right now, and I can't use Timer.DelayCall here :<
// Subclasses that draw their own background/layout (e.g. OtherGuildInfo,
// WarDeclarationGump, GuildMemberInfoGump) can opt out of the standard
// 600x440 frame and three-button tab strip drawn at the top of the gump.
protected virtual bool ShowTabStrip => true;
public virtual void PopulateGump()
protected override void BuildLayout(ref DynamicGumpBuilder builder)
{
AddPage(0);
builder.AddPage();
AddBackground(0, 0, 600, 440, 0x24AE);
AddBackground(66, 40, 150, 26, 0x2486);
AddButton(71, 45, 0x845, 0x846, 1);
AddHtmlLocalized(96, 43, 110, 26, 1063014, 0x0); // My Guild
AddBackground(236, 40, 150, 26, 0x2486);
AddButton(241, 45, 0x845, 0x846, 2);
AddHtmlLocalized(266, 43, 110, 26, 1062974, 0x0); // Guild Roster
AddBackground(401, 40, 150, 26, 0x2486);
AddButton(406, 45, 0x845, 0x846, 3);
AddHtmlLocalized(431, 43, 110, 26, 1062978, 0x0); // Diplomacy
AddPage(1);
if (ShowTabStrip)
{
builder.AddBackground(0, 0, 600, 440, 0x24AE);
builder.AddBackground(66, 40, 150, 26, 0x2486);
builder.AddButton(71, 45, 0x845, 0x846, 1);
builder.AddHtmlLocalized(96, 43, 110, 26, 1063014, 0x0); // My Guild
builder.AddBackground(236, 40, 150, 26, 0x2486);
builder.AddButton(241, 45, 0x845, 0x846, 2);
builder.AddHtmlLocalized(266, 43, 110, 26, 1062974, 0x0); // Guild Roster
builder.AddBackground(401, 40, 150, 26, 0x2486);
builder.AddButton(406, 45, 0x845, 0x846, 3);
builder.AddHtmlLocalized(431, 43, 110, 26, 1062978, 0x0); // Diplomacy
builder.AddPage(1);
}
BuildContent(ref builder);
}
protected abstract void BuildContent(ref DynamicGumpBuilder builder);
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (sender.Mobile is not PlayerMobile pm)
@ -46,7 +56,7 @@ namespace Server.Guilds
return;
}
if (!IsMember(pm, guild))
if (!IsMember(pm, Guild))
{
return;
}
@ -55,29 +65,27 @@ namespace Server.Guilds
{
case 1:
{
pm.SendGump(new GuildInfoGump(pm, guild));
pm.SendGump(new GuildInfoGump(pm, Guild));
break;
}
case 2:
{
pm.SendGump(new GuildRosterGump(pm, guild));
pm.SendGump(new GuildRosterGump(pm, Guild));
break;
}
case 3:
{
pm.SendGump(new GuildDiplomacyGump(pm, guild));
pm.SendGump(new GuildDiplomacyGump(pm, Guild));
break;
}
}
}
public static bool IsLeader(Mobile m, Guild g) =>
!(m.Deleted || g.Disbanded || m is not PlayerMobile ||
m.AccessLevel < AccessLevel.GameMaster && g.Leader != m);
!(m.Deleted || g.Disbanded || m is not PlayerMobile || m.AccessLevel < AccessLevel.GameMaster && g.Leader != m);
public static bool IsMember(Mobile m, Guild g) =>
!(m.Deleted || g.Disbanded || m is not PlayerMobile ||
m.AccessLevel < AccessLevel.GameMaster && !g.IsMember(m));
!(m.Deleted || g.Disbanded || m is not PlayerMobile || m.AccessLevel < AccessLevel.GameMaster && !g.IsMember(m));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool CheckProfanity(string s, int maxLength = 50) =>
@ -94,15 +102,24 @@ namespace Server.Guilds
ProfanityProtection.DisallowedSearchValues
);
public void AddHtmlText(int x, int y, int width, int height, TextDefinition text, bool back, bool scroll)
protected static void AddHtmlText(
ref DynamicGumpBuilder builder,
int x,
int y,
int width,
int height,
TextDefinition text,
bool back,
bool scroll
)
{
if (text?.Number > 0)
{
AddHtmlLocalized(x, y, width, height, text.Number, back, scroll);
builder.AddHtmlLocalized(x, y, width, height, text.Number, back, scroll);
}
else if (text?.String != null)
{
AddHtml(x, y, width, height, text.String, back, scroll);
builder.AddHtml(x, y, width, height, text.String, background: back, scrollbar: scroll);
}
}
}