111 lines
3.9 KiB
C#
111 lines
3.9 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 DroppedNades(IPlayerHud playerHud) : BasePower(playerHud)
|
|
{
|
|
private readonly Dictionary<CCSPlayerController, DateTime> _lastUse = new();
|
|
|
|
public override int Id => 34;
|
|
public override string Name => "Dropped Nades";
|
|
public override string Description => "MAG-7 shots drop 5 grenades on the ground. This power is force-only.";
|
|
public override char ChatColor => ChatColors.DarkRed;
|
|
public override string HtmlColor => "#AA0000";
|
|
public override bool CanBeRandomlyAssigned => false;
|
|
|
|
protected override void OnInitialize()
|
|
{
|
|
RegisterEventHandler<EventRoundStart>(OnRoundStart);
|
|
RegisterEventHandler<EventWeaponFire>(OnWeaponFire);
|
|
}
|
|
|
|
private HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info)
|
|
{
|
|
_lastUse.Clear();
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
private HookResult OnWeaponFire(EventWeaponFire @event, GameEventInfo info)
|
|
{
|
|
var controller = @event.Userid;
|
|
if (!Ensure.Player(controller).IsValid().Check() || !IsAssignedTo(controller!))
|
|
{
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
var pawn = controller!.PlayerPawn.Value;
|
|
var weapon = pawn?.WeaponServices?.ActiveWeapon.Value;
|
|
if (pawn == null || !pawn.IsValid || weapon == null || weapon.DesignerName != "weapon_mag7")
|
|
{
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
var now = DateTime.UtcNow;
|
|
if (!GlobalConfig.NoDelayEnabled &&
|
|
_lastUse.TryGetValue(controller, out var lastUseTime) &&
|
|
(now - lastUseTime).TotalSeconds < 0.35)
|
|
{
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
_lastUse[controller] = now;
|
|
|
|
var origin = pawn.AbsOrigin;
|
|
if (origin == null)
|
|
{
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
int grenadeCount = GlobalConfig.GetDroppedNadesCount(5);
|
|
var random = new Random();
|
|
var viewAngle = pawn.V_angle;
|
|
float baseYawRad = viewAngle.Y * MathF.PI / 180f;
|
|
var forward = new Vector(MathF.Cos(baseYawRad), MathF.Sin(baseYawRad), 0.0f);
|
|
var right = new Vector(-forward.Y, forward.X, 0.0f);
|
|
|
|
int droppedGrenades = 0;
|
|
int attempts = 0;
|
|
int maxAttempts = grenadeCount + 8;
|
|
|
|
while (droppedGrenades < grenadeCount && attempts < maxAttempts)
|
|
{
|
|
int i = attempts;
|
|
attempts++;
|
|
float lateralOffset = (float)(random.NextDouble() * 18.0 - 9.0);
|
|
float forwardOffset = (float)(random.NextDouble() * 12.0 + 16.0);
|
|
var spawnPos = new Vector(
|
|
origin.X + forward.X * forwardOffset + right.X * lateralOffset,
|
|
origin.Y + forward.Y * forwardOffset + right.Y * lateralOffset,
|
|
origin.Z + 10.0f
|
|
);
|
|
|
|
float yaw = viewAngle.Y + (float)(random.NextDouble() * 16.0 - 8.0);
|
|
var angle = new QAngle(8.0f, yaw, 0.0f);
|
|
var velocity = new Vector(
|
|
forward.X * (float)(random.NextDouble() * 40.0 + 45.0) + right.X * (float)(random.NextDouble() * 16.0 - 8.0),
|
|
forward.Y * (float)(random.NextDouble() * 40.0 + 45.0) + right.Y * (float)(random.NextDouble() * 16.0 - 8.0),
|
|
(float)(random.NextDouble() * 12.0 + 8.0)
|
|
);
|
|
|
|
var grenadeWeapon = controller.GiveNamedItem<CHEGrenade>("weapon_hegrenade");
|
|
if (grenadeWeapon == null || !grenadeWeapon.IsValid)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (grenadeWeapon.IsHeldByPlayer)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
grenadeWeapon.Teleport(spawnPos, angle, velocity);
|
|
droppedGrenades++;
|
|
}
|
|
return HookResult.Continue;
|
|
}
|
|
}
|