From 70a69d3efe50bb501a4dae81f9b26896c81239f0 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 26 Apr 2026 09:55:46 -0700 Subject: [PATCH] perf: Migrate ConPVP game board gumps to DynamicGump (#2419) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Migrates the four ConPVP game board (scoreboard) gumps from legacy `Gump` to `DynamicGump`: - **`BRBoardGump`** (Bombing Run) — variable layout: row-per-team based on `Participants.Count`. Migrated to `DynamicGump`, `Singleton`, private constructor + `DisplayTo`, `SetNoClose()`. - **`CTFBoardGump`** (Capture the Flag) — variable layout: row-per-team filtered to only teams with a flag. Same migration shape. - **`DDBoardGump`** (Double Domination) — variable layout: row-per-team. Same migration shape. - **`KHBoardGump`** (King of the Hill) — variable layout: row-per-team. `sealed`. Same migration shape. ### Refresh-via-this decision For all four boards, **score data lives on the `*Game` / `*TeamInfo` objects, not the gump**. The gump just renders a snapshot of those values at the moment it is sent. The three call sites per board are: 1. `OnDoubleClick` on the in-world scoreboard item — one-shot manual open. 2. After death/kill score events (in `OnDeath`) — game logic pushes a fresh board to the dying player so they see updated scores. 3. End-of-game broadcast loop — sends final results to every participant. None of these are button-driven refreshes from inside the gump, and the gump owns no mutable state. Therefore each event allocates a fresh gump (now via `DisplayTo(...)`) rather than calling `SendGump(this)` on a long-lived instance — that pattern doesn't fit when the data source is external. The win comes from `DynamicGump`'s ref-struct builder writing directly to buffers, eliminating the legacy `GumpEntry` list allocations on every send. ### Mechanics - `: Gump` → `: DynamicGump`; layout moved from constructor to `BuildLayout(ref DynamicGumpBuilder)`. - `Closable = false` → `builder.SetNoClose()`. - Constructors are `private`; static `DisplayTo(Mobile, *Game, ...)` validates `mob?.NetState != null && game != null` before constructing. - Team-section-mode parameter (`section`) preserved on BR / CTF / DD as an optional `DisplayTo` param even though no current caller uses it. - The four `m_Game` / similar fields are renamed to `_game`; new fields use `_camelCase` per CLAUDE.md §12. - `AddBorderedText` / `AddColoredText` helpers became `static` and take `ref DynamicGumpBuilder`. - Updated all 12 internal call sites (3 per file) to go through `DisplayTo`. No external callers. - No `OnResponse` was defined on any of these gumps (the only button is a close button), so no `RelayInfo` signature changes were needed. Touches 4 game files, but only the gump classes — game logic (BR death/scoring, CTF flag handling, DD domination, KH king timer) is untouched. --- .../Engines/ConPVP/Games/BombingRun.cs | 157 ++++++++--------- .../UOContent/Engines/ConPVP/Games/CTF.cs | 161 ++++++++--------- .../Engines/ConPVP/Games/DoubleDom.cs | 162 ++++++++---------- .../Engines/ConPVP/Games/KingOfTheHill.cs | 137 +++++++-------- 4 files changed, 291 insertions(+), 326 deletions(-) diff --git a/Projects/UOContent/Engines/ConPVP/Games/BombingRun.cs b/Projects/UOContent/Engines/ConPVP/Games/BombingRun.cs index d0ed57bad..489efff71 100644 --- a/Projects/UOContent/Engines/ConPVP/Games/BombingRun.cs +++ b/Projects/UOContent/Engines/ConPVP/Games/BombingRun.cs @@ -63,10 +63,7 @@ public partial class BRBomb : Item var mob = FindOwner(parent); - if (mob != null) - { - mob.SolidHueOverride = 0x0499; - } + mob?.SolidHueOverride = 0x0499; } public override void OnRemoved(IEntity parent) @@ -989,32 +986,51 @@ public sealed partial class BRBoard : Item { if (m_TeamInfo?.Game != null) { - from.SendGump(new BRBoardGump(from, m_TeamInfo.Game)); + BRBoardGump.DisplayTo(from, m_TeamInfo.Game); } } } -public class BRBoardGump : Gump +public class BRBoardGump : DynamicGump { private const int LabelColor32 = 0xFFFFFF; private const int BlackColor32 = 0x000000; + private readonly Mobile _mob; + private readonly BRGame _game; + private readonly BRTeamInfo _section; + public override bool Singleton => true; - public BRBoardGump(Mobile mob, BRGame game, BRTeamInfo section = null) : base(60, 60) + private BRBoardGump(Mobile mob, BRGame game, BRTeamInfo section) : base(60, 60) { - // m_Game = game; + _mob = mob; + _game = game; + _section = section; + } - var ourTeam = game.GetTeamInfo(mob); + public static void DisplayTo(Mobile mob, BRGame game, BRTeamInfo section = null) + { + if (mob?.NetState == null || game == null) + { + return; + } + + mob.SendGump(new BRBoardGump(mob, game, section)); + } + + protected override void BuildLayout(ref DynamicGumpBuilder builder) + { + var ourTeam = _game.GetTeamInfo(_mob); var entries = new List(); var total = 0; - if (section == null) + if (_section == null) { - for (var i = 0; i < game.Context.Participants.Count; ++i) + for (var i = 0; i < _game.Context.Participants.Count; ++i) { - var teamInfo = game.Controller.TeamInfo[i % game.Controller.TeamInfo.Length]; + var teamInfo = _game.Controller.TeamInfo[i % _game.Controller.TeamInfo.Length]; if (teamInfo == null) { @@ -1028,7 +1044,7 @@ public class BRBoardGump : Gump } else { - foreach (var player in section.Players.Values) + foreach (var player in _section.Players.Values) { if (player.Score > 0) { @@ -1041,46 +1057,45 @@ public class BRBoardGump : Gump var height = 0; - if (section == null) + if (_section == null) { height = 73 + entries.Count * 75 + 28; } - Closable = false; + builder.SetNoClose(); - AddPage(0); + builder.AddPage(); - AddBackground(1, 1, 398, height, 3600); + builder.AddBackground(1, 1, 398, height, 3600); - AddImageTiled(16, 15, 369, height - 29, 3604); + builder.AddImageTiled(16, 15, 369, height - 29, 3604); for (var i = 0; i < total; i += 1) { - AddImageTiled(22, 58 + i * 75, 357, 70, 0x2430); + builder.AddImageTiled(22, 58 + i * 75, 357, 70, 0x2430); } - AddAlphaRegion(16, 15, 369, height - 29); + builder.AddAlphaRegion(16, 15, 369, height - 29); - AddImage(215, -45, 0xEE40); - // AddImage( 330, 141, 0x8BA ); + builder.AddImage(215, -45, 0xEE40); - AddBorderedText(22, 22, 294, 20, "BR Scoreboard".Center(), LabelColor32, BlackColor32); + AddBorderedText(ref builder, 22, 22, 294, 20, "BR Scoreboard".Center(), LabelColor32, BlackColor32); - AddImageTiled(32, 50, 264, 1, 9107); - AddImageTiled(42, 52, 264, 1, 9157); + builder.AddImageTiled(32, 50, 264, 1, 9107); + builder.AddImageTiled(42, 52, 264, 1, 9157); - if (section == null) + if (_section == null) { for (var i = 0; i < entries.Count; ++i) { var teamInfo = entries[i]; - AddImage(30, 70 + i * 75, 10152); - AddImage(30, 85 + i * 75, 10151); - AddImage(30, 100 + i * 75, 10151); - AddImage(30, 106 + i * 75, 10154); + builder.AddImage(30, 70 + i * 75, 10152); + builder.AddImage(30, 85 + i * 75, 10151); + builder.AddImage(30, 100 + i * 75, 10151); + builder.AddImage(30, 106 + i * 75, 10154); - AddImage(24, 60 + i * 75, teamInfo == ourTeam ? 9730 : 9727, teamInfo.Color - 1); + builder.AddImage(24, 60 + i * 75, teamInfo == ourTeam ? 9730 : 9727, teamInfo.Color - 1); var borderColor = teamInfo.Color == 0x455 ? LabelColor32 : BlackColor32; var nameColor = teamInfo.Color switch @@ -1096,6 +1111,7 @@ public class BRBoardGump : Gump }; AddBorderedText( + ref builder, 60, 65 + i * 75, 250, @@ -1105,50 +1121,52 @@ public class BRBoardGump : Gump borderColor ); - AddBorderedText(50 + 10, 85 + i * 75, 100, 20, "Score:", 0xFFC000, BlackColor32); - AddBorderedText(50 + 15, 105 + i * 75, 100, 20, teamInfo.Score.ToString("N0"), 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 50 + 10, 85 + i * 75, 100, 20, "Score:", 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 50 + 15, 105 + i * 75, 100, 20, $"{teamInfo.Score:N0}", 0xFFC000, BlackColor32); - AddBorderedText(110 + 10, 85 + i * 75, 100, 20, "Kills:", 0xFFC000, BlackColor32); - AddBorderedText(110 + 15, 105 + i * 75, 100, 20, teamInfo.Kills.ToString("N0"), 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 110 + 10, 85 + i * 75, 100, 20, "Kills:", 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 110 + 15, 105 + i * 75, 100, 20, $"{teamInfo.Kills:N0}", 0xFFC000, BlackColor32); - AddBorderedText(160 + 10, 85 + i * 75, 100, 20, "Points:", 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 160 + 10, 85 + i * 75, 100, 20, "Points:", 0xFFC000, BlackColor32); AddBorderedText( + ref builder, 160 + 15, 105 + i * 75, 100, 20, - teamInfo.Captures.ToString("N0"), + $"{teamInfo.Captures:N0}", 0xFFC000, BlackColor32 ); var pl = teamInfo.Leader; - AddBorderedText(235 + 10, 85 + i * 75, 250, 20, "Leader:", 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 235 + 10, 85 + i * 75, 250, 20, "Leader:", 0xFFC000, BlackColor32); if (pl != null) { - AddBorderedText(235 + 15, 105 + i * 75, 250, 20, pl.Player.Name, 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 235 + 15, 105 + i * 75, 250, 20, pl.Player.Name, 0xFFC000, BlackColor32); } } } - AddButton(314, height - 42, 247, 248, 1); + builder.AddButton(314, height - 42, 247, 248, 1); } - private void AddBorderedText(int x, int y, int width, int height, string text, int color, int borderColor) + private static void AddBorderedText( + ref DynamicGumpBuilder builder, int x, int y, int width, int height, string text, int color, int borderColor + ) { - AddColoredText(x - 1, y - 1, width, height, text, borderColor); - AddColoredText(x - 1, y + 1, width, height, text, borderColor); - AddColoredText(x + 1, y - 1, width, height, text, borderColor); - AddColoredText(x + 1, y + 1, width, height, text, borderColor); - AddColoredText(x, y, width, height, text, color); + AddColoredText(ref builder, x - 1, y - 1, width, height, text, borderColor); + AddColoredText(ref builder, x - 1, y + 1, width, height, text, borderColor); + AddColoredText(ref builder, x + 1, y - 1, width, height, text, borderColor); + AddColoredText(ref builder, x + 1, y + 1, width, height, text, borderColor); + AddColoredText(ref builder, x, y, width, height, text, color); } - private void AddColoredText(int x, int y, int width, int height, string text, int color) - { - AddHtml(x, y, width, height, color == 0 ? text : text.Color(color)); - } + private static void AddColoredText( + ref DynamicGumpBuilder builder, int x, int y, int width, int height, string text, int color + ) => builder.AddHtml(x, y, width, height, color == 0 ? text : text.Color(color)); } public sealed class BRPlayerInfo : IRankedCTF, IComparable @@ -1297,10 +1315,7 @@ public sealed class BRTeamInfo : IRankedCTF, IComparable set { m_Goal = value; - if (m_Goal != null) - { - m_Goal.Team = this; - } + m_Goal?.Team = this; } } @@ -1338,15 +1353,9 @@ public sealed class BRTeamInfo : IRankedCTF, IComparable Players.Clear(); - if (Board != null) - { - Board.m_TeamInfo = this; - } + Board?.m_TeamInfo = this; - if (m_Goal != null) - { - m_Goal.Team = this; - } + m_Goal?.Team = this; } public void Serialize(IGenericWriter op) @@ -1362,15 +1371,7 @@ public sealed class BRTeamInfo : IRankedCTF, IComparable op.Write(m_Goal); } - public override string ToString() - { - if (TeamName != null) - { - return $"({Name}) ..."; - } - - return "..."; - } + public override string ToString() => TeamName != null ? $"({Name}) ..." : "..."; } public sealed class BRController : EventController @@ -1640,7 +1641,7 @@ public sealed class BRGame : EventGame } } - mob.SendGump(new BRBoardGump(mob, this)); + BRBoardGump.DisplayTo(mob, this); m_Context.Requip(mob, corpse); DelayBounce(TimeSpan.FromSeconds(30.0), mob, corpse); @@ -1839,7 +1840,7 @@ public sealed class BRGame : EventGame if (dp?.Mobile != null) { - dp.Mobile.SendGump(new BRBoardGump(dp.Mobile, this)); + BRBoardGump.DisplayTo(dp.Mobile, this); } } @@ -1852,10 +1853,7 @@ public sealed class BRGame : EventGame { for (var j = 0; j < p.Players.Length; ++j) { - if (p.Players[j] != null) - { - p.Players[j].Eliminated = true; - } + p.Players[j]?.Eliminated = true; } } } @@ -1872,10 +1870,7 @@ public sealed class BRGame : EventGame { var teamInfo = Controller.TeamInfo[i]; - if (teamInfo.Board != null) - { - teamInfo.Board.m_TeamInfo = null; - } + teamInfo.Board?.m_TeamInfo = null; teamInfo.Game = null; } diff --git a/Projects/UOContent/Engines/ConPVP/Games/CTF.cs b/Projects/UOContent/Engines/ConPVP/Games/CTF.cs index 120d261ab..2a0326ef3 100644 --- a/Projects/UOContent/Engines/ConPVP/Games/CTF.cs +++ b/Projects/UOContent/Engines/ConPVP/Games/CTF.cs @@ -24,34 +24,51 @@ public sealed partial class CTFBoard : Item { if (m_TeamInfo?.Game != null) { - from.SendGump(new CTFBoardGump(from, m_TeamInfo.Game)); + CTFBoardGump.DisplayTo(from, m_TeamInfo.Game); } } } -public class CTFBoardGump : Gump +public class CTFBoardGump : DynamicGump { private const int LabelColor32 = 0xFFFFFF; private const int BlackColor32 = 0x000000; - private CTFGame m_Game; + private readonly Mobile _mob; + private readonly CTFGame _game; + private readonly CTFTeamInfo _section; public override bool Singleton => true; - public CTFBoardGump(Mobile mob, CTFGame game, CTFTeamInfo section = null) + private CTFBoardGump(Mobile mob, CTFGame game, CTFTeamInfo section) : base(60, 60) { - m_Game = game; + _mob = mob; + _game = game; + _section = section; + } - var ourTeam = game.GetTeamInfo(mob); + public static void DisplayTo(Mobile mob, CTFGame game, CTFTeamInfo section = null) + { + if (mob?.NetState == null || game == null) + { + return; + } + + mob.SendGump(new CTFBoardGump(mob, game, section)); + } + + protected override void BuildLayout(ref DynamicGumpBuilder builder) + { + var ourTeam = _game.GetTeamInfo(_mob); var entries = new List(); - if (section == null) + if (_section == null) { - for (var i = 0; i < game.Context.Participants.Count; ++i) + for (var i = 0; i < _game.Context.Participants.Count; ++i) { - var teamInfo = game.Controller.TeamInfo[i % 8]; + var teamInfo = _game.Controller.TeamInfo[i % 8]; if (teamInfo?.Flag == null) { @@ -63,7 +80,7 @@ public class CTFBoardGump : Gump } else { - foreach (var player in section.Players.Values) + foreach (var player in _section.Players.Values) { if (player.Score > 0) { @@ -76,51 +93,48 @@ public class CTFBoardGump : Gump var height = 0; - if (section == null) + if (_section == null) { height = 73 + entries.Count * 75 + 28; } - Closable = false; + builder.SetNoClose(); - AddPage(0); + builder.AddPage(); - AddBackground(1, 1, 398, height, 3600); + builder.AddBackground(1, 1, 398, height, 3600); - AddImageTiled(16, 15, 369, height - 29, 3604); + builder.AddImageTiled(16, 15, 369, height - 29, 3604); for (var i = 0; i < entries.Count; i += 1) { - AddImageTiled(22, 58 + i * 75, 357, 70, 0x2430); + builder.AddImageTiled(22, 58 + i * 75, 357, 70, 0x2430); } - AddAlphaRegion(16, 15, 369, height - 29); + builder.AddAlphaRegion(16, 15, 369, height - 29); - AddImage(215, -45, 0xEE40); - // AddImage( 330, 141, 0x8BA ); + builder.AddImage(215, -45, 0xEE40); - AddBorderedText(22, 22, 294, 20, "CTF Scoreboard".Center(), LabelColor32, BlackColor32); + AddBorderedText(ref builder, 22, 22, 294, 20, "CTF Scoreboard".Center(), LabelColor32, BlackColor32); - AddImageTiled(32, 50, 264, 1, 9107); - AddImageTiled(42, 52, 264, 1, 9157); + builder.AddImageTiled(32, 50, 264, 1, 9107); + builder.AddImageTiled(42, 52, 264, 1, 9157); - if (section == null) + if (_section == null) { for (var i = 0; i < entries.Count; ++i) { - var teamInfo = entries[i] as CTFTeamInfo; - - if (teamInfo == null) + if (entries[i] is not CTFTeamInfo teamInfo) { continue; } - AddImage(30, 70 + i * 75, 10152); - AddImage(30, 85 + i * 75, 10151); - AddImage(30, 100 + i * 75, 10151); - AddImage(30, 106 + i * 75, 10154); + builder.AddImage(30, 70 + i * 75, 10152); + builder.AddImage(30, 85 + i * 75, 10151); + builder.AddImage(30, 100 + i * 75, 10151); + builder.AddImage(30, 106 + i * 75, 10154); - AddImage(24, 60 + i * 75, teamInfo == ourTeam ? 9730 : 9727, teamInfo.Color - 1); + builder.AddImage(24, 60 + i * 75, teamInfo == ourTeam ? 9730 : 9727, teamInfo.Color - 1); var borderColor = teamInfo.Color == 0x455 ? LabelColor32 : BlackColor32; var nameColor = teamInfo.Color switch @@ -136,6 +150,7 @@ public class CTFBoardGump : Gump }; AddBorderedText( + ref builder, 60, 65 + i * 75, 250, @@ -145,49 +160,50 @@ public class CTFBoardGump : Gump borderColor ); - AddBorderedText(50 + 10, 85 + i * 75, 100, 20, "Score:", 0xFFC000, BlackColor32); - AddBorderedText(50 + 15, 105 + i * 75, 100, 20, teamInfo.Score.ToString("N0"), 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 50 + 10, 85 + i * 75, 100, 20, "Score:", 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 50 + 15, 105 + i * 75, 100, 20, $"{teamInfo.Score:N0}", 0xFFC000, BlackColor32); - AddBorderedText(110 + 10, 85 + i * 75, 100, 20, "Kills:", 0xFFC000, BlackColor32); - AddBorderedText(110 + 15, 105 + i * 75, 100, 20, teamInfo.Kills.ToString("N0"), 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 110 + 10, 85 + i * 75, 100, 20, "Kills:", 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 110 + 15, 105 + i * 75, 100, 20, $"{teamInfo.Kills:N0}", 0xFFC000, BlackColor32); - AddBorderedText(160 + 10, 85 + i * 75, 100, 20, "Captures:", 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 160 + 10, 85 + i * 75, 100, 20, "Captures:", 0xFFC000, BlackColor32); AddBorderedText( + ref builder, 160 + 15, 105 + i * 75, 100, 20, - teamInfo.Captures.ToString("N0"), + $"{teamInfo.Captures:N0}", 0xFFC000, BlackColor32 ); var pl = teamInfo.Leader; - AddBorderedText(235 + 10, 85 + i * 75, 250, 20, "Leader:", 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 235 + 10, 85 + i * 75, 250, 20, "Leader:", 0xFFC000, BlackColor32); if (pl != null) { - AddBorderedText(235 + 15, 105 + i * 75, 250, 20, pl.Player.Name, 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 235 + 15, 105 + i * 75, 250, 20, pl.Player.Name, 0xFFC000, BlackColor32); } } } - AddButton(314, height - 42, 247, 248, 1); + builder.AddButton(314, height - 42, 247, 248, 1); } - private void AddBorderedText(int x, int y, int width, int height, string text, int color, int borderColor) + private static void AddBorderedText(ref DynamicGumpBuilder builder, int x, int y, int width, int height, string text, int color, int borderColor) { - AddColoredText(x - 1, y - 1, width, height, text, borderColor); - AddColoredText(x - 1, y + 1, width, height, text, borderColor); - AddColoredText(x + 1, y - 1, width, height, text, borderColor); - AddColoredText(x + 1, y + 1, width, height, text, borderColor); - AddColoredText(x, y, width, height, text, color); + AddColoredText(ref builder, x - 1, y - 1, width, height, text, borderColor); + AddColoredText(ref builder, x - 1, y + 1, width, height, text, borderColor); + AddColoredText(ref builder, x + 1, y - 1, width, height, text, borderColor); + AddColoredText(ref builder, x + 1, y + 1, width, height, text, borderColor); + AddColoredText(ref builder, x, y, width, height, text, color); } - private void AddColoredText(int x, int y, int width, int height, string text, int color) + private static void AddColoredText(ref DynamicGumpBuilder builder, int x, int y, int width, int height, string text, int color) { - AddHtml(x, y, width, height, color == 0 ? text : text.Color(color)); + builder.AddHtml(x, y, width, height, color == 0 ? text : text.Color(color)); } } @@ -249,10 +265,7 @@ public sealed partial class CTFFlag : Item { var playerInfo = useTeam[from]; - if (playerInfo != null) - { - playerInfo.Score += 4; // return - } + playerInfo?.Score += 4; // return m_Returner = from; m_ReturnTime = Core.Now; @@ -401,10 +414,7 @@ public sealed partial class CTFFlag : Item { var assistInfo = useTeam[teamFlag.m_Fragger]; - if (assistInfo != null) - { - assistInfo.Score += 6; // frag assist - } + assistInfo?.Score += 6; // frag assist } if (teamFlag.m_Returner != null && @@ -412,10 +422,7 @@ public sealed partial class CTFFlag : Item { var assistInfo = useTeam[teamFlag.m_Returner]; - if (assistInfo != null) - { - assistInfo.Score += 4; // return assist - } + assistInfo?.Score += 4; // return assist } } } @@ -481,10 +488,7 @@ public sealed partial class CTFFlag : Item var mob = FindOwner(parent); - if (mob != null) - { - mob.SolidHueOverride = 0x4001; - } + mob?.SolidHueOverride = 0x4001; } public override void OnRemoved(IEntity parent) @@ -493,10 +497,7 @@ public sealed partial class CTFFlag : Item var mob = FindOwner(parent); - if (mob != null) - { - mob.SolidHueOverride = m_TeamInfo?.Game.GetColor(mob) ?? -1; - } + mob?.SolidHueOverride = m_TeamInfo?.Game.GetColor(mob) ?? -1; } } @@ -671,10 +672,7 @@ public sealed class CTFTeamInfo : IRankedCTF Flag.SendHome(); } - if (Board != null) - { - Board.m_TeamInfo = this; - } + Board?.m_TeamInfo = this; } public void Serialize(IGenericWriter op) @@ -852,10 +850,7 @@ public sealed class CTFGame : EventGame for (var j = 0; j < p.Players.Length; ++j) { - if (p.Players[j] != null) - { - p.Players[j].Mobile.SendMessage(0x35, text); - } + p.Players[j]?.Mobile.SendMessage(0x35, text); } } } @@ -908,10 +903,7 @@ public sealed class CTFGame : EventGame { for (var i = 0; i < p.Players.Length; ++i) { - if (p.Players[i] != null) - { - p.Players[i].Mobile.SolidHueOverride = hueOverride; - } + p.Players[i]?.Mobile.SolidHueOverride = hueOverride; } } @@ -1025,7 +1017,7 @@ public sealed class CTFGame : EventGame } } - mob.SendGump(new CTFBoardGump(mob, this)); + CTFBoardGump.DisplayTo(mob, this); m_Context.Requip(mob, corpse); DelayBounce(TimeSpan.FromSeconds(30.0), mob, corpse); @@ -1224,7 +1216,7 @@ public sealed class CTFGame : EventGame if (dp?.Mobile != null) { - dp.Mobile.SendGump(new CTFBoardGump(dp.Mobile, this)); + CTFBoardGump.DisplayTo(dp.Mobile, this); } } @@ -1260,10 +1252,7 @@ public sealed class CTFGame : EventGame teamInfo.Flag.m_TeamInfo = null; } - if (teamInfo.Board != null) - { - teamInfo.Board.m_TeamInfo = null; - } + teamInfo.Board?.m_TeamInfo = null; teamInfo.Game = null; } diff --git a/Projects/UOContent/Engines/ConPVP/Games/DoubleDom.cs b/Projects/UOContent/Engines/ConPVP/Games/DoubleDom.cs index 0bf0dccc9..73897404e 100644 --- a/Projects/UOContent/Engines/ConPVP/Games/DoubleDom.cs +++ b/Projects/UOContent/Engines/ConPVP/Games/DoubleDom.cs @@ -22,32 +22,51 @@ public sealed partial class DDBoard : Item { if (m_TeamInfo?.Game != null) { - from.SendGump(new DDBoardGump(from, m_TeamInfo.Game)); + DDBoardGump.DisplayTo(from, m_TeamInfo.Game); } } } -public class DDBoardGump : Gump +public class DDBoardGump : DynamicGump { private const int LabelColor32 = 0xFFFFFF; private const int BlackColor32 = 0x000000; + private readonly Mobile _mob; + private readonly DDGame _game; + private readonly DDTeamInfo _section; + public override bool Singleton => true; - public DDBoardGump(Mobile mob, DDGame game, DDTeamInfo section = null) + private DDBoardGump(Mobile mob, DDGame game, DDTeamInfo section) : base(60, 60) { - // m_Game = game; + _mob = mob; + _game = game; + _section = section; + } - var ourTeam = game.GetTeamInfo(mob); + public static void DisplayTo(Mobile mob, DDGame game, DDTeamInfo section = null) + { + if (mob?.NetState == null || game == null) + { + return; + } + + mob.SendGump(new DDBoardGump(mob, game, section)); + } + + protected override void BuildLayout(ref DynamicGumpBuilder builder) + { + var ourTeam = _game.GetTeamInfo(_mob); var entries = new List(); - if (section == null) + if (_section == null) { - for (var i = 0; i < game.Context.Participants.Count; ++i) + for (var i = 0; i < _game.Context.Participants.Count; ++i) { - var teamInfo = game.Controller.TeamInfo[i % game.Controller.TeamInfo.Length]; + var teamInfo = _game.Controller.TeamInfo[i % _game.Controller.TeamInfo.Length]; if (teamInfo != null) { @@ -57,7 +76,7 @@ public class DDBoardGump : Gump } else { - foreach (var player in section.Players.Values) + foreach (var player in _section.Players.Values) { if (player.Score > 0) { @@ -70,35 +89,34 @@ public class DDBoardGump : Gump var height = 0; - if (section == null) + if (_section == null) { height = 73 + entries.Count * 75 + 28; } - Closable = false; + builder.SetNoClose(); - AddPage(0); + builder.AddPage(); - AddBackground(1, 1, 398, height, 3600); + builder.AddBackground(1, 1, 398, height, 3600); - AddImageTiled(16, 15, 369, height - 29, 3604); + builder.AddImageTiled(16, 15, 369, height - 29, 3604); for (var i = 0; i < entries.Count; i += 1) { - AddImageTiled(22, 58 + i * 75, 357, 70, 0x2430); + builder.AddImageTiled(22, 58 + i * 75, 357, 70, 0x2430); } - AddAlphaRegion(16, 15, 369, height - 29); + builder.AddAlphaRegion(16, 15, 369, height - 29); - AddImage(215, -45, 0xEE40); - // AddImage( 330, 141, 0x8BA ); + builder.AddImage(215, -45, 0xEE40); - AddBorderedText(22, 22, 294, 20, "DD Scoreboard".Center(), LabelColor32, BlackColor32); + AddBorderedText(ref builder, 22, 22, 294, 20, "DD Scoreboard".Center(), LabelColor32, BlackColor32); - AddImageTiled(32, 50, 264, 1, 9107); - AddImageTiled(42, 52, 264, 1, 9157); + builder.AddImageTiled(32, 50, 264, 1, 9107); + builder.AddImageTiled(42, 52, 264, 1, 9157); - if (section == null) + if (_section == null) { for (var i = 0; i < entries.Count; ++i) { @@ -107,12 +125,12 @@ public class DDBoardGump : Gump continue; } - AddImage(30, 70 + i * 75, 10152); - AddImage(30, 85 + i * 75, 10151); - AddImage(30, 100 + i * 75, 10151); - AddImage(30, 106 + i * 75, 10154); + builder.AddImage(30, 70 + i * 75, 10152); + builder.AddImage(30, 85 + i * 75, 10151); + builder.AddImage(30, 100 + i * 75, 10151); + builder.AddImage(30, 106 + i * 75, 10154); - AddImage(24, 60 + i * 75, teamInfo == ourTeam ? 9730 : 9727, teamInfo.Color - 1); + builder.AddImage(24, 60 + i * 75, teamInfo == ourTeam ? 9730 : 9727, teamInfo.Color - 1); var borderColor = teamInfo.Color == 0x455 ? LabelColor32 : BlackColor32; var nameColor = teamInfo.Color switch @@ -128,6 +146,7 @@ public class DDBoardGump : Gump }; AddBorderedText( + ref builder, 60, 65 + i * 75, 250, @@ -137,49 +156,50 @@ public class DDBoardGump : Gump borderColor ); - AddBorderedText(50 + 10, 85 + i * 75, 100, 20, "Score:", 0xFFC000, BlackColor32); - AddBorderedText(50 + 15, 105 + i * 75, 100, 20, teamInfo.Score.ToString("N0"), 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 50 + 10, 85 + i * 75, 100, 20, "Score:", 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 50 + 15, 105 + i * 75, 100, 20, $"{teamInfo.Score:N0}", 0xFFC000, BlackColor32); - AddBorderedText(110 + 10, 85 + i * 75, 100, 20, "Kills:", 0xFFC000, BlackColor32); - AddBorderedText(110 + 15, 105 + i * 75, 100, 20, teamInfo.Kills.ToString("N0"), 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 110 + 10, 85 + i * 75, 100, 20, "Kills:", 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 110 + 15, 105 + i * 75, 100, 20, $"{teamInfo.Kills:N0}", 0xFFC000, BlackColor32); - AddBorderedText(160 + 10, 85 + i * 75, 100, 20, "Captures:", 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 160 + 10, 85 + i * 75, 100, 20, "Captures:", 0xFFC000, BlackColor32); AddBorderedText( + ref builder, 160 + 15, 105 + i * 75, 100, 20, - teamInfo.Captures.ToString("N0"), + $"{teamInfo.Captures:N0}", 0xFFC000, BlackColor32 ); var pl = teamInfo.Leader; - AddBorderedText(235 + 10, 85 + i * 75, 250, 20, "Leader:", 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 235 + 10, 85 + i * 75, 250, 20, "Leader:", 0xFFC000, BlackColor32); if (pl != null) { - AddBorderedText(235 + 15, 105 + i * 75, 250, 20, pl.Player.Name, 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 235 + 15, 105 + i * 75, 250, 20, pl.Player.Name, 0xFFC000, BlackColor32); } } } - AddButton(314, height - 42, 247, 248, 1); + builder.AddButton(314, height - 42, 247, 248, 1); } - private void AddBorderedText(int x, int y, int width, int height, string text, int color, int borderColor) + private static void AddBorderedText(ref DynamicGumpBuilder builder, int x, int y, int width, int height, string text, int color, int borderColor) { - AddColoredText(x - 1, y - 1, width, height, text, borderColor); - AddColoredText(x - 1, y + 1, width, height, text, borderColor); - AddColoredText(x + 1, y - 1, width, height, text, borderColor); - AddColoredText(x + 1, y + 1, width, height, text, borderColor); - AddColoredText(x, y, width, height, text, color); + AddColoredText(ref builder, x - 1, y - 1, width, height, text, borderColor); + AddColoredText(ref builder, x - 1, y + 1, width, height, text, borderColor); + AddColoredText(ref builder, x + 1, y - 1, width, height, text, borderColor); + AddColoredText(ref builder, x + 1, y + 1, width, height, text, borderColor); + AddColoredText(ref builder, x, y, width, height, text, color); } - private void AddColoredText(int x, int y, int width, int height, string text, int color) + private static void AddColoredText(ref DynamicGumpBuilder builder, int x, int y, int width, int height, string text, int color) { - AddHtml(x, y, width, height, color == 0 ? text : text.Color(color)); + builder.AddHtml(x, y, width, height, color == 0 ? text : text.Color(color)); } } @@ -324,10 +344,7 @@ public sealed class DDTeamInfo : IRankedCTF Players.Clear(); - if (Board != null) - { - Board.m_TeamInfo = this; - } + Board?.m_TeamInfo = this; } public void Serialize(IGenericWriter op) @@ -462,10 +479,7 @@ public sealed class DDGame : EventGame for (var j = 0; j < p.Players.Length; ++j) { - if (p.Players[j] != null) - { - p.Players[j].Mobile.SendMessage(0x35, text); - } + p.Players[j]?.Mobile.SendMessage(0x35, text); } } } @@ -508,10 +522,7 @@ public sealed class DDGame : EventGame { for (var i = 0; i < p.Players.Length; ++i) { - if (p.Players[i] != null) - { - p.Players[i].Mobile.SolidHueOverride = hueOverride; - } + p.Players[i]?.Mobile.SolidHueOverride = hueOverride; } } @@ -578,14 +589,11 @@ public sealed class DDGame : EventGame } playerInfo = victInfo[mob]; - if (playerInfo != null) - { - playerInfo.Score -= 1; - } + playerInfo?.Score -= 1; } } - mob.SendGump(new DDBoardGump(mob, this)); + DDBoardGump.DisplayTo(mob, this); m_Context.Requip(mob, corpse); DelayBounce(TimeSpan.FromSeconds(30.0), mob, corpse); @@ -608,15 +616,9 @@ public sealed class DDGame : EventGame teamInfo.Reset(); } - if (Controller.PointA != null) - { - Controller.PointA.Game = this; - } + Controller.PointA?.Game = this; - if (Controller.PointB != null) - { - Controller.PointB.Game = this; - } + Controller.PointB?.Game = this; for (var i = 0; i < m_Context.Participants.Count; ++i) { @@ -800,7 +802,7 @@ public sealed class DDGame : EventGame if (dp?.Mobile != null) { - dp.Mobile.SendGump(new DDBoardGump(dp.Mobile, this)); + DDBoardGump.DisplayTo(dp.Mobile, this); } } @@ -811,10 +813,7 @@ public sealed class DDGame : EventGame for (var j = 0; j < p.Players.Length; ++j) { - if (p.Players[j] != null) - { - p.Players[j].Eliminated = true; - } + p.Players[j]?.Eliminated = true; } } @@ -830,23 +829,14 @@ public sealed class DDGame : EventGame { var teamInfo = Controller.TeamInfo[i]; - if (teamInfo.Board != null) - { - teamInfo.Board.m_TeamInfo = null; - } + teamInfo.Board?.m_TeamInfo = null; teamInfo.Game = null; } - if (Controller.PointA != null) - { - Controller.PointA.Game = null; - } + Controller.PointA?.Game = null; - if (Controller.PointB != null) - { - Controller.PointB.Game = null; - } + Controller.PointB?.Game = null; m_Capturable = false; diff --git a/Projects/UOContent/Engines/ConPVP/Games/KingOfTheHill.cs b/Projects/UOContent/Engines/ConPVP/Games/KingOfTheHill.cs index ea7093404..43ae9c4b6 100644 --- a/Projects/UOContent/Engines/ConPVP/Games/KingOfTheHill.cs +++ b/Projects/UOContent/Engines/ConPVP/Games/KingOfTheHill.cs @@ -275,7 +275,7 @@ public partial class KHBoard : Item { if (m_Game != null) { - from.SendGump(new KHBoardGump(from, m_Game)); + KHBoardGump.DisplayTo(from, m_Game); } else { @@ -284,27 +284,41 @@ public partial class KHBoard : Item } } -public sealed class KHBoardGump : Gump +public sealed class KHBoardGump : DynamicGump { private const int LabelColor32 = 0xFFFFFF; private const int BlackColor32 = 0x000000; - private KHGame m_Game; + private readonly Mobile _mob; + private readonly KHGame _game; public override bool Singleton => true; - public KHBoardGump(Mobile mob, KHGame game) - : base(60, 60) + private KHBoardGump(Mobile mob, KHGame game) : base(60, 60) { - m_Game = game; + _mob = mob; + _game = game; + } - var ourTeam = game.GetTeamInfo(mob); + public static void DisplayTo(Mobile mob, KHGame game) + { + if (mob?.NetState == null || game == null) + { + return; + } + + mob.SendGump(new KHBoardGump(mob, game)); + } + + protected override void BuildLayout(ref DynamicGumpBuilder builder) + { + var ourTeam = _game.GetTeamInfo(_mob); var entries = new List(); - for (var i = 0; i < game.Context.Participants.Count; ++i) + for (var i = 0; i < _game.Context.Participants.Count; ++i) { - var teamInfo = game.Controller.TeamInfo[i % game.Controller.TeamInfo.Length]; + var teamInfo = _game.Controller.TeamInfo[i % _game.Controller.TeamInfo.Length]; if (teamInfo != null) { @@ -313,47 +327,41 @@ public sealed class KHBoardGump : Gump } entries.Sort(); - /* - delegate( IRankedCTF a, IRankedCTF b ) - { - return b.Score - a.Score; - } );*/ var height = 73 + entries.Count * 75 + 28; - Closable = false; + builder.SetNoClose(); - AddPage(0); + builder.AddPage(); - AddBackground(1, 1, 398, height, 3600); + builder.AddBackground(1, 1, 398, height, 3600); - AddImageTiled(16, 15, 369, height - 29, 3604); + builder.AddImageTiled(16, 15, 369, height - 29, 3604); for (var i = 0; i < entries.Count; i += 1) { - AddImageTiled(22, 58 + i * 75, 357, 70, 0x2430); + builder.AddImageTiled(22, 58 + i * 75, 357, 70, 0x2430); } - AddAlphaRegion(16, 15, 369, height - 29); + builder.AddAlphaRegion(16, 15, 369, height - 29); - AddImage(215, -45, 0xEE40); - // AddImage( 330, 141, 0x8BA ); + builder.AddImage(215, -45, 0xEE40); - AddBorderedText(22, 22, 294, 20, "King of the Hill Scoreboard".Center(), LabelColor32, BlackColor32); + AddBorderedText(ref builder, 22, 22, 294, 20, "King of the Hill Scoreboard".Center(), LabelColor32, BlackColor32); - AddImageTiled(32, 50, 264, 1, 9107); - AddImageTiled(42, 52, 264, 1, 9157); + builder.AddImageTiled(32, 50, 264, 1, 9107); + builder.AddImageTiled(42, 52, 264, 1, 9157); for (var i = 0; i < entries.Count; ++i) { var teamInfo = entries[i]; - AddImage(30, 70 + i * 75, 10152); - AddImage(30, 85 + i * 75, 10151); - AddImage(30, 100 + i * 75, 10151); - AddImage(30, 106 + i * 75, 10154); + builder.AddImage(30, 70 + i * 75, 10152); + builder.AddImage(30, 85 + i * 75, 10151); + builder.AddImage(30, 100 + i * 75, 10151); + builder.AddImage(30, 106 + i * 75, 10154); - AddImage(24, 60 + i * 75, teamInfo == ourTeam ? 9730 : 9727, teamInfo.Color - 1); + builder.AddImage(24, 60 + i * 75, teamInfo == ourTeam ? 9730 : 9727, teamInfo.Color - 1); var borderColor = teamInfo.Color == 0x455 ? LabelColor32 : BlackColor32; var nameColor = teamInfo.Color switch @@ -369,6 +377,7 @@ public sealed class KHBoardGump : Gump }; AddBorderedText( + ref builder, 60, 65 + i * 75, 250, @@ -378,36 +387,36 @@ public sealed class KHBoardGump : Gump borderColor ); - AddBorderedText(50 + 10, 85 + i * 75, 100, 20, "Score:", 0xFFC000, BlackColor32); - AddBorderedText(50 + 15, 105 + i * 75, 100, 20, teamInfo.Score.ToString("N0"), 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 50 + 10, 85 + i * 75, 100, 20, "Score:", 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 50 + 15, 105 + i * 75, 100, 20, $"{teamInfo.Score:N0}", 0xFFC000, BlackColor32); - AddBorderedText(110 + 10, 85 + i * 75, 100, 20, "Kills:", 0xFFC000, BlackColor32); - AddBorderedText(110 + 15, 105 + i * 75, 100, 20, teamInfo.Kills.ToString("N0"), 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 110 + 10, 85 + i * 75, 100, 20, "Kills:", 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 110 + 15, 105 + i * 75, 100, 20, $"{teamInfo.Kills:N0}", 0xFFC000, BlackColor32); - AddBorderedText(160 + 10, 85 + i * 75, 100, 20, "Captures:", 0xFFC000, BlackColor32); - AddBorderedText(160 + 15, 105 + i * 75, 100, 20, teamInfo.Captures.ToString("N0"), 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 160 + 10, 85 + i * 75, 100, 20, "Captures:", 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 160 + 15, 105 + i * 75, 100, 20, $"{teamInfo.Captures:N0}", 0xFFC000, BlackColor32); var leader = teamInfo.Leader?.Name ?? "(none)"; - AddBorderedText(235 + 10, 85 + i * 75, 250, 20, "Leader:", 0xFFC000, BlackColor32); - AddBorderedText(235 + 15, 105 + i * 75, 250, 20, leader, 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 235 + 10, 85 + i * 75, 250, 20, "Leader:", 0xFFC000, BlackColor32); + AddBorderedText(ref builder, 235 + 15, 105 + i * 75, 250, 20, leader, 0xFFC000, BlackColor32); } - AddButton(314, height - 42, 247, 248, 1); + builder.AddButton(314, height - 42, 247, 248, 1); } - private void AddBorderedText(int x, int y, int width, int height, string text, int color, int borderColor) + private static void AddBorderedText(ref DynamicGumpBuilder builder, int x, int y, int width, int height, string text, int color, int borderColor) { - AddColoredText(x - 1, y - 1, width, height, text, borderColor); - AddColoredText(x - 1, y + 1, width, height, text, borderColor); - AddColoredText(x + 1, y - 1, width, height, text, borderColor); - AddColoredText(x + 1, y + 1, width, height, text, borderColor); - AddColoredText(x, y, width, height, text, color); + AddColoredText(ref builder, x - 1, y - 1, width, height, text, borderColor); + AddColoredText(ref builder, x - 1, y + 1, width, height, text, borderColor); + AddColoredText(ref builder, x + 1, y - 1, width, height, text, borderColor); + AddColoredText(ref builder, x + 1, y + 1, width, height, text, borderColor); + AddColoredText(ref builder, x, y, width, height, text, color); } - private void AddColoredText(int x, int y, int width, int height, string text, int color) + private static void AddColoredText(ref DynamicGumpBuilder builder, int x, int y, int width, int height, string text, int color) { - AddHtml(x, y, width, height, color == 0 ? text : text.Color(color)); + builder.AddHtml(x, y, width, height, color == 0 ? text : text.Color(color)); } } @@ -803,10 +812,7 @@ public sealed class KHGame : EventGame for (var j = 0; j < p.Players.Length; ++j) { - if (p.Players[j] != null) - { - p.Players[j].Mobile.SendMessage(0x35, text); - } + p.Players[j]?.Mobile.SendMessage(0x35, text); } } } @@ -849,10 +855,7 @@ public sealed class KHGame : EventGame { for (var i = 0; i < p.Players.Length; ++i) { - if (p.Players[i] != null) - { - p.Players[i].Mobile.SolidHueOverride = hueOverride; - } + p.Players[i]?.Mobile.SolidHueOverride = hueOverride; } } @@ -929,7 +932,7 @@ public sealed class KHGame : EventGame } } - mob.SendGump(new KHBoardGump(mob, this)); + KHBoardGump.DisplayTo(mob, this); m_Context.Requip(mob, corpse); DelayBounce(TimeSpan.FromSeconds(30.0), mob, corpse); @@ -957,10 +960,7 @@ public sealed class KHGame : EventGame for (var i = 0; i < Controller.Hills.Length; i++) { - if (Controller.Hills[i] != null) - { - Controller.Hills[i].Game = this; - } + Controller.Hills[i]?.Game = this; } foreach (var board in Controller.Boards) @@ -1139,7 +1139,7 @@ public sealed class KHGame : EventGame if (dp?.Mobile != null) { - dp.Mobile.SendGump(new KHBoardGump(dp.Mobile, this)); + KHBoardGump.DisplayTo(dp.Mobile, this); } } @@ -1152,10 +1152,7 @@ public sealed class KHGame : EventGame { for (var j = 0; j < p.Players.Length; ++j) { - if (p.Players[j] != null) - { - p.Players[j].Eliminated = true; - } + p.Players[j]?.Eliminated = true; } } } @@ -1175,18 +1172,12 @@ public sealed class KHGame : EventGame for (var i = 0; i < Controller.Hills.Length; ++i) { - if (Controller.Hills[i] != null) - { - Controller.Hills[i].Game = null; - } + Controller.Hills[i]?.Game = null; } foreach (var board in Controller.Boards) { - if (board != null) - { - board.m_Game = null; - } + board?.m_Game = null; } for (var i = 0; i < m_Context.Participants.Count; ++i)