perf: Migrate Travel/Moongate gumps to DynamicGump (#2412)

## Summary

Migrates the three player-facing travel/moongate gumps from legacy `Gump` to the modern `DynamicGump` system.

- `GoGump` (Gumps/Go/GoGump.cs) → `DynamicGump`. The category-tree layout's row count varies with the current `GoCategory`'s child count and pagination. Refreshes via `SendGump(this)` after mutating `_node`/`_page` instead of allocating a new instance per nav/page click.
- `MoongateGump` (Items/Misc/PublicMoongate.cs) → `DynamicGump`. The destination tab strip and per-map pages are gated by ruleset (sigil bearer, murderer, faction facet) and expansion/young flag, plus the configured map selection. The set of pages and the active-map swap make the layout shape per-instance.
- `MoongateConfirmGump` (Items/Skill Items/Magical/Misc/Moongate.cs) → `DynamicGump`. Per the **dynamic-cliloc rule**, the gump bakes one of two different cliloc numbers (1062050 Felucca-warning vs 1062049 generic confirm) and selects between an AOS and pre-AOS layout shape — both characteristics force `DynamicGump` rather than `StaticGump<T>` because cached layout bytes would otherwise lock in the wrong cliloc/shape.

All three now use a `private` constructor with a `public static DisplayTo(...)` entry point that validates prerequisites before any gump is allocated (empty-gump rule, CLAUDE.md §13). All are `Singleton` and use `SendGump(this)` self-refresh on internal navigation. Updated callers: `PublicMoongate.UseGate` and `Moongate.BeginConfirmation` now call `DisplayTo(...)`.
This commit is contained in:
Kamron Batman 2026-04-25 17:03:24 -07:00 • committed by GitHub
parent 2423950cca
commit 83f771c99a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 218 additions and 188 deletions

View file

@ -157,7 +157,7 @@ public partial class Moongate : Item
from.SendSound(0x20E, from);
}
from.SendGump(new MoongateConfirmGump(from, this));
MoongateConfirmGump.DisplayTo(from, this);
}
else
{
@ -301,90 +301,80 @@ public partial class ConfirmationMoongate : Moongate
}
}
public class MoongateConfirmGump : Gump
public class MoongateConfirmGump : DynamicGump
{
private Mobile _from;
private Moongate _gate;
private readonly Mobile _from;
private readonly Moongate _gate;
public override bool Singleton => true;
public MoongateConfirmGump(Mobile from, Moongate gate) : base(Core.AOS ? 110 : 20, Core.AOS ? 100 : 30)
private MoongateConfirmGump(Mobile from, Moongate gate) : base(Core.AOS ? 110 : 20, Core.AOS ? 100 : 30)
{
_from = from;
_gate = gate;
}
public static void DisplayTo(Mobile from, Moongate gate)
{
if (from?.NetState == null || gate == null || gate.Deleted)
{
return;
}
from.SendGump(new MoongateConfirmGump(from, gate));
}
protected override void BuildLayout(ref DynamicGumpBuilder builder)
{
builder.AddPage();
if (Core.AOS)
{
Closable = false;
builder.SetNoClose();
AddPage(0);
builder.AddBackground(0, 0, 420, 280, 5054);
AddBackground(0, 0, 420, 280, 5054);
builder.AddImageTiled(10, 10, 400, 20, 2624);
builder.AddAlphaRegion(10, 10, 400, 20);
AddImageTiled(10, 10, 400, 20, 2624);
AddAlphaRegion(10, 10, 400, 20);
builder.AddHtmlLocalized(10, 10, 400, 20, 1062051, 30720); // Gate Warning
AddHtmlLocalized(10, 10, 400, 20, 1062051, 30720); // Gate Warning
builder.AddImageTiled(10, 40, 400, 200, 2624);
builder.AddAlphaRegion(10, 40, 400, 200);
AddImageTiled(10, 40, 400, 200, 2624);
AddAlphaRegion(10, 40, 400, 200);
if (from.Map != Map.Felucca && gate.TargetMap == Map.Felucca && gate.ShowFeluccaWarning)
if (_from.Map != Map.Felucca && _gate.TargetMap == Map.Felucca && _gate.ShowFeluccaWarning)
{
AddHtmlLocalized(
10,
40,
400,
200,
1062050, // This Gate goes to Felucca... Continue to enter the gate, Cancel to stay here
32512,
false,
true
);
// This Gate goes to Felucca... Continue to enter the gate, Cancel to stay here
builder.AddHtmlLocalized(10, 40, 400, 200, 1062050, 32512, false, true);
}
else
{
AddHtmlLocalized(
10,
40,
400,
200,
1062049, // Dost thou wish to step into the moongate? Continue to enter the gate, Cancel to stay here
32512,
false,
true
);
// Dost thou wish to step into the moongate? Continue to enter the gate, Cancel to stay here
builder.AddHtmlLocalized(10, 40, 400, 200, 1062049, 32512, false, true);
}
AddImageTiled(10, 250, 400, 20, 2624);
AddAlphaRegion(10, 250, 400, 20);
builder.AddImageTiled(10, 250, 400, 20, 2624);
builder.AddAlphaRegion(10, 250, 400, 20);
AddButton(10, 250, 4005, 4007, 1);
AddHtmlLocalized(40, 250, 170, 20, 1011036, 32767); // OKAY
builder.AddButton(10, 250, 4005, 4007, 1);
builder.AddHtmlLocalized(40, 250, 170, 20, 1011036, 32767); // OKAY
AddButton(210, 250, 4005, 4007, 0);
AddHtmlLocalized(240, 250, 170, 20, 1011012, 32767); // CANCEL
builder.AddButton(210, 250, 4005, 4007, 0);
builder.AddHtmlLocalized(240, 250, 170, 20, 1011012, 32767); // CANCEL
}
else
{
AddPage(0);
builder.AddBackground(0, 0, 420, 400, 5054);
builder.AddBackground(10, 10, 400, 380, 3000);
AddBackground(0, 0, 420, 400, 5054);
AddBackground(10, 10, 400, 380, 3000);
// Dost thou wish to step into the moongate? Continue to enter the gate, Cancel to stay here
builder.AddHtmlLocalized(20, 40, 380, 60, 1062049);
AddHtmlLocalized(
20,
40,
380,
60,
1062049 // Dost thou wish to step into the moongate? Continue to enter the gate, Cancel to stay here
);
builder.AddHtmlLocalized(55, 110, 290, 20, 1011012); // CANCEL
builder.AddButton(20, 110, 4005, 4007, 0);
AddHtmlLocalized(55, 110, 290, 20, 1011012); // CANCEL
AddButton(20, 110, 4005, 4007, 0);
AddHtmlLocalized(55, 140, 290, 40, 1011011); // CONTINUE
AddButton(20, 140, 4005, 4007, 1);
builder.AddHtmlLocalized(55, 140, 290, 40, 1011011); // CONTINUE
builder.AddButton(20, 140, 4005, 4007, 1);
}
}