diff --git a/CS2MenuManager/API/Menu/CenterHtmlMenu.cs b/CS2MenuManager/API/Menu/CenterHtmlMenu.cs index 643c5ba..194ef86 100644 --- a/CS2MenuManager/API/Menu/CenterHtmlMenu.cs +++ b/CS2MenuManager/API/Menu/CenterHtmlMenu.cs @@ -50,6 +50,14 @@ public class CenterHtmlMenuInstance : BaseMenuInstance /// public override int NumPerPage => 5; + // Display runs on every tick; each of these walks the localization stack and + // ReplaceColorTags reflects over ChatColors, none of which changes here. + private readonly string _prevLabel; + private readonly string _exitLabel; + private readonly string _nextLabel; + private readonly StringBuilder _builder = new(); + private CounterStrikeSharp.API.Core.EventShowSurvivalRespawnStatus? _panelEvent; + /// /// Gets the number of items displayed per page. /// @@ -70,6 +78,10 @@ public CenterHtmlMenuInstance(CCSPlayerController player, IMenu menu) : base(pla if (Menu is CenterHtmlMenu { CenterHtmlMenu_MaxOptionLength: > 0 } centerHtmlMenu) Menu.ItemOptions.ForEach(option => option.Text = option.Text.TruncateHtml(centerHtmlMenu.CenterHtmlMenu_MaxOptionLength)); + _prevLabel = Player.Localizer("Prev"); + _exitLabel = Player.Localizer("Exit"); + _nextLabel = Player.Localizer("Next"); + Menu.Plugin.RegisterListener(Display); } @@ -81,7 +93,8 @@ public override void Display() if (Menu is not CenterHtmlMenu centerHtmlMenu) return; - StringBuilder builder = new(); + StringBuilder builder = _builder; + builder.Clear(); builder.Append($"{centerHtmlMenu.Title}
"); int keyOffset = 1; @@ -102,7 +115,7 @@ public override void Display() } AddPageOptions(centerHtmlMenu, builder); - Player.PrintToCenterHtml(builder.ToString()); + SendPanel(builder.ToString()); } /// @@ -113,15 +126,30 @@ public override void Close(bool exitSound) base.Close(exitSound); Menu.Plugin.RemoveListener(Display); + _panelEvent?.Free(); + _panelEvent = null; + if (Player.IsValid) Player.PrintToCenterHtml(" "); } + // The panel only stays up while it is resent, so a game event is fired every + // tick; building and freeing one each time is most of what that costs. + private void SendPanel(string text) + { + if (!Player.IsValid) + return; + + _panelEvent ??= new CounterStrikeSharp.API.Core.EventShowSurvivalRespawnStatus(true) { Userid = Player, Duration = 5 }; + _panelEvent.LocToken = text; + _panelEvent.FireEventToClient(Player); + } + private void AddPageOptions(CenterHtmlMenu centerHtmlMenu, StringBuilder builder) { - string prevText = $"!8 < {Player.Localizer("Prev")}"; - string closeText = $"!0 X {Player.Localizer("Exit")}"; - string nextText = $"!9 > {Player.Localizer("Next")}"; + string prevText = $"!8 < {_prevLabel}"; + string closeText = $"!0 X {_exitLabel}"; + string nextText = $"!9 > {_nextLabel}"; if (centerHtmlMenu.CenterHtmlMenu_InlinePageOptions) AddInlinePageOptions(prevText, closeText, nextText, builder);