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 _shieldEnergy = new(); private readonly Dictionary _shieldActive = new(); protected override void OnInitialize() { RegisterListener(OnTick); RegisterEventHandler(OnRoundStart); RegisterEventHandler(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; } }