Skip to content

Commit 2741636

Browse files
committed
Added a center HTML menu as a fallback instead of a chat menu
1 parent acf955d commit 2741636

3 files changed

Lines changed: 110 additions & 71 deletions

File tree

src/SharpModMenu/MenuDriver.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ namespace SharpModMenu;
1212
internal sealed class MenuDriver : IMenuAPI
1313
{
1414
private Dictionary<ulong, PlayerMenuState> MenuStates = new();
15-
internal List<(CBaseEntity ent, CCSPlayerController target)> MenuEntities { get; } = new();
15+
public List<(CBaseEntity ent, CCSPlayerController target)> MenuEntities { get; } = new();
16+
public List<PlayerMenuState> ActiveHtmlMenuStates { get; } = new();
1617

1718
internal PlayerMenuState GetMenuState(CCSPlayerController player, bool create = false)
1819
{

src/SharpModMenu/PlayerMenuState.cs

Lines changed: 96 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,22 @@ public void HandleInput(PlayerKey key, bool fromBind)
8383
}
8484
}
8585

86+
private bool _PresentingHtml;
87+
private bool PresentingHtml
88+
{
89+
get => _PresentingHtml;
90+
set
91+
{
92+
if (value == _PresentingHtml)
93+
return;
94+
_PresentingHtml = value;
95+
if (value)
96+
Driver.ActiveHtmlMenuStates.Add(this);
97+
else
98+
Driver.ActiveHtmlMenuStates.Remove(this);
99+
}
100+
}
101+
86102
public void Refresh(bool sortPriorities = true)
87103
{
88104
if (sortPriorities)
@@ -118,8 +134,15 @@ public void Refresh(bool sortPriorities = true)
118134
return;
119135
}
120136

121-
if (!DrawActiveMenu())
122-
DrawActiveMenuChat();
137+
if (DrawActiveMenu())
138+
{
139+
PresentingHtml = false;
140+
}
141+
else
142+
{
143+
DrawActiveMenuHtml();
144+
PresentingHtml = true;
145+
}
123146
}
124147

125148
public void Dispose()
@@ -255,6 +278,9 @@ private void UpdateEntity(
255278

256279
private CCSGOViewModel? LastViewmodel { get; set; }
257280
private Menu? LastPresented { get; set; }
281+
private readonly StringBuilder ForegroundTextSb = new();
282+
private readonly StringBuilder BackgroundTextSb = new();
283+
private readonly StringBuilder BackgroundSb = new();
258284
public bool DrawActiveMenu()
259285
{
260286
if (ReferenceEquals(CurrentMenu, LastPresented))
@@ -320,49 +346,7 @@ void writeLine(string text, bool background)
320346
linesWrote++;
321347
}
322348

323-
{ // build the strings
324-
325-
writeLine(CurrentMenu.Title, background: true);
326-
327-
var itemsStart = CurrentMenu.CurrentPage * Menu.ItemsPerPage;
328-
var itemsInPage = Math.Min(CurrentMenu.Items.Count, itemsStart + Menu.ItemsPerPage) - itemsStart;
329-
330-
for (int i = 0; i < itemsInPage; i++)
331-
{
332-
var item = CurrentMenu.Items[itemsStart + i];
333-
writeLine($"{i + 1}. {item.Title}", background: !item.Enabled);
334-
if (item.Subtitle is not null)
335-
writeLine($" {item.Subtitle}", background: true);
336-
}
337-
338-
var btnStates = CurrentMenu.GetButtonStates();
339-
if (btnStates.ShowNavigation || btnStates.ShowExitButton)
340-
{
341-
int maxItemsPerPage = Math.Min(Menu.ItemsPerPage, CurrentMenu.Items.Count);
342-
int blankLines = maxItemsPerPage - itemsInPage + 1;
343-
344-
for (int i = 0; i < blankLines; i++)
345-
writeLine(string.Empty, background: false);
346-
347-
if (btnStates.ShowNavigation)
348-
{
349-
if (btnStates.ShowPrevButton)
350-
writeLine("8. Previous", background: false);
351-
else if (btnStates.ShowBackButton)
352-
writeLine("8. Back", background: false);
353-
else
354-
writeLine(string.Empty, background: false);
355-
356-
if (btnStates.ShowNextButton)
357-
writeLine("9. Next", background: false);
358-
else
359-
writeLine(string.Empty, background: false);
360-
}
361-
362-
if (btnStates.ShowExitButton)
363-
writeLine("0. Exit", background: true);
364-
}
365-
}
349+
BuildMenuStrings(CurrentMenu, writeLine);
366350

367351
var position = eyeAngles.Position + eyeAngles.Forward * 7.0f + eyeAngles.Right * MenuPosition.X + eyeAngles.Up * MenuPosition.Y;
368352
var angle = new Vector3()
@@ -378,41 +362,84 @@ void writeLine(string text, bool background)
378362
return true;
379363
}
380364

381-
private readonly StringBuilder ForegroundTextSb = new();
382-
private readonly StringBuilder BackgroundTextSb = new();
383-
private readonly StringBuilder BackgroundSb = new();
384365

385-
public void DrawActiveMenuChat()
366+
private readonly StringBuilder HtmlTextSb = new();
367+
public string? HtmlContent { get; set; } = null;
368+
public void DrawActiveMenuHtml()
386369
{
387370
if (CurrentMenu is null)
371+
{
372+
HtmlContent = null;
388373
return;
374+
}
389375

390-
Player.PrintToChat($"{ChatColors.White}{CurrentMenu.Title}:{ChatColors.Default}");
391-
392-
var btnStates = CurrentMenu.GetButtonStates();
393376

394-
var itemsStart = CurrentMenu.CurrentPage * Menu.ItemsPerPage;
395-
var itemsTo = Math.Min(itemsStart + Menu.ItemsPerPage, CurrentMenu.Items.Count);
396-
for (int i = 0; i < Menu.ItemsPerPage && itemsStart + i < itemsTo; i++)
377+
bool firstLine = true;
378+
int linesWrote = 0;
379+
void writeLine(string text, bool background)
397380
{
398-
var item = CurrentMenu.Items[itemsStart + i];
381+
if (string.IsNullOrEmpty(text))
382+
return;
399383

400-
if (item.Enabled)
401-
Player.PrintToChat($"{ChatColors.Yellow}{i + 1}. {item.Title}{ChatColors.Default}");
384+
if (firstLine)
385+
firstLine = false;
402386
else
403-
Player.PrintToChat($"{ChatColors.Grey}{i + 1}. {item.Title}{ChatColors.Default}");
387+
HtmlTextSb.Append("<br>");
404388

405-
if (!string.IsNullOrEmpty(item.Subtitle))
406-
Player.PrintToChat($"{ChatColors.Silver} {item.Subtitle}{ChatColors.Default}");
389+
var color = background ? "#E7CCA5" : "#E28B12";
390+
HtmlTextSb.Append($"<font color='{color}'>{text}</font>");
391+
linesWrote++;
407392
}
408393

409-
if (btnStates.ShowBackButton)
410-
Player.PrintToChat($"{ChatColors.Orange}8. Back{ChatColors.Default}");
411-
if (btnStates.ShowPrevButton)
412-
Player.PrintToChat($"{ChatColors.Orange}8. Previous{ChatColors.Default}");
413-
if (btnStates.ShowNextButton)
414-
Player.PrintToChat($"{ChatColors.Orange}9. Next{ChatColors.Default}");
415-
if (btnStates.ShowExitButton)
416-
Player.PrintToChat($"{ChatColors.White}0. Exit{ChatColors.Default}");
394+
HtmlTextSb.Clear();
395+
HtmlTextSb.Append("<font class='fontSize-s'>");
396+
BuildMenuStrings(CurrentMenu, writeLine);
397+
HtmlTextSb.Append("</font>");
398+
399+
HtmlContent = HtmlTextSb.ToString();
400+
}
401+
402+
private void BuildMenuStrings(Menu currentMenu, Action<string, bool> writeLine)
403+
{
404+
writeLine(currentMenu.Title, true);
405+
406+
var itemsStart = currentMenu.CurrentPage * Menu.ItemsPerPage;
407+
var itemsInPage = Math.Min(currentMenu.Items.Count, itemsStart + Menu.ItemsPerPage) - itemsStart;
408+
409+
for (int i = 0; i < itemsInPage; i++)
410+
{
411+
var item = currentMenu.Items[itemsStart + i];
412+
writeLine($"{i + 1}. {item.Title}", !item.Enabled);
413+
if (item.Subtitle is not null)
414+
writeLine($" {item.Subtitle}", true);
415+
}
416+
417+
var btnStates = currentMenu.GetButtonStates();
418+
if (btnStates.ShowNavigation || btnStates.ShowExitButton)
419+
{
420+
int maxItemsPerPage = Math.Min(Menu.ItemsPerPage, currentMenu.Items.Count);
421+
int blankLines = maxItemsPerPage - itemsInPage + 1;
422+
423+
for (int i = 0; i < blankLines; i++)
424+
writeLine(string.Empty, false);
425+
426+
if (btnStates.ShowNavigation)
427+
{
428+
if (btnStates.ShowPrevButton)
429+
writeLine("8. Previous", false);
430+
else if (btnStates.ShowBackButton)
431+
writeLine("8. Back", false);
432+
else
433+
writeLine(string.Empty, false);
434+
435+
if (btnStates.ShowNextButton)
436+
writeLine("9. Next", false);
437+
else
438+
writeLine(string.Empty, false);
439+
}
440+
441+
if (btnStates.ShowExitButton)
442+
writeLine("0. Exit", true);
443+
}
417444
}
418445
}

src/SharpModMenu/SharpModMenu.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public override void Load(bool hotReload)
2828
DriverInstance = new();
2929
UniversalMenu.RegisterDriver("SharpModMenu", DriverInstance);
3030

31+
RegisterListener<OnTick>(OnTick);
3132
RegisterListener<CheckTransmit>(OnCheckTransmit);
3233
}
3334

@@ -36,7 +37,17 @@ public override void Unload(bool hotReload)
3637
UniversalMenu.UnregisterDriver("SharpModMenu");
3738
}
3839

39-
// prevent transmitting a player's menu entities to other players
40+
private void OnTick()
41+
{
42+
foreach (var menuState in DriverInstance!.ActiveHtmlMenuStates)
43+
{
44+
if (menuState.HtmlContent is null)
45+
continue;
46+
menuState.Player.PrintToCenterHtml(menuState.HtmlContent);
47+
}
48+
}
49+
50+
// prevent transmitting a player's menuState entities to other players
4051
// TODO: hot path, this needs to be extremely quick, precompute data structure for fast iteration
4152
// NOTE: do not replace with foreach, else you will put a lot of pressure on the garbage collector
4253
private void OnCheckTransmit(CCheckTransmitInfoList infoList)

0 commit comments

Comments
 (0)