perf: Migrate Quest gumps to DynamicGump (#2416)
## Summary Migrates the Quest system gumps from legacy `Gump` to `DynamicGump` / `StaticGump<T>`. **Renames** `Engines/ML Quests/Gumps/BaseQuestGump` to **`BaseMLQuestGump`** to disambiguate from the Core quest abstract (`Engines/Quests/Core/QuestSystem.cs`). Both abstracts now extend `DynamicGump`. **Abstract bases**: - `Server.Engines.Quests.BaseQuestGump` (Core) - now `abstract DynamicGump`. Holds constants and a static `AddHtmlObject(ref DynamicGumpBuilder, ...)` helper. Concrete subclasses each provide their own `BuildLayout`. - `Server.Engines.MLQuests.Gumps.BaseMLQuestGump` (ML, renamed) - now `abstract DynamicGump` with a `protected abstract BuildContent(ref DynamicGumpBuilder)` hook. The base's `BuildLayout` draws shared chrome (background art, frame, label header) and then invokes `BuildContent`; subclasses use `BuildPage`, `SetTitle`, `RegisterButton`, `SetPageCount`, and content helpers (`AddDescription`, `AddObjectives`, `AddObjectivesProgress`, `AddRewardsPage`, `AddRewards`, `AddConversation`). **Concrete Core gumps** migrated to `DynamicGump`: - `QuestCancelGump`, `QuestOfferGump` (Core), `QuestObjectivesGump`, `QuestConversationsGump`, `QuestLogUpdatedGump`, `QuestItemInfoGump`, `SheetMusicOfferGump` (Impresario), `PaintedImageGump` (renamed from `PaintedImage.InternalGump`). **Concrete ML gumps** migrated to `DynamicGump` (extending `BaseMLQuestGump` or directly): - `InfoNPCGump`, `QuestConversationGump`, `QuestLogDetailedGump`, `QuestLogGump`, `QuestOfferGump` (ML), `QuestReportBackGump`, `QuestRewardGump`, `QuestCancelConfirmGump`, `RaceChangeConfirmGump`. **`StaticGump<T>` migrations**: - `ScrollOfAbraxusGump` (Dark Tides). Its layout is a single hard-coded cliloc (1060116) with no per-instance dynamic content - safe to cache. **Cliloc rule**: Every other quest dialog bakes per-instance cliloc IDs into its layout (quest titles, NPC names, race-specific prompts, era-conditional progress messages, escort destinations). Per the cliloc rule, baking different cliloc numbers into a cached layout would defeat `StaticGump<T>` caching - so all of these are `DynamicGump`. **Signature changes** to support the migration: - `QuestObjective.RenderMessage`/`RenderProgress` now take `ref DynamicGumpBuilder builder` (15 overrides updated across Collector, Solen Matriarch, Ambitious Solen Queen, Study of the Solen Hive, Terrible Hatchlings, The Summoning, Uzeraan Turmoil, Witch Apprentice, Emino's Undertaking). - ML `BaseObjective.WriteToGump` / `BaseObjectiveInstance.WriteToGump` / `BaseReward.WriteToGump` now take `ref DynamicGumpBuilder` (KillObjective, GainSkillObjective, EscortObjective, CollectObjective, DeliverObjective, BaseReward). **Empty-gump and `Singleton` rules**: All concrete gumps now have private constructors with static `DisplayTo` entry points that null-check the player NetState before allocation. All gumps that shouldn't stack are `Singleton => true`. **External callers updated**: `MLQuest.SendOffer`/`OnRefuse`, `MLQuestEntry.SendProgressGump`/`SendRewardGump`/`SendReportBackGump`, `MLQuestSystem.QuestGumpRequest` and `ViewQuestsCommand`, `BoonCollector` (Darius/Nedrick), `SirHelper.OnDoubleClick` (no longer caches a single shared `InfoNPCGump` instance - `DisplayTo` constructs one per click and the gump's `Singleton => true` handles deduplication), `RaceChangeDeed.OnDoubleClick`, `PaintedImage.OnDoubleClick`, `ScrollOfAbraxus.OnDoubleClick`, `Impresario.OnTalk`, and `PlayerMobile`'s `BaseQuestGump` alias is now `BaseMLQuestGump`. **Concrete subclasses found beyond the listed entry points**: `SheetMusicOfferGump` (in Impresario.cs), `PaintedImageGump` (was `PaintedImage.InternalGump`), `QuestObjectivesGump`, `QuestConversationsGump`, `QuestLogUpdatedGump`, `QuestItemInfoGump` (the Core base has these embedded across `QuestSystem.cs`/`QuestObjective.cs`/`QuestConversation.cs`/`QuestItemInfo.cs`). **Code-standards cleanup**: Renamed legacy `m_X` private fields to `_x` in rewritten files; braces on all control flow.
This commit is contained in:
parent
ab5f615840
commit
b90ac0d481
39 changed files with 1023 additions and 706 deletions
|
|
@ -244,7 +244,7 @@ namespace Server.Engines.Quests
|
|||
|
||||
public virtual void SendOffer()
|
||||
{
|
||||
From.SendGump(new QuestOfferGump(this));
|
||||
QuestOfferGump.DisplayTo(From, this);
|
||||
}
|
||||
|
||||
public virtual void GetContextMenuEntries(ref PooledRefList<ContextMenuEntry> list)
|
||||
|
|
@ -264,7 +264,7 @@ namespace Server.Engines.Quests
|
|||
|
||||
public virtual void ShowQuestLogUpdated()
|
||||
{
|
||||
From.SendGump(new QuestLogUpdatedGump(this));
|
||||
QuestLogUpdatedGump.DisplayTo(From, this);
|
||||
}
|
||||
|
||||
public virtual void ShowQuestLog()
|
||||
|
|
@ -277,13 +277,13 @@ namespace Server.Engines.Quests
|
|||
gumps.Close<QuestConversationsGump>();
|
||||
gumps.Close<QuestObjectivesGump>();
|
||||
|
||||
gumps.Send(new QuestObjectivesGump(Objectives));
|
||||
QuestObjectivesGump.DisplayTo(From, Objectives);
|
||||
|
||||
var last = Objectives[^1];
|
||||
|
||||
if (last.Info != null)
|
||||
{
|
||||
gumps.Send(new QuestItemInfoGump(last.Info));
|
||||
QuestItemInfoGump.DisplayTo(From, last.Info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -298,20 +298,20 @@ namespace Server.Engines.Quests
|
|||
gumps.Close<QuestObjectivesGump>();
|
||||
gumps.Close<QuestConversationsGump>();
|
||||
|
||||
gumps.Send(new QuestConversationsGump(Conversations));
|
||||
QuestConversationsGump.DisplayTo(From, Conversations);
|
||||
|
||||
var last = Conversations[^1];
|
||||
|
||||
if (last.Info != null)
|
||||
{
|
||||
From.SendGump(new QuestItemInfoGump(last.Info));
|
||||
QuestItemInfoGump.DisplayTo(From, last.Info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void BeginCancelQuest()
|
||||
{
|
||||
From.SendGump(new QuestCancelGump(this));
|
||||
QuestCancelGump.DisplayTo(From, this);
|
||||
}
|
||||
|
||||
public virtual void EndCancelQuest(bool shouldCancel)
|
||||
|
|
@ -394,11 +394,19 @@ namespace Server.Engines.Quests
|
|||
var gumps = From.GetGumps();
|
||||
gumps.Close<QuestItemInfoGump>();
|
||||
gumps.Close<QuestObjectivesGump>();
|
||||
gumps.Send(conv.Logged ? new QuestConversationsGump(Conversations) : new QuestConversationsGump(conv));
|
||||
|
||||
if (conv.Logged)
|
||||
{
|
||||
QuestConversationsGump.DisplayTo(From, Conversations);
|
||||
}
|
||||
else
|
||||
{
|
||||
QuestConversationsGump.DisplayTo(From, conv);
|
||||
}
|
||||
|
||||
if (conv.Info != null)
|
||||
{
|
||||
From.SendGump(new QuestItemInfoGump(conv.Info));
|
||||
QuestItemInfoGump.DisplayTo(From, conv.Info);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -519,142 +527,166 @@ namespace Server.Engines.Quests
|
|||
|
||||
public class QuestCancelGump : BaseQuestGump
|
||||
{
|
||||
private readonly QuestSystem m_System;
|
||||
private readonly QuestSystem _system;
|
||||
|
||||
public QuestCancelGump(QuestSystem system) : base(120, 50)
|
||||
public override bool Singleton => true;
|
||||
|
||||
private QuestCancelGump(QuestSystem system) : base(120, 50) => _system = system;
|
||||
|
||||
public static void DisplayTo(Mobile from, QuestSystem system)
|
||||
{
|
||||
m_System = system;
|
||||
|
||||
Closable = false;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddImageTiled(0, 0, 348, 262, 2702);
|
||||
AddAlphaRegion(0, 0, 348, 262);
|
||||
|
||||
AddImage(0, 15, 10152);
|
||||
AddImageTiled(0, 30, 17, 200, 10151);
|
||||
AddImage(0, 230, 10154);
|
||||
|
||||
AddImage(15, 0, 10252);
|
||||
AddImageTiled(30, 0, 300, 17, 10250);
|
||||
AddImage(315, 0, 10254);
|
||||
|
||||
AddImage(15, 244, 10252);
|
||||
AddImageTiled(30, 244, 300, 17, 10250);
|
||||
AddImage(315, 244, 10254);
|
||||
|
||||
AddImage(330, 15, 10152);
|
||||
AddImageTiled(330, 30, 17, 200, 10151);
|
||||
AddImage(330, 230, 10154);
|
||||
|
||||
AddImage(333, 2, 10006);
|
||||
AddImage(333, 248, 10006);
|
||||
AddImage(2, 248, 10006);
|
||||
AddImage(2, 2, 10006);
|
||||
|
||||
AddHtmlLocalized(25, 22, 200, 20, 1049000, 32000); // Confirm Quest Cancellation
|
||||
AddImage(25, 40, 3007);
|
||||
|
||||
if (system.IsTutorial)
|
||||
if (from?.NetState == null || system == null)
|
||||
{
|
||||
AddHtmlLocalized(
|
||||
return;
|
||||
}
|
||||
|
||||
from.SendGump(new QuestCancelGump(system));
|
||||
}
|
||||
|
||||
protected override void BuildLayout(ref DynamicGumpBuilder builder)
|
||||
{
|
||||
builder.SetNoClose();
|
||||
|
||||
builder.AddPage();
|
||||
|
||||
builder.AddImageTiled(0, 0, 348, 262, 2702);
|
||||
builder.AddAlphaRegion(0, 0, 348, 262);
|
||||
|
||||
builder.AddImage(0, 15, 10152);
|
||||
builder.AddImageTiled(0, 30, 17, 200, 10151);
|
||||
builder.AddImage(0, 230, 10154);
|
||||
|
||||
builder.AddImage(15, 0, 10252);
|
||||
builder.AddImageTiled(30, 0, 300, 17, 10250);
|
||||
builder.AddImage(315, 0, 10254);
|
||||
|
||||
builder.AddImage(15, 244, 10252);
|
||||
builder.AddImageTiled(30, 244, 300, 17, 10250);
|
||||
builder.AddImage(315, 244, 10254);
|
||||
|
||||
builder.AddImage(330, 15, 10152);
|
||||
builder.AddImageTiled(330, 30, 17, 200, 10151);
|
||||
builder.AddImage(330, 230, 10154);
|
||||
|
||||
builder.AddImage(333, 2, 10006);
|
||||
builder.AddImage(333, 248, 10006);
|
||||
builder.AddImage(2, 248, 10006);
|
||||
builder.AddImage(2, 2, 10006);
|
||||
|
||||
builder.AddHtmlLocalized(25, 22, 200, 20, 1049000, 32000); // Confirm Quest Cancellation
|
||||
builder.AddImage(25, 40, 3007);
|
||||
|
||||
if (_system.IsTutorial)
|
||||
{
|
||||
builder.AddHtmlLocalized(
|
||||
25,
|
||||
55,
|
||||
300,
|
||||
120,
|
||||
1060836,
|
||||
White
|
||||
BaseQuestGump.White
|
||||
); // This quest will give you valuable information, skills and equipment that will help you advance in the game at a quicker pace.<BR><BR>Are you certain you wish to cancel at this time?
|
||||
}
|
||||
else
|
||||
{
|
||||
AddHtmlLocalized(25, 60, 300, 20, 1049001, White); // You have chosen to abort your quest:
|
||||
AddImage(25, 81, 0x25E7);
|
||||
AddHtmlObject(48, 80, 280, 20, system.Name, DarkGreen, false, false);
|
||||
builder.AddHtmlLocalized(25, 60, 300, 20, 1049001, BaseQuestGump.White); // You have chosen to abort your quest:
|
||||
builder.AddImage(25, 81, 0x25E7);
|
||||
BaseQuestGump.AddHtmlObject(ref builder, 48, 80, 280, 20, _system.Name, BaseQuestGump.DarkGreen, false, false);
|
||||
|
||||
AddHtmlLocalized(25, 120, 280, 20, 1049002, White); // Can this quest be restarted after quitting?
|
||||
AddImage(25, 141, 0x25E7);
|
||||
AddHtmlLocalized(
|
||||
builder.AddHtmlLocalized(25, 120, 280, 20, 1049002, BaseQuestGump.White); // Can this quest be restarted after quitting?
|
||||
builder.AddImage(25, 141, 0x25E7);
|
||||
builder.AddHtmlLocalized(
|
||||
48,
|
||||
140,
|
||||
280,
|
||||
20,
|
||||
system.RestartDelay < TimeSpan.MaxValue ? 1049016 : 1049017,
|
||||
DarkGreen
|
||||
_system.RestartDelay < TimeSpan.MaxValue ? 1049016 : 1049017,
|
||||
BaseQuestGump.DarkGreen
|
||||
); // Yes/No
|
||||
}
|
||||
|
||||
AddRadio(25, 175, 9720, 9723, true, 1);
|
||||
AddHtmlLocalized(60, 180, 280, 20, 1049005, White); // Yes, I really want to quit!
|
||||
builder.AddRadio(25, 175, 9720, 9723, true, 1);
|
||||
builder.AddHtmlLocalized(60, 180, 280, 20, 1049005, BaseQuestGump.White); // Yes, I really want to quit!
|
||||
|
||||
AddRadio(25, 210, 9720, 9723, false, 0);
|
||||
AddHtmlLocalized(60, 215, 280, 20, 1049006, White); // No, I don't want to quit.
|
||||
builder.AddRadio(25, 210, 9720, 9723, false, 0);
|
||||
builder.AddHtmlLocalized(60, 215, 280, 20, 1049006, BaseQuestGump.White); // No, I don't want to quit.
|
||||
|
||||
AddButton(265, 220, 247, 248, 1);
|
||||
builder.AddButton(265, 220, 247, 248, 1);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, in RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 1)
|
||||
{
|
||||
m_System.EndCancelQuest(info.IsSwitched(1));
|
||||
_system.EndCancelQuest(info.IsSwitched(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class QuestOfferGump : BaseQuestGump
|
||||
{
|
||||
private readonly QuestSystem m_System;
|
||||
private readonly QuestSystem _system;
|
||||
|
||||
public QuestOfferGump(QuestSystem system) : base(75, 25)
|
||||
public override bool Singleton => true;
|
||||
|
||||
private QuestOfferGump(QuestSystem system) : base(75, 25) => _system = system;
|
||||
|
||||
public static void DisplayTo(Mobile from, QuestSystem system)
|
||||
{
|
||||
m_System = system;
|
||||
if (from?.NetState == null || system == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Closable = false;
|
||||
from.SendGump(new QuestOfferGump(system));
|
||||
}
|
||||
|
||||
AddPage(0);
|
||||
protected override void BuildLayout(ref DynamicGumpBuilder builder)
|
||||
{
|
||||
builder.SetNoClose();
|
||||
|
||||
AddImageTiled(50, 20, 400, 400, 2624);
|
||||
AddAlphaRegion(50, 20, 400, 400);
|
||||
builder.AddPage();
|
||||
|
||||
AddImage(90, 33, 9005);
|
||||
AddHtmlLocalized(130, 45, 270, 20, 1049010, White); // Quest Offer
|
||||
AddImageTiled(130, 65, 175, 1, 9101);
|
||||
builder.AddImageTiled(50, 20, 400, 400, 2624);
|
||||
builder.AddAlphaRegion(50, 20, 400, 400);
|
||||
|
||||
AddImage(140, 110, 1209);
|
||||
AddHtmlObject(160, 108, 250, 20, system.Name, DarkGreen, false, false);
|
||||
builder.AddImage(90, 33, 9005);
|
||||
builder.AddHtmlLocalized(130, 45, 270, 20, 1049010, BaseQuestGump.White); // Quest Offer
|
||||
builder.AddImageTiled(130, 65, 175, 1, 9101);
|
||||
|
||||
AddHtmlObject(98, 140, 312, 200, system.OfferMessage, LightGreen, false, true);
|
||||
builder.AddImage(140, 110, 1209);
|
||||
BaseQuestGump.AddHtmlObject(ref builder, 160, 108, 250, 20, _system.Name, BaseQuestGump.DarkGreen, false, false);
|
||||
|
||||
AddRadio(85, 350, 9720, 9723, true, 1);
|
||||
AddHtmlLocalized(120, 356, 280, 20, 1049011, White); // I accept!
|
||||
BaseQuestGump.AddHtmlObject(ref builder, 98, 140, 312, 200, _system.OfferMessage, BaseQuestGump.LightGreen, false, true);
|
||||
|
||||
AddRadio(85, 385, 9720, 9723, false, 0);
|
||||
AddHtmlLocalized(120, 391, 280, 20, 1049012, White); // No thanks, I decline.
|
||||
builder.AddRadio(85, 350, 9720, 9723, true, 1);
|
||||
builder.AddHtmlLocalized(120, 356, 280, 20, 1049011, BaseQuestGump.White); // I accept!
|
||||
|
||||
AddButton(340, 390, 247, 248, 1);
|
||||
builder.AddRadio(85, 385, 9720, 9723, false, 0);
|
||||
builder.AddHtmlLocalized(120, 391, 280, 20, 1049012, BaseQuestGump.White); // No thanks, I decline.
|
||||
|
||||
AddImageTiled(50, 29, 30, 390, 10460);
|
||||
AddImageTiled(34, 140, 17, 279, 9263);
|
||||
builder.AddButton(340, 390, 247, 248, 1);
|
||||
|
||||
AddImage(48, 135, 10411);
|
||||
AddImage(-16, 285, 10402);
|
||||
AddImage(0, 10, 10421);
|
||||
AddImage(25, 0, 10420);
|
||||
builder.AddImageTiled(50, 29, 30, 390, 10460);
|
||||
builder.AddImageTiled(34, 140, 17, 279, 9263);
|
||||
|
||||
AddImageTiled(83, 15, 350, 15, 10250);
|
||||
builder.AddImage(48, 135, 10411);
|
||||
builder.AddImage(-16, 285, 10402);
|
||||
builder.AddImage(0, 10, 10421);
|
||||
builder.AddImage(25, 0, 10420);
|
||||
|
||||
AddImage(34, 419, 10306);
|
||||
AddImage(442, 419, 10304);
|
||||
AddImageTiled(51, 419, 392, 17, 10101);
|
||||
builder.AddImageTiled(83, 15, 350, 15, 10250);
|
||||
|
||||
AddImageTiled(415, 29, 44, 390, 2605);
|
||||
AddImageTiled(415, 29, 30, 390, 10460);
|
||||
AddImage(425, 0, 10441);
|
||||
builder.AddImage(34, 419, 10306);
|
||||
builder.AddImage(442, 419, 10304);
|
||||
builder.AddImageTiled(51, 419, 392, 17, 10101);
|
||||
|
||||
AddImage(370, 50, 1417);
|
||||
AddImage(379, 60, system.Picture);
|
||||
builder.AddImageTiled(415, 29, 44, 390, 2605);
|
||||
builder.AddImageTiled(415, 29, 30, 390, 10460);
|
||||
builder.AddImage(425, 0, 10441);
|
||||
|
||||
builder.AddImage(370, 50, 1417);
|
||||
builder.AddImage(379, 60, _system.Picture);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, in RelayInfo info)
|
||||
|
|
@ -663,17 +695,17 @@ namespace Server.Engines.Quests
|
|||
{
|
||||
if (info.IsSwitched(1))
|
||||
{
|
||||
m_System.Accept();
|
||||
_system.Accept();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_System.Decline();
|
||||
_system.Decline();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BaseQuestGump : Gump
|
||||
public abstract class BaseQuestGump : DynamicGump
|
||||
{
|
||||
public const int Black = 0x0000;
|
||||
public const int White = 0x7FFF;
|
||||
|
|
@ -681,19 +713,29 @@ namespace Server.Engines.Quests
|
|||
public const int LightGreen = 90000;
|
||||
public const int Blue = 19777215;
|
||||
|
||||
public BaseQuestGump(int x, int y) : base(x, y)
|
||||
protected BaseQuestGump(int x, int y) : base(x, y)
|
||||
{
|
||||
}
|
||||
|
||||
public void AddHtmlObject(int x, int y, int width, int height, object message, int color, bool back, bool scroll)
|
||||
public static void AddHtmlObject(
|
||||
ref DynamicGumpBuilder builder,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
object message,
|
||||
int color,
|
||||
bool back,
|
||||
bool scroll
|
||||
)
|
||||
{
|
||||
if (message is int html)
|
||||
{
|
||||
AddHtmlLocalized(x, y, width, height, html, color.C16216(), back, scroll);
|
||||
builder.AddHtmlLocalized(x, y, width, height, html, color.C16216(), back, scroll);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddHtml(x, y, width, height, Html.Color($"{message}", color.C16216()), back, scroll);
|
||||
builder.AddHtml(x, y, width, height, Html.Color($"{message}", color.C16216()), background: back, scrollbar: scroll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue