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 _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(OnRoundStart); RegisterEventHandler(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("weapon_hegrenade"); if (grenadeWeapon == null || !grenadeWeapon.IsValid) { continue; } if (grenadeWeapon.IsHeldByPlayer) { continue; } grenadeWeapon.Teleport(spawnPos, angle, velocity); droppedGrenades++; } return HookResult.Continue; } }