Files
2026-07-26 23:47:38 +02:00

107 lines
3.7 KiB
C#

using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using Cs2SuperPowers.Players;
namespace Cs2SuperPowers.Powers;
public class Jetpack(IPlayerHud playerHud) : BasePower(playerHud)
{
private const float MaxFuel = 180.0f;
private const float FuelBurnPerTick = 0.8f;
private const float FuelRechargePerTick = 0.9f;
private const float LiftPerTick = 14.0f;
private const float MaxVerticalSpeed = 260.0f;
private static readonly TimeSpan HudRefreshInterval = TimeSpan.FromMilliseconds(125);
public override int Id => 33;
public override string Name => "Jetpack";
public override string Description => "Hold Jump (Space) to fly with a fuel-based jetpack.";
public override char ChatColor => ChatColors.Orange;
public override string HtmlColor => "#FF8C00";
private readonly Dictionary<CCSPlayerController, float> _fuelByPlayer = new();
private readonly Dictionary<CCSPlayerController, DateTime> _lastHudUpdate = new();
protected override void OnInitialize()
{
RegisterListener<Listeners.OnTick>(OnTick);
RegisterEventHandler<EventRoundStart>(OnRoundStart);
}
private HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info)
{
_fuelByPlayer.Clear();
_lastHudUpdate.Clear();
return HookResult.Continue;
}
public override void AssignToPlayer(CCSPlayerController player, bool showMessages)
{
base.AssignToPlayer(player, showMessages);
_fuelByPlayer[player] = MaxFuel;
_lastHudUpdate.Remove(player);
}
public override void UnassignFromPlayer(CCSPlayerController player)
{
base.UnassignFromPlayer(player);
_fuelByPlayer.Remove(player);
_lastHudUpdate.Remove(player);
}
private void OnTick()
{
foreach (var player in Utilities.GetPlayers())
{
if (!player.IsValid || !player.PawnIsAlive)
continue;
if (!IsAssignedTo(player))
continue;
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid)
continue;
float fuel = _fuelByPlayer.GetValueOrDefault(player, MaxFuel);
bool isJumpPressed = player.Buttons.HasFlag(PlayerButtons.Jump);
if (isJumpPressed && fuel > 0.0f)
{
var currentVelocity = pawn.AbsVelocity;
currentVelocity.Z = Math.Min(currentVelocity.Z + LiftPerTick, MaxVerticalSpeed);
pawn.Teleport(pawn.AbsOrigin, null, currentVelocity);
fuel = Math.Max(0.0f, fuel - FuelBurnPerTick);
}
else
{
fuel = Math.Min(MaxFuel, fuel + FuelRechargePerTick);
}
_fuelByPlayer[player] = fuel;
if (isJumpPressed)
{
var now = DateTime.UtcNow;
if (!_lastHudUpdate.TryGetValue(player, out var lastHudUpdate) ||
now - lastHudUpdate >= HudRefreshInterval)
{
_lastHudUpdate[player] = now;
player.PrintToCenterHtml(BuildFuelMessage(fuel));
}
}
}
}
private static string BuildFuelMessage(float fuel)
{
int percent = (int)MathF.Round((fuel / MaxFuel) * 100.0f);
int filledBars = (int)MathF.Round((fuel / MaxFuel) * 10.0f);
filledBars = Math.Clamp(filledBars, 0, 10);
string bar = new string('|', filledBars).PadRight(10, '.');
string color = percent > 60 ? "#4CAF50" : percent > 30 ? "#FFC107" : "#F44336";
return $"<font color='#FFFFFF'>Jetpack Fuel:</font> <font color='{color}'>{percent}%</font><br><font color='{color}'>{bar}</font>";
}
}