Files
CS2-SimpleAdmin/Modules/CS2-SimpleAdmin_FunCommands/CS2-SimpleAdmin_FunCommands/Menus.cs
Dawid Bepierszcz 78318102fe Refactor fun commands to external module
Commented out fun command implementations (noclip, godmode, freeze, unfreeze, resize) in funcommands.cs and removed their registration from RegisterCommands.cs. These commands are now intended to be provided by the new CS2-SimpleAdmin_FunCommands external module, improving modularity and maintainability.
2025-10-19 03:12:58 +02:00

391 lines
15 KiB
C#

using System.Globalization;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
namespace CS2_SimpleAdmin_FunCommands;
/// <summary>
/// Menu creation methods for Fun Commands module.
/// This file demonstrates different menu patterns using SimpleAdmin API.
/// </summary>
public partial class CS2_SimpleAdmin_FunCommands
{
// =================================
// SIMPLE PLAYER SELECTION MENUS
// =================================
// Pattern: Direct player selection with immediate action
// Use CreateMenuWithPlayers when you just need to select a player and execute an action
/// <summary>
/// Creates a simple player selection menu for god mode.
/// PATTERN: CreateMenuWithPlayers with method reference
/// </summary>
private object CreateGodModeMenu(CCSPlayerController admin)
{
return _sharedApi!.CreateMenuWithPlayers(
Localizer?["fun_menu_god"] ?? "God Mode", // Menu title from translation
"fun", // Category ID (for back button navigation)
admin, // Admin opening the menu
player => player.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE && admin.CanTarget(player), // Filter: only alive, targetable players
God); // Action to execute (method reference)
}
private object CreateNoClipMenu(CCSPlayerController admin)
{
return _sharedApi!.CreateMenuWithPlayers(
Localizer?["fun_menu_noclip"] ?? "No Clip",
"fun",
admin,
player => player.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE && admin.CanTarget(player),
NoClip);
}
/// <summary>
/// Creates a player selection menu for respawn command.
/// PATTERN: CreateMenuWithPlayers with method reference
/// </summary>
private object CreateRespawnMenu(CCSPlayerController admin)
{
return _sharedApi!.CreateMenuWithPlayers(
Localizer?["fun_menu_respawn"] ?? "Respawn", // Menu title from translation
"fun", // Category ID
admin, // Admin
admin.CanTarget, // Filter: only targetable players (no LifeState check - can respawn dead players)
Respawn); // Use the Respawn method which includes death position teleport
}
// =================================
// NESTED MENUS - PLAYER → VALUE SELECTION
// =================================
// Pattern: First select player, then select a value/option for that player
// Use CreateMenuWithBack + AddSubMenu for multi-level menus
/// <summary>
/// Creates a nested menu: Player selection → Weapon selection.
/// PATTERN: CreateMenuWithBack + foreach + AddSubMenu
/// </summary>
private object CreateGiveWeaponMenu(CCSPlayerController admin)
{
var menu = _sharedApi!.CreateMenuWithBack(
Localizer?["fun_menu_give"] ?? "Give Weapon",
"fun",
admin);
var players = _sharedApi.GetValidPlayers().Where(p =>
p.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE && admin.CanTarget(p));
foreach (var player in players)
{
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName;
// AddSubMenu automatically adds a "Back" button to the submenu
// The lambda receives 'p' but we use captured 'player' variable (closure)
_sharedApi.AddSubMenu(menu, playerName, p => CreateWeaponSelectionMenu(admin, player));
}
return menu;
}
/// <summary>
/// Creates weapon selection submenu for a specific player.
/// PATTERN: CreateMenuWithBack + foreach + AddMenuOption
/// </summary>
private object CreateWeaponSelectionMenu(CCSPlayerController admin, CCSPlayerController target)
{
var weaponMenu = _sharedApi!.CreateMenuWithBack(
Localizer?["fun_menu_give_player", target.PlayerName] ?? $"Give Weapon: {target.PlayerName}",
"fun",
admin);
// Loop through cached weapons (performance optimization)
foreach (var weapon in GetWeaponsCache())
{
// AddMenuOption for each selectable option
// IMPORTANT: Always validate target.IsValid before executing action
_sharedApi.AddMenuOption(weaponMenu, weapon.Value.ToString(), _ =>
{
if (target.IsValid) // Player might disconnect before selection
{
target.GiveNamedItem(weapon.Value);
LogAndShowActivity(admin, target, "fun_admin_give_message", $"css_give", weapon.Value.ToString());
}
});
}
return weaponMenu;
}
private object CreateStripWeaponsMenu(CCSPlayerController admin)
{
return _sharedApi!.CreateMenuWithPlayers(
Localizer?["fun_menu_strip"] ?? "Strip Weapons",
"fun",
admin,
player => player.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE && admin.CanTarget(player),
(adminPlayer, targetPlayer) =>
{
targetPlayer.RemoveWeapons();
LogAndShowActivity(adminPlayer, targetPlayer, "fun_admin_strip_message", "css_strip");
});
}
private object CreateFreezeMenu(CCSPlayerController admin)
{
return _sharedApi!.CreateMenuWithPlayers(
Localizer?["fun_menu_freeze"] ?? "Freeze",
"fun",
admin,
player => player.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE && admin.CanTarget(player),
(adminPlayer, targetPlayer) => { Freeze(adminPlayer, targetPlayer, -1); });
}
/// <summary>
/// Creates a nested menu for setting player HP with predefined values.
/// PATTERN: Same as Give Weapon (player selection → value selection)
/// This is a common pattern you'll use frequently!
/// </summary>
private object CreateSetHpMenu(CCSPlayerController admin)
{
var menu = _sharedApi!.CreateMenuWithBack(
Localizer?["fun_menu_hp"] ?? "Set HP",
"fun",
admin);
var players = _sharedApi.GetValidPlayers().Where(p =>
p.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE && admin.CanTarget(p));
foreach (var player in players)
{
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName;
_sharedApi.AddSubMenu(menu, playerName, p => CreateHpSelectionMenu(admin, player));
}
return menu;
}
/// <summary>
/// Creates HP value selection submenu.
/// TIP: Use arrays for predefined values - easy to modify and maintain
/// </summary>
private object CreateHpSelectionMenu(CCSPlayerController admin, CCSPlayerController target)
{
var hpSelectionMenu = _sharedApi!.CreateMenuWithBack(
Localizer?["fun_menu_hp_player", target.PlayerName] ?? $"Set HP: {target.PlayerName}",
"fun",
admin);
// Predefined HP values - easy to customize
var hpValues = new[] { 1, 10, 25, 50, 100, 200, 500, 999 };
foreach (var hp in hpValues)
{
_sharedApi.AddMenuOption(hpSelectionMenu,
Localizer?["fun_menu_hp_value", hp] ?? $"{hp} HP",
_ =>
{
if (target.IsValid)
{
target.SetHp(hp);
LogAndShowActivity(admin, target, "fun_admin_hp_message", "css_hp", hp.ToString());
}
});
}
return hpSelectionMenu;
}
private object CreateSetSpeedMenu(CCSPlayerController admin)
{
var menu = _sharedApi!.CreateMenuWithBack(
Localizer?["fun_menu_speed"] ?? "Set Speed",
"fun",
admin);
var players = _sharedApi.GetValidPlayers().Where(p =>
p.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE && admin.CanTarget(p));
foreach (var player in players)
{
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName;
_sharedApi.AddSubMenu(menu, playerName, p => CreateSpeedSelectionMenu(admin, player));
}
return menu;
}
/// <summary>
/// Creates speed value selection submenu.
/// TIP: Use tuples (value, display) when you need different internal value vs display text
/// Example: (0.5f, "0.5") - float value for code, string for display
/// </summary>
private object CreateSpeedSelectionMenu(CCSPlayerController admin, CCSPlayerController target)
{
var speedSelectionMenu = _sharedApi!.CreateMenuWithBack(
Localizer?["fun_menu_speed_player", target.PlayerName] ?? $"Set Speed: {target.PlayerName}",
"fun",
admin);
// Tuple pattern: (actualValue, displayText)
// Useful when display text differs from actual value
var speedValues = new[]
{
(0.1f, "0.1"), (0.25f, "0.25"), (0.5f, "0.5"), (0.75f, "0.75"), (1f, "1"), (2f, "2"), (3f, "3"), (4f, "4")
};
foreach (var (speed, display) in speedValues)
{
_sharedApi.AddMenuOption(speedSelectionMenu,
Localizer?["fun_menu_speed_value", display] ?? $"Speed {display}",
_ =>
{
if (target.IsValid)
{
target.SetSpeed(speed);
// Track speed modification for timer
if (speed == 1f)
SpeedPlayers.Remove(target);
else
SpeedPlayers[target] = speed;
LogAndShowActivity(admin, target, "fun_admin_speed_message", "css_speed", speed.ToString(CultureInfo.InvariantCulture));
}
});
}
return speedSelectionMenu;
}
private object CreateSetGravityMenu(CCSPlayerController admin)
{
var menu = _sharedApi!.CreateMenuWithBack(
Localizer?["fun_menu_gravity"] ?? "Set Gravity",
"fun",
admin);
var players = _sharedApi.GetValidPlayers().Where(p =>
p.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE && admin.CanTarget(p));
foreach (var player in players)
{
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName;
_sharedApi.AddSubMenu(menu, playerName, p => CreateGravitySelectionMenu(admin, player));
}
return menu;
}
private object CreateGravitySelectionMenu(CCSPlayerController admin, CCSPlayerController target)
{
var gravitySelectionMenu = _sharedApi!.CreateMenuWithBack(
Localizer?["fun_menu_gravity_player", target.PlayerName] ?? $"Set Gravity: {target.PlayerName}",
"fun",
admin);
var gravityValues = new[]
{ (0.1f, "0.1"), (0.25f, "0.25"), (0.5f, "0.5"), (0.75f, "0.75"), (1f, "1"), (2f, "2") };
foreach (var (gravity, display) in gravityValues)
{
_sharedApi.AddMenuOption(gravitySelectionMenu,
Localizer?["fun_menu_gravity_value", display] ?? $"Gravity {display}",
_ =>
{
if (target.IsValid)
{
target.SetGravity(Convert.ToSingle(gravity, CultureInfo.InvariantCulture));
// Track gravity modification for timer
if (gravity == 1f)
GravityPlayers.Remove(target);
else
GravityPlayers[target] = gravity;
LogAndShowActivity(admin, target, "fun_admin_gravity_message", "css_gravity", gravity.ToString(CultureInfo.InvariantCulture));
}
});
}
return gravitySelectionMenu;
}
private object CreateSetMoneyMenu(CCSPlayerController admin)
{
var menu = _sharedApi!.CreateMenuWithBack(
Localizer?["fun_menu_money"] ?? "Set Money",
"fun",
admin);
var players = _sharedApi.GetValidPlayers().Where(p => admin.CanTarget(p));
foreach (var player in players)
{
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName;
_sharedApi.AddSubMenu(menu, playerName, p => CreateMoneySelectionMenu(admin, player));
}
return menu;
}
private object CreateMoneySelectionMenu(CCSPlayerController admin, CCSPlayerController target)
{
var moneySelectionMenu = _sharedApi!.CreateMenuWithBack(
Localizer?["fun_menu_money_player", target.PlayerName] ?? $"Set Money: {target.PlayerName}",
"fun",
admin);
var moneyValues = new[] { 0, 1000, 2500, 5000, 10000, 16000 };
foreach (var money in moneyValues)
{
_sharedApi.AddMenuOption(moneySelectionMenu,
Localizer?["fun_menu_money_value", money] ?? $"${money}",
_ =>
{
if (target.IsValid)
{
target.SetMoney(money);
LogAndShowActivity(admin, target, "fun_admin_money_message", "css_money", money.ToString());
}
});
}
return moneySelectionMenu;
}
private object CreateSetResizeMenu(CCSPlayerController admin)
{
var menu = _sharedApi!.CreateMenuWithBack(
Localizer?["fun_menu_resize"] ?? "Resize Player",
"fun",
admin);
var players = _sharedApi.GetValidPlayers().Where(p =>
p.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE && admin.CanTarget(p));
foreach (var player in players)
{
var playerName = player.PlayerName.Length > 26 ? player.PlayerName[..26] : player.PlayerName;
_sharedApi.AddSubMenu(menu, playerName, p => CreateResizeSelectionMenu(admin, player));
}
return menu;
}
private object CreateResizeSelectionMenu(CCSPlayerController admin, CCSPlayerController target)
{
var resizeSelectionMenu = _sharedApi!.CreateMenuWithBack(
Localizer?["fun_menu_resize_player", target.PlayerName] ?? $"Resize: {target.PlayerName}",
"fun",
admin);
var resizeValues = new[]
{ (0.5f, "0.5"), (0.75f, "0.75"), (1f, "1"), (1.25f, "1.25"), (1.5f, "1.5"), (2f, "2"), (3f, "3") };
foreach (var (resize, display) in resizeValues)
{
_sharedApi.AddMenuOption(resizeSelectionMenu,
Localizer?["fun_menu_resize_value", display] ?? $"Size {display}",
_ =>
{
if (target.IsValid)
{
Resize(admin, target, resize);
}
});
}
return resizeSelectionMenu;
}
}