perf: Migrate Holiday and Decorative gumps to DynamicGump/StaticGump (#2413)

## Summary

Migrates 10 player-facing legacy `Gump` subclasses for holiday and decorative items to the modern `DynamicGump` / `StaticGump<T>` system. All migrated gumps are `Singleton`, use private constructors gated by static `DisplayTo(...)` entry points (empty-gump rule, CLAUDE.md §13), and replace legacy `m_X` fields with `_x` per coding standards.

Per-gump base type and rationale:

- **Mistletoe.cs** — `MistletoeAddonGump` -> `StaticGump<MistletoeAddonGump>`. Fixed re-deed confirmation layout.
- **StValentinesBears.cs** — Renamed `InternalGump` -> `StValentinesBearsGump`, base `StaticGump<T>`. Fixed sign-bear layout with three text entries; legacy `m_Bear` -> `_bear`. Switched legacy `AddTextEntry(..., size)` -> `AddTextEntryLimited(...)` (modern API split).
- **Wreath.cs** — `WreathAddonGump` -> `StaticGump<WreathAddonGump>`. Fixed re-deed confirmation layout.
- **HolidayPottedPlant.cs** — Renamed `InternalGump` -> `HolidayPottedPlantGump`, base `StaticGump<T>`. Fixed plant-picker layout.
- **SnowStatue.cs** — Renamed `InternalGump` -> `SnowStatueGump`, base `StaticGump<T>`. Fixed statue-picker layout. Dropped unused `Mobile from` ctor arg.
- **TapestryOfSosaria.cs** — Renamed `InternalGump` -> `TapestryOfSosariaGump`, base `StaticGump<T>`. Single image, fixed.
- **HouseRaffleDeed.cs** — `WritOfLeaseGump` -> `DynamicGump`. Description HTML is computed per-instance from deed expiration / days-left, so layout text varies per instance. Added `Singleton => true` (was missing implicitly via legacy default).
- **SpecialScroll.cs** — Renamed `InternalGump` -> `SpecialScrollGump`, base `DynamicGump`. **Cliloc rule**: `_scroll.Message`, `_scroll.Title`, `_scroll.SkillLabel` are dynamic cliloc numbers per scroll type — `AddHtmlLocalized` bakes the cliloc number into the cached layout, so `StaticGump<T>` cannot cache it.
- **BallotBox.cs** — Renamed `InternalGump` -> `BallotBoxGump`, base `DynamicGump`. Layout shape varies: variable topic-line count, owner-vs-voter buttons, and vote-tally bars all add/remove elements. Legacy `m_Box` -> `_box`. Updated the `TopicPrompt` callbacks to call `BallotBoxGump.DisplayTo(...)` instead of allocating a new gump directly.
- **AquariumGump.cs** — `AquariumGump` -> `DynamicGump`. Per-page layout depends on each item's `LabelNumber` and (for `BaseFish`) `GetDescription()` cliloc — those vary per fish/decoration. Two `DisplayTo` overloads (auto-detect access vs explicit edit flag) to mirror the original two call sites in `Aquarium.cs`. Legacy `m_Aquarium` -> `_aquarium`.

### Skipped

- **HouseRaffleManagementGump.cs** — Skipped as **staff-only**. Only invoked via `ManagementEntry` context entry inside `HouseRaffleStone.cs`, gated by `from.AccessLevel >= AccessLevel.Seer`. Per task instructions, staff-only gumps are out of scope for this PR.

### External callers updated

- `Aquarium.cs` — Two `new AquariumGump(...)` sites swapped to `AquariumGump.DisplayTo(...)`.

All other migrated inner classes were nested in the same file and only had local references, which were updated to call the new `DisplayTo(...)` static entry point.
This commit is contained in:
Kamron Batman 2026-04-25 17:22:41 -07:00 committed by GitHub
parent 83f771c99a
commit ec85d97482
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 422 additions and 317 deletions

View file

@ -56,7 +56,6 @@ public partial class MistletoeAddon : Item, IDyable, IAddon
}
from.SendLocalizedMessage(500295); // You are too far away to do that.
return false;
}
return false;
@ -104,7 +103,7 @@ public partial class MistletoeAddon : Item, IDyable, IAddon
if (from.InRange(GetWorldLocation(), 3))
{
from.SendGump(new MistletoeAddonGump(from, this));
MistletoeAddonGump.DisplayTo(from, this);
}
else
{
@ -112,27 +111,35 @@ public partial class MistletoeAddon : Item, IDyable, IAddon
}
}
private class MistletoeAddonGump : Gump
private class MistletoeAddonGump : StaticGump<MistletoeAddonGump>
{
private readonly MistletoeAddon _addon;
private readonly Mobile _from;
public override bool Singleton => true;
public MistletoeAddonGump(Mobile from, MistletoeAddon addon) : base(150, 50)
private MistletoeAddonGump(MistletoeAddon addon) : base(150, 50) => _addon = addon;
public static void DisplayTo(Mobile from, MistletoeAddon addon)
{
_from = from;
_addon = addon;
if (from?.NetState == null || addon?.Deleted != false)
{
return;
}
AddPage(0);
from.SendGump(new MistletoeAddonGump(addon));
}
AddBackground(0, 0, 220, 170, 0x13BE);
AddBackground(10, 10, 200, 150, 0xBB8);
AddHtmlLocalized(20, 30, 180, 60, 1062839); // Do you wish to re-deed this decoration?
AddHtmlLocalized(55, 100, 160, 25, 1011011); // CONTINUE
AddButton(20, 100, 0xFA5, 0xFA7, 1);
AddHtmlLocalized(55, 125, 160, 25, 1011012); // CANCEL
AddButton(20, 125, 0xFA5, 0xFA7, 0);
protected override void BuildLayout(ref StaticGumpBuilder builder)
{
builder.AddPage();
builder.AddBackground(0, 0, 220, 170, 0x13BE);
builder.AddBackground(10, 10, 200, 150, 0xBB8);
builder.AddHtmlLocalized(20, 30, 180, 60, 1062839); // Do you wish to re-deed this decoration?
builder.AddHtmlLocalized(55, 100, 160, 25, 1011011); // CONTINUE
builder.AddButton(20, 100, 0xFA5, 0xFA7, 1);
builder.AddHtmlLocalized(55, 125, 160, 25, 1011012); // CANCEL
builder.AddButton(20, 125, 0xFA5, 0xFA7, 0);
}
public override void OnResponse(NetState sender, in RelayInfo info)
@ -142,14 +149,16 @@ public partial class MistletoeAddon : Item, IDyable, IAddon
return;
}
if (_from.InRange(_addon.GetWorldLocation(), 3))
var from = sender.Mobile;
if (from.InRange(_addon.GetWorldLocation(), 3))
{
_from.AddToBackpack(_addon.Deed);
from.AddToBackpack(_addon.Deed);
_addon.Delete();
}
else
{
_from.SendLocalizedMessage(500295); // You are too far away to do that.
from.SendLocalizedMessage(500295); // You are too far away to do that.
}
}
}

