perf: Migrate Bulletin/Poll/SOS gumps to DynamicGump (#2418)

## Summary

Migrates three legacy `Gump`-based dialogs to the modern builder API:

- **PlayerBBGump** (`Projects/UOContent/Items/Misc/PlayerBulletinBoards.cs`) — `DynamicGump`. The bulletin board renders a different post per page (variable per-instance state), so the layout cannot be cached. Now `Singleton`, with a private constructor and a static `DisplayTo` entry point. Scroll/banish/delete/post-props buttons mutate `_page` and self-refresh via `SendGump(this)` instead of allocating a fresh gump on every click. Prompt-driven flows (post message / set title / post greeting) re-enter through `DisplayTo` after the prompt completes.
- **MessageGump** + **OldMessageGump** (`Projects/UOContent/Items/Skill Items/Fishing/Misc/SOS.cs`) — `StaticGump<T>`. Both render a fixed structure (background + body + button) where only the formatted sextant coordinate string varies per SOS bottle. The cliloc IDs that *appear in the gump packet* are constant (`MessageGump` uses 1018326; `OldMessageGump` uses no `AddHtmlLocalized` at all — its message is pre-formatted into a string before construction), so the layout cache is safe per the cliloc rule. The varying coordinate text is fed through an HTML placeholder via `BuildStrings`. Both gumps are now `Singleton` with private constructors and static `DisplayTo` entry points.
- **ShardPollGump** (`Projects/UOContent/Misc/ShardPoller.cs`) — `DynamicGump`. The gump's structure changes both with the number of poll options (variable loop) and with the `editing` flag (admin sees radios + add-option row + result percentages; players see only radios). The dual-purpose view is preserved as a single `DynamicGump` with the `editing` flag still controlling layout shape — staff path verified to still render the editor with the totals header, vote percentages, and "Create new option" radio. `Closable = false` becomes `builder.SetNoClose()`. Now `Singleton`, with private constructor and a `DisplayTo` that returns the gump instance so `EventSink_Login_Callback` can still call `QueuePoll` on it. The cancel/edit re-issue paths use `SendGump(this)` for self-refresh; the queued login flow uses `DisplayTo` so each queued poll gets its own gump.

External callers (`OnDoubleClick`, `PostPrompt`, `SetTitlePrompt`, `ShardPollPrompt`, `EventSink_Login_Callback`, the Timer-delayed queued poll send) all updated to use the new `DisplayTo` entry points. Legacy `m_X` field naming was already absent in two of the three files; the bulletin board fields kept their `_camelCase` names. `dotnet build Projects/UOContent/UOContent.csproj` reports 0 warnings, 0 errors.
This commit is contained in:
Kamron Batman 2026-04-25 20:49:12 -07:00 committed by GitHub
parent 4e565ca6da
commit 802849bebc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 203 additions and 123 deletions

View file

@ -114,7 +114,7 @@ public abstract partial class BasePlayerBB : Item, ISecurable
} }
else if (CheckAccess(house, from)) else if (CheckAccess(house, from))
{ {
from.SendGump(new PlayerBBGump(from, house, this, 0)); PlayerBBGump.DisplayTo(from, house, this, 0);
} }
} }
@ -198,7 +198,7 @@ public abstract partial class BasePlayerBB : Item, ISecurable
} }
} }
from.SendGump(new PlayerBBGump(from, house, board, page)); PlayerBBGump.DisplayTo(from, house, board, page);
} }
} }
@ -256,7 +256,7 @@ public abstract partial class BasePlayerBB : Item, ISecurable
board.Title = text; board.Title = text;
} }
from.SendGump(new PlayerBBGump(from, house, board, page)); PlayerBBGump.DisplayTo(from, house, board, page);
} }
} }
} }
@ -289,97 +289,110 @@ public partial class PlayerBBMessage
} }
} }
public class PlayerBBGump : Gump public class PlayerBBGump : DynamicGump
{ {
private const int LabelColor = 0x7FFF; private const int LabelColor = 0x7FFF;
private const int LabelHue = 1153; private const int LabelHue = 1153;
private BasePlayerBB _board; private readonly BasePlayerBB _board;
private Mobile _from; private readonly Mobile _from;
private BaseHouse _house; private readonly BaseHouse _house;
private int _page; private int _page;
public override bool Singleton => true; public override bool Singleton => true;
public PlayerBBGump(Mobile from, BaseHouse house, BasePlayerBB board, int page) : base(50, 10) private PlayerBBGump(Mobile from, BaseHouse house, BasePlayerBB board, int page) : base(50, 10)
{ {
_page = page; _page = page;
_from = from; _from = from;
_house = house; _house = house;
_board = board; _board = board;
}
AddPage(0); public static void DisplayTo(Mobile from, BaseHouse house, BasePlayerBB board, int page)
{
AddImage(30, 30, 5400); if (from?.NetState == null || house == null || board == null || board.Deleted)
AddButton(393, 145, 2084, 2084, 4); // Scroll up
AddButton(390, 371, 2085, 2085, 5); // Scroll down
AddButton(32, 183, 5412, 5413, 1); // Post message
if (house.IsOwner(from))
{ {
AddButton(63, 90, 5601, 5605, 2); return;
AddHtmlLocalized(81, 89, 230, 20, 1062400, LabelColor); // Set title
AddButton(63, 109, 5601, 5605, 3);
AddHtmlLocalized(81, 108, 230, 20, 1062401, LabelColor); // Post greeting
} }
var title = board.Title; from.SendGump(new PlayerBBGump(from, house, board, page));
}
protected override void BuildLayout(ref DynamicGumpBuilder builder)
{
var page = _page;
builder.AddPage();
builder.AddImage(30, 30, 5400);
builder.AddButton(393, 145, 2084, 2084, 4); // Scroll up
builder.AddButton(390, 371, 2085, 2085, 5); // Scroll down
builder.AddButton(32, 183, 5412, 5413, 1); // Post message
if (_house.IsOwner(_from))
{
builder.AddButton(63, 90, 5601, 5605, 2);
builder.AddHtmlLocalized(81, 89, 230, 20, 1062400, LabelColor); // Set title
builder.AddButton(63, 109, 5601, 5605, 3);
builder.AddHtmlLocalized(81, 108, 230, 20, 1062401, LabelColor); // Post greeting
}
var title = _board.Title;
if (title != null) if (title != null)
{ {
AddHtml(183, 68, 180, 23, title); builder.AddHtml(183, 68, 180, 23, title);
} }
AddHtmlLocalized(385, 89, 60, 20, 1062409, LabelColor); // Post builder.AddHtmlLocalized(385, 89, 60, 20, 1062409, LabelColor); // Post
AddLabel(440, 89, LabelHue, page.ToString()); builder.AddLabel(440, 89, LabelHue, $"{page}");
AddLabel(455, 89, LabelHue, "/"); builder.AddLabel(455, 89, LabelHue, "/");
AddLabel(470, 89, LabelHue, board.Messages.Count.ToString()); builder.AddLabel(470, 89, LabelHue, $"{_board.Messages.Count}");
var message = board.Greeting; var message = _board.Greeting;
if (page >= 1 && page <= board.Messages.Count) if (page >= 1 && page <= _board.Messages.Count)
{ {
message = board.Messages[page - 1]; message = _board.Messages[page - 1];
} }
AddImageTiled(150, 220, 240, 1, 2700); // Separator builder.AddImageTiled(150, 220, 240, 1, 2700); // Separator
AddHtmlLocalized(150, 180, 100, 20, 1062405, 16715); // Posted On: builder.AddHtmlLocalized(150, 180, 100, 20, 1062405, 16715); // Posted On:
AddHtmlLocalized(150, 200, 100, 20, 1062406, 16715); // Posted By: builder.AddHtmlLocalized(150, 200, 100, 20, 1062406, 16715); // Posted By:
if (message != null) if (message != null)
{ {
AddHtml(255, 180, 150, 20, message.Time.ToString("yyyy-MM-dd HH:mm:ss")); builder.AddHtml(255, 180, 150, 20, $"{message.Time:yyyy-MM-dd HH:mm:ss}");
var poster = message.Poster; var poster = message.Poster;
var name = (poster?.Name?.Trim()).DefaultIfNullOrEmpty("Someone"); var posterName = poster?.Name ?? "Someone";
builder.AddHtml(255, 200, 150, 20, posterName.AsSpan().Trim());
AddHtml(255, 200, 150, 20, name); builder.AddHtml(150, 240, 250, 100, message.Message ?? "");
AddHtml(150, 240, 250, 100, message.Message ?? ""); if (message != _board.Greeting && _house.IsOwner(_from))
if (message != board.Greeting && house.IsOwner(from))
{ {
AddButton(130, 395, 1209, 1210, 6); builder.AddButton(130, 395, 1209, 1210, 6);
AddHtmlLocalized(150, 393, 150, 20, 1062410, LabelColor); // Banish Poster builder.AddHtmlLocalized(150, 393, 150, 20, 1062410, LabelColor); // Banish Poster
AddButton(310, 395, 1209, 1210, 7); builder.AddButton(310, 395, 1209, 1210, 7);
AddHtmlLocalized(330, 393, 150, 20, 1062411, LabelColor); // Delete Message builder.AddHtmlLocalized(330, 393, 150, 20, 1062411, LabelColor); // Delete Message
} }
if (from.AccessLevel >= AccessLevel.GameMaster) if (_from.AccessLevel >= AccessLevel.GameMaster)
{ {
AddButton(135, 242, 1209, 1210, 8); // Post props builder.AddButton(135, 242, 1209, 1210, 8); // Post props
} }
} }
} }
public override void OnResponse(NetState sender, in RelayInfo info) public override void OnResponse(NetState sender, in RelayInfo info)
{ {
var page = _page;
var from = _from; var from = _from;
var house = _house; var house = _house;
var board = _board; var board = _board;
@ -406,16 +419,15 @@ public class PlayerBBGump : Gump
{ {
case 1: // Post message case 1: // Post message
{ {
from.Prompt = new BasePlayerBB.PostPrompt(page, house, board, false); from.Prompt = new BasePlayerBB.PostPrompt(_page, house, board, false);
from.SendLocalizedMessage(1062397); // Please enter your message: from.SendLocalizedMessage(1062397); // Please enter your message:
break; break;
} }
case 2: // Set title case 2: // Set title
{ {
if (house.IsOwner(from)) if (house.IsOwner(from))
{ {
from.Prompt = new BasePlayerBB.SetTitlePrompt(page, house, board); from.Prompt = new BasePlayerBB.SetTitlePrompt(_page, house, board);
from.SendLocalizedMessage(1062402); // Enter new title: from.SendLocalizedMessage(1062402); // Enter new title:
} }
@ -425,7 +437,7 @@ public class PlayerBBGump : Gump
{ {
if (house.IsOwner(from)) if (house.IsOwner(from))
{ {
from.Prompt = new BasePlayerBB.PostPrompt(page, house, board, true); from.Prompt = new BasePlayerBB.PostPrompt(_page, house, board, true);
from.SendLocalizedMessage(1062404); // Enter new greeting (this will always be the first post): from.SendLocalizedMessage(1062404); // Enter new greeting (this will always be the first post):
} }
@ -433,40 +445,38 @@ public class PlayerBBGump : Gump
} }
case 4: // Scroll up case 4: // Scroll up
{ {
if (page == 0) if (_page == 0)
{ {
page = board.Messages.Count; _page = board.Messages.Count;
} }
else else
{ {
page -= 1; _page -= 1;
} }
from.SendGump(new PlayerBBGump(from, house, board, page)); from.SendGump(this);
break; break;
} }
case 5: // Scroll down case 5: // Scroll down
{ {
page += 1; _page += 1;
page %= board.Messages.Count + 1; _page %= board.Messages.Count + 1;
from.SendGump(new PlayerBBGump(from, house, board, page));
from.SendGump(this);
break; break;
} }
case 6: // Banish poster case 6: // Banish poster
{ {
if (house.IsOwner(from)) if (house.IsOwner(from))
{ {
if (page >= 1 && page <= board.Messages.Count) if (_page >= 1 && _page <= board.Messages.Count)
{ {
var message = board.Messages[page - 1]; var message = board.Messages[_page - 1];
var poster = message.Poster; var poster = message.Poster;
if (poster == null) if (poster == null)
{ {
from.SendGump(new PlayerBBGump(from, house, board, page)); from.SendGump(this);
return; return;
} }
@ -511,7 +521,7 @@ public class PlayerBBGump : Gump
} }
} }
from.SendGump(new PlayerBBGump(from, house, board, page)); from.SendGump(this);
} }
break; break;
@ -520,12 +530,13 @@ public class PlayerBBGump : Gump
{ {
if (house.IsOwner(from)) if (house.IsOwner(from))
{ {
if (page >= 1 && page <= board.Messages.Count) if (_page >= 1 && _page <= board.Messages.Count)
{ {
board.RemoveFromMessagesAt(page - 1); board.RemoveFromMessagesAt(_page - 1);
} }
from.SendGump(new PlayerBBGump(from, house, board, 0)); _page = 0;
from.SendGump(this);
} }
break; break;
@ -536,12 +547,12 @@ public class PlayerBBGump : Gump
{ {
var message = board.Greeting; var message = board.Greeting;
if (page >= 1 && page <= board.Messages.Count) if (_page >= 1 && _page <= board.Messages.Count)
{ {
message = board.Messages[page - 1]; message = board.Messages[_page - 1];
} }
from.SendGump(new PlayerBBGump(from, house, board, page)); from.SendGump(this);
from.SendGump(new PropertiesGump(from, message)); from.SendGump(new PropertiesGump(from, message));
} }

View file

@ -127,11 +127,11 @@ public partial class SOS : Item
if (UseNewMessages || entry == null) if (UseNewMessages || entry == null)
{ {
from.SendGump(new MessageGump(TargetMap, TargetLocation)); MessageGump.DisplayTo(from, TargetMap, TargetLocation);
} }
else else
{ {
from.SendGump(new OldMessageGump(entry, TargetMap, TargetLocation, from.Language)); OldMessageGump.DisplayTo(from, entry, TargetMap, TargetLocation, from.Language);
} }
} }
else else
@ -226,10 +226,24 @@ public partial class SOS : Item
return water; return water;
} }
private class MessageGump : Gump private class MessageGump : StaticGump<MessageGump>
{ {
public MessageGump(Map map, Point3D loc) : base(150, 50) private readonly string _fmt;
public override bool Singleton => true;
private MessageGump(string fmt) : base(150, 50)
{ {
_fmt = fmt;
}
public static void DisplayTo(Mobile from, Map map, Point3D loc)
{
if (from?.NetState == null)
{
return;
}
int xLong = 0, yLat = 0; int xLong = 0, yLat = 0;
int xMins = 0, yMins = 0; int xMins = 0, yMins = 0;
bool xEast = false, ySouth = false; bool xEast = false, ySouth = false;
@ -244,31 +258,55 @@ public partial class SOS : Item
fmt = "?????"; fmt = "?????";
} }
AddPage(0); from.SendGump(new MessageGump(fmt));
}
AddBackground(0, 40, 350, 300, 2520); protected override void BuildLayout(ref StaticGumpBuilder builder)
{
builder.AddPage();
builder.AddBackground(0, 40, 350, 300, 2520);
/* This is a message hastily scribbled by a passenger aboard a sinking ship. /* This is a message hastily scribbled by a passenger aboard a sinking ship.
* While it is probably too late to save the passengers and crew, * While it is probably too late to save the passengers and crew,
* perhaps some treasure went down with the ship! * perhaps some treasure went down with the ship!
* The message gives the ship's last known sextant co-ordinates. * The message gives the ship's last known sextant co-ordinates.
*/ */
AddHtmlLocalized(30, 80, 285, 160, 1018326, true, true); builder.AddHtmlLocalized(30, 80, 285, 160, 1018326, true, true);
AddHtml(35, 240, 230, 20, fmt); builder.AddHtmlPlaceholder(35, 240, 230, 20, "fmt");
AddButton(35, 265, 4005, 4007, 0); builder.AddButton(35, 265, 4005, 4007, 0);
AddHtmlLocalized(70, 265, 100, 20, 1011036); // OKAY builder.AddHtmlLocalized(70, 265, 100, 20, 1011036); // OKAY
}
protected override void BuildStrings(ref GumpStringsBuilder builder)
{
builder.SetStringSlot("fmt", _fmt);
} }
} }
private class OldMessageGump : Gump private class OldMessageGump : StaticGump<OldMessageGump>
{ {
private const int Width = 350; private const int Width = 350;
private const int Height = 300; private const int Height = 300;
public OldMessageGump(TextDefinition entry, Map map, Point3D loc, string lang) : base((640 - Width) / 2, (480 - Height) / 2) private readonly string _message;
public override bool Singleton => true;
private OldMessageGump(string message) : base((640 - Width) / 2, (480 - Height) / 2)
{ {
_message = message;
}
public static void DisplayTo(Mobile from, TextDefinition entry, Map map, Point3D loc, string lang)
{
if (from?.NetState == null || entry == null)
{
return;
}
int xLong = 0, yLat = 0; int xLong = 0, yLat = 0;
int xMins = 0, yMins = 0; int xMins = 0, yMins = 0;
bool xEast = false, ySouth = false; bool xEast = false, ySouth = false;
@ -283,12 +321,22 @@ public partial class SOS : Item
fmt = "?????"; fmt = "?????";
} }
AddPage(0);
AddBackground(0, 0, Width, Height, 2520);
// Gumps do not support non-ascii string arguments. Probably why this was not used on OSI // Gumps do not support non-ascii string arguments. Probably why this was not used on OSI
var message = entry.Number > 0 ? Localization.Format(entry.Number, lang, $"{fmt}") : string.Format(entry.String, fmt); var message = entry.Number > 0 ? Localization.Format(entry.Number, lang, $"{fmt}") : string.Format(entry.String, fmt);
AddHtml(38, 38, Width - 83, Height - 86, message);
from.SendGump(new OldMessageGump(message));
}
protected override void BuildLayout(ref StaticGumpBuilder builder)
{
builder.AddPage();
builder.AddBackground(0, 0, Width, Height, 2520);
builder.AddHtmlPlaceholder(38, 38, Width - 83, Height - 86, "message");
}
protected override void BuildStrings(ref GumpStringsBuilder builder)
{
builder.SetStringSlot("message", _message);
} }
} }
} }

