using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static CounterStrikeSharp.API.Core.Listeners; using static jRandomSkills.jRandomSkills; namespace jRandomSkills { public class PsychicDefusing : ISkill { private const Skills skillName = Skills.PsychicDefusing; private static readonly Dictionary SkillPlayerInfo = []; private static Vector? bombLocation = null; private static readonly float maxDefusingRange = Config.GetValue(skillName, "maxDefusingRange"); private static readonly float defusingTime = Config.GetValue(skillName, "defusingTime"); private static readonly float tickRate = 64f; public static void LoadSkill() { SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); Instance.RegisterEventHandler((@event, info) => { Instance.AddTimer(0.1f, () => { foreach (var player in Utilities.GetPlayers()) { if (!Instance.IsPlayerValid(player)) continue; var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo?.Skill != skillName) continue; EnableSkill(player); } }); return HookResult.Continue; }); Instance.RegisterEventHandler((@event, info) => { SkillPlayerInfo.Clear(); bombLocation = null; return HookResult.Continue; }); Instance.RegisterEventHandler((@event, info) => { var player = @event.Userid; if (player == null || !player.IsValid) return HookResult.Continue; var pawn = player.PlayerPawn.Value; if (pawn == null || !pawn.IsValid) return HookResult.Continue; var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo?.Skill == skillName) SkillPlayerInfo.Remove(pawn); return HookResult.Continue; }); Instance.RegisterEventHandler((@event, info) => { var plantedBomb = Utilities.FindAllEntitiesByDesignerName("planted_c4").FirstOrDefault(); if (plantedBomb != null) bombLocation = plantedBomb.AbsOrigin; return HookResult.Continue; }); Instance.RegisterListener(() => { if (bombLocation == null) return; foreach (var skillInfo in SkillPlayerInfo) { var player = skillInfo.Key; var info = skillInfo.Value; if (player.AbsOrigin == null || SkillUtils.GetDistance(player.AbsOrigin, bombLocation) > maxDefusingRange) { info.Defusing = false; info.DefusingTime = defusingTime; continue; } if (!info.Defusing) player.EmitSound("c4.disarmstart"); info.Defusing = true; info.DefusingTime -= (1f / tickRate); if (info.DefusingTime <= 0) { var plantedBomb = Utilities.FindAllEntitiesByDesignerName("planted_c4").FirstOrDefault(); if (plantedBomb != null) { plantedBomb.Remove(); SkillUtils.TerminateRound(CsTeam.CounterTerrorist); } SkillPlayerInfo.Clear(); } var playerController = player.Controller.Value; if (playerController == null || !player.Controller.IsValid) return; UpdateHUD(playerController.As(), info); } }); } public static void EnableSkill(CCSPlayerController player) { var pawn = player.PlayerPawn.Value; if (pawn == null || !pawn.IsValid) return; SkillPlayerInfo[pawn] = new PlayerSkillInfo { SteamID = player.SteamID, Defusing = false, DefusingTime = defusingTime, }; } public static void DisableSkill(CCSPlayerController player) { var pawn = player.PlayerPawn.Value; if (pawn == null || !pawn.IsValid) return; SkillPlayerInfo.Remove(pawn); } private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) { if (!skillInfo.Defusing) return; int cooldown = (int)skillInfo.DefusingTime + 1; var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); if (skillData == null) return; string infoLine = $"{Localization.GetTranslation("your_skill")}:
"; string skillLine = $"{skillData.Name}
"; string remainingLine = cooldown != 0 ? $"{Localization.GetTranslation("psychicdefusing_hud_info", $"{cooldown}")}
" : ""; var hudContent = infoLine + skillLine + remainingLine; player.PrintToCenterHtml(hudContent); } public class PlayerSkillInfo { public ulong SteamID { get; set; } public bool Defusing { get; set; } public float DefusingTime { get; set; } } public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#507529", CsTeam onlyTeam = CsTeam.CounterTerrorist, bool needsTeammates = false, float maxDefusingRange = 80f, float defusingTime = 10f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) { public float MaxDefusingRange { get; set; } = maxDefusingRange; public float DefusingTime { get; set; } = defusingTime; } } }