jRandomSkills/jRandomSkills - SRC Files/src/player/skills/Bankrupt.cs
ByDexter b0b50a224f QoE Update
## Added

- **`CurseSkillPerPlayer`** (config.json) — limits how many curse skills (Darkness, JumpBan, PrimaryBan, Bankrupt and 14 others) can be stacked on a single player per round. `null` = unlimited (default), `1` = one curse per player, `2` = two. When the limit is reached the target is rejected and the curser gets a chat warning. Enforced centrally in `SkillAction`, so no per-skill code is needed.
- **Tripwire cooldown mode** — replaces the fixed wire limit with a Replicator-style cooldown. Players can place as many wires as they want as long as the cooldown is up; remaining time is shown on the HUD. Configurable via `Cooldown` in skillsInfo.json (default 20s).
- **Tripwire team colors** — T wires red (255, 64, 64), CT wires blue (64, 128, 255).

## Fixed

- **ExpensiveAmmo** also charged money for knife swings and grenade throws. It now only charges when a bullet-firing weapon is fired.
- **Knockback** also triggered on grenade throws; bound to the same allowlist.

## Removed

- Dead code: `Earthquake.cs` and `HealingChicken.cs` (neither was registered in the `Skills` enum, so neither ever ran), `EntityManager.CreateTrackedEnvShake`, `EntityManager.CreateTrackedChicken`, `PlayerManager.UpdatePlayerSkill`.

## Changed

- **Tripwire wires are now removed when the owner dies or loses the skill.** Previously they stayed on the map until the end of the round.
- `PlayerEvents.cs` split into three partial files: player events in `PlayerEvents.cs`, round and skill dispatch in `RoundEvents.cs`, entity and weapon hooks in `EntityEvents.cs`. Behaviour is unchanged; all members stay in the same `Event` class.
- 28 copy-pasted enemy-gathering LINQ chains reduced to the shared helper (Bankrupt, CarefulBullets, Darkness, Deactivator, Deaf, ExpensiveAmmo, Giant, Glitch, Jammer, JumpBan, JumpCurse, LifeSwap, Magnifier, MoneySwap, Nightmare, Poison, PrimaryBan, WildThrow).
2026-07-30 20:52:07 +03:00

132 lines
No EOL
5.5 KiB
C#

using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
namespace src.player.skills
{
public class Bankrupt : ISkill
{
private const Skills skillName = Skills.Bankrupt;
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
foreach (var player in PlayerManager.GetTickPlayers())
{
if (player != null && player.IsValid)
SkillUtils.CloseMenu(player);
}
}
public static void OnTick()
{
if (Server.TickCount % 32 != 0) return;
foreach (var player in PlayerManager.GetTickPlayers())
{
if (player == null || !player.IsValid) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue;
if (!SkillUtils.HasMenu(player)) continue;
var enemies = SkillUtils.GetSelectableEnemies(player, true);
ConcurrentBag<(string, string)> menuItems = [];
foreach (var e in enemies)
{
int money = e.InGameMoneyServices?.Account ?? 0;
menuItems.Add(($"\u202A{e.PlayerName}\u202C : {money}$", e.Index.ToString()));
}
if (!menuItems.IsEmpty)
SkillUtils.UpdateMenu(player, menuItems);
}
}
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
playerInfo.SkillUsed = false;
var enemies = PlayerManager.GetTickPlayers().Where(p => p.IsValid && p.PlayerPawn?.Value?.Health > 0 && p.Team != player.Team && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0)
{
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"\u202A{e.PlayerName}\u202C : {(e.InGameMoneyServices?.Account ?? 0)}$", e.Index.ToString()))];
SkillUtils.CreateMenu(player, menuItems);
}
else
{
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("selectplayerskill_incorrect_enemy_index")}");
}
}
public static void TypeSkill(CCSPlayerController player, string[] commands)
{
if (player == null || !player.IsValid || commands.Length < 1) return;
string option = commands[0];
if (string.IsNullOrEmpty(option)) return;
var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed)
{
playerEvent.PrintToChat($" {ChatColors.Red}{playerEvent.GetTranslation("selectplayerskill_used_info")}");
return;
}
if (uint.TryParse(option, out uint enemyIndex))
{
var enemy = Utilities.GetEntityFromIndex<CCSPlayerController>((int)enemyIndex);
if (enemy != null && enemy.IsValid && enemy.PlayerPawn?.Value?.Health > 0 && enemy.Team != player.Team)
{
ResetMoney(enemy);
playerInfo.SkillUsed = true;
SkillUtils.CloseMenu(player);
playerEvent.PrintToChat($" {ChatColors.Lime}{playerEvent.GetTranslation("bankrupt_player_info", enemy.PlayerName)}");
var enemyEvent = PlayerManager.GetPlayerFromEvent(enemy);
if (enemyEvent != null && enemyEvent.IsValid)
enemyEvent.PrintToChat($" {ChatColors.Red}{enemyEvent.GetTranslation("bankrupt_enemy_info")}");
return;
}
}
playerEvent.PrintToChat($" {ChatColors.Red}{playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")}");
}
private static void ResetMoney(CCSPlayerController enemy)
{
if (enemy == null || !enemy.IsValid) return;
var enemyMoneyServices = enemy.InGameMoneyServices;
if (enemyMoneyServices == null) return;
enemyMoneyServices.Account = 0;
Utilities.SetStateChanged(enemy, "CCSPlayerController", "m_pInGameMoneyServices");
}
public static void DisableSkill(CCSPlayerController player)
{
if (player != null && player.IsValid)
SkillUtils.CloseMenu(player);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#abab33", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = Rarity.Common) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)
{
}
}
}