115 lines
3.7 KiB
C#
115 lines
3.7 KiB
C#
using CounterStrikeSharp.API;
|
|
using CounterStrikeSharp.API.Core;
|
|
using CounterStrikeSharp.API.Modules.Utils;
|
|
using Cs2SuperPowers.Players;
|
|
using Cs2SuperPowers.Players.PlayerValidations;
|
|
|
|
namespace Cs2SuperPowers.Powers;
|
|
|
|
public class Shield(IPlayerHud playerHud) : BasePower(playerHud)
|
|
{
|
|
public override int Id => 32;
|
|
public override string Name => "Shield";
|
|
public override string Description => "Hold E (Use) to activate a shield that blocks all damage! Shield has 100 energy points (regenerates 10 per second when not in use).";
|
|
public override char ChatColor => ChatColors.Yellow;
|
|
public override string HtmlColor => "#FFFF00";
|
|
|
|
private readonly Dictionary<CCSPlayerController, float> _shieldEnergy = new();
|
|
private readonly Dictionary<CCSPlayerController, bool> _shieldActive = new();
|
|
|
|
protected override void OnInitialize()
|
|
{
|
|
RegisterListener<Listeners.OnTick>(OnTick);
|
|
RegisterEventHandler<EventRoundStart>(OnRoundStart);
|
|
RegisterEventHandler<EventPlayerHurt>(OnPlayerHurt);
|
|
}
|
|
|
|
private HookResult OnRoundStart(EventRoundStart @event, GameEventInfo _)
|
|
{
|
|
_shieldEnergy.Clear();
|
|
_shieldActive.Clear();
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
public override void AssignToPlayer(CCSPlayerController player, bool showMessages)
|
|
{
|
|
base.AssignToPlayer(player, showMessages);
|
|
_shieldEnergy[player] = 100.0f;
|
|
_shieldActive[player] = false;
|
|
}
|
|
|
|
public override void UnassignFromPlayer(CCSPlayerController player)
|
|
{
|
|
base.UnassignFromPlayer(player);
|
|
_shieldEnergy.Remove(player);
|
|
_shieldActive.Remove(player);
|
|
}
|
|
|
|
private void OnTick()
|
|
{
|
|
foreach (var player in Utilities.GetPlayers())
|
|
{
|
|
if (!player.IsValid || !player.PawnIsAlive)
|
|
continue;
|
|
|
|
if (!IsAssignedTo(player))
|
|
continue;
|
|
|
|
if (!_shieldEnergy.ContainsKey(player))
|
|
continue;
|
|
|
|
var usePressed = player.Buttons.HasFlag(PlayerButtons.Use);
|
|
|
|
if (usePressed && _shieldEnergy[player] > 0)
|
|
{
|
|
// Shield is active!
|
|
_shieldActive[player] = true;
|
|
_shieldEnergy[player] -= 0.5f; // Consume 0.5 energy per tick
|
|
|
|
// Update HUD (center alert) every second
|
|
if (Math.Abs(_shieldEnergy[player] % 20) < 1)
|
|
{
|
|
player.PrintToCenterAlert($"{ChatColor}Shield: {Math.Ceiling(_shieldEnergy[player])}%");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Shield not active, regenerate
|
|
_shieldActive[player] = false;
|
|
if (_shieldEnergy[player] < 100.0f)
|
|
{
|
|
_shieldEnergy[player] += 0.3f; // Regenerate 0.3 per tick
|
|
if (_shieldEnergy[player] > 100.0f)
|
|
_shieldEnergy[player] = 100.0f;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private HookResult OnPlayerHurt(EventPlayerHurt @event, GameEventInfo info)
|
|
{
|
|
var victim = @event.Userid;
|
|
|
|
if (!Ensure.Player(victim).IsValid().Check() || !IsAssignedTo(victim!))
|
|
{
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
var validatedVictim = victim!;
|
|
if (_shieldActive.GetValueOrDefault(validatedVictim, false))
|
|
{
|
|
var pawn = validatedVictim.PlayerPawn.Value;
|
|
if (pawn == null || !pawn.IsValid)
|
|
{
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
pawn.Health = Math.Min(pawn.MaxHealth, pawn.Health + @event.DmgHealth);
|
|
Utilities.SetStateChanged(pawn, "CBaseEntity", "m_iHealth");
|
|
return HookResult.Handled;
|
|
}
|
|
|
|
return HookResult.Continue;
|
|
}
|
|
}
|