feat: add BasePower abstraction

This commit is contained in:
admin
2026-07-26 23:47:38 +02:00
commit 6dbbfc0dde
83 changed files with 7587 additions and 0 deletions
+149
View File
@@ -0,0 +1,149 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using Cs2SuperPowers.Players;
using Cs2SuperPowers.Players.PlayerValidations;
namespace Cs2SuperPowers.Powers.Assign;
public class RandomAssignLogic : IPowerAssignLogic
{
// Configuration for special rounds
private const double SpecialRoundChance = 0.25;
// Powers that can be assigned during special rounds (everyone gets the same power)
private readonly string[] SpecialRoundPowers =
{
"Go Fast", "Grenade Launcher", "Air Strike", "Not So Decoy", "I Am Chicken!"
};
private readonly List<Delegate> _registeredHandlers = new();
public void Initialize(BasePlugin pluginRef, IReadOnlyCollection<ISuperPower> powers)
{
BasePlugin.GameEventHandler<EventPlayerDisconnect> disconnectHandler = (@event, _) =>
{
var player = @event.Userid;
if (!Ensure.Player(player).IsValid().Check()) return HookResult.Continue;
PlayerPowers.Instance.RemovePower(player!);
return HookResult.Continue;
};
_registeredHandlers.Add(disconnectHandler);
pluginRef.RegisterEventHandler(disconnectHandler);
BasePlugin.GameEventHandler<EventRoundStart> roundStartHandler = (_, _) =>
{
var gameRules = Utilities
.FindAllEntitiesByDesignerName<CBaseEntity>("cs_gamerules")
.Single()
.As<CCSGameRulesProxy>()
.GameRules!;
if (gameRules.WarmupPeriod)
{
return HookResult.Continue;
}
var activePlayerCount = Utilities.GetPlayers().Count(player =>
player.IsValid && player.Team != CsTeam.None && player.Team != CsTeam.Spectator);
var randomAssignablePowers = powers
.Where(p => p.CanBeRandomlyAssigned && p.MinimumPlayersRequired <= activePlayerCount)
.ToArray();
if (randomAssignablePowers.Length == 0)
{
return HookResult.Continue;
}
var random = new Random();
var isSpecialRound = random.NextDouble() < SpecialRoundChance;
if (isSpecialRound)
{
// Special round: everyone gets the same power
var specialRoundCandidates = randomAssignablePowers
.Where(p => SpecialRoundPowers.Contains(p.Name))
.ToArray();
var specialPower = specialRoundCandidates.Length == 0
? null
: specialRoundCandidates[random.Next(specialRoundCandidates.Length)];
if (specialPower != null)
{
// Assign the same power to all players (without individual messages)
foreach (var player in Utilities.GetPlayers())
{
if (player.Team == CsTeam.Spectator || player.Team == CsTeam.None) continue;
PlayerPowers.Instance.AddPower(player!, specialPower, showMessages: false);
}
// Announce special round to all players
Server.PrintToChatAll($"{ChatColors.Gold}SPECIAL ROUND!{ChatColors.Default}");
Server.PrintToChatAll($"{ChatColors.Yellow}Everyone has the same power: {ChatColors.Default}{specialPower.ChatColor}{specialPower.Name}{ChatColors.Default}");
}
else
{
// Fallback to normal assignment if special power not found
foreach (var player in Utilities.GetPlayers())
{
if (player.Team == CsTeam.Spectator || player.Team == CsTeam.None) continue;
var randomPower = randomAssignablePowers.OrderBy(_ => random.Next()).First();
PlayerPowers.Instance.AddPower(player!, randomPower, showMessages: true);
}
}
}
else
{
// Normal round: random powers for each player
foreach (var player in Utilities.GetPlayers())
{
if (player.Team == CsTeam.Spectator || player.Team == CsTeam.None) continue;
var randomPower = randomAssignablePowers.OrderBy(_ => random.Next()).First();
PlayerPowers.Instance.AddPower(player!, randomPower, showMessages: true);
}
// Show individual powers to each team
foreach (var player in Utilities.GetPlayers())
{
var team = player.Team;
player.PrintToChat($"Your {ChatColors.Blue}Team {ChatColors.Default}powers are:");
PlayerPowers.Instance
.GetAssignedPowers()
.Where(x => x.Player.Team == team)
.Select(x => {
player.PrintToChat($"{ChatColors.DarkRed} ► {x.Player.PlayerName} {ChatColors.Default}: {x.Power.ChatColor}{x.Power.Name}");
return x;
})
.ToList();
}
}
return HookResult.Continue;
};
_registeredHandlers.Add(roundStartHandler);
pluginRef.RegisterEventHandler(roundStartHandler, HookMode.Pre);
BasePlugin.GameEventHandler<EventPlayerDeath> deathHandler = (@event, _) =>
{
var victim = @event.Userid;
var attacker = @event.Attacker;
if (victim == null || attacker == null || victim == attacker) return HookResult.Continue;
if (!PlayerPowers.Instance.TryGetValue(attacker, out var attackerPower))
{
return HookResult.Continue;
}
victim.PrintToChat($"You have been killed by {ChatColors.DarkRed}{attacker.PlayerName}{ChatColors.Lime}");
victim.PrintToChat($"His/her super power was: {attackerPower!.ChatColor}{attackerPower.Name}");
return HookResult.Continue;
};
_registeredHandlers.Add(deathHandler);
pluginRef.RegisterEventHandler(deathHandler);
}
}