feat: add BasePower abstraction
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
using CounterStrikeSharp.API.Core;
|
||||
|
||||
namespace Cs2SuperPowers.Powers.Assign;
|
||||
|
||||
public interface IPowerAssignLogic
|
||||
{
|
||||
void Initialize(BasePlugin pluginRef, IReadOnlyCollection<ISuperPower> powers);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user