157 lines
5.9 KiB
C#
157 lines
5.9 KiB
C#
using CounterStrikeSharp.API;
|
|
using CounterStrikeSharp.API.Core;
|
|
using CounterStrikeSharp.API.Core.Attributes;
|
|
using CounterStrikeSharp.API.Modules.Utils;
|
|
using Cs2SuperPowers.Players;
|
|
using Cs2SuperPowers.Players.PlayerValidations;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace Cs2SuperPowers.Powers;
|
|
|
|
public class BlindingLight(IPlayerHud playerHud) : BasePower(playerHud)
|
|
{
|
|
public override int Id => 22;
|
|
public override string Name => "Blinding Light";
|
|
|
|
public override string Description => $"Inflict a blinding flash of light that disorients enemies. Press E (Use) to activate the power.";
|
|
|
|
public override char ChatColor => ChatColors.BlueGrey;
|
|
|
|
public override string HtmlColor => "#cdcece";
|
|
|
|
private readonly List<BlindingLightInfo> _registrations = new();
|
|
|
|
private const int SecondsBetweenActivations = 8;
|
|
|
|
public override void AssignToPlayer(CCSPlayerController player, bool showMessages)
|
|
{
|
|
base.AssignToPlayer(player, showMessages);
|
|
if (!_registrations.Any(r => r.Player == player))
|
|
{
|
|
_registrations.Add(new BlindingLightInfo(player, DateTime.MinValue));
|
|
}
|
|
Plugin!.Logger.LogInformation("BlindingLight assigned to {PlayerName} ({SteamID})", player.PlayerName, player.SteamID);
|
|
}
|
|
|
|
public override void UnassignFromPlayer(CCSPlayerController player)
|
|
{
|
|
base.UnassignFromPlayer(player);
|
|
var registration = _registrations.FirstOrDefault(r => r.Player == player);
|
|
if (registration != null)
|
|
{
|
|
_registrations.Remove(registration);
|
|
}
|
|
Plugin!.Logger.LogInformation("BlindingLight unassigned from {PlayerName} ({SteamID})", player.PlayerName, player.SteamID);
|
|
}
|
|
|
|
protected override void OnInitialize()
|
|
{
|
|
RegisterListener<Listeners.OnTick>(OnTick);
|
|
RegisterEventHandler<EventRoundStart>(OnRoundStart);
|
|
RegisterEventHandler<EventPlayerDeath>(OnPlayerDeath);
|
|
Plugin!.Logger.LogInformation("BlindingLight initialized!");
|
|
}
|
|
|
|
private HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info)
|
|
{
|
|
var player = @event.Userid;
|
|
var registration = _registrations
|
|
.FirstOrDefault(r => r.Player == player);
|
|
if (registration != null)
|
|
{
|
|
registration.WasUsePressedLastTick = false;
|
|
}
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
private HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info)
|
|
{
|
|
_registrations.Clear();
|
|
foreach (var player in PlayerPowers.Instance.GetPlayersWithPower(this))
|
|
{
|
|
_registrations.Add(new BlindingLightInfo(player, DateTime.MinValue));
|
|
}
|
|
Plugin!.Logger.LogInformation("BlindingLight: Round start, registered {Count} players", _registrations.Count);
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
private void OnTick()
|
|
{
|
|
foreach (var registration in _registrations.ToList())
|
|
{
|
|
if (!Ensure.Player(registration.Player).IsValid().Check())
|
|
{
|
|
_registrations.Remove(registration);
|
|
continue;
|
|
}
|
|
|
|
var usePressed = registration.Player.Buttons.HasFlag(PlayerButtons.Use);
|
|
var canUsePower = (DateTime.UtcNow - registration.LastUse).TotalSeconds > SecondsBetweenActivations;
|
|
|
|
if (usePressed && !registration.WasUsePressedLastTick)
|
|
{
|
|
Plugin!.Logger.LogInformation("BlindingLight: {PlayerName} pressed use! CanUse: {CanUse}", registration.Player.PlayerName, canUsePower);
|
|
if (canUsePower)
|
|
{
|
|
ActivatePower(registration);
|
|
}
|
|
else
|
|
{
|
|
var secondsBeforeNextUse =
|
|
SecondsBetweenActivations - (int)(DateTime.UtcNow - registration.LastUse).TotalSeconds;
|
|
registration.Player
|
|
.PrintToCenterAlert($"You need to wait {ChatColors.DarkRed}{secondsBeforeNextUse} {ChatColors.Default}seconds before using the power.");
|
|
}
|
|
}
|
|
|
|
registration.WasUsePressedLastTick = usePressed;
|
|
}
|
|
}
|
|
|
|
private void ActivatePower(BlindingLightInfo registration)
|
|
{
|
|
// Check for at least 1 player in the opposing team
|
|
var playerTeam = registration.Player.Team;
|
|
var enemyCount = Utilities.GetPlayers().Count(p =>
|
|
p.IsValid && p.Team != CsTeam.None && p.Team != CsTeam.Spectator && p.Team != playerTeam);
|
|
Plugin!.Logger.LogInformation("BlindingLight: Activating for {PlayerName}, enemy count: {EnemyCount}", registration.Player.PlayerName, enemyCount);
|
|
|
|
if (enemyCount < 1)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var flashProjectile = Utilities.CreateEntityByName<CFlashbangProjectile>("flashbang_projectile");
|
|
if (flashProjectile == null || !flashProjectile.IsValid)
|
|
{
|
|
Plugin!.Logger.LogError("BlindingLight: Failed to create flashbang projectile!");
|
|
return;
|
|
}
|
|
|
|
var player = registration.Player;
|
|
var pos = player.PlayerPawn.Value!.AbsOrigin;
|
|
pos!.Z += 10;
|
|
|
|
flashProjectile.TicksAtZeroVelocity = 100;
|
|
flashProjectile.TeamNum = player.TeamNum;
|
|
flashProjectile.Teleport(pos, null, new Vector(0, 0, -10));
|
|
flashProjectile.DispatchSpawn();
|
|
flashProjectile.AcceptInput("InitializeSpawnFromWorld", player.PlayerPawn.Value, player.PlayerPawn.Value);
|
|
flashProjectile.DetonateTime = 0;
|
|
|
|
Plugin!.Logger.LogInformation("BlindingLight: Flashbang created and detonated!");
|
|
registration.UpdateUse();
|
|
}
|
|
}
|
|
|
|
public record BlindingLightInfo(CCSPlayerController Player, DateTime LastUse)
|
|
{
|
|
public DateTime LastUse { get; private set; } = LastUse;
|
|
public bool WasUsePressedLastTick { get; set; } = false;
|
|
|
|
public void UpdateUse()
|
|
{
|
|
LastUse = DateTime.UtcNow;
|
|
}
|
|
}
|