feat: add BasePower abstraction
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user