View file

@ -167,8 +167,7 @@ public partial class ShardPoller : Item
if (spg == null) if (spg == null)
{ {
spg = new ShardPollGump(from, poller, false, null); spg = ShardPollGump.DisplayTo(from, poller, false, null);
from.SendGump(spg);
} }
else else
{ {
@ -186,7 +185,7 @@ public partial class ShardPoller : Item
{ {
if (from.AccessLevel >= AccessLevel.Administrator) if (from.AccessLevel >= AccessLevel.Administrator)
{ {
from.SendGump(new ShardPollGump(from, this, true, null)); ShardPollGump.DisplayTo(from, this, true, null);
} }
} }
@ -340,23 +339,51 @@ public partial class ShardPollOption
} }
} }
public class ShardPollGump : Gump public class ShardPollGump : DynamicGump
{ {
private const int LabelColor32 = 0xFFFFFF; private const int LabelColor32 = 0xFFFFFF;
private readonly Mobile _from; private readonly Mobile _from;
private readonly ShardPoller _poller; private readonly ShardPoller _poller;
private Queue<ShardPoller> _polls; private Queue<ShardPoller> _polls;
public ShardPollGump(Mobile from, ShardPoller poller, bool editing, Queue<ShardPoller> polls) : base(50, 50) public override bool Singleton => true;
private ShardPollGump(Mobile from, ShardPoller poller, bool editing, Queue<ShardPoller> polls) : base(50, 50)
{ {
_from = from; _from = from;
_poller = poller; _poller = poller;
Editing = editing; Editing = editing;
_polls = polls; _polls = polls;
}
Closable = false; public static ShardPollGump DisplayTo(Mobile from, ShardPoller poller, bool editing, Queue<ShardPoller> polls)
{
if (from?.NetState == null || poller == null || poller.Deleted)
{
return null;
}
AddPage(0); var gump = new ShardPollGump(from, poller, editing, polls);
from.SendGump(gump);
return gump;
}
public bool Editing { get; }
public void QueuePoll(ShardPoller poller)
{
_polls ??= new Queue<ShardPoller>(4);
_polls.Enqueue(poller);
}
protected override void BuildLayout(ref DynamicGumpBuilder builder)
{
var poller = _poller;
var editing = Editing;
builder.SetNoClose();
builder.AddPage();
var totalVotes = 0; var totalVotes = 0;
var totalOptionHeight = 0; var totalOptionHeight = 0;
@ -377,10 +404,10 @@ public class ShardPollGump : Gump
var height = 115 + totalOptionHeight; var height = 115 + totalOptionHeight;
AddBackground(1, 1, 398, height - 2, 3600); builder.AddBackground(1, 1, 398, height - 2, 3600);
AddAlphaRegion(16, 15, 369, height - 31); builder.AddAlphaRegion(16, 15, 369, height - 31);
AddItem(308, 30, 0x1E5E); builder.AddItem(308, 30, 0x1E5E);
string title; string title;
@ -393,18 +420,18 @@ public class ShardPollGump : Gump
title = "Shard Poll"; title = "Shard Poll";
} }
AddHtml(22, 22, 294, 20, title.Center(LabelColor32)); builder.AddHtml(22, 22, 294, 20, title.Center(LabelColor32));
if (editing) if (editing)
{ {
AddHtml(22, 22, 294, 20, Html.Color($"{totalVotes} total", LabelColor32)); builder.AddHtml(22, 22, 294, 20, Html.Color($"{totalVotes} total", LabelColor32));
AddButton(287, 23, 0x2622, 0x2623, 2); builder.AddButton(287, 23, 0x2622, 0x2623, 2);
} }
AddHtml(22, 50, 294, 40, poller.Title.Color(0x99CC66)); builder.AddHtml(22, 50, 294, 40, poller.Title.Color(0x99CC66));
AddImageTiled(32, 88, 264, 1, 9107); builder.AddImageTiled(32, 88, 264, 1, 9107);
AddImageTiled(42, 90, 264, 1, 9157); builder.AddImageTiled(42, 90, 264, 1, 9157);
var y = 100; var y = 100;
@ -426,16 +453,16 @@ public class ShardPollGump : Gump
if (isViewingResults) if (isViewingResults)
{ {
AddImage(24, y - 15, 0x25FE); builder.AddImage(24, y - 15, 0x25FE);
} }
else else
{ {
AddRadio(24, y - 15, 0x25F9, 0x25FC, false, 1 + i); builder.AddRadio(24, y - 15, 0x25F9, 0x25FC, false, 1 + i);
} }
var lineBreaks = option.GetBreaks(); var lineBreaks = option.GetBreaks();
AddHtml(60, y - 9 * lineBreaks, 250, 18 * lineBreaks, text.Color(LabelColor32)); builder.AddHtml(60, y - 9 * lineBreaks, 250, 18 * lineBreaks, text.Color(LabelColor32));
y += optHeight / 2; y += optHeight / 2;
y += 5; y += 5;
@ -443,20 +470,12 @@ public class ShardPollGump : Gump
if (editing && !isViewingResults) if (editing && !isViewingResults)
{ {
AddRadio(24, y + 15 - 15, 0x25F9, 0x25FC, false, 1 + poller.Options.Length); builder.AddRadio(24, y + 15 - 15, 0x25F9, 0x25FC, false, 1 + poller.Options.Length);
AddHtml(60, y + 15 - 9, 250, 18, "Create new option.".Color(0x99CC66)); builder.AddHtml(60, y + 15 - 9, 250, 18, "Create new option.".Color(0x99CC66));
} }
AddButton(314, height - 73, 247, 248, 1); builder.AddButton(314, height - 73, 247, 248, 1);
AddButton(314, height - 47, 242, 241, 0); builder.AddButton(314, height - 47, 242, 241, 0);
}
public bool Editing { get; }
public void QueuePoll(ShardPoller poller)
{
_polls ??= new Queue<ShardPoller>(4);
_polls.Enqueue(poller);
} }
public override void OnResponse(NetState sender, in RelayInfo info) public override void OnResponse(NetState sender, in RelayInfo info)
@ -467,9 +486,11 @@ public class ShardPollGump : Gump
if (shardPoller != null) if (shardPoller != null)
{ {
var from = _from;
var queuedPolls = _polls;
Timer.StartTimer( Timer.StartTimer(
TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0),
() => _from.SendGump(new ShardPollGump(_from, shardPoller, false, _polls)) () => DisplayTo(from, shardPoller, false, queuedPolls)
); );
} }
} }
@ -514,7 +535,7 @@ public class ShardPollGump : Gump
else else
{ {
_from.SendMessage("You may not edit an active poll. Deactivate it first."); _from.SendMessage("You may not edit an active poll. Deactivate it first.");
_from.SendGump(new ShardPollGump(_from, _poller, Editing, _polls)); _from.SendGump(this);
} }
} }
else else
@ -535,7 +556,7 @@ public class ShardPollGump : Gump
} }
else if (info.ButtonID == 2 && Editing) else if (info.ButtonID == 2 && Editing)
{ {
_from.SendGump(new ShardPollGump(_from, _poller, Editing, _polls)); _from.SendGump(this);
_from.SendGump(new PropertiesGump(_from, _poller)); _from.SendGump(new PropertiesGump(_from, _poller));
} }
} }
@ -554,7 +575,7 @@ public partial class ShardPollPrompt : Prompt
public override void OnCancel(Mobile from) public override void OnCancel(Mobile from)
{ {
from.SendGump(new ShardPollGump(from, _poller, true, null)); ShardPollGump.DisplayTo(from, _poller, true, null);
} }
private static string UrlRegex_Match(Match m) private static string UrlRegex_Match(Match m)
@ -603,7 +624,7 @@ public partial class ShardPollPrompt : Prompt
} }
} }
from.SendGump(new ShardPollGump(from, _poller, true, null)); ShardPollGump.DisplayTo(from, _poller, true, null);
} }
[GeneratedRegex(@"\[url(?:=(.*?))?\](.*?)\[/url\]", RegexOptions.IgnoreCase | RegexOptions.Compiled)] [GeneratedRegex(@"\[url(?:=(.*?))?\](.*?)\[/url\]", RegexOptions.IgnoreCase | RegexOptions.Compiled)]