View file

@ -101,51 +101,63 @@ namespace Server.Items
return;
}
from.SendGump(new InternalGump(this));
StValentinesBearsGump.DisplayTo(from, this);
}
private class InternalGump : Gump
private class StValentinesBearsGump : StaticGump<StValentinesBearsGump>
{
private readonly StValentinesBear m_Bear;
private readonly StValentinesBear _bear;
public InternalGump(StValentinesBear bear)
: base(50, 50)
public override bool Singleton => true;
protected override bool Cached => false;
private StValentinesBearsGump(StValentinesBear bear) : base(50, 50)
{
m_Bear = bear;
_bear = bear;
}
AddPage(0);
AddBackground(0, 0, 420, 320, 9300);
AddHtml(10, 10, 400, 21, "<CENTER>St. Valentine Bear</CENTER>");
AddHtmlLocalized(
10,
40,
400,
75,
1150293,
0
); // Enter up to three lines of personalized greeting for your St. Valentine Bear. You many enter up to 25 characters per line. Once you enter text, you will only be able to correct mistakes for 10 minutes.
public static void DisplayTo(Mobile from, StValentinesBear bear)
{
if (from?.NetState == null || bear?.Deleted != false)
{
return;
}
AddHtmlLocalized(10, 129, 400, 21, 1150296, 0); // Line 1:
AddBackground(10, 150, 400, 24, 9350);
AddTextEntry(15, 152, 390, 20, 0, 0, "", 25);
from.SendGump(new StValentinesBearsGump(bear));
}
AddHtmlLocalized(10, 179, 400, 21, 1150297, 0); // Line 2:
AddBackground(10, 200, 400, 24, 9350);
AddTextEntry(15, 202, 390, 20, 0, 1, "", 25);
protected override void BuildLayout(ref StaticGumpBuilder builder)
{
builder.AddPage();
builder.AddBackground(0, 0, 420, 320, 9300);
// St. Valentine Bear
builder.AddHtmlLocalized(10, 10, 400, 21, 1154645, "#1150294", 0);
AddHtmlLocalized(10, 229, 400, 21, 1150298, 0); // Line 3:
AddBackground(10, 250, 400, 24, 9350);
AddTextEntry(15, 252, 390, 20, 0, 2, "", 25);
// Enter up to three lines of personalized greeting for your St. Valentine Bear. You many enter up to 25 characters per line. Once you enter text, you will only be able to correct mistakes for 10 minutes.
builder.AddHtmlLocalized(10, 40, 400, 75, 1150293, 0);
AddButton(15, 285, 242, 241, 0);
AddButton(335, 285, 247, 248, 1);
builder.AddHtmlLocalized(10, 129, 400, 21, 1150296, 0); // Line 1:
builder.AddBackground(10, 150, 400, 24, 9350);
builder.AddTextEntryLimited(15, 152, 390, 20, 0, 0, "", 25);
builder.AddHtmlLocalized(10, 179, 400, 21, 1150297, 0); // Line 2:
builder.AddBackground(10, 200, 400, 24, 9350);
builder.AddTextEntryLimited(15, 202, 390, 20, 0, 1, "", 25);
builder.AddHtmlLocalized(10, 229, 400, 21, 1150298, 0); // Line 3:
builder.AddBackground(10, 250, 400, 24, 9350);
builder.AddTextEntryLimited(15, 252, 390, 20, 0, 2, "", 25);
builder.AddButton(15, 285, 242, 241, 0);
builder.AddButton(335, 285, 247, 248, 1);
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
var from = sender.Mobile;
if (m_Bear.Deleted || !m_Bear.IsChildOf(from.Backpack) || !m_Bear.CanSign || info.ButtonID != 1)
if (_bear.Deleted || !_bear.IsChildOf(from.Backpack) || !_bear.CanSign || info.ButtonID != 1)
{
return;
}
@ -170,14 +182,14 @@ namespace Server.Items
return;
}
if (!m_Bear.IsSigned)
if (!_bear.IsSigned)
{
m_Bear.EditLimit = Core.Now + TimeSpan.FromMinutes(10);
_bear.EditLimit = Core.Now + TimeSpan.FromMinutes(10);
}
m_Bear.Line1 = line1.FixHtml();
m_Bear.Line2 = line2.FixHtml();
m_Bear.Line3 = line3.FixHtml();
_bear.Line1 = line1.FixHtml();
_bear.Line2 = line2.FixHtml();
_bear.Line3 = line3.FixHtml();
from.SendMessage("You add the personalized greeting to your St. Valentine Bear.");
}

View file

@ -45,7 +45,7 @@ namespace Server.Items
}
from.SendLocalizedMessage(1152318); // You may not use this item out of season.
return false;
return true;
}
public override void OnSingleClick(Mobile from)

View file

@ -83,102 +83,119 @@ namespace Server.Items
}
else
{
var isOwner = IsOwner(from);
from.SendGump(new InternalGump(this, isOwner));
BallotBoxGump.DisplayTo(from, this, IsOwner(from));
}
}
private class InternalGump : Gump
private class BallotBoxGump : DynamicGump
{
private readonly BallotBox m_Box;
private readonly BallotBox _box;
private readonly bool _isOwner;
public InternalGump(BallotBox box, bool isOwner) : base(110, 70)
public override bool Singleton => true;
private BallotBoxGump(BallotBox box, bool isOwner) : base(110, 70)
{
m_Box = box;
_box = box;
_isOwner = isOwner;
}
AddBackground(0, 0, 400, 350, 0xA28);
if (isOwner)
public static void DisplayTo(Mobile from, BallotBox box, bool isOwner)
{
if (from?.NetState == null || box?.Deleted != false)
{
AddHtmlLocalized(0, 15, 400, 35, 1011000); // <center>Ballot Box Owner's Menu</center>
return;
}
from.SendGump(new BallotBoxGump(box, isOwner));
}
protected override void BuildLayout(ref DynamicGumpBuilder builder)
{
builder.AddPage();
builder.AddBackground(0, 0, 400, 350, 0xA28);
if (_isOwner)
{
builder.AddHtmlLocalized(0, 15, 400, 35, 1011000); // <center>Ballot Box Owner's Menu</center>
}
else
{
AddHtmlLocalized(0, 15, 400, 35, 1011001); // <center>Ballot Box -- Vote Here!</center>
builder.AddHtmlLocalized(0, 15, 400, 35, 1011001); // <center>Ballot Box -- Vote Here!</center>
}
AddHtmlLocalized(0, 50, 400, 35, 1011002); // <center>Topic</center>
builder.AddHtmlLocalized(0, 50, 400, 35, 1011002); // <center>Topic</center>
var lineCount = box.Topic.Length;
AddBackground(25, 90, 350, Math.Max(20 * lineCount, 20), 0x1400);
var lineCount = _box.Topic.Length;
builder.AddBackground(25, 90, 350, Math.Max(20 * lineCount, 20), 0x1400);
for (var i = 0; i < lineCount; i++)
{
var line = box.Topic[i];
var line = _box.Topic[i];
if (!string.IsNullOrEmpty(line))
{
AddLabelCropped(30, 90 + i * 20, 340, 20, 0x3E3, line);
builder.AddLabelCropped(30, 90 + i * 20, 340, 20, 0x3E3, line);
}
}
var yesCount = box.Yes.Count;
var noCount = box.No.Count;
var yesCount = _box.Yes.Count;
var noCount = _box.No.Count;
var totalVotes = yesCount + noCount;
AddHtmlLocalized(0, 215, 400, 35, 1011003); // <center>votes</center>
builder.AddHtmlLocalized(0, 215, 400, 35, 1011003); // <center>votes</center>
if (!isOwner)
if (!_isOwner)
{
AddButton(20, 240, 0xFA5, 0xFA7, 3);
builder.AddButton(20, 240, 0xFA5, 0xFA7, 3);
}
AddHtmlLocalized(55, 242, 25, 35, 1011004); // aye:
AddLabel(78, 242, 0x0, $"[{yesCount}]");
builder.AddHtmlLocalized(55, 242, 25, 35, 1011004); // aye:
builder.AddLabel(78, 242, 0x0, $"[{yesCount}]");
if (!isOwner)
if (!_isOwner)
{
AddButton(20, 275, 0xFA5, 0xFA7, 4);
builder.AddButton(20, 275, 0xFA5, 0xFA7, 4);
}
AddHtmlLocalized(55, 277, 25, 35, 1011005); // nay:
AddLabel(78, 277, 0x0, $"[{noCount}]");
builder.AddHtmlLocalized(55, 277, 25, 35, 1011005); // nay:
builder.AddLabel(78, 277, 0x0, $"[{noCount}]");
if (totalVotes > 0)
{
AddImageTiled(130, 242, yesCount * 225 / totalVotes, 10, 0xD6);
AddImageTiled(130, 277, noCount * 225 / totalVotes, 10, 0xD6);
builder.AddImageTiled(130, 242, yesCount * 225 / totalVotes, 10, 0xD6);
builder.AddImageTiled(130, 277, noCount * 225 / totalVotes, 10, 0xD6);
}
AddButton(45, 305, 0xFA5, 0xFA7, 0);
AddHtmlLocalized(80, 308, 40, 35, 1011008); // done
builder.AddButton(45, 305, 0xFA5, 0xFA7, 0);
builder.AddHtmlLocalized(80, 308, 40, 35, 1011008); // done
if (isOwner)
if (_isOwner)
{
AddButton(120, 305, 0xFA5, 0xFA7, 1);
AddHtmlLocalized(155, 308, 100, 35, 1011006); // change topic
builder.AddButton(120, 305, 0xFA5, 0xFA7, 1);
builder.AddHtmlLocalized(155, 308, 100, 35, 1011006); // change topic
AddButton(240, 305, 0xFA5, 0xFA7, 2);
AddHtmlLocalized(275, 308, 300, 100, 1011007); // reset votes
builder.AddButton(240, 305, 0xFA5, 0xFA7, 2);
builder.AddHtmlLocalized(275, 308, 300, 100, 1011007); // reset votes
}
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (m_Box.Deleted || info.ButtonID == 0)
if (_box.Deleted || info.ButtonID == 0)
{
return;
}
var from = sender.Mobile;
if (from.Map != m_Box.Map || !from.InRange(m_Box.GetWorldLocation(), 2))
if (from.Map != _box.Map || !from.InRange(_box.GetWorldLocation(), 2))
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
return;
}
var isOwner = m_Box.IsOwner(from);
var isOwner = _box.IsOwner(from);
switch (info.ButtonID)
{
@ -186,15 +203,15 @@ namespace Server.Items
{
if (isOwner)
{
m_Box.ClearTopic();
m_Box.ClearVotes();
_box.ClearTopic();
_box.ClearVotes();
from.SendLocalizedMessage(
500370,
"",
0x35
); // Enter a line of text for your ballot, and hit ENTER. Hit ESC after the last line is entered.
from.Prompt = new TopicPrompt(m_Box);
from.Prompt = new TopicPrompt(_box);
}
break;
@ -203,7 +220,7 @@ namespace Server.Items
{
if (isOwner)
{
m_Box.ClearVotes();
_box.ClearVotes();
from.SendLocalizedMessage(500371); // Votes zeroed out.
}
@ -213,13 +230,13 @@ namespace Server.Items
{
if (!isOwner)
{
if (m_Box.HasVoted(from))
if (_box.HasVoted(from))
{
from.SendLocalizedMessage(500374); // You have already voted on this ballot.
}
else
{
m_Box.AddToYes(from);
_box.AddToYes(from);
from.SendLocalizedMessage(500373); // Your vote has been registered.
}
}
@ -230,13 +247,13 @@ namespace Server.Items
{
if (!isOwner)
{
if (m_Box.HasVoted(from))
if (_box.HasVoted(from))
{
from.SendLocalizedMessage(500374); // You have already voted on this ballot.
}
else
{
m_Box.AddToNo(from);
_box.AddToNo(from);
from.SendLocalizedMessage(500373); // Your vote has been registered.
}
}
@ -245,7 +262,7 @@ namespace Server.Items
}
default:
{
from.SendGump(new InternalGump(m_Box, isOwner));
DisplayTo(from, _box, isOwner);
break;
}
}
@ -254,52 +271,52 @@ namespace Server.Items
private class TopicPrompt : Prompt
{
private readonly BallotBox m_Box;
private readonly BallotBox _box;
public TopicPrompt(BallotBox box) => m_Box = box;
public TopicPrompt(BallotBox box) => _box = box;
public override void OnResponse(Mobile from, string text)
{
if (m_Box.Deleted || !m_Box.IsOwner(from))
if (_box.Deleted || !_box.IsOwner(from))
{
return;
}
if (from.Map != m_Box.Map || !from.InRange(m_Box.GetWorldLocation(), 2))
if (from.Map != _box.Map || !from.InRange(_box.GetWorldLocation(), 2))
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
return;
}
m_Box.AddLineToTopic(text.TrimEnd());
_box.AddLineToTopic(text.TrimEnd());
if (m_Box.Topic.Length < MaxTopicLines)
if (_box.Topic.Length < MaxTopicLines)
{
from.SendLocalizedMessage(500377, "", 0x35); // Next line or ESC to finish:
from.Prompt = new TopicPrompt(m_Box);
from.Prompt = new TopicPrompt(_box);
}
else
{
from.SendLocalizedMessage(500376, "", 0x35); // Ballot entry complete.
from.SendGump(new InternalGump(m_Box, true));
BallotBoxGump.DisplayTo(from, _box, true);
}
}
public override void OnCancel(Mobile from)
{
if (m_Box.Deleted || !m_Box.IsOwner(from))
if (_box.Deleted || !_box.IsOwner(from))
{
return;
}
if (from.Map != m_Box.Map || !from.InRange(m_Box.GetWorldLocation(), 2))
if (from.Map != _box.Map || !from.InRange(_box.GetWorldLocation(), 2))
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
return;
}
from.SendLocalizedMessage(500376, "", 0x35); // Ballot entry complete.
from.SendGump(new InternalGump(m_Box, true));
BallotBoxGump.DisplayTo(from, _box, true);
}
}
}

View file

@ -167,9 +167,8 @@ namespace Server.Items
}
public virtual bool HasAccess(Mobile from) =>
from?.Deleted == false && (
from.AccessLevel >= AccessLevel.GameMaster ||
BaseHouse.FindHouseAt(this)?.IsCoOwner(from) == true);
from?.Deleted == false && (from.AccessLevel >= AccessLevel.GameMaster ||
BaseHouse.FindHouseAt(this)?.IsCoOwner(from) == true);
public override bool OnDragDrop(Mobile from, Item dropped)
{
@ -876,7 +875,7 @@ namespace Server.Items
return;
}
from.SendGump(new AquariumGump(this, HasAccess(from)), true);
AquariumGump.DisplayTo(from, this);
from.PlaySound(0x5A4);
}
@ -1128,7 +1127,7 @@ namespace Server.Items
return;
}
from.SendGump(new AquariumGump(aquarium, true));
AquariumGump.DisplayTo(from, aquarium);
}
}

View file

@ -1,105 +1,111 @@
using Server.Gumps;
using Server.Network;
namespace Server.Items
namespace Server.Items;
public class AquariumGump : DynamicGump
{
public class AquariumGump : Gump
private readonly Aquarium _aquarium;
private readonly bool _edit;
public override bool Singleton => true;
private AquariumGump(Aquarium aquarium, bool edit) : base(100, 100)
{
private readonly Aquarium m_Aquarium;
_aquarium = aquarium;
_edit = edit;
}
public AquariumGump(Aquarium aquarium, bool edit) : base(100, 100)
public static void DisplayTo(Mobile from, Aquarium aquarium)
{
if (from?.NetState == null || aquarium?.Deleted != false)
{
m_Aquarium = aquarium;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(0, 0, 350, 323, 0xE10);
AddImage(0, 0, 0x2C96);
if (m_Aquarium.Items.Count == 0)
{
return;
}
for (var i = 1; i <= m_Aquarium.Items.Count; i++)
{
DisplayPage(i, edit);
}
return;
}
public void DisplayPage(int page, bool edit)
from.SendGump(new AquariumGump(aquarium, aquarium.HasAccess(from)));
}
protected override void BuildLayout(ref DynamicGumpBuilder builder)
{
builder.AddPage();
builder.AddBackground(0, 0, 350, 323, 0xE10);
builder.AddImage(0, 0, 0x2C96);
for (var i = 1; i <= _aquarium.Items.Count; i++)
{
AddPage(page);
DisplayPage(ref builder, i, _edit);
}
}
var item = m_Aquarium.Items[page - 1];
private void DisplayPage(ref DynamicGumpBuilder builder, int page, bool edit)
{
builder.AddPage(page);
// item name
if (item.LabelNumber != 0)
{
AddHtmlLocalized(20, 217, 250, 20, item.LabelNumber, 0x7FFF); // Name
}
var item = _aquarium.Items[page - 1];
// item details
if (item is BaseFish fish)
{
AddHtmlLocalized(20, 239, 315, 20, fish.GetDescription(), 0x7FFF);
}
else
{
AddHtmlLocalized(20, 239, 315, 20, 1073634, 0x7FFF); // An aquarium decoration
}
// item image
AddItem(150, 80, item.ItemID, item.Hue);
// item number / all items
AddHtml(20, 195, 250, 20, Html.Color($"{page}/{m_Aquarium.Items.Count}", 0xFFFFFF));
// remove item
if (edit)
{
AddBackground(230, 195, 100, 26, 0x13BE);
AddButton(235, 200, 0x845, 0x846, page);
AddHtmlLocalized(260, 198, 60, 26, 1073838, 0x0); // Remove
}
// next page
if (page < m_Aquarium.Items.Count)
{
AddButton(195, 280, 0xFA5, 0xFA7, 0, GumpButtonType.Page, page + 1);
AddHtmlLocalized(230, 283, 100, 18, 1044045, 0x7FFF); // NEXT PAGE
}
// previous page
if (page > 1)
{
AddButton(45, 280, 0xFAE, 0xFAF, 0, GumpButtonType.Page, page - 1);
AddHtmlLocalized(80, 283, 100, 18, 1044044, 0x7FFF); // PREV PAGE
}
// item name
if (item.LabelNumber != 0)
{
builder.AddHtmlLocalized(20, 217, 250, 20, item.LabelNumber, 0x7FFF); // Name
}
public override void OnResponse(NetState sender, in RelayInfo info)
// item details
if (item is BaseFish fish)
{
if (m_Aquarium?.Deleted != false)
{
return;
}
builder.AddHtmlLocalized(20, 239, 315, 20, fish.GetDescription(), 0x7FFF);
}
else
{
builder.AddHtmlLocalized(20, 239, 315, 20, 1073634, 0x7FFF); // An aquarium decoration
}
var edit = m_Aquarium.HasAccess(sender.Mobile);
// item image
builder.AddItem(150, 80, item.ItemID, item.Hue);
if (info.ButtonID > 0 && info.ButtonID <= m_Aquarium.Items.Count && edit)
{
m_Aquarium.RemoveItem(sender.Mobile, info.ButtonID - 1);
}
// item number / all items
builder.AddHtml(20, 195, 250, 20, Html.Color($"{page}/{_aquarium.Items.Count}", 0xFFFFFF));
if (info.ButtonID > 0)
{
sender.Mobile.SendGump(new AquariumGump(m_Aquarium, edit));
}
// remove item
if (edit)
{
builder.AddBackground(230, 195, 100, 26, 0x13BE);
builder.AddButton(235, 200, 0x845, 0x846, page);
builder.AddHtmlLocalized(260, 198, 60, 26, 1073838, 0x0); // Remove
}
// next page
if (page < _aquarium.Items.Count)
{
builder.AddButton(195, 280, 0xFA5, 0xFA7, 0, GumpButtonType.Page, page + 1);
builder.AddHtmlLocalized(230, 283, 100, 18, 1044045, 0x7FFF); // NEXT PAGE
}
// previous page
if (page > 1)
{
builder.AddButton(45, 280, 0xFAE, 0xFAF, 0, GumpButtonType.Page, page - 1);
builder.AddHtmlLocalized(80, 283, 100, 18, 1044044, 0x7FFF); // PREV PAGE
}
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (_aquarium?.Deleted != false)
{
return;
}
var edit = _aquarium.HasAccess(sender.Mobile);
if (info.ButtonID > 0 && info.ButtonID <= _aquarium.Items.Count && edit)
{
_aquarium.RemoveItem(sender.Mobile, info.ButtonID - 1);
}
if (info.ButtonID > 0)
{
sender.Mobile.SendGump(this);
}
}
}

View file

@ -36,7 +36,7 @@ public partial class TapestryOfSosaria : Item, ISecurable
{
if (from.InRange(GetWorldLocation(), 2))
{
from.SendGump(new InternalGump());
TapestryOfSosariaGump.DisplayTo(from);
}
else
{
@ -49,13 +49,28 @@ public partial class TapestryOfSosaria : Item, ISecurable
Level = (SecureLevel)reader.ReadEncodedInt();
}
private class InternalGump : Gump
private class TapestryOfSosariaGump : StaticGump<TapestryOfSosariaGump>
{
public override bool Singleton => true;
public InternalGump() : base(50, 50)
private TapestryOfSosariaGump() : base(50, 50)
{
AddImage(0, 0, 0x2C95);
}
public static void DisplayTo(Mobile from)
{
if (from?.NetState == null)
{
return;
}
from.SendGump(new TapestryOfSosariaGump());
}
protected override void BuildLayout(ref StaticGumpBuilder builder)
{
builder.AddPage();
builder.AddImage(0, 0, 0x2C95);
}
}
}

View file

@ -33,7 +33,7 @@ public partial class PottedPlantDeed : Item
{
if (IsChildOf(from.Backpack))
{
from.SendGump(new InternalGump(this));
HolidayPottedPlantGump.DisplayTo(from, this);
}
else
{
@ -41,41 +41,49 @@ public partial class PottedPlantDeed : Item
}
}
private class InternalGump : Gump
private class HolidayPottedPlantGump : StaticGump<HolidayPottedPlantGump>
{
private readonly PottedPlantDeed _deed;
public override bool Singleton => true;
public InternalGump(PottedPlantDeed deed) : base(100, 200)
private HolidayPottedPlantGump(PottedPlantDeed deed) : base(100, 200)
{
_deed = deed;
}
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
public static void DisplayTo(Mobile from, PottedPlantDeed deed)
{
if (from?.NetState == null || deed?.Deleted != false)
{
return;
}
AddPage(0);
AddBackground(0, 0, 360, 195, 0xA28);
from.SendGump(new HolidayPottedPlantGump(deed));
}
AddPage(1);
AddLabel(45, 15, 0, "Choose a Potted Plant:");
protected override void BuildLayout(ref StaticGumpBuilder builder)
{
builder.AddPage();
builder.AddBackground(0, 0, 360, 195, 0xA28);
AddItem(45, 75, 0x11C8);
AddButton(55, 50, 0x845, 0x846, 1);
builder.AddPage(1);
builder.AddLabel(45, 15, 0, "Choose a Potted Plant:");
AddItem(100, 75, 0x11C9);
AddButton(115, 50, 0x845, 0x846, 2);
builder.AddItem(45, 75, 0x11C8);
builder.AddButton(55, 50, 0x845, 0x846, 1);
AddItem(160, 75, 0x11CA);
AddButton(175, 50, 0x845, 0x846, 3);
builder.AddItem(100, 75, 0x11C9);
builder.AddButton(115, 50, 0x845, 0x846, 2);
AddItem(225, 75, 0x11CB);
AddButton(235, 50, 0x845, 0x846, 4);
builder.AddItem(160, 75, 0x11CA);
builder.AddButton(175, 50, 0x845, 0x846, 3);
AddItem(280, 75, 0x11CC);
AddButton(295, 50, 0x845, 0x846, 5);
builder.AddItem(225, 75, 0x11CB);
builder.AddButton(235, 50, 0x845, 0x846, 4);
builder.AddItem(280, 75, 0x11CC);
builder.AddButton(295, 50, 0x845, 0x846, 5);
}
public override void OnResponse(NetState sender, in RelayInfo info)

View file

@ -65,7 +65,7 @@ public partial class SnowStatueDeed : Item
{
if (IsChildOf(from.Backpack))
{
from.SendGump(new InternalGump(from, this));
SnowStatueGump.DisplayTo(from, this);
}
else
{
@ -73,38 +73,46 @@ public partial class SnowStatueDeed : Item
}
}
private class InternalGump : Gump
private class SnowStatueGump : StaticGump<SnowStatueGump>
{
private readonly SnowStatueDeed _deed;
public override bool Singleton => true;
public InternalGump(Mobile from, SnowStatueDeed deed) : base(100, 200)
private SnowStatueGump(SnowStatueDeed deed) : base(100, 200)
{
_deed = deed;
}
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
public static void DisplayTo(Mobile from, SnowStatueDeed deed)
{
if (from?.NetState == null || deed?.Deleted != false)
{
return;
}
AddPage(0);
AddBackground(0, 0, 360, 225, 0xA28);
from.SendGump(new SnowStatueGump(deed));
}
AddPage(1);
AddHtmlLocalized(45, 15, 200, 20, 1156487); // Select One:
protected override void BuildLayout(ref StaticGumpBuilder builder)
{
builder.AddPage();
builder.AddBackground(0, 0, 360, 225, 0xA28);
AddItem(35, 75, 0x456E);
AddButton(65, 50, 0x845, 0x846, 1);
builder.AddPage(1);
builder.AddHtmlLocalized(45, 15, 200, 20, 1156487); // Select One:
AddItem(120, 75, 0x4578);
AddButton(135, 50, 0x845, 0x846, 2);
builder.AddItem(35, 75, 0x456E);
builder.AddButton(65, 50, 0x845, 0x846, 1);
AddItem(190, 75, 0x457A);
AddButton(205, 50, 0x845, 0x846, 3);
builder.AddItem(120, 75, 0x4578);
builder.AddButton(135, 50, 0x845, 0x846, 2);
AddItem(250, 75, 0x457C);
AddButton(275, 50, 0x845, 0x846, 4);
builder.AddItem(190, 75, 0x457A);
builder.AddButton(205, 50, 0x845, 0x846, 3);
builder.AddItem(250, 75, 0x457C);
builder.AddButton(275, 50, 0x845, 0x846, 4);
}
public override void OnResponse(NetState sender, in RelayInfo info)

View file

@ -56,7 +56,6 @@ public partial class WreathAddon : Item, IDyable, IAddon
}
from.SendLocalizedMessage(500295); // You are too far away to do that.
return false;
}
return false;
@ -99,7 +98,7 @@ public partial class WreathAddon : Item, IDyable, IAddon
if (from.InRange(GetWorldLocation(), 3))
{
from.SendGump(new WreathAddonGump(from, this));
WreathAddonGump.DisplayTo(from, this);
}
else
{
@ -107,47 +106,54 @@ public partial class WreathAddon : Item, IDyable, IAddon
}
}
private class WreathAddonGump : Gump
private class WreathAddonGump : StaticGump<WreathAddonGump>
{
private readonly WreathAddon _addon;
private readonly Mobile _from;
public override bool Singleton => true;
public WreathAddonGump(Mobile from, WreathAddon addon) : base(150, 50)
private WreathAddonGump(WreathAddon addon) : base(150, 50) => _addon = addon;
public static void DisplayTo(Mobile from, WreathAddon addon)
{
_from = from;
_addon = addon;
AddPage(0);
AddBackground(0, 0, 220, 170, 0x13BE);
AddBackground(10, 10, 200, 150, 0xBB8);
AddHtmlLocalized(20, 30, 180, 60, 1062839); // Do you wish to re-deed this decoration?
AddHtmlLocalized(55, 100, 160, 25, 1011011); // CONTINUE
AddButton(20, 100, 0xFA5, 0xFA7, 1);
AddHtmlLocalized(55, 125, 160, 25, 1011012); // CANCEL
AddButton(20, 125, 0xFA5, 0xFA7, 0);
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (_addon.Deleted)
if (from?.NetState == null || addon?.Deleted != false)
{
return;
}
if (info.ButtonID == 1)
from.SendGump(new WreathAddonGump(addon));
}
protected override void BuildLayout(ref StaticGumpBuilder builder)
{
builder.AddPage();
builder.AddBackground(0, 0, 220, 170, 0x13BE);
builder.AddBackground(10, 10, 200, 150, 0xBB8);
builder.AddHtmlLocalized(20, 30, 180, 60, 1062839); // Do you wish to re-deed this decoration?
builder.AddHtmlLocalized(55, 100, 160, 25, 1011011); // CONTINUE
builder.AddButton(20, 100, 0xFA5, 0xFA7, 1);
builder.AddHtmlLocalized(55, 125, 160, 25, 1011012); // CANCEL
builder.AddButton(20, 125, 0xFA5, 0xFA7, 0);
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (_addon.Deleted || info.ButtonID != 1)
{
if (_from.InRange(_addon.GetWorldLocation(), 3))
{
_from.AddToBackpack(_addon.Deed);
_addon.Delete();
}
else
{
_from.SendLocalizedMessage(500295); // You are too far away to do that.
}
return;
}
var from = sender.Mobile;
if (from.InRange(_addon.GetWorldLocation(), 3))
{
from.AddToBackpack(_addon.Deed);
_addon.Delete();
}
else
{
from.SendLocalizedMessage(500295); // You are too far away to do that.
}
}
}

View file

@ -84,7 +84,7 @@ public partial class HouseRaffleDeed : Item
if (IsChildOf(from.Backpack))
{
from.SendGump(new WritOfLeaseGump(this));
WritOfLeaseGump.DisplayTo(from, this);
}
else
{
@ -92,32 +92,49 @@ public partial class HouseRaffleDeed : Item
}
}
private class WritOfLeaseGump : Gump
private class WritOfLeaseGump : DynamicGump
{
private readonly HouseRaffleDeed _deed;
public override bool Singleton => true;
public WritOfLeaseGump(HouseRaffleDeed deed) : base(150, 50)
private WritOfLeaseGump(HouseRaffleDeed deed) : base(150, 50)
{
AddPage(0);
_deed = deed;
}
AddImage(0, 0, 9380);
AddImage(114, 0, 9381);
AddImage(171, 0, 9382);
AddImage(0, 140, 9383);
AddImage(114, 140, 9384);
AddImage(171, 140, 9385);
AddImage(0, 182, 9383);
AddImage(114, 182, 9384);
AddImage(171, 182, 9385);
AddImage(0, 224, 9383);
AddImage(114, 224, 9384);
AddImage(171, 224, 9385);
AddImage(0, 266, 9386);
AddImage(114, 266, 9387);
AddImage(171, 266, 9388);
public static void DisplayTo(Mobile from, HouseRaffleDeed deed)
{
if (from?.NetState == null || deed?.Deleted != false)
{
return;
}
AddHtmlLocalized(30, 48, 229, 20, 1150484, 200); // WRIT OF LEASE
AddHtml(28, 75, 231, 280, FormatDescription(deed), false, true);
from.SendGump(new WritOfLeaseGump(deed));
}
protected override void BuildLayout(ref DynamicGumpBuilder builder)
{
builder.AddPage();
builder.AddImage(0, 0, 9380);
builder.AddImage(114, 0, 9381);
builder.AddImage(171, 0, 9382);
builder.AddImage(0, 140, 9383);
builder.AddImage(114, 140, 9384);
builder.AddImage(171, 140, 9385);
builder.AddImage(0, 182, 9383);
builder.AddImage(114, 182, 9384);
builder.AddImage(171, 182, 9385);
builder.AddImage(0, 224, 9383);
builder.AddImage(114, 224, 9384);
builder.AddImage(171, 224, 9385);
builder.AddImage(0, 266, 9386);
builder.AddImage(114, 266, 9387);
builder.AddImage(171, 266, 9388);
builder.AddHtmlLocalized(30, 48, 229, 20, 1150484, 200); // WRIT OF LEASE
builder.AddHtml(28, 75, 231, 280, FormatDescription(_deed), background: false, scrollbar: true);
}
private static string FormatDescription(HouseRaffleDeed deed)

View file

@ -73,52 +73,60 @@ public abstract partial class SpecialScroll : Item
return;
}
from.SendGump(new InternalGump(from, this));
SpecialScrollGump.DisplayTo(from, this);
}
public class InternalGump : Gump
public class SpecialScrollGump : DynamicGump
{
private readonly Mobile _mobile;
private readonly SpecialScroll _scroll;
public override bool Singleton => true;
public InternalGump(Mobile mobile, SpecialScroll scroll) : base(25, 50)
private SpecialScrollGump(SpecialScroll scroll) : base(25, 50) => _scroll = scroll;
public static void DisplayTo(Mobile from, SpecialScroll scroll)
{
_mobile = mobile;
_scroll = scroll;
if (from?.NetState == null || scroll?.Deleted != false)
{
return;
}
AddPage(0);
from.SendGump(new SpecialScrollGump(scroll));
}
AddBackground(25, 10, 420, 200, 5054);
protected override void BuildLayout(ref DynamicGumpBuilder builder)
{
builder.AddPage();
AddImageTiled(33, 20, 401, 181, 2624);
AddAlphaRegion(33, 20, 401, 181);
builder.AddBackground(25, 10, 420, 200, 5054);
AddHtmlLocalized(40, 48, 387, 100, _scroll.Message, true, true);
builder.AddImageTiled(33, 20, 401, 181, 2624);
builder.AddAlphaRegion(33, 20, 401, 181);
AddHtmlLocalized(125, 148, 200, 20, 1049478, 0x7FFF); // Do you wish to use this scroll?
builder.AddHtmlLocalized(40, 48, 387, 100, _scroll.Message, true, true);
AddButton(100, 172, 4005, 4007, 1);
AddHtmlLocalized(135, 172, 120, 20, 1046362, 0x7FFF); // Yes
builder.AddHtmlLocalized(125, 148, 200, 20, 1049478, 0x7FFF); // Do you wish to use this scroll?
AddButton(275, 172, 4005, 4007, 0);
AddHtmlLocalized(310, 172, 120, 20, 1046363, 0x7FFF); // No
builder.AddButton(100, 172, 4005, 4007, 1);
builder.AddHtmlLocalized(135, 172, 120, 20, 1046362, 0x7FFF); // Yes
builder.AddButton(275, 172, 4005, 4007, 0);
builder.AddHtmlLocalized(310, 172, 120, 20, 1046363, 0x7FFF); // No
if (_scroll.Title != 0)
{
AddHtmlLocalized(40, 20, 260, 20, _scroll.Title, 0x7FFF);
builder.AddHtmlLocalized(40, 20, 260, 20, _scroll.Title, 0x7FFF);
}
else
{
AddHtml(40, 20, 260, 20, _scroll.DefaultTitle);
builder.AddHtml(40, 20, 260, 20, _scroll.DefaultTitle);
}
var skillLabel = _scroll.SkillLabel;
if (skillLabel > 0)
{
AddHtmlLocalized(310, 20, 120, 20, skillLabel, 0x7FFF);
builder.AddHtmlLocalized(310, 20, 120, 20, skillLabel, 0x7FFF);
}
}
@ -126,7 +134,7 @@ public abstract partial class SpecialScroll : Item
{
if (info.ButtonID == 1)
{
_scroll.Use(_mobile);
_scroll.Use(state.Mobile);
}
}
}