using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Commands; using CounterStrikeSharp.API.Modules.Utils; namespace Outnumbered; public sealed partial class OutnumberedPlugin { // Player commands ([ConsoleCommand] auto-registers; css_ maps to ! / chat triggers). // Info commands (!rank/!me/!stats/!top/!info) live in Ranks.cs; weapon menu in Weapons.cs; !s1..!sN in Progression.cs. private static readonly string[] PlayerCommandList = { "Shop: switch to the healthshot (X) — numbers select, X = back/close, crouch = quick exit", "!skills — open the skill tree | !s1-!sN — buy a skill directly", "!prestige — reset at level 100 for a permanent boost", "!guns (!weapons, !loadout) — weapon menu | !rifles !smgs !snipers !shotguns !heavy !pistols", "!abilities (!perks) — your killstreak abilities | !ability1-5 — activate one", "!rank (!me) — rank/level/prestige | !stats — live bonuses & handicap", "!top (!leaderboard) — top players | !info (!about, !help) — how it works", "!hud — toggle the HUD | !dmg (!damage) — toggle the per-hit damage readout", "!commands — this list", }; private static readonly string[] AdminCommandList = { "targets: a player name, @me, or @all", "!og_givexp ", "!og_givepoints ", "!og_setlevel ", "!og_setprestige ", "!og_resetplayer — full progression reset", "!og_reload — live-reload config + ranks (no session reset)", }; [ConsoleCommand("css_commands", "List all player commands")] [ConsoleCommand("css_cmds", "List all player commands")] [CommandHelper(0, "", CommandUsage.CLIENT_ONLY)] public void Cmd_Commands(CCSPlayerController? p, CommandInfo info) { if (p is not { IsValid: true }) return; p.PrintToChat($" {ChatColors.Gold}[Outnumbered] Commands:"); foreach (var line in PlayerCommandList) p.PrintToChat($" {ChatColors.Lime}{line}"); } [RequiresPermissions("@outnumbered/admin")] [ConsoleCommand("css_admin_commands", "List admin commands")] [ConsoleCommand("css_admincommands", "List admin commands")] [CommandHelper(0, "", CommandUsage.CLIENT_AND_SERVER)] public void Cmd_AdminCommands(CCSPlayerController? p, CommandInfo info) { if (p is not { IsValid: true }) return; p.PrintToChat($" {ChatColors.Gold}[Outnumbered] Admin commands:"); foreach (var line in AdminCommandList) p.PrintToChat($" {ChatColors.Lime}{line}"); } [ConsoleCommand("css_skills", "Open the skill tree to spend points")] [CommandHelper(0, "", CommandUsage.CLIENT_ONLY)] public void Cmd_Skills(CCSPlayerController? player, CommandInfo info) { if (player is { IsValid: true }) OpenSkillMenu(player); } [ConsoleCommand("css_prestige", "Prestige (at max level) for a permanent boost")] [CommandHelper(0, "", CommandUsage.CLIENT_ONLY)] public void Cmd_Prestige(CCSPlayerController? player, CommandInfo info) { if (player is { IsValid: true }) OpenPrestige(player); } [ConsoleCommand("css_abilities", "Show your killstreak abilities")] [ConsoleCommand("css_perks", "Show your killstreak abilities")] [CommandHelper(0, "", CommandUsage.CLIENT_ONLY)] public void Cmd_Abilities(CCSPlayerController? player, CommandInfo info) { if (player is { IsValid: true }) ShowAbilities(player); } [ConsoleCommand("css_dmg", "Toggle a per-hit final-damage readout (tuning aid)")] [ConsoleCommand("css_damage", "Toggle a per-hit final-damage readout (tuning aid)")] [CommandHelper(0, "", CommandUsage.CLIENT_ONLY)] public void Cmd_Dmg(CCSPlayerController? player, CommandInfo info) { if (player is not { IsValid: true }) return; var sid = player.AuthorizedSteamID?.SteamId64; if (sid is null) return; if (_dmgReadout.Remove(sid.Value)) player.PrintToChat("[Outnumbered] damage readout OFF."); else { _dmgReadout.Add(sid.Value); player.PrintToChat("[Outnumbered] damage readout ON — final hp/armor shown per hit."); } } [ConsoleCommand("css_hud", "Toggle the on-screen HUD on/off")] [CommandHelper(0, "", CommandUsage.CLIENT_ONLY)] public void Cmd_Hud(CCSPlayerController? player, CommandInfo info) { if (player is not { IsValid: true }) return; var sid = player.AuthorizedSteamID?.SteamId64; if (sid is null) return; if (_hudOff.Remove(sid.Value)) player.PrintToChat("[Outnumbered] HUD ON."); else { _hudOff.Add(sid.Value); player.PrintToChat("[Outnumbered] HUD OFF."); DestroyHud(player.Slot); player.PrintToCenterHtml(""); } } // Bindable alternates for the abilities (grenade keys are the primary input; these always work too). // e.g. bind "h" "css_ability1". Registered as a loop tied to the AbilityRegistry (mirrors RegisterSkillCommands), // so a new/reordered ability needs no per-command method. Called from Load. private void RegisterAbilityCommands() { for (int i = 0; i < AbilityCount; i++) { int idx = i; AddCommand($"css_ability{i + 1}", $"Activate ability {i + 1} ({AbilityRegistry[i].Name})", (p, _) => { if (p is { IsValid: true }) TryActivateAbility(p, idx); }); } } }