Skip to content

Commit cc03472

Browse files
authored
Merge pull request #21 from schwarper/Update
feat(ScreenMenu): Implement background support feat(ScreenMenu): Add DisplayAt and DisplayAtToAll commands - Displays the menu, starting from the given item. feat(Display): Make time parameter mandatory - Previously, the time parameter defaulted to 0. It must now be specified explicitly.
2 parents 49a284a + 0f9a37b commit cc03472

15 files changed

Lines changed: 161 additions & 60 deletions

API/Class/BaseMenu.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ public virtual ItemOption AddItem(string display, DisableOption disableOption)
7979
/// <param name="time">The duration for which the menu is displayed.</param>
8080
public abstract void Display(CCSPlayerController player, int time);
8181

82+
/// <summary>
83+
/// Displays the menu to a specific player for a specified duration, starting from the given item.
84+
/// </summary>
85+
/// <param name="player">The player to whom the menu is displayed.</param>
86+
/// <param name="firstItem">First item to begin drawing from.</param>
87+
/// <param name="time">The duration for which the menu is displayed.</param>
88+
public abstract void DisplayAt(CCSPlayerController player, int firstItem, int time);
89+
8290
/// <summary>
8391
/// Displays the menu to all players for a specified duration.
8492
/// </summary>
@@ -94,6 +102,23 @@ public void DisplayToAll(int time)
94102
Display(player, time);
95103
}
96104
}
105+
106+
/// <summary>
107+
/// Displays the menu to all players for a specified duration, starting from the given item.
108+
/// <param name="firstItem">First item to begin drawing from.</param>
109+
/// </summary>
110+
/// <param name="time">The duration for which the menu is displayed.</param>
111+
public void DisplayAtToAll(int firstItem, int time)
112+
{
113+
List<CCSPlayerController> players = Utilities.GetPlayers();
114+
foreach (CCSPlayerController player in players)
115+
{
116+
if (player.IsBot)
117+
continue;
118+
119+
DisplayAt(player, firstItem, time);
120+
}
121+
}
97122
}
98123

99124
/// <summary>
@@ -155,6 +180,7 @@ public abstract class BaseMenuInstance(CCSPlayerController player, IMenu menu) :
155180
/// </summary>
156181
protected bool HasExitButton => Menu.ExitButton;
157182

183+
internal int CurrentChoiceIndex;
158184
private readonly Dictionary<string, CommandCallback> _keyCommands = [];
159185

160186
internal void PrevSubMenu()
@@ -273,7 +299,7 @@ internal void DeregisterOnKeyPress()
273299
if (Menu is WasdMenu || (Menu is ScreenMenu screenMenu && screenMenu.MenuType == MenuType.Scrollable))
274300
return;
275301

276-
foreach (var kvp in _keyCommands)
302+
foreach (KeyValuePair<string, CommandCallback> kvp in _keyCommands)
277303
Menu.Plugin.RemoveCommand(kvp.Key, kvp.Value);
278304

279305
_keyCommands.Clear();

API/Class/Config.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,6 @@ public class Cfg
6161
DisabledTextColor = Color.FromArgb(231, 210, 177),
6262
PositionX = -5.5f,
6363
PositionY = 0.0f,
64-
Background = true,
65-
BackgroundHeight = 0,
66-
BackgroundWidth = 0.2f,
6764
Font = "Tahoma Bold",
6865
Size = 32,
6966
FreezePlayer = false,
@@ -134,9 +131,6 @@ public class ScreenMenu
134131
public Color DisabledTextColor { get; set; }
135132
public float PositionX { get; set; }
136133
public float PositionY { get; set; }
137-
public bool Background { get; set; }
138-
public float BackgroundHeight { get; set; }
139-
public float BackgroundWidth { get; set; }
140134
public string Font { get; set; } = string.Empty;
141135
public int Size { get; set; }
142136
public bool FreezePlayer { get; set; }
@@ -215,9 +209,6 @@ public static void LoadConfig()
215209

216210
model.SetIfPresent("ScreenMenu.PositionX", (float value) => Config.ScreenMenu.PositionX = value);
217211
model.SetIfPresent("ScreenMenu.PositionY", (float value) => Config.ScreenMenu.PositionY = value);
218-
model.SetIfPresent("ScreenMenu.Background", (bool value) => Config.ScreenMenu.Background = value);
219-
model.SetIfPresent("ScreenMenu.BackgroundHeight", (float value) => Config.ScreenMenu.BackgroundHeight = value);
220-
model.SetIfPresent("ScreenMenu.BackgroundWidth", (float value) => Config.ScreenMenu.BackgroundWidth = value);
221212
model.SetIfPresent("ScreenMenu.Font", (string value) => Config.ScreenMenu.Font = value);
222213
model.SetIfPresent("ScreenMenu.Size", (int value) => Config.ScreenMenu.Size = value);
223214
model.SetIfPresent("ScreenMenu.FreezePlayer", (bool value) => Config.ScreenMenu.FreezePlayer = value);

API/Class/Library.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ internal static partial class Library
5050

5151
if (size.HasValue)
5252
{
53-
(var newX, var newY, var newSize) = GetWorldTextPosition(player, resolution.PositionX, resolution.PositionY, size.Value);
53+
(float newX, float newY, float newSize) = GetWorldTextPosition(player, resolution.PositionX, resolution.PositionY, size.Value);
5454

5555
resolution.PositionX = newX;
5656
resolution.PositionY = newY;
@@ -113,7 +113,7 @@ private static (float x, float y, float size) GetWorldTextPosition(CCSPlayerCont
113113
return handle.Value;
114114
}
115115

116-
public static CPointWorldText? CreateWorldText(string text, int size, Color color, string font, bool background, float backgroundheight, float backgroundwidth)
116+
public static CPointWorldText? CreateWorldText(string text, int size, Color color, string font, bool background, float offset)
117117
{
118118
CPointWorldText entity = Utilities.CreateEntityByName<CPointWorldText>("point_worldtext")!;
119119

@@ -133,8 +133,9 @@ private static (float x, float y, float size) GetWorldTextPosition(CCSPlayerCont
133133
entity.RenderMode = RenderMode_t.kRenderNormal;
134134

135135
entity.DrawBackground = background;
136-
entity.BackgroundBorderHeight = backgroundheight;
137-
entity.BackgroundBorderWidth = backgroundwidth;
136+
entity.BackgroundBorderHeight = 0.1f;
137+
entity.BackgroundBorderWidth = 0.1f;
138+
entity.DepthOffset = offset;
138139

139140
entity.DispatchSpawn();
140141
return entity;
@@ -145,7 +146,7 @@ public static void CreateFakeWorldText(this CCSPlayerController player, ScreenMe
145146
if (_isFakeCreated)
146147
return;
147148

148-
CPointWorldText? entity = CreateWorldText(" ", 35, Color.Orange, "Arial", false, 0, 0);
149+
CPointWorldText? entity = CreateWorldText(" ", 35, Color.Orange, "Arial", false, 0f);
149150
if (entity == null) { instance.Close(); return; }
150151

151152
CCSGOViewModel? viewModel = player.EnsureCustomView();

API/Class/MenuManager.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using CounterStrikeSharp.API.Core;
22
using CS2MenuManager.API.Interface;
33
using CS2MenuManager.API.Menu;
4-
using static CS2MenuManager.API.Class.ConfigManager;
54
using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
65

76
namespace CS2MenuManager.API.Class;
@@ -54,8 +53,9 @@ internal static void DisposeActiveMenu(CCSPlayerController player)
5453
/// <typeparam name="TMenu">The type of the menu.</typeparam>
5554
/// <param name="player">The player controller.</param>
5655
/// <param name="menu">The menu to open.</param>
56+
/// <param name="firstItem">The index of the first item to display.</param>
5757
/// <param name="createInstance">The function to create a menu instance.</param>
58-
public static void OpenMenu<TMenu>(CCSPlayerController player, TMenu menu, Func<CCSPlayerController, TMenu, IMenuInstance> createInstance)
58+
public static void OpenMenu<TMenu>(CCSPlayerController player, TMenu menu, int? firstItem, Func<CCSPlayerController, TMenu, IMenuInstance> createInstance)
5959
where TMenu : IMenu
6060
{
6161
CloseActiveMenu(player);
@@ -69,6 +69,21 @@ public static void OpenMenu<TMenu>(CCSPlayerController player, TMenu menu, Func<
6969
{
7070
baseMenuInstance.RegisterOnKeyPress();
7171
baseMenuInstance.RegisterPlayerDisconnectEvent();
72+
73+
if (firstItem.HasValue)
74+
{
75+
int item = Math.Clamp(firstItem.Value, 0, menu.ItemOptions.Count - 1);
76+
77+
while (baseMenuInstance.CurrentChoiceIndex != item)
78+
{
79+
baseMenuInstance.CurrentChoiceIndex++;
80+
81+
if (baseMenuInstance.CurrentChoiceIndex >= baseMenuInstance.CurrentOffset + baseMenuInstance.NumPerPage)
82+
baseMenuInstance.NextPage();
83+
}
84+
85+
baseMenuInstance.CurrentChoiceIndex -= baseMenuInstance.CurrentOffset;
86+
}
7287
}
7388

7489
Timer? timer = menu.MenuTime > 0 ?

API/Interface/IMenu.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,26 @@ public interface IMenu
6363
/// <param name="time">The duration for which the menu is displayed.</param>
6464
void Display(CCSPlayerController player, int time);
6565

66+
/// <summary>
67+
/// Displays the menu to a specific player for a specified duration, starting from the given item.
68+
/// </summary>
69+
/// <param name="player">The player to whom the menu is displayed.</param>
70+
/// <param name="firstItem">First item to begin drawing from.</param>
71+
/// <param name="time">The duration for which the menu is displayed.</param>
72+
void DisplayAt(CCSPlayerController player, int firstItem, int time);
73+
6674
/// <summary>
6775
/// Displays the menu to all players for a specified duration.
6876
/// </summary>
6977
/// <param name="time">The duration for which the menu is displayed.</param>
7078
void DisplayToAll(int time);
79+
80+
/// <summary>
81+
/// Displays the menu to all players for a specified duration, starting from the given item.
82+
/// <param name="firstItem">First item to begin drawing from.</param>
83+
/// </summary>
84+
/// <param name="time">The duration for which the menu is displayed.</param>
85+
void DisplayAtToAll(int firstItem, int time);
7186
}
7287

7388
/// <summary>

API/Menu/CenterHtmlMenu.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,24 @@ static CenterHtmlMenu()
7171
/// </summary>
7272
/// <param name="player">The player to whom the menu is displayed.</param>
7373
/// <param name="time">The duration for which the menu is displayed.</param>
74-
public override void Display(CCSPlayerController player, int time = 0)
74+
public override void Display(CCSPlayerController player, int time)
7575
{
7676
Title = Title.TruncateHtml(MaxTitleLength);
7777
MenuTime = time;
78-
MenuManager.OpenMenu(player, this, (p, m) => new CenterHtmlMenuInstance(p, m));
78+
MenuManager.OpenMenu(player, this, null, (p, m) => new CenterHtmlMenuInstance(p, m));
79+
}
80+
81+
/// <summary>
82+
/// Displays the menu to the specified player for a specified duration, starting from the given item.
83+
/// </summary>
84+
/// <param name="player">The player to whom the menu is displayed.</param>
85+
/// <param name="firstItem">The index of the first item to display.</param>
86+
/// <param name="time">The duration for which the menu is displayed.</param>
87+
public override void DisplayAt(CCSPlayerController player, int firstItem, int time)
88+
{
89+
Title = Title.TruncateHtml(MaxTitleLength);
90+
MenuTime = time;
91+
MenuManager.OpenMenu(player, this, firstItem, (p, m) => new CenterHtmlMenuInstance(p, m));
7992
}
8093
}
8194

API/Menu/ChatMenu.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,22 @@ static ChatMenu()
5353
/// </summary>
5454
/// <param name="player">The player to whom the menu is displayed.</param>
5555
/// <param name="time">The duration for which the menu is displayed.</param>
56-
public override void Display(CCSPlayerController player, int time = 0)
56+
public override void Display(CCSPlayerController player, int time)
5757
{
5858
MenuTime = time;
59-
MenuManager.OpenMenu(player, this, (p, m) => new ChatMenuInstance(p, m));
59+
MenuManager.OpenMenu(player, this, null, (p, m) => new ChatMenuInstance(p, m));
60+
}
61+
62+
/// <summary>
63+
/// Displays the menu to the specified player for a specified duration, starting from the given item.
64+
/// </summary>
65+
/// <param name="player">The player to whom the menu is displayed.</param>
66+
/// <param name="firstItem">The index of the first item to display.</param>
67+
/// <param name="time">The duration for which the menu is displayed.</param>
68+
public override void DisplayAt(CCSPlayerController player, int firstItem, int time)
69+
{
70+
MenuTime = time;
71+
MenuManager.OpenMenu(player, this, firstItem, (p, m) => new ChatMenuInstance(p, m));
6072
}
6173
}
6274

API/Menu/ConsoleMenu.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,22 @@ public class ConsoleMenu(string title, BasePlugin plugin) : BaseMenu(title, plug
1818
/// </summary>
1919
/// <param name="player">The player to whom the menu is displayed.</param>
2020
/// <param name="time">The duration for which the menu is displayed.</param>
21-
public override void Display(CCSPlayerController player, int time = 0)
21+
public override void Display(CCSPlayerController player, int time)
2222
{
2323
MenuTime = time;
24-
MenuManager.OpenMenu(player, this, (p, m) => new ConsoleMenuInstance(p, m));
24+
MenuManager.OpenMenu(player, this, null, (p, m) => new ConsoleMenuInstance(p, m));
25+
}
26+
27+
/// <summary>
28+
/// Displays the menu to the specified player for a specified duration, starting from the given item.
29+
/// </summary>
30+
/// <param name="player">The player to whom the menu is displayed.</param>
31+
/// <param name="firstItem">The index of the first item to display.</param>
32+
/// <param name="time">The duration for which the menu is displayed.</param>
33+
public override void DisplayAt(CCSPlayerController player, int firstItem, int time)
34+
{
35+
MenuTime = time;
36+
MenuManager.OpenMenu(player, this, firstItem, (p, m) => new ConsoleMenuInstance(p, m));
2537
}
2638
}
2739

API/Menu/ScreenMenu.cs

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,6 @@ static ScreenMenu()
3636
/// </summary>
3737
public Color DisabledTextColor { get; set; } = Config.ScreenMenu.DisabledTextColor;
3838

39-
/// <summary>
40-
/// Gets or sets a value indicating whether the menu has a background.
41-
/// </summary>
42-
public bool Background { get; set; } = Config.ScreenMenu.Background;
43-
44-
/// <summary>
45-
/// Gets or sets the height of the background.
46-
/// </summary>
47-
public float BackgroundHeight { get; set; } = Config.ScreenMenu.BackgroundHeight;
48-
49-
/// <summary>
50-
/// Gets or sets the width of the background.
51-
/// </summary>
52-
public float BackgroundWidth { get; set; } = Config.ScreenMenu.BackgroundWidth;
53-
5439
/// <summary>
5540
/// Gets or sets the font used for the text.
5641
/// </summary>
@@ -101,10 +86,22 @@ static ScreenMenu()
10186
/// </summary>
10287
/// <param name="player">The player to whom the menu is displayed.</param>
10388
/// <param name="time">The duration for which the menu is displayed.</param>
104-
public override void Display(CCSPlayerController player, int time = 0)
89+
public override void Display(CCSPlayerController player, int time)
10590
{
10691
MenuTime = time;
107-
MenuManager.OpenMenu(player, this, (p, m) => new ScreenMenuInstance(p, m));
92+
MenuManager.OpenMenu(player, this, null, (p, m) => new ScreenMenuInstance(p, m));
93+
}
94+
95+
/// <summary>
96+
/// Displays the menu to the specified player for a specified duration, starting from the given item.
97+
/// </summary>
98+
/// <param name="player">The player to whom the menu is displayed.</param>
99+
/// <param name="firstItem">The index of the first item to display.</param>
100+
/// <param name="time">The duration for which the menu is displayed.</param>
101+
public override void DisplayAt(CCSPlayerController player, int firstItem, int time)
102+
{
103+
MenuTime = time;
104+
MenuManager.OpenMenu(player, this, firstItem, (p, m) => new ScreenMenuInstance(p, m));
108105
}
109106
}
110107

@@ -115,11 +112,6 @@ public class ScreenMenuInstance : BaseMenuInstance
115112
{
116113
private readonly Dictionary<string, Action> Buttons = [];
117114

118-
/// <summary>
119-
/// Gets or sets the index of the currently selected option.
120-
/// </summary>
121-
public int CurrentChoiceIndex;
122-
123115
/// <summary>
124116
/// Gets the number of items displayed per page.
125117
/// </summary>
@@ -172,6 +164,7 @@ public override void Display()
172164

173165
List<(string Text, int GlobalIndex, bool disabled)> visibleOptions = GetVisibleOptions();
174166

167+
int maxLength = 0;
175168
for (int i = 0; i < visibleOptions.Count; i++)
176169
{
177170
(string text, int _, bool disabled) = visibleOptions[i];
@@ -193,6 +186,9 @@ public override void Display()
193186
noneOptions.AppendLine(displayLine);
194187
disabledOptions.AppendLine();
195188
}
189+
190+
if (maxLength < displayLine.Length)
191+
maxLength = displayLine.Length;
196192
}
197193

198194
noneOptions.AppendLine();
@@ -206,15 +202,25 @@ public override void Display()
206202
disabledOptions.AppendLine(Player.Localizer("SelectKey", screenMenu.SelectKey));
207203
}
208204

209-
UpdateWorldText(ref WorldText, noneOptions.ToString(), screenMenu, screenMenu.TextColor);
210-
UpdateWorldText(ref WorldTextDisabled, disabledOptions.ToString(), screenMenu, screenMenu.DisabledTextColor);
205+
for (int i = 0; i < maxLength - 5; i++)
206+
disabledOptions.Append('ᅠ');
207+
208+
UpdateWorldText(ref WorldText, noneOptions.ToString(), false, screenMenu, screenMenu.TextColor);
209+
UpdateWorldText(ref WorldTextDisabled, disabledOptions.ToString(), true, screenMenu, screenMenu.DisabledTextColor);
211210
}
212211

213-
private static void UpdateWorldText(ref CPointWorldText? worldText, string message, ScreenMenu screenMenu, Color color)
212+
private static void UpdateWorldText(ref CPointWorldText? worldText, string message, bool background, ScreenMenu screenMenu, Color color)
214213
{
215214
if (worldText == null || !worldText.IsValid)
216215
{
217-
worldText = CreateWorldText(message, screenMenu.Size, color, screenMenu.Font, false, screenMenu.BackgroundHeight, screenMenu.BackgroundWidth);
216+
worldText = CreateWorldText(
217+
message,
218+
screenMenu.Size,
219+
color,
220+
screenMenu.Font,
221+
background,
222+
background ? -0.001f : 0f
223+
);
218224
}
219225
else
220226
{
@@ -403,6 +409,7 @@ private void HandleOption(int globalIndex)
403409
int end = Math.Min(start + NumPerPage, totalItems);
404410

405411
int displayNumber = 1;
412+
int maxLength = 0;
406413
for (int i = start; i < end; i++)
407414
{
408415
ItemOption option = Menu.ItemOptions[i];
@@ -417,6 +424,9 @@ private void HandleOption(int globalIndex)
417424

418425
visible.Add((text, i, option.DisableOption != DisableOption.None));
419426
displayNumber++;
427+
428+
if (text.Length > maxLength)
429+
maxLength = text.Length;
420430
}
421431

422432
if (visible.Count > 0)

0 commit comments

Comments
 (0)