Files
CS2-SuperPowers/Cs2SuperPowersPlugin.cs
T
2026-07-26 23:47:38 +02:00

305 lines
12 KiB
C#

using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes.Registration;
using CounterStrikeSharp.API.Modules.Commands;
using CounterStrikeSharp.API.Modules.Utils;
using Cs2SuperPowers.Players;
using Cs2SuperPowers.Powers;
using Cs2SuperPowers.Powers.Assign;
using Microsoft.Extensions.Logging;
namespace Cs2SuperPowers;
public class Cs2SuperPowersPlugin : BasePlugin
{
public override string ModuleName => "Cs2SuperPowersPlugin";
public override string ModuleVersion => "0.1.0";
public override string ModuleAuthor => "Latoch";
public override string ModuleDescription => "This CS2 server plugin unleashes the divine within! Experience a chaotic and exhilarating gameplay where players wield incredible superpowers.";
private readonly ISuperPower[] _superPowers;
private readonly IPowerAssignLogic _powerAssignLogic;
private readonly IPlayerHud _playerHud;
private readonly Random _random = new Random();
// Store listener delegate to prevent garbage collection!
private readonly Listeners.CheckTransmit _checkTransmitHandler;
public Cs2SuperPowersPlugin(IEnumerable<ISuperPower> superPowers, IPowerAssignLogic powerAssignLogic, IPlayerHud playerHud) : base()
{
_superPowers = superPowers.ToArray();
_powerAssignLogic = powerAssignLogic;
_playerHud = playerHud;
// Initialize CheckTransmit handler here to store a reference!
_checkTransmitHandler = OnCheckTransmit;
}
public override void Load(bool hotReload)
{
Logger.LogInformation("Loading {ModuleName} with HotReload = {HotReload}", ModuleName, hotReload);
base.Load(hotReload);
// Register CheckTransmit listener using stored handler!
RegisterListener<Listeners.CheckTransmit>(_checkTransmitHandler);
foreach (var superPower in _superPowers)
{
Logger.LogInformation("Initializing SuperPower {Name} with Id = {Id}", superPower.Name, superPower.Id);
superPower.Initialize(this);
Logger.LogInformation("Finished Initializing SuperPower {Name}", superPower.Name);
}
_playerHud.Initialize(this);
_powerAssignLogic.Initialize(this, _superPowers);
Logger.LogInformation("Finished loading {ModuleName} with HotReload = {HotReload}", ModuleName, hotReload);
}
public void OnCheckTransmit(CCheckTransmitInfoList infoList)
{
foreach ((CCheckTransmitInfo info, CCSPlayerController? player) in infoList)
{
if (player == null || !player.IsValid) continue;
Wallhack._onPlayerTransmitHandler(info, player);
}
}
[ConsoleCommand("css_reroll", "Reroll your super power")]
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
public void OnRerollCommand(CCSPlayerController? player, CommandInfo command)
{
if (player == null || !player.IsValid || !player.PawnIsAlive)
{
return;
}
var activePlayerCount = Utilities.GetPlayers().Count(currentPlayer =>
currentPlayer.IsValid && currentPlayer.Team != CsTeam.None && currentPlayer.Team != CsTeam.Spectator);
var randomAssignablePowers = _superPowers
.Where(power => power.CanBeRandomlyAssigned && power.MinimumPlayersRequired <= activePlayerCount)
.ToArray();
if (randomAssignablePowers.Length == 0)
{
player.PrintToChat("No eligible powers are available right now.");
return;
}
var randomPower = randomAssignablePowers[_random.Next(randomAssignablePowers.Length)];
PlayerPowers.Instance.AddPower(player, randomPower, showMessages: true);
}
[ConsoleCommand("css_forcepower", "Force a super power on a player: /forcepower <player name> <power name or id>")]
[CommandHelper(minArgs: 2, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
public void OnForcePowerCommand(CCSPlayerController? caller, CommandInfo command)
{
var playerNameArg = command.GetArg(1);
var powerArg = command.GetArg(2);
// Find target player
CCSPlayerController? targetPlayer = null;
foreach (var player in Utilities.GetPlayers())
{
if (player.IsValid && player.PlayerName.Contains(playerNameArg, StringComparison.OrdinalIgnoreCase))
{
targetPlayer = player;
break;
}
}
if (targetPlayer == null)
{
command.ReplyToCommand($"Could not find player containing '{playerNameArg}'");
return;
}
// Find power
ISuperPower? targetPower = null;
if (int.TryParse(powerArg, out var powerId))
{
targetPower = _superPowers.FirstOrDefault(p => p.Id == powerId);
}
else
{
targetPower = _superPowers.FirstOrDefault(p => p.Name.Contains(powerArg, StringComparison.OrdinalIgnoreCase));
}
if (targetPower == null)
{
command.ReplyToCommand($"Could not find power '{powerArg}'");
return;
}
// Assign power
PlayerPowers.Instance.AddPower(targetPlayer, targetPower, showMessages: true);
command.ReplyToCommand($"Gave {targetPlayer.PlayerName} the power '{targetPower.Name}'");
}
[ConsoleCommand("css_nodelay", "Turn off cooldowns for Grenade Launcher, Not So Decoy, and Air Strike!")]
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
public void OnNoDelayCommand(CCSPlayerController? caller, CommandInfo command)
{
GlobalConfig.NoDelayEnabled = true;
if (caller != null && caller.IsValid)
{
caller.PrintToChat($"NoDelay mode turned ON! Cooldowns disabled for Grenade Launcher, Not So Decoy, Air Strike!");
}
else
{
Server.PrintToChatAll($"NoDelay mode turned ON! Cooldowns disabled for Grenade Launcher, Not So Decoy, Air Strike!");
}
}
[ConsoleCommand("css_delay", "Turn on cooldowns for Grenade Launcher, Not So Decoy, and Air Strike!")]
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
public void OnDelayCommand(CCSPlayerController? caller, CommandInfo command)
{
GlobalConfig.NoDelayEnabled = false;
if (caller != null && caller.IsValid)
{
caller.PrintToChat($"NoDelay mode turned OFF! Cooldowns re-enabled!");
}
else
{
Server.PrintToChatAll($"NoDelay mode turned OFF! Cooldowns re-enabled!");
}
}
[ConsoleCommand("css_boost", "Shows boost levels for all abilities.")]
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
public void OnBoostCommand(CCSPlayerController? caller, CommandInfo command)
{
string message = $"Boost Levels:\n GrenadeLauncher: {GlobalConfig.GrenadeLauncherBoostLevel} ({GlobalConfig.GetGrenadeLauncherCount(1)}x)\n NotSoDecoy: {GlobalConfig.NotSoDecoyBoostLevel} ({GlobalConfig.GetNotSoDecoyCount(20)} grenades)\n AirStrike: {GlobalConfig.AirStrikeBoostLevel} ({GlobalConfig.GetAirStrikeCount(20)} grenades)\n Dropped Nades: {GlobalConfig.DroppedNadesBoostLevel} ({GlobalConfig.GetDroppedNadesCount(5)} grenades)";
if (caller != null && caller.IsValid)
{
caller.PrintToChat(message);
}
else
{
Server.PrintToChatAll(message);
}
}
[ConsoleCommand("css_boost_grenade", "Sets boost level for GrenadeLauncher (0+).")]
[CommandHelper(minArgs: 1, usage: "[level >= 0]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
public void OnBoostGrenadeCommand(CCSPlayerController? caller, CommandInfo command)
{
if (int.TryParse(command.GetArg(1), out int level) && level >= 0)
{
GlobalConfig.GrenadeLauncherBoostLevel = level;
string message = $"GrenadeLauncher Boost Level set to {level} ({GlobalConfig.GetGrenadeLauncherCount(1)}x)!";
if (caller != null && caller.IsValid)
{
caller.PrintToChat(message);
}
else
{
Server.PrintToChatAll(message);
}
}
else
{
string message = "Invalid level! Use 0 or higher.";
if (caller != null && caller.IsValid)
{
caller.PrintToChat(message);
}
else
{
Server.PrintToChatAll(message);
}
}
}
[ConsoleCommand("css_boost_decoy", "Sets boost level for NotSoDecoy (0+).")]
[CommandHelper(minArgs: 1, usage: "[level >= 0]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
public void OnBoostDecoyCommand(CCSPlayerController? caller, CommandInfo command)
{
if (int.TryParse(command.GetArg(1), out int level) && level >= 0)
{
GlobalConfig.NotSoDecoyBoostLevel = level;
string message = $"NotSoDecoy Boost Level set to {level} ({GlobalConfig.GetNotSoDecoyCount(20)} grenades)!";
if (caller != null && caller.IsValid)
{
caller.PrintToChat(message);
}
else
{
Server.PrintToChatAll(message);
}
}
else
{
string message = "Invalid level! Use 0 or higher.";
if (caller != null && caller.IsValid)
{
caller.PrintToChat(message);
}
else
{
Server.PrintToChatAll(message);
}
}
}
[ConsoleCommand("css_boost_airstrike", "Sets boost level for AirStrike (0+).")]
[CommandHelper(minArgs: 1, usage: "[level >= 0]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
public void OnBoostAirstrikeCommand(CCSPlayerController? caller, CommandInfo command)
{
if (int.TryParse(command.GetArg(1), out int level) && level >= 0)
{
GlobalConfig.AirStrikeBoostLevel = level;
string message = $"AirStrike Boost Level set to {level} ({GlobalConfig.GetAirStrikeCount(20)} grenades)!";
if (caller != null && caller.IsValid)
{
caller.PrintToChat(message);
}
else
{
Server.PrintToChatAll(message);
}
}
else
{
string message = "Invalid level! Use 0 or higher.";
if (caller != null && caller.IsValid)
{
caller.PrintToChat(message);
}
else
{
Server.PrintToChatAll(message);
}
}
}
[ConsoleCommand("css_boost_dropped_nades", "Sets boost level for Dropped Nades (0+).")]
[CommandHelper(minArgs: 1, usage: "[level >= 0]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
public void OnBoostDroppedNadesCommand(CCSPlayerController? caller, CommandInfo command)
{
if (int.TryParse(command.GetArg(1), out int level) && level >= 0)
{
GlobalConfig.DroppedNadesBoostLevel = level;
string message = $"Dropped Nades Boost Level set to {level} ({GlobalConfig.GetDroppedNadesCount(5)} grenades)!";
if (caller != null && caller.IsValid)
{
caller.PrintToChat(message);
}
else
{
Server.PrintToChatAll(message);
}
}
else
{
string message = "Invalid level! Use 0 or higher.";
if (caller != null && caller.IsValid)
{
caller.PrintToChat(message);
}
else
{
Server.PrintToChatAll(message);
}
}
}
}