128 lines
4.1 KiB
C#
128 lines
4.1 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 DoubleJump(IPlayerHud playerHud) : BasePower(playerHud)
|
|
{
|
|
public override int Id => 28;
|
|
public override string Name => "Double Jump";
|
|
public override string Description => "Jump again in mid-air! A classic double jump ability.";
|
|
public override char ChatColor => ChatColors.Blue;
|
|
public override string HtmlColor => "#0000FF";
|
|
|
|
private readonly Dictionary<CCSPlayerController, bool> _canDoubleJump = new();
|
|
private readonly Dictionary<CCSPlayerController, bool> _wasOnGround = new();
|
|
private readonly Dictionary<CCSPlayerController, bool> _requireJumpRelease = new();
|
|
|
|
protected override void OnInitialize()
|
|
{
|
|
RegisterListener<Listeners.OnTick>(OnTick);
|
|
RegisterEventHandler<EventRoundStart>(OnRoundStart);
|
|
RegisterEventHandler<EventPlayerHurt>(OnPlayerHurt);
|
|
}
|
|
|
|
private HookResult OnRoundStart(EventRoundStart @event, GameEventInfo _)
|
|
{
|
|
_canDoubleJump.Clear();
|
|
_wasOnGround.Clear();
|
|
_requireJumpRelease.Clear();
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
public override void AssignToPlayer(CCSPlayerController player, bool showMessages)
|
|
{
|
|
base.AssignToPlayer(player, showMessages);
|
|
_canDoubleJump[player] = true;
|
|
_wasOnGround[player] = true;
|
|
_requireJumpRelease[player] = false;
|
|
}
|
|
|
|
public override void UnassignFromPlayer(CCSPlayerController player)
|
|
{
|
|
base.UnassignFromPlayer(player);
|
|
_canDoubleJump.Remove(player);
|
|
_wasOnGround.Remove(player);
|
|
_requireJumpRelease.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;
|
|
|
|
var isOnGround = pawn.GroundEntity.IsValid;
|
|
var jumpPressed = player.Buttons.HasFlag(PlayerButtons.Jump);
|
|
var wasOnGroundLastTick = _wasOnGround.GetValueOrDefault(player, true);
|
|
|
|
if (isOnGround)
|
|
{
|
|
_canDoubleJump[player] = true;
|
|
_requireJumpRelease[player] = false;
|
|
}
|
|
else if (wasOnGroundLastTick)
|
|
{
|
|
_canDoubleJump[player] = true;
|
|
_requireJumpRelease[player] = jumpPressed;
|
|
}
|
|
|
|
if (!isOnGround && !jumpPressed)
|
|
{
|
|
_requireJumpRelease[player] = false;
|
|
}
|
|
|
|
if (!isOnGround &&
|
|
jumpPressed &&
|
|
!_requireJumpRelease.GetValueOrDefault(player, false) &&
|
|
_canDoubleJump.GetValueOrDefault(player, false))
|
|
{
|
|
var velocity = pawn.AbsVelocity;
|
|
velocity.Z = Math.Max(velocity.Z, 300.0f);
|
|
pawn.Teleport(pawn.AbsOrigin, null, velocity);
|
|
_canDoubleJump[player] = false;
|
|
_requireJumpRelease[player] = true;
|
|
}
|
|
|
|
_wasOnGround[player] = isOnGround;
|
|
}
|
|
}
|
|
|
|
private HookResult OnPlayerHurt(EventPlayerHurt @event, GameEventInfo info)
|
|
{
|
|
var victim = @event.Userid;
|
|
if (!Ensure.Player(victim).IsValid().Check() || !IsAssignedTo(victim!))
|
|
{
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
bool isWorldDamage = !Ensure.Player(@event.Attacker).IsValid().Check();
|
|
bool hasNoWeapon = string.IsNullOrEmpty(@event.Weapon);
|
|
|
|
if (!isWorldDamage || !hasNoWeapon)
|
|
{
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
var pawn = victim!.PlayerPawn.Value;
|
|
if (pawn == null || !pawn.IsValid)
|
|
{
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
pawn.Health = Math.Min(pawn.MaxHealth, pawn.Health + @event.DmgHealth);
|
|
return HookResult.Stop;
|
|
}
|
|
}
|