107 lines
3.7 KiB
C#
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>";
|
|
}
|
|
}
|