diff --git a/WASDMenuAPI - SRC Files/Classes/WasdManager.cs b/WASDMenuAPI - SRC Files/Classes/WasdManager.cs index 9f62692..0055097 100644 --- a/WASDMenuAPI - SRC Files/Classes/WasdManager.cs +++ b/WASDMenuAPI - SRC Files/Classes/WasdManager.cs @@ -35,11 +35,13 @@ public class WasdManager : IWasdMenuManager menuPlayer?.OpenSubMenu(menu); } - public IWasdMenu CreateMenu(string title = "", string controlText = "") + public IWasdMenu CreateMenu(string title, string itemText, string itemHoverText, string controlText) { WasdMenu menu = new() { Title = title, + ItemText = itemText, + ItemHoverText = itemHoverText, ControlText = controlText }; return menu; diff --git a/WASDMenuAPI - SRC Files/Classes/WasdMenu.cs b/WASDMenuAPI - SRC Files/Classes/WasdMenu.cs index 8a3f49e..de2aa0a 100644 --- a/WASDMenuAPI - SRC Files/Classes/WasdMenu.cs +++ b/WASDMenuAPI - SRC Files/Classes/WasdMenu.cs @@ -6,6 +6,8 @@ namespace WASDMenuAPI.Classes; public class WasdMenu : IWasdMenu { public string Title { get; set; } = ""; + public string ItemText { get; set; } = ""; + public string ItemHoverText { get; set; } = ""; public string ControlText { get; set; } = ""; public LinkedList? Options { get; set; } = new(); public LinkedListNode? Prev { get; set; } = null; diff --git a/WASDMenuAPI - SRC Files/Classes/WasdMenuPlayer.cs b/WASDMenuAPI - SRC Files/Classes/WasdMenuPlayer.cs index b559be8..554397a 100644 --- a/WASDMenuAPI - SRC Files/Classes/WasdMenuPlayer.cs +++ b/WASDMenuAPI - SRC Files/Classes/WasdMenuPlayer.cs @@ -123,14 +123,22 @@ public class WasdMenuPlayer return; StringBuilder builder = new(); + string itemText = ""; + string itemHoverText = ""; string endControl = ""; LinkedListNode? option = MenuStart; if (!string.IsNullOrEmpty(option?.Value?.Parent?.Title)) - builder.AppendLine($"{option.Value.Parent?.Title}
"); + builder.AppendLine(option.Value.Parent?.Title ?? ""); + + if (!string.IsNullOrEmpty(option?.Value?.Parent?.ItemText)) + itemText = option?.Value?.Parent?.ItemText ?? ""; + + if (!string.IsNullOrEmpty(option?.Value?.Parent?.ItemHoverText)) + itemHoverText = option?.Value?.Parent?.ItemHoverText ?? ""; if (!string.IsNullOrEmpty(option?.Value?.Parent?.ControlText)) - endControl = option?.Value?.Parent?.ControlText ?? ""; + endControl = option?.Value?.Parent?.ControlText ?? ""; int shown = 0; int maxOptions = VisibleOptions; @@ -176,10 +184,10 @@ public class WasdMenuPlayer else text = SafeSubstring(text, 0, maxLength); - builder.AppendLine($"
[ {text} ]
"); + builder.AppendLine(string.Format(itemHoverText, text)); } else - builder.AppendLine($"{SafeSubstring(text, 0, maxLength)}
"); + builder.AppendLine(string.Format(itemText, $"{SafeSubstring(text, 0, maxLength)}")); option = option.Next; shown++; @@ -188,7 +196,6 @@ public class WasdMenuPlayer if (!string.IsNullOrEmpty(endControl)) builder.AppendLine(endControl); - builder.AppendLine(""); CenterHtml = builder.ToString(); } diff --git a/WASDMenuAPI - SRC Files/Interfaces/IWasdMenu.cs b/WASDMenuAPI - SRC Files/Interfaces/IWasdMenu.cs index b884854..ce04798 100644 --- a/WASDMenuAPI - SRC Files/Interfaces/IWasdMenu.cs +++ b/WASDMenuAPI - SRC Files/Interfaces/IWasdMenu.cs @@ -5,6 +5,8 @@ namespace WASDSharedAPI; public interface IWasdMenu { public string? Title { get; set; } + public string? ItemText { get; set; } + public string? ItemHoverText { get; set; } public string? ControlText { get; set; } public LinkedList? Options { get; set; } // previous option node diff --git a/WASDMenuAPI - SRC Files/Interfaces/IWasdMenuManager.cs b/WASDMenuAPI - SRC Files/Interfaces/IWasdMenuManager.cs index b895851..911a9a4 100644 --- a/WASDMenuAPI - SRC Files/Interfaces/IWasdMenuManager.cs +++ b/WASDMenuAPI - SRC Files/Interfaces/IWasdMenuManager.cs @@ -15,7 +15,7 @@ public interface IWasdMenuManager //open menu as submenu public void OpenSubMenu(CCSPlayerController? player, IWasdMenu? menu); //create new menu object - public IWasdMenu CreateMenu(string title = "", string ControlText = ""); + public IWasdMenu CreateMenu(string title, string itemText, string itemHoverText, string ControlText); public bool HasMenu(CCSPlayerController? player); public void UpdateActiveMenu(CCSPlayerController? player, Dictionary> list); } \ No newline at end of file diff --git a/jRandomSkills - SRC Files/!jRandomSkills.csproj b/jRandomSkills - SRC Files/!jRandomSkills.csproj index 0683baa..f46d9e5 100644 --- a/jRandomSkills - SRC Files/!jRandomSkills.csproj +++ b/jRandomSkills - SRC Files/!jRandomSkills.csproj @@ -14,8 +14,8 @@ - - + + diff --git a/jRandomSkills - SRC Files/src/command/Command.cs b/jRandomSkills - SRC Files/src/command/Command.cs index 97e70a1..709aca4 100644 --- a/jRandomSkills - SRC Files/src/command/Command.cs +++ b/jRandomSkills - SRC Files/src/command/Command.cs @@ -5,7 +5,7 @@ using CounterStrikeSharp.API.Modules.Commands; using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.utils; -using System.Reflection.Metadata; +using System.Collections.Concurrent; using static jRandomSkills.jRandomSkills; namespace jRandomSkills @@ -13,32 +13,50 @@ namespace jRandomSkills public static class Command { private static bool gamePaused = false; - private static readonly Config.Settings config = Config.LoadedConfig.Settings; + private static Config.SettingsModel config = Config.LoadedConfig; + private static readonly ConcurrentDictionary oldCommands = []; + private static readonly object setLock = new(); public static void Load() { + config = Config.LoadedConfig; if (config == null || config == null) return; - var commands = new Dictionary, (string description, CommandInfo.CommandCallback handler)> - { - { SplitCommands(config.SetSkillCommands.Alias), ("Set skill", Command_SetSkill) }, - { SplitCommands(config.SkillsListCommands.Alias), ("Delete all records", Command_SkillsListMenu) }, - { SplitCommands(config.UseSkillCommands.Alias), ("Use/Type skill", Command_UseTypeSkill) }, - { SplitCommands(config.ChangeMapCommands.Alias), ("Change map", Command_ChangeMap) }, - { SplitCommands(config.ConsoleCommands.Alias), ("Console command", Command_CustomCommand) }, - { SplitCommands(config.StartGameCommands.Alias), ("Start game", Command_StartGame) }, - { SplitCommands(config.SwapCommands.Alias), ("Swap team", Command_Swap) }, - { SplitCommands(config.ShuffleCommands.Alias), ("Shuffle team", Command_Shuffle) }, - { SplitCommands(config.PauseCommands.Alias), ("Pause game", Command_Pause) }, - { SplitCommands(config.HealCommands.Alias), ("Heal", Command_Heal) }, - { SplitCommands(config.SetScoreCommands.Alias), ("Set teams score", Command_SetScore) }, - { SplitCommands(config.SetStaticSkillCommands.Alias), ("Set static skill", Command_SetStaticSkill) }, - { SplitCommands(config.ChangeLanguageCommands.Alias), ("Change language", Command_ChangeLanguage) }, - { SplitCommands(config.ReloadCommands.Alias), ("Reaload configs", Command_Reload) }, - }; - foreach (var commandPair in commands) - foreach (var command in commandPair.Key) - Instance.AddCommand($"css_{command}", commandPair.Value.description, commandPair.Value.handler); + lock (setLock) + { + if (oldCommands.Count != 0) + { + foreach (var command in oldCommands) + Instance.RemoveCommand(command.Key, command.Value); + oldCommands.Clear(); + } + + var commands = new Dictionary, (string description, CommandInfo.CommandCallback handler)> + { + { SplitCommands(config.NormalCommands.SetSkillCommand.Alias), ("Set skill", Command_SetSkill) }, + { SplitCommands(config.NormalCommands.SkillsListCommand.Alias), ("Delete all records", Command_SkillsListMenu) }, + { SplitCommands(config.NormalCommands.UseSkillCommand.Alias), ("Use/Type skill", Command_UseTypeSkill) }, + { SplitCommands(config.NormalCommands.ConsoleCommand.Alias), ("Console command", Command_CustomCommand) }, + { SplitCommands(config.NormalCommands.HealCommand.Alias), ("Heal", Command_Heal) }, + { SplitCommands(config.NormalCommands.SetStaticSkillCommand.Alias), ("Set static skill", Command_SetStaticSkill) }, + { SplitCommands(config.NormalCommands.ChangeLanguageCommand.Alias), ("Change language", Command_ChangeLanguage) }, + { SplitCommands(config.NormalCommands.ReloadCommand.Alias), ("Reaload configs", Command_Reload) }, + + { SplitCommands(config.VotingCommands.ChangeMapCommand.Alias), ("Change map", Command_ChangeMap) }, + { SplitCommands(config.VotingCommands.StartGameCommand.Alias), ("Start game", Command_StartGame) }, + { SplitCommands(config.VotingCommands.SwapCommand.Alias), ("Swap team", Command_Swap) }, + { SplitCommands(config.VotingCommands.ShuffleCommand.Alias), ("Shuffle team", Command_Shuffle) }, + { SplitCommands(config.VotingCommands.PauseCommand.Alias), ("Pause game", Command_Pause) }, + { SplitCommands(config.VotingCommands.SetScoreCommand.Alias), ("Set teams score", Command_SetScore) }, + }; + + foreach (var commandPair in commands) + foreach (var command in commandPair.Key) + { + Instance.AddCommand($"css_{command}", commandPair.Value.description, commandPair.Value.handler); + oldCommands.TryAdd($"css_{command}", commandPair.Value.handler); + } + } } private static IEnumerable SplitCommands(string commands) @@ -69,7 +87,7 @@ namespace jRandomSkills private static void Command_SetSkill(CCSPlayerController? player, CommandInfo command) { Debug.WriteToDebug($"Player {player?.PlayerPawn} used the css_setskill {command.ArgString} command."); - if (!AdminManager.PlayerHasPermissions(player, config.SetSkillCommands.Permissions)) return; + if (!AdminManager.PlayerHasPermissions(player, config.NormalCommands.SetSkillCommand.Permissions)) return; var targetPlayer = Utilities.GetPlayers().FirstOrDefault(p => !p.IsBot && (p.SteamID.ToString().Equals(command.GetArg(1), StringComparison.CurrentCultureIgnoreCase) || p.PlayerName.Equals(command.GetArg(1), StringComparison.CurrentCultureIgnoreCase))); @@ -123,7 +141,7 @@ namespace jRandomSkills skillPlayer.Skill = skill.Skill; skillPlayer.SpecialSkill = src.player.Skills.None; Instance.SkillAction(skill.Skill.ToString(), "EnableSkill", [targetPlayer]); - skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.Settings.SkillDescriptionDuration); + skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration); if (player == null) { @@ -156,7 +174,7 @@ namespace jRandomSkills private static void Command_SkillsListMenu(CCSPlayerController? player, CommandInfo command) { Debug.WriteToDebug($"Player {player?.PlayerPawn} used the css_skills {command.ArgString} command."); - if (player == null || !AdminManager.PlayerHasPermissions(player, config.SkillsListCommands.Permissions)) return; + if (player == null || !AdminManager.PlayerHasPermissions(player, config.NormalCommands.SkillsListCommand.Permissions)) return; Menu.DisplaySkillsList(player); } @@ -164,9 +182,9 @@ namespace jRandomSkills private static void Command_ChangeMap(CCSPlayerController? player, CommandInfo command) { Debug.WriteToDebug($"Player {player?.PlayerPawn} used the css_map {command.ArgString} command."); - if (player != null && player.IsValid && !AdminManager.PlayerHasPermissions(player, config.ChangeMapCommands.Permissions)) + if (player != null && player.IsValid && !AdminManager.PlayerHasPermissions(player, config.VotingCommands.ChangeMapCommand.Permissions)) { - if (!config.ChangeMapCommands.EnableVoting) return; + if (!config.VotingCommands.ChangeMapCommand.EnableVoting) return; player.Vote(VoteType.ChangeMap, command.ArgString); return; } @@ -197,9 +215,9 @@ namespace jRandomSkills private static void Command_StartGame(CCSPlayerController? player, CommandInfo command) { Debug.WriteToDebug($"Player {player?.PlayerPawn} used the css_start {command.ArgString} command."); - if (player != null && player.IsValid && !AdminManager.PlayerHasPermissions(player, config.StartGameCommands.Permissions)) + if (player != null && player.IsValid && !AdminManager.PlayerHasPermissions(player, config.VotingCommands.StartGameCommand.Permissions)) { - if (!config.StartGameCommands.EnableVoting) return; + if (!config.VotingCommands.StartGameCommand.EnableVoting) return; player.Vote(VoteType.StartGame); return; } @@ -209,10 +227,11 @@ namespace jRandomSkills private static void StartGame(CommandInfo command) { int cheats = command.GetArg(1) == "sv" ? 1 : 0; - Server.ExecuteCommand($"mp_freezetime {(cheats == 1 ? 0 : 15)}"); - Server.ExecuteCommand("mp_overtime_enable 1"); - Server.ExecuteCommand($"sv_cheats {cheats}"); - Server.ExecuteCommand("mp_forcecamera 0"); + + foreach (string consoleCommand in cheats == 1 + ? Config.LoadedConfig.VotingCommands.StartGameCommand.SVStartParams.Split(";") + : Config.LoadedConfig.VotingCommands.StartGameCommand.StartParams.Split(";")) + Server.ExecuteCommand(consoleCommand); if (Instance?.GameRules?.WarmupPeriod == true) { @@ -230,9 +249,9 @@ namespace jRandomSkills private static void Command_Swap(CCSPlayerController? player, CommandInfo command) { Debug.WriteToDebug($"Player {player?.PlayerPawn} used the css_swap {command.ArgString} command."); - if (player != null && player.IsValid && !AdminManager.PlayerHasPermissions(player, config.SwapCommands.Permissions)) + if (player != null && player.IsValid && !AdminManager.PlayerHasPermissions(player, config.VotingCommands.SwapCommand.Permissions)) { - if (!config.SwapCommands.EnableVoting) return; + if (!config.VotingCommands.SwapCommand.EnableVoting) return; player.Vote(VoteType.SwapTeam); return; } @@ -251,9 +270,9 @@ namespace jRandomSkills private static void Command_Shuffle(CCSPlayerController? player, CommandInfo command) { Debug.WriteToDebug($"Player {player?.PlayerPawn} used the css_shuffle {command.ArgString} command."); - if (player != null && player.IsValid && !AdminManager.PlayerHasPermissions(player, config.ShuffleCommands.Permissions)) + if (player != null && player.IsValid && !AdminManager.PlayerHasPermissions(player, config.VotingCommands.ShuffleCommand.Permissions)) { - if (!config.ShuffleCommands.EnableVoting) return; + if (!config.VotingCommands.ShuffleCommand.EnableVoting) return; player.Vote(VoteType.ShuffleTeam); return; } @@ -277,9 +296,9 @@ namespace jRandomSkills private static void Command_Pause(CCSPlayerController? player, CommandInfo command) { Debug.WriteToDebug($"Player {player?.PlayerPawn} used the css_pause {command.ArgString} command."); - if (player != null && player.IsValid && !AdminManager.PlayerHasPermissions(player, config.PauseCommands.Permissions)) + if (player != null && player.IsValid && !AdminManager.PlayerHasPermissions(player, config.VotingCommands.PauseCommand.Permissions)) { - if (!config.PauseCommands.EnableVoting) return; + if (!config.VotingCommands.PauseCommand.EnableVoting) return; player.Vote(VoteType.PauseGame); return; } @@ -298,7 +317,7 @@ namespace jRandomSkills { Debug.WriteToDebug($"Player {player?.PlayerPawn} used the css_heal {command.ArgString} command."); if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return; - if (!AdminManager.PlayerHasPermissions(player, config.HealCommands.Permissions)) return; + if (!AdminManager.PlayerHasPermissions(player, config.NormalCommands.HealCommand.Permissions)) return; SkillUtils.AddHealth(player.PlayerPawn.Value, 100); player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("healed")}"); } @@ -307,9 +326,9 @@ namespace jRandomSkills private static void Command_SetScore(CCSPlayerController? player, CommandInfo command) { Debug.WriteToDebug($"Player {player?.PlayerPawn} used the css_setscore {command.ArgString} command."); - if (player != null && player.IsValid && !AdminManager.PlayerHasPermissions(player, config.SetScoreCommands.Permissions)) + if (player != null && player.IsValid && !AdminManager.PlayerHasPermissions(player, config.VotingCommands.SetScoreCommand.Permissions)) { - if (!config.SetScoreCommands.EnableVoting) return; + if (!config.VotingCommands.SetScoreCommand.EnableVoting) return; player.Vote(VoteType.SetScore, command.ArgString); return; } @@ -332,7 +351,7 @@ namespace jRandomSkills private static void Command_CustomCommand(CCSPlayerController? player, CommandInfo command) { Debug.WriteToDebug($"Player {player?.PlayerPawn} used the css_console {command.ArgString} command."); - if (player == null || !AdminManager.PlayerHasPermissions(player, config.ConsoleCommands.Permissions)) return; + if (player == null || !AdminManager.PlayerHasPermissions(player, config.NormalCommands.ConsoleCommand.Permissions)) return; string param = command.ArgString; Server.ExecuteCommand(param); } @@ -341,7 +360,7 @@ namespace jRandomSkills private static void Command_SetStaticSkill(CCSPlayerController? player, CommandInfo command) { Debug.WriteToDebug($"Player {player?.PlayerPawn} used the css_setstaticskill {command.ArgString} command."); - if (!AdminManager.PlayerHasPermissions(player, config.SetStaticSkillCommands.Permissions)) return; + if (!AdminManager.PlayerHasPermissions(player, config.NormalCommands.SetStaticSkillCommand.Permissions)) return; var targetPlayer = Utilities.GetPlayers().FirstOrDefault(p => !p.IsBot && (p.SteamID.ToString().Equals(command.GetArg(1), StringComparison.CurrentCultureIgnoreCase) || p.PlayerName.Equals(command.GetArg(1), StringComparison.CurrentCultureIgnoreCase))); @@ -397,12 +416,12 @@ namespace jRandomSkills Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [targetPlayer]); skillPlayer.Skill = skill.Skill; skillPlayer.SpecialSkill = src.player.Skills.None; - skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.Settings.SkillDescriptionDuration); + skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration); if (skill.Skill == src.player.Skills.None) - Event.staticSkills.Remove(targetPlayer.SteamID); + Event.staticSkills.TryRemove(targetPlayer.SteamID, out _); else - Event.staticSkills.Add(targetPlayer.SteamID, skill); + Event.staticSkills.TryAdd(targetPlayer.SteamID, skill); Instance.SkillAction(skill.Skill.ToString(), "EnableSkill", [targetPlayer]); if (player == null) @@ -437,33 +456,41 @@ namespace jRandomSkills { Debug.WriteToDebug($"Player {player?.PlayerPawn} used the css_lang {command.ArgString} command."); if (player == null || !player.IsValid) return; - if (!AdminManager.PlayerHasPermissions(player, config.ChangeLanguageCommands.Permissions)) return; + if (!AdminManager.PlayerHasPermissions(player, config.NormalCommands.ChangeLanguageCommand.Permissions)) return; - string newLangCode = command.GetArg(1); - if (Localization.portugalIsoCodes.Contains(newLangCode.ToUpper())) - newLangCode = "pt-br"; - if (Localization.chinaIsoCodes.Contains(newLangCode.ToUpper())) - newLangCode = "zh"; - if (Localization.frenchIsoCodes.Contains(newLangCode.ToUpper())) - newLangCode = "fr"; - newLangCode = newLangCode.ToLower(); + string fileName = Config.LoadedConfig.LanguageSystem.DefaultLangCode; + string newLangCode = command.GetArg(1).ToUpper(); + foreach (var langInfo in Config.LoadedConfig.LanguageSystem.LanguageInfos) + if (langInfo.IsoCodes.Contains(newLangCode)) + fileName = langInfo.FileName; if (!Localization.HasTranslation(newLangCode)) - newLangCode = "en"; - Localization.ChangePlayerLanguage(player, newLangCode); + fileName = Config.LoadedConfig.LanguageSystem.DefaultLangCode; + else + fileName = newLangCode.ToLower(); + Localization.ChangePlayerLanguage(player, fileName); } [CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)] private static void Command_Reload(CCSPlayerController? player, CommandInfo command) { Debug.WriteToDebug($"Player {player?.PlayerPawn} used the css_lang {command.ArgString} command."); - if (!AdminManager.PlayerHasPermissions(player, config.ReloadCommands.Permissions)) return; + if (!AdminManager.PlayerHasPermissions(player, config.NormalCommands.ReloadCommand.Permissions)) return; - Config.LoadConfig(); - Localization.Load(); - if (player != null && player.IsValid) - player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("reload")}"); - else - Server.PrintToConsole($" {ChatColors.Green}{Localization.GetTranslation("reload")}"); + lock (setLock) + { + Config.LoadConfig(); + SkillsInfo.LoadSkillsInfo(); + Localization.Load(); + Command.Load(); + + foreach (var skill in SkillData.Skills) + skill.Color = SkillsInfo.GetValue(skill.Skill, "color"); + + if (player != null && player.IsValid) + player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("reload")}"); + else + Server.PrintToConsole($" {ChatColors.Green}{Localization.GetTranslation("reload")}"); + } } } } \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/command/VoteSystem.cs b/jRandomSkills - SRC Files/src/command/VoteSystem.cs index 8dac8c0..c4aa232 100644 --- a/jRandomSkills - SRC Files/src/command/VoteSystem.cs +++ b/jRandomSkills - SRC Files/src/command/VoteSystem.cs @@ -2,12 +2,13 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.utils; +using System.Collections.Concurrent; namespace jRandomSkills { public static class VoteSystem { - private static readonly HashSet votes = []; + private static readonly ConcurrentDictionary votes = []; private static VoteData? CreateVote(VoteType voteType, string? args = null) { @@ -19,7 +20,7 @@ namespace jRandomSkills if (vote.MinimumPlayersToStartVoting > Utilities.GetPlayers().Count(p => !p.IsBot)) return null; - votes.Add(vote); + votes.TryAdd(vote, 0); string commandName = $"!{VoteTypeCommands.GetCommand(vote.Type)?.Replace("css_", "")}{(!string.IsNullOrEmpty(vote?.Args) ? $" {vote?.Args}" : "")}"; Localization.PrintTranslationToChatAll($" {ChatColors.Lime}{{0}}", ["vote_started"], [commandName]); @@ -29,7 +30,7 @@ namespace jRandomSkills if (vote == null) return vote; jRandomSkills.Instance.AddTimer(vote.TimeToVote, () => { - if (!votes.Contains(vote) || !vote.GetActive()) return; + if (!votes.ContainsKey(vote) || !vote.GetActive()) return; vote.SetActive(false); vote.TimeToNextSameVoting = vote.TimeToNextVoting; Localization.PrintTranslationToChatAll($" {ChatColors.Red}{{0}}", ["vote_timeout"], [commandName]); @@ -38,23 +39,23 @@ namespace jRandomSkills float[] times = [vote.TimeToVote, vote.TimeToVote + vote.TimeToNextVoting, vote.TimeToVote + vote.TimeToNextSameVoting]; jRandomSkills.Instance.AddTimer(times.Max(), () => { - if (!votes.Contains(vote)) return; - votes.Remove(vote); + if (!votes.ContainsKey(vote)) return; + votes.TryRemove(vote, out _); }); return vote; } public static void Vote(this CCSPlayerController player, VoteType voteType, string? args = null) { - var vote = votes.FirstOrDefault(v => v.Type == voteType && v.Args == args && v.GetActive()); + var vote = votes.Keys.FirstOrDefault(v => v.Type == voteType && v.Args == args && v.GetActive()); if (vote == null) { - if (votes.Any(v => v.NextVoting() > DateTime.Now)) + if (votes.Keys.Any(v => v.NextVoting() > DateTime.Now)) { player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("vote_wait")}"); return; } - else if (votes.Any(v => v.Type == voteType && v.NextSameVoting() > DateTime.Now)) + else if (votes.Keys.Any(v => v.Type == voteType && v.NextSameVoting() > DateTime.Now)) { player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("vote_same_wait")}"); return; @@ -69,7 +70,7 @@ namespace jRandomSkills return; } - if (!vote.PlayersVoted.Add(player.SteamID)) + if (!vote.PlayersVoted.TryAdd(player.SteamID, 0)) player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("vote_alredy_voted")}"); else CheckVote(vote); } @@ -101,7 +102,7 @@ namespace jRandomSkills public int MinimumPlayersToStartVoting { get; set; } = minimumPlayersToStartVoting; public VoteType Type { get; set; } = type; public string? Args { get; set; } = args; - public HashSet PlayersVoted { get; set; } = []; + public ConcurrentDictionary PlayersVoted { get; set; } = []; private DateTime CreatedTime { get; set; } = DateTime.Now; @@ -138,15 +139,15 @@ namespace jRandomSkills public static class VoteTypeCommands { - private static readonly Dictionary names = new() - { - { VoteType.StartGame, "css_start" }, - { VoteType.PauseGame, "css_pause" }, - { VoteType.ShuffleTeam, "css_shuffle" }, - { VoteType.SwapTeam, "css_swap" }, - { VoteType.ChangeMap, "css_map" }, - { VoteType.SetScore, "css_setscore" }, - }; + private static readonly ConcurrentDictionary names = new( + [ + new KeyValuePair(VoteType.StartGame, "css_start"), + new KeyValuePair(VoteType.PauseGame, "css_pause"), + new KeyValuePair(VoteType.ShuffleTeam, "css_shuffle"), + new KeyValuePair(VoteType.SwapTeam, "css_swap"), + new KeyValuePair(VoteType.ChangeMap, "css_map"), + new KeyValuePair(VoteType.SetScore, "css_setscore"), + ]); public static string GetCommand(VoteType type) => names[type]; } diff --git a/jRandomSkills - SRC Files/src/jRandomSkills.cs b/jRandomSkills - SRC Files/src/jRandomSkills.cs index 0101ca6..feb2be4 100644 --- a/jRandomSkills - SRC Files/src/jRandomSkills.cs +++ b/jRandomSkills - SRC Files/src/jRandomSkills.cs @@ -19,17 +19,19 @@ namespace jRandomSkills public Random Random { get; } = new Random(); public CCSGameRules? GameRules { get; set; } public IWasdMenuManager? MenuManager; + public const string Tag = "jRandomSkills"; public override string ModuleName => "[CS2] [ jRandomSkills ]"; public override string ModuleAuthor => "D3X, Juzlus"; public override string ModuleDescription => "Plugin adds random skills every round for CS2 by D3X. Modified by Juzlus."; - public override string ModuleVersion => "1.1.5"; + public override string ModuleVersion => "1.1.7"; public override void Load(bool hotReload) { Instance = this; Config.LoadConfig(); + SkillsInfo.LoadSkillsInfo(); Localization.Load(); Debug.Load(); PlayerOnTick.Load(); @@ -42,11 +44,11 @@ namespace jRandomSkills internal void LoadAllSkills() { foreach (var skill in Enum.GetValues(typeof(Skills))) - if (Config.GetValue(skill, "active")) + if (SkillsInfo.GetValue(skill, "active")) SkillAction(skill.ToString()!, "LoadSkill"); - Debug.WriteToDebug($"jRandomSkills v{Instance.ModuleVersion} ({SkillData.Skills.Count - 1}/{Config.LoadedConfig.SkillsInfo.Length - 1} Skills) loaded!"); - Debug.WriteToDebug($"GameModes: {(Config.GameModes)Config.LoadedConfig.Settings.GameMode}, Lang: {Config.LoadedConfig.Settings.LangCode}"); + Debug.WriteToDebug($"jRandomSkills v{Instance.ModuleVersion} ({SkillData.Skills.Count - 1}/{SkillsInfo.LoadedConfig.Count - 1} Skills) loaded!"); + Debug.WriteToDebug($"GameModes: {(Config.GameModes)Config.LoadedConfig.GameMode}, Lang: {Config.LoadedConfig.LanguageSystem.DefaultLangCode}"); foreach (var skill in SkillData.Skills) Debug.WriteToDebug($"Loaded: {skill.Skill}"); } @@ -106,6 +108,7 @@ namespace jRandomSkills public float? SkillChance { get; set; } public bool IsDrawing { get; set; } public DateTime SkillDescriptionHudExpired { get; set; } + public string? PrintHTML { get; set; } } #pragma warning disable IDE1006 @@ -113,7 +116,7 @@ namespace jRandomSkills #pragma warning restore IDE1006 { public Skills Skill { get; } = skill; - public string Color { get; } = color; + public string Color { get; set; } = color; public bool Display { get; } = display; public static implicit operator Skills(jSkill_SkillInfo v) diff --git a/jRandomSkills - SRC Files/src/lang/en.json b/jRandomSkills - SRC Files/src/lang/en.json index 1cb54d3..d3b93e4 100644 --- a/jRandomSkills - SRC Files/src/lang/en.json +++ b/jRandomSkills - SRC Files/src/lang/en.json @@ -215,7 +215,7 @@ "lifeswap_select_info": "Swap health with player:", "longknife": "Long Knife", - "longknife_desc": "A primary knife attack deals damage regardless of distance", + "longknife_desc": "A knife attack deals damage regardless of distance", "longzeus": "Long Zeus", "longzeus_desc": "Zeus deals damage regardless of distance", @@ -237,6 +237,7 @@ "muhammed": "Muhammed", "muhammed_desc": "You explode upon death, killing nearby players", + "muhammed_explosion": "ALLAHU AKBAR!!!", "ninja": "Ninja", "ninja_desc": "Standing still increases your invisibility by 33%, crouching by 33%, and holding a knife by 33%", @@ -452,5 +453,7 @@ "summary_start": "======SUMMARY=OF=THE=LAST=ROUND======", "summary_end": "=======================================", - "menu_controlls": "W/S - Scroll | E - Select
" + "menu_controlls_scroll": "W/S - Scroll", + "menu_controlls_padding": " | ", + "menu_controlls_select": "E - Select" } \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/lang/fr.json b/jRandomSkills - SRC Files/src/lang/fr.json index 8131605..d5548be 100644 --- a/jRandomSkills - SRC Files/src/lang/fr.json +++ b/jRandomSkills - SRC Files/src/lang/fr.json @@ -215,7 +215,7 @@ "lifeswap_select_info": "Échanger la santé avec le joueur :", "longknife": "Couteau Long", - "longknife_desc": "Une attaque primaire au couteau inflige des dégâts quelle que soit la distance", + "longknife_desc": "Une attaque au couteau inflige des dégâts quelle que soit la distance", "longzeus": "Zeus Longue Portée", "longzeus_desc": "Le Zeus inflige des dégâts quelle que soit la distance", @@ -237,6 +237,7 @@ "muhammed": "Bombe", "muhammed_desc": "Vous explosez à votre mort, tuant les joueurs proches", + "muhammed_explosion": "ALLAHU AKBAR!!!", "ninja": "Ninja", "ninja_desc": "Rester immobile augmente votre invisibilité de 33%, s’accroupir de 33%, et tenir un couteau de 33%", @@ -452,5 +453,7 @@ "summary_start": "======RÉSUMÉ=DU=DERNIER=ROUND======", "summary_end": "===================================", - "menu_controlls": "W/S - Défilement | E - Sélectionner
" -} \ No newline at end of file + "menu_controlls_scroll": "W/S - Défilement", + "menu_controlls_padding": " | ", + "menu_controlls_select": "E - Sélectionner" +} diff --git a/jRandomSkills - SRC Files/src/lang/pl.json b/jRandomSkills - SRC Files/src/lang/pl.json index b84c5ac..60a9b5f 100644 --- a/jRandomSkills - SRC Files/src/lang/pl.json +++ b/jRandomSkills - SRC Files/src/lang/pl.json @@ -215,7 +215,7 @@ "lifeswap_select_info": "Zamień się zdrowiem z graczem:", "longknife": "Długi Nóż", - "longknife_desc": "Podstawowy atak nożem zadaje obrażenia niezależnie od odległości", + "longknife_desc": "Atak nożem zadaje obrażenia niezależnie od odległości", "longzeus": "Długi Zeus", "longzeus_desc": "Zeus zadaje obrażenia niezależnie od odległości", @@ -237,6 +237,7 @@ "muhammed": "Muhammed", "muhammed_desc": "Po śmierci eksplodujesz i zabijasz graczy znajdujących się w zasięgu", + "muhammed_explosion": "ALLAHU AKBAR!!!", "ninja": "Ninja", "ninja_desc": "Stojąc nieruchomo zwiększasz swoją niewidzialność o 33%, kucając o 33%, a trzymając nóż o 33%", @@ -452,5 +453,7 @@ "summary_start": "======PODSUMOWANIE=Z=OSTATNIEJ=RUNDY======", "summary_end": "============================================", - "menu_controlls": "W/S – Przewijanie | E - Wybierz
" + "menu_controlls_scroll": "W/S – Przewijanie", + "menu_controlls_padding": " | ", + "menu_controlls_select": "E - Wybierz" } \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/lang/pt-br.json b/jRandomSkills - SRC Files/src/lang/pt-br.json index fb05ea3..180a374 100644 --- a/jRandomSkills - SRC Files/src/lang/pt-br.json +++ b/jRandomSkills - SRC Files/src/lang/pt-br.json @@ -215,7 +215,7 @@ "lifeswap_select_info": "Trocar vida com jogador:", "longknife": "Faca Longa", - "longknife_desc": "Um ataque com faca primária causa dano independentemente da distância", + "longknife_desc": "Um ataque com faca causa danos independentemente da distância", "longzeus": "Zeus Longo", "longzeus_desc": "Zeus causa dano independentemente da distância", @@ -237,6 +237,7 @@ "muhammed": "Muhammed", "muhammed_desc": "Você explode ao morrer, matando jogadores próximos", + "muhammed_explosion": "ALLAHU AKBAR!!!", "ninja": "Ninja", "ninja_desc": "Ficar parado aumenta sua invisibilidade em 33%, agachar em 33%, e segurar uma faca em 33%", @@ -452,5 +453,7 @@ "summary_start": "=======RESUMO=DA=ÚLTIMA=RODADA=======", "summary_end": "=======================================", - "menu_controlls": "W/S - Rolar | E - Selecionar
" + "menu_controlls_scroll": "W/S - Rolar", + "menu_controlls_padding": " | ", + "menu_controlls_select": "E - Selecionar" } \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/lang/zh.json b/jRandomSkills - SRC Files/src/lang/zh.json index b6263c9..7b51cba 100644 --- a/jRandomSkills - SRC Files/src/lang/zh.json +++ b/jRandomSkills - SRC Files/src/lang/zh.json @@ -215,7 +215,7 @@ "lifeswap_select_info": "选择你想与之交换生命值的玩家:", "longknife": "长刀", - "longknife_desc": "近战刀具攻击无论距离远近均可造成伤害", + "longknife_desc": "刀具攻击造成的伤害与距离无关", "longzeus": "长宙斯", "longzeus_desc": "宙斯电击枪无论距离多远都能造成伤害", @@ -237,6 +237,7 @@ "muhammed": "穆罕默德", "muhammed_desc": "你死亡时会爆炸,杀死附近的玩家", + "muhammed_explosion": "真主至大!!!", "ninja": "忍者", "ninja_desc": "站立不动增加33%隐形,蹲下增加33%,持刀增加33%", @@ -452,5 +453,7 @@ "summary_start": "=============上一回合总结==============", "summary_end": "=======================================", - "menu_controlls": "W/S - 滚动 | E - 选择
" + "menu_controlls_scroll": "W/S - 滚动", + "menu_controlls_padding": " | ", + "menu_controlls_select": "E - 选择" } \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/Debug.cs b/jRandomSkills - SRC Files/src/player/Debug.cs index ac762c6..1f84ebb 100644 --- a/jRandomSkills - SRC Files/src/player/Debug.cs +++ b/jRandomSkills - SRC Files/src/player/Debug.cs @@ -127,7 +127,7 @@ namespace jRandomSkills public static void WriteToDebug(string message) { - if (Config.LoadedConfig.Settings.DebugMode != true) + if (Config.LoadedConfig.DebugMode != true) return; string filename = $"debug_{sessionId}.txt"; diff --git a/jRandomSkills - SRC Files/src/player/PlayerEvents.cs b/jRandomSkills - SRC Files/src/player/PlayerEvents.cs index 684e73c..3a36b78 100644 --- a/jRandomSkills - SRC Files/src/player/PlayerEvents.cs +++ b/jRandomSkills - SRC Files/src/player/PlayerEvents.cs @@ -10,25 +10,28 @@ using jRandomSkills.src.player; using jRandomSkills.src.utils; using static CounterStrikeSharp.API.Core.Listeners; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public static partial class Event { + public static DateTime freezeTimeEnd = DateTime.MinValue; public static bool isTransmitRegistered = false; - public static readonly jSkill_SkillInfo noneSkill = new(Skills.None, Config.GetValue(Skills.None, "color"), false); + public static readonly jSkill_SkillInfo noneSkill = new(Skills.None, SkillsInfo.GetValue(Skills.None, "color"), false); private static jSkill_SkillInfo ctSkill = noneSkill; private static jSkill_SkillInfo tSkill = noneSkill; private static jSkill_SkillInfo allSkill = noneSkill; private static List debugSkills = new(SkillData.Skills); - public static readonly Config.DefaultSkillInfo[] terroristSkills = Config.LoadedConfig.SkillsInfo.Where(s => s.OnlyTeam == (int)CsTeam.Terrorist).ToArray(); - public static readonly Config.DefaultSkillInfo[] counterterroristSkills = Config.LoadedConfig.SkillsInfo.Where(s => s.OnlyTeam == (int)CsTeam.CounterTerrorist).ToArray(); - private static readonly Config.DefaultSkillInfo[] allTeamsSkills = Config.LoadedConfig.SkillsInfo.Where(s => s.OnlyTeam == 0).ToArray(); + public static readonly SkillsInfo.DefaultSkillInfo[] terroristSkills = SkillsInfo.LoadedConfig.Where(s => s.OnlyTeam == (int)CsTeam.Terrorist).ToArray(); + public static readonly SkillsInfo.DefaultSkillInfo[] counterterroristSkills = SkillsInfo.LoadedConfig.Where(s => s.OnlyTeam == (int)CsTeam.CounterTerrorist).ToArray(); + private static readonly SkillsInfo.DefaultSkillInfo[] allTeamsSkills = SkillsInfo.LoadedConfig.Where(s => s.OnlyTeam == 0).ToArray(); - private static readonly Dictionary> playersSkills = []; - public static readonly Dictionary staticSkills = []; + private static readonly ConcurrentDictionary> playersSkills = []; + public static readonly ConcurrentDictionary staticSkills = []; + private static readonly object setLock = new object(); public static void Load() { @@ -172,10 +175,13 @@ namespace jRandomSkills private static HookResult PlayerHurt(EventPlayerHurt @event, GameEventInfo info) { - foreach (var playerSkill in Instance.SkillPlayer) + lock (setLock) + { + foreach (var playerSkill in Instance.SkillPlayer) if (!playerSkill.IsDrawing) Instance.SkillAction(playerSkill.Skill.ToString(), "PlayerHurt", [@event]); - return HookResult.Continue; + return HookResult.Continue; + } } private static HookResult PlayerJump(EventPlayerJump @event, GameEventInfo info) @@ -206,14 +212,10 @@ namespace jRandomSkills { foreach (var playerSkill in Instance.SkillPlayer) if (!playerSkill.IsDrawing) - Instance.SkillAction(playerSkill.Skill.ToString(), "OnTick"); - - foreach (var playerSkill in Instance.SkillPlayer) - { - if (playerSkill.SkillDescriptionHudExpired >= DateTime.Now) - if (playerSkill.Skill != Skills.None) - ShowSkillDescription(Utilities.GetPlayerFromSteamId(playerSkill.SteamID)); - } + if (SkillsInfo.GetValue(playerSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime()) + return; + else + Instance.SkillAction(playerSkill.Skill.ToString(), "OnTick"); } private static HookResult PlayerConnectFull(EventPlayerConnectFull @event, GameEventInfo info) @@ -262,11 +264,13 @@ namespace jRandomSkills var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (skillPlayer == null) continue; skillPlayer.IsDrawing = true; + skillPlayer.PrintHTML = null; } Instance.RemoveListener(CheckTransmit); int freezetime = ConVar.Find("mp_freezetime")?.GetPrimitiveValue() ?? 0; - Instance.AddTimer((Instance?.GameRules?.TeamIntroPeriod == true ? 7 : 0) + Math.Max(freezetime - Config.LoadedConfig.Settings.SkillTimeBeforeStart, 0) + .3f, SetSkill); + freezeTimeEnd = DateTime.Now.AddSeconds(freezetime + (Instance?.GameRules?.TeamIntroPeriod == true ? 7 : 0)); + Instance?.AddTimer((Instance?.GameRules?.TeamIntroPeriod == true ? 7 : 0) + Math.Max(freezetime - Config.LoadedConfig.SkillTimeBeforeStart, 0) + .3f, SetSkill); return HookResult.Continue; } @@ -298,11 +302,11 @@ namespace jRandomSkills var skillInfo = SkillData.Skills.FirstOrDefault(p => p.Skill == _playerSkill.Skill); var specialSkillInfo = SkillData.Skills.FirstOrDefault(s => s.Skill == _playerSkill.SpecialSkill); if (skillInfo == null) continue; - skillsText += $" {ChatColors.DarkRed}{_player.PlayerName}{ChatColors.Lime}: {(_playerSkill.SpecialSkill == Skills.None || specialSkillInfo == null ? player.GetSkillName(skillInfo.Skill) : $"{player.GetSkillName(specialSkillInfo.Skill)} -> {player.GetSkillName(skillInfo.Skill)}")}\n"; + skillsText += $" {ChatColors.DarkRed}{_player.PlayerName}{ChatColors.Lime}: {(_playerSkill.SpecialSkill == Skills.None || specialSkillInfo == null ? player.GetSkillName(skillInfo.Skill, _playerSkill.SkillChance) : $"{player.GetSkillName(specialSkillInfo.Skill)} -> {player.GetSkillName(skillInfo.Skill, _playerSkill.SkillChance)}")}\n"; } } - if (Config.LoadedConfig.Settings.SummaryAfterTheRound && !string.IsNullOrEmpty(skillsText)) + if (Config.LoadedConfig.SummaryAfterTheRound && !string.IsNullOrEmpty(skillsText)) { player.PrintToChat(" "); player.PrintToChat($" {ChatColors.Lime}{player.GetTranslation("summary_start")}"); @@ -319,39 +323,42 @@ namespace jRandomSkills private static HookResult PlayerDeath(EventPlayerDeath @event, GameEventInfo info) { - foreach (var playerSkill in Instance.SkillPlayer) - if (!playerSkill.IsDrawing) - Instance.SkillAction(playerSkill.Skill.ToString(), "PlayerDeath", [@event]); - - var victim = @event.Userid; - var attacker = @event.Attacker; - if (victim == null || attacker == null) return HookResult.Continue; - - var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == victim.SteamID); - if (playerInfo == null || playerInfo.IsDrawing) return HookResult.Continue; - Instance.SkillAction(playerInfo.Skill.ToString(), "DisableSkill", [victim]); - - if (victim == attacker) return HookResult.Continue; - if (Config.LoadedConfig.Settings.KillerSkillInfo) + lock (setLock) { - var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); - if (attackerInfo != null) - { - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == attackerInfo.Skill); - var specialSkillData = SkillData.Skills.FirstOrDefault(s => s.Skill == attackerInfo.SpecialSkill); - if (skillData == null || specialSkillData == null) return HookResult.Continue; - string skillDesc = victim.GetSkillDescription(skillData.Skill); + foreach (var playerSkill in Instance.SkillPlayer) + if (!playerSkill.IsDrawing) + Instance.SkillAction(playerSkill.Skill.ToString(), "PlayerDeath", [@event]); - SkillUtils.PrintToChat(victim, $"{victim.GetTranslation("enemy_skill")} {ChatColors.DarkRed}{attacker.PlayerName}{ChatColors.Lime}:", false); - SkillUtils.PrintToChat(victim, $"{ChatColors.DarkRed}{(attackerInfo.SpecialSkill == Skills.None ? victim.GetSkillName(skillData.Skill) : $"{victim.GetSkillName(specialSkillData.Skill)} -> {victim.GetSkillName(skillData.Skill)}")}{ChatColors.Lime} - {skillDesc}", false); + var victim = @event.Userid; + var attacker = @event.Attacker; + if (victim == null || attacker == null) return HookResult.Continue; + + var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == victim.SteamID); + if (playerInfo == null || playerInfo.IsDrawing) return HookResult.Continue; + Instance.SkillAction(playerInfo.Skill.ToString(), "DisableSkill", [victim]); + + if (victim == attacker) return HookResult.Continue; + if (Config.LoadedConfig.KillerSkillInfo) + { + var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); + if (attackerInfo != null) + { + var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == attackerInfo.Skill); + var specialSkillData = SkillData.Skills.FirstOrDefault(s => s.Skill == attackerInfo.SpecialSkill); + if (skillData == null || specialSkillData == null) return HookResult.Continue; + string skillDesc = victim.GetSkillDescription(skillData.Skill); + + SkillUtils.PrintToChat(victim, $"{victim.GetTranslation("enemy_skill")} {ChatColors.DarkRed}{attacker.PlayerName}{ChatColors.Lime}:", false); + SkillUtils.PrintToChat(victim, $"{ChatColors.DarkRed}{(attackerInfo.SpecialSkill == Skills.None ? victim.GetSkillName(skillData.Skill) : $"{victim.GetSkillName(specialSkillData.Skill)} -> {victim.GetSkillName(skillData.Skill)}")}{ChatColors.Lime} - {skillDesc}", false); + } } + return HookResult.Continue; } - return HookResult.Continue; } private static void CheckUseSkill(CCSPlayerController player, PlayerButtons pressed, PlayerButtons released) { - string? button = Config.LoadedConfig.Settings.AlternativeSkillButton; + string? button = Config.LoadedConfig.AlternativeSkillButton; if (string.IsNullOrEmpty(button)) return; if (Enum.TryParse(button, out var skillButton)) @@ -363,6 +370,9 @@ namespace jRandomSkills var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo == null || playerInfo.IsDrawing) return; + if (SkillsInfo.GetValue(playerInfo.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime()) + return; + var playerPawn = player.PlayerPawn.Value; if (playerPawn?.CBodyComponent == null) return; if (!player.IsValid || !player.PawnIsAlive) return; @@ -382,7 +392,7 @@ namespace jRandomSkills { var validPlayers = Utilities.GetPlayers().Where(p => p.IsValid && !p.IsBot && !p.IsHLTV && p .Team is CsTeam.CounterTerrorist or CsTeam.Terrorist).ToList(); - if (Config.LoadedConfig.Settings.GameMode == (int)Config.GameModes.TeamSkills) + if (Config.LoadedConfig.GameMode == (int)Config.GameModes.TeamSkills) { List tSkills = new(SkillData.Skills); tSkills.RemoveAll(s => s.Skill == tSkill.Skill || s.Skill == Skills.None || counterterroristSkills.Any(s2 => s2.Name == s.Skill.ToString())); @@ -392,13 +402,13 @@ namespace jRandomSkills ctSkills.RemoveAll(s => s.Skill == ctSkill.Skill || s.Skill == Skills.None || terroristSkills.Any(s2 => s2.Name == s.Skill.ToString())); ctSkill = ctSkills.Count == 0 ? noneSkill : ctSkills[Instance.Random.Next(ctSkills.Count)]; } - else if (Config.LoadedConfig.Settings.GameMode == (int)Config.GameModes.SameSkills) + else if (Config.LoadedConfig.GameMode == (int)Config.GameModes.SameSkills) { List allSkills = new(SkillData.Skills); allSkills.RemoveAll(s => s.Skill == allSkill.Skill || s.Skill == Skills.None || !allTeamsSkills.Any(s2 => s2.Name == s.Skill.ToString())); allSkill = allSkills.Count == 0 ? noneSkill : allSkills[Instance.Random.Next(allSkills.Count)]; } - else if (Config.LoadedConfig.Settings.GameMode == (int)Config.GameModes.Debug && debugSkills.Count == 0) + else if (Config.LoadedConfig.GameMode == (int)Config.GameModes.Debug && debugSkills.Count == 0) debugSkills = new(SkillData.Skills); foreach (var player in validPlayers) @@ -421,7 +431,7 @@ namespace jRandomSkills if (Instance?.GameRules != null && Instance?.GameRules.WarmupPeriod == false) { - Config.GameModes gameMode = (Config.GameModes)Config.LoadedConfig.Settings.GameMode; + Config.GameModes gameMode = (Config.GameModes)Config.LoadedConfig.GameMode; if (staticSkills.TryGetValue(player.SteamID, out var staticSkill)) randomSkill = staticSkill; else if (gameMode == Config.GameModes.Normal || gameMode == Config.GameModes.NoRepeat) @@ -431,7 +441,7 @@ namespace jRandomSkills if (validPlayers.Count(p => p.Team == player.Team) == 1) { - Config.DefaultSkillInfo[] skillsNeedsTeammates = Config.LoadedConfig.SkillsInfo.Where(s => s.NeedsTeammates).ToArray(); + SkillsInfo.DefaultSkillInfo[] skillsNeedsTeammates = SkillsInfo.LoadedConfig.Where(s => s.NeedsTeammates).ToArray(); skillList.RemoveAll(s => skillsNeedsTeammates.Any(s2 => s2.Name == s.Skill.ToString())); } @@ -452,7 +462,7 @@ namespace jRandomSkills if (playersSkills.TryGetValue(player.SteamID, out List? value)) value.Add(randomSkill); else - playersSkills.Add(player.SteamID, [randomSkill]); + playersSkills.TryAdd(player.SteamID, [randomSkill]); } } else if (gameMode == Config.GameModes.TeamSkills) @@ -474,21 +484,29 @@ namespace jRandomSkills skillPlayer.Skill = randomSkill.Skill; skillPlayer.SpecialSkill = Skills.None; - Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", new [] { player }); - Debug.WriteToDebug($"Player {skillPlayer.PlayerName} has got the skill \"{player.GetSkillName(randomSkill.Skill)}\"."); - skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.Settings.SkillDescriptionDuration); - if (Config.LoadedConfig.Settings.TeamMateSkillInfo) + if (SkillsInfo.GetValue(randomSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime()) + Instance?.AddTimer(Config.LoadedConfig.SkillTimeBeforeStart, () => { + if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID && p.Skill == randomSkill.Skill) == null) return; + Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", new[] { player }); + }); + else + Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", new[] { player }); + + Debug.WriteToDebug($"Player {skillPlayer.PlayerName} has got the skill \"{player.GetSkillName(randomSkill.Skill)}\"."); + skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration); + + if (Config.LoadedConfig.TeamMateSkillInfo) { Instance?.AddTimer(.5f, () => { foreach (var teammate in teammates) { - var teammateSkill = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == teammate.SteamID)?.Skill; - if (teammateSkill != null) + var teammateInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == teammate.SteamID); + if (teammateInfo != null && teammateInfo?.Skill != null) { - var skillInfo = SkillData.Skills.FirstOrDefault(p => p.Skill == teammateSkill); - teammateSkills += $" {ChatColors.DarkRed}{teammate.PlayerName}{ChatColors.Lime}: {(skillInfo == null ? player.GetSkillName(Skills.None) : player.GetSkillName(skillInfo.Skill))}\n"; + var skillInfo = SkillData.Skills.FirstOrDefault(p => p.Skill == teammateInfo.Skill); + teammateSkills += $" {ChatColors.DarkRed}{teammate.PlayerName}{ChatColors.Lime}: {(skillInfo == null ? player.GetSkillName(Skills.None) : player.GetSkillName(skillInfo.Skill, teammateInfo.SkillChance))}\n"; } } @@ -508,7 +526,7 @@ namespace jRandomSkills { var validPlayers = Utilities.GetPlayers().Where(p => p.IsValid && !p.IsBot && !p.IsHLTV && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist).ToList(); - if (Config.LoadedConfig.Settings.GameMode == (int)Config.GameModes.TeamSkills) + if (Config.LoadedConfig.GameMode == (int)Config.GameModes.TeamSkills) { List tSkills = new(SkillData.Skills); tSkills.RemoveAll(s => s.Skill == tSkill.Skill || s.Skill == Skills.None || counterterroristSkills.Any(s2 => s2.Name == s.Skill.ToString())); @@ -532,7 +550,7 @@ namespace jRandomSkills jSkill_SkillInfo randomSkill = noneSkill; if (Instance?.GameRules != null && Instance?.GameRules.WarmupPeriod == false) { - Config.GameModes gameMode = (Config.GameModes)Config.LoadedConfig.Settings.GameMode; + Config.GameModes gameMode = (Config.GameModes)Config.LoadedConfig.GameMode; if (staticSkills.TryGetValue(player.SteamID, out var staticSkill)) randomSkill = staticSkill; else if (gameMode == Config.GameModes.Normal || gameMode == Config.GameModes.NoRepeat) @@ -542,7 +560,7 @@ namespace jRandomSkills if (validPlayers.Count(p => p.Team == player.Team) == 1) { - Config.DefaultSkillInfo[] skillsNeedsTeammates = Config.LoadedConfig.SkillsInfo.Where(s => s.NeedsTeammates).ToArray(); + SkillsInfo.DefaultSkillInfo[] skillsNeedsTeammates = SkillsInfo.LoadedConfig.Where(s => s.NeedsTeammates).ToArray(); skillList.RemoveAll(s => skillsNeedsTeammates.Any(s2 => s2.Name == s.Skill.ToString())); } @@ -563,7 +581,7 @@ namespace jRandomSkills if (playersSkills.TryGetValue(player.SteamID, out List? value)) value.Add(randomSkill); else - playersSkills.Add(player.SteamID, [randomSkill]); + playersSkills.TryAdd(player.SteamID, [randomSkill]); } } else if (gameMode == Config.GameModes.TeamSkills) @@ -577,9 +595,17 @@ namespace jRandomSkills skillPlayer.Skill = randomSkill.Skill; skillPlayer.SpecialSkill = Skills.None; - Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", new[] { player }); + + if (SkillsInfo.GetValue(randomSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime()) + Instance?.AddTimer(Config.LoadedConfig.SkillTimeBeforeStart, () => { + if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID && p.Skill == randomSkill.Skill) == null) return; + Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", new[] { player }); + }); + else + Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", new[] { player }); + Debug.WriteToDebug($"Player {skillPlayer.PlayerName} has got the skill \"{player.GetSkillName(randomSkill.Skill)}\"."); - skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.Settings.SkillDescriptionDuration); + skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration); } public static void CheckTransmit([CastFrom(typeof(nint))] CCheckTransmitInfoList infoList) @@ -589,26 +615,22 @@ namespace jRandomSkills Instance.SkillAction(playerSkill.Skill.ToString(), "CheckTransmit", [infoList]); } - private static void ShowSkillDescription(CCSPlayerController? player) + public static void UpdateSkillHUD(CCSPlayerController? player, string? headerLine, string? centerLine, string? extraLine, bool isDescription) { if (player == null || !player.IsValid) return; + var config = Config.LoadedConfig.HtmlHudCustomisation; + var emptySymbol = $" "; + var emptySymbol2 = $" "; - var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo == null) return; + string infoLine = string.IsNullOrEmpty(headerLine) + ? "" + : $"{headerLine}:
"; - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == playerInfo.Skill); - if (skillData == null) return; + string skillLine = $"{emptySymbol2}{centerLine}{emptySymbol2}"; - var skillName = playerInfo.Skill.ToString().ToLower(); - var value = Math.Round((double)(playerInfo.SkillChance ?? 1), 2); - var desc2 = player.GetTranslation($"{skillName}_desc2", value); - var skilLDescription = desc2 == $"{skillName}_desc2" - ? player.GetTranslation($"{skillName}_desc") - : (desc2.Contains('%') ? desc2.Replace(value.ToString(), (value * 100).ToString()) : desc2); - - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = $"{skilLDescription}
"; + string remainingLine = string.IsNullOrWhiteSpace(extraLine) + ? "" + : $"
{emptySymbol}{extraLine}{emptySymbol}"; var hudContent = infoLine + skillLine + remainingLine; player.PrintToCenterHtml(hudContent); diff --git a/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs b/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs index 2c96fe1..c104ec8 100644 --- a/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs +++ b/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs @@ -1,5 +1,6 @@ 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; @@ -40,7 +41,7 @@ namespace jRandomSkills { if (Instance?.GameRules == null || Instance?.GameRules?.Handle == IntPtr.Zero) InitializeGameRules(); - else if (Instance != null && Config.LoadedConfig.Settings.FlashingHtmlHudFix) + else if (Instance != null && Config.LoadedConfig.FlashingHtmlHudFix) Instance.GameRules.GameRestart = Instance.GameRules?.RestartRoundTime < Server.CurrentTime; } @@ -52,17 +53,20 @@ namespace jRandomSkills string infoLine = ""; string skillLine = ""; + string remainingLine = ""; + bool showDescirptionHUD = skillPlayer.SkillDescriptionHudExpired >= DateTime.Now; + bool isDescription = true; if (SkillData.Skills.Count == 0) { - infoLine = $"{player.GetTranslation("your_skill")}:
"; - skillLine = $"{player.GetTranslation("none")}
"; + infoLine = player.GetTranslation("your_skill"); + skillLine = player.GetTranslation("none"); } else if (skillPlayer.IsDrawing) { var randomSkill = SkillData.Skills[Instance.Random.Next(SkillData.Skills.Count)]; - infoLine = $"{player.GetTranslation("drawing_skill")}:
"; - skillLine = $"{player.GetSkillName(randomSkill.Skill)}
"; + infoLine = player.GetTranslation("drawing_skill"); + skillLine = $"{player.GetSkillName(randomSkill.Skill)}"; } else if (!skillPlayer.IsDrawing) { @@ -71,11 +75,21 @@ namespace jRandomSkills var skillInfo = SkillData.Skills.FirstOrDefault(s => s.Skill == skillPlayer.Skill); if (skillInfo != null) { - infoLine = $"{player.GetTranslation("your_skill")}:
"; - skillLine = $"{player.GetSkillName(skillInfo.Skill)}
"; + infoLine = player.GetTranslation("your_skill"); + skillLine = $"{player.GetSkillName(skillInfo.Skill, skillPlayer.SkillChance)}"; + if (skillInfo.Skill != Skills.None) + { + remainingLine = string.IsNullOrEmpty(skillPlayer.PrintHTML) + ? showDescirptionHUD ? player.GetSkillDescription(skillInfo.Skill, skillPlayer.SkillChance) : "" + : skillPlayer.PrintHTML; + isDescription = string.IsNullOrEmpty(skillPlayer.PrintHTML); + } } - } else if (player?.IsValid == true && Config.LoadedConfig.Settings.DisableSpectateHUD) + } else if (player?.IsValid == true) { + if (player.Team is CsTeam.Spectator or CsTeam.None && Config.LoadedConfig.DisableSpectateHUD) + return; + var pawn = player.Pawn.Value; if (pawn == null) return; @@ -94,15 +108,19 @@ namespace jRandomSkills string pName = observeredPlayerSkill.PlayerName; if (pName.Length > 18) pName = $"{pName[..17]}..."; - infoLine = $"{player.GetTranslation("observer_skill")} {pName}:
"; - skillLine = $"{(observeredPlayerSkill.SpecialSkill == Skills.None ? player.GetSkillName(observeredPlayerSkillInfo.Skill) : $"{player.GetSkillName(observeredPlayerSpecialSkillInfo.Skill)}({player.GetSkillName(observeredPlayerSkillInfo.Skill)})")}
"; + var observerSkill = player.GetTranslation("observer_skill"); + infoLine = string.IsNullOrEmpty(observerSkill) ? pName : $"{observerSkill} {pName}"; + skillLine = $"{(observeredPlayerSkill.SpecialSkill == Skills.None + ? player.GetSkillName(observeredPlayerSkillInfo.Skill, observeredPlayerSkill.SkillChance) + : $"{player.GetSkillName(observeredPlayerSpecialSkillInfo.Skill)}({player.GetSkillName(observeredPlayerSkillInfo.Skill)})")}"; + if (showDescirptionHUD) + remainingLine = player.GetSkillDescription(observeredPlayerSkill.Skill, observeredPlayerSkill.SkillChance); } } - if (string.IsNullOrEmpty(infoLine) && string.IsNullOrEmpty(skillLine)) return; - var hudContent = infoLine + skillLine; + if (string.IsNullOrEmpty(skillLine)) return; if (player == null || !player.IsValid) return; - player.PrintToCenterHtml(hudContent); + Event.UpdateSkillHUD(player, infoLine, skillLine, remainingLine, isDescription); } } } \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Aimbot.cs b/jRandomSkills - SRC Files/src/player/skills/Aimbot.cs index c6e3df5..7fb09d3 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Aimbot.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Aimbot.cs @@ -4,17 +4,18 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using System.Runtime.InteropServices; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Aimbot : ISkill { private const Skills skillName = Skills.Aimbot; - private static readonly Dictionary hitGroups = []; + private static readonly ConcurrentDictionary hitGroups = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void OnTakeDamage(DynamicHook h) @@ -66,7 +67,7 @@ namespace jRandomSkills Marshal.WriteInt32(hit.Key, 56, hit.Value); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff0000", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff0000", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Anomaly.cs b/jRandomSkills - SRC Files/src/player/skills/Anomaly.cs index b1334df..bceddb5 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Anomaly.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Anomaly.cs @@ -3,6 +3,7 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; +using System.Collections.Concurrent; using static jRandomSkills.jRandomSkills; namespace jRandomSkills @@ -10,19 +11,19 @@ namespace jRandomSkills public class Anomaly : ISkill { private const Skills skillName = Skills.Anomaly; - private static readonly int maxSize = Config.GetValue(skillName, "secondsInBack"); private static readonly float tickRate = 64; - private static readonly float timerCooldown = Config.GetValue(skillName, "cooldown"); - private static readonly Dictionary SkillPlayerInfo = []; + private static readonly ConcurrentDictionary SkillPlayerInfo = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - SkillPlayerInfo.Clear(); + lock (setLock) + SkillPlayerInfo.Clear(); } public static void OnTick() @@ -41,7 +42,7 @@ namespace jRandomSkills if (skillInfo.LastRotations == null || skillInfo.LastPositions == null) continue; skillInfo.LastPositions.Add(new Vector(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z)); skillInfo.LastRotations.Add(new QAngle(pawn.EyeAngles.X, pawn.EyeAngles.Y, pawn.EyeAngles.Z)); - if (skillInfo.LastRotations.Count > maxSize) + if (skillInfo.LastRotations.Count > SkillsInfo.GetValue(skillName, "secondsInBack")) { skillInfo.LastPositions.RemoveAt(0); skillInfo.LastRotations.RemoveAt(0); @@ -53,19 +54,20 @@ namespace jRandomSkills public static void EnableSkill(CCSPlayerController player) { - SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo { SteamID = player.SteamID, CanUse = true, Cooldown = DateTime.MinValue, LastPositions = [], LastRotations = [], - }; + }); } public static void DisableSkill(CCSPlayerController player) { - SkillPlayerInfo.Remove(player.SteamID); + SkillPlayerInfo.TryRemove(player.SteamID, out _); + SkillUtils.ResetPrintHTML(player); } private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) @@ -73,22 +75,20 @@ namespace jRandomSkills float cooldown = 0; if (skillInfo != null) { - float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "cooldown")) - DateTime.Now).TotalSeconds); cooldown = Math.Max(time, 0); if (cooldown == 0 && skillInfo?.CanUse == false) skillInfo.CanUse = true; } - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = cooldown != 0 ? $"{player.GetTranslation("hud_info", $"{cooldown}")}
" : ""; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + if (cooldown == 0) + playerInfo.PrintHTML = null; + else + playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"{cooldown}")}"; } public static void UseSkill(CCSPlayerController player) @@ -121,7 +121,7 @@ namespace jRandomSkills public List? LastRotations { get; set; } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a86eff", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, int secondsInBack = 5, float cooldown = 15) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a86eff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, int secondsInBack = 5, float cooldown = 15) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int SecondsInBack { get; set; } = secondsInBack; public float Cooldown { get; set; } = cooldown; diff --git a/jRandomSkills - SRC Files/src/player/skills/AntyFlash.cs b/jRandomSkills - SRC Files/src/player/skills/AntyFlash.cs index 1aa710c..418fb20 100644 --- a/jRandomSkills - SRC Files/src/player/skills/AntyFlash.cs +++ b/jRandomSkills - SRC Files/src/player/skills/AntyFlash.cs @@ -12,7 +12,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerBlind(EventPlayerBlind @event) @@ -31,7 +31,7 @@ namespace jRandomSkills if (playerInfo?.Skill == skillName) playerPawn.FlashDuration = 0.0f; else if (attackerInfo?.Skill == skillName) - playerPawn.FlashDuration = 7.0f; + playerPawn.FlashDuration = SkillsInfo.GetValue(skillName, "flashDuration"); } public static void EnableSkill(CCSPlayerController player) @@ -39,8 +39,9 @@ namespace jRandomSkills SkillUtils.TryGiveWeapon(player, CsItem.FlashbangGrenade); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#D6E6FF", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#D6E6FF", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float flashDuration = 7f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { + public float FlashDuration { get; set; } = flashDuration; } } } \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/AntyHead.cs b/jRandomSkills - SRC Files/src/player/skills/AntyHead.cs index 0b49459..e6a3ea5 100644 --- a/jRandomSkills - SRC Files/src/player/skills/AntyHead.cs +++ b/jRandomSkills - SRC Files/src/player/skills/AntyHead.cs @@ -11,7 +11,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerHurt(EventPlayerHurt @event) @@ -38,7 +38,7 @@ namespace jRandomSkills playerPawn.Health = (int)newHealth; } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8B4513", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8B4513", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/AreaReaper.cs b/jRandomSkills - SRC Files/src/player/skills/AreaReaper.cs index 87c4feb..0ecfffd 100644 --- a/jRandomSkills - SRC Files/src/player/skills/AreaReaper.cs +++ b/jRandomSkills - SRC Files/src/player/skills/AreaReaper.cs @@ -4,6 +4,7 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { @@ -15,7 +16,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -59,7 +60,7 @@ namespace jRandomSkills if (playerInfo == null) return; playerInfo.SkillChance = 0; - HashSet<(string, string)> menuItems = [(player.GetTranslation("bombsite_a"), "a"), (player.GetTranslation("bombsite_b"), "b")]; + ConcurrentBag<(string, string)> menuItems = [(player.GetTranslation("bombsite_a"), "a"), (player.GetTranslation("bombsite_b"), "b")]; SkillUtils.CreateMenu(player, menuItems); } @@ -78,7 +79,7 @@ namespace jRandomSkills bombTarget.AcceptInput("Enable"); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#edf5b5", CsTeam onlyTeam = CsTeam.CounterTerrorist, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#edf5b5", CsTeam onlyTeam = CsTeam.CounterTerrorist, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Armored.cs b/jRandomSkills - SRC Files/src/player/skills/Armored.cs index a3576d6..c7ec373 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Armored.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Armored.cs @@ -13,7 +13,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } public static void EnableSkill(CCSPlayerController player) @@ -21,10 +21,10 @@ namespace jRandomSkills var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo == null) return; - float newScale = (float)Instance.Random.NextDouble() * (Config.GetValue(skillName, "ChanceTo") - Config.GetValue(skillName, "ChanceFrom")) + Config.GetValue(skillName, "ChanceFrom"); + float newScale = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue(skillName, "ChanceTo") - SkillsInfo.GetValue(skillName, "ChanceFrom")) + SkillsInfo.GetValue(skillName, "ChanceFrom"); playerInfo.SkillChance = newScale; newScale = (float)Math.Round(newScale, 2); - SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetTranslation("armored")}{ChatColors.Lime}: " + player.GetTranslation("armored_desc2", newScale), false); + SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newScale)}", false); } public static void OnTakeDamage(DynamicHook h) @@ -57,7 +57,7 @@ namespace jRandomSkills } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#d1430a", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float chanceFrom = .65f, float chanceTo = .85f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#d1430a", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float chanceFrom = .65f, float chanceTo = .85f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float ChanceFrom { get; set; } = chanceFrom; public float ChanceTo { get; set; } = chanceTo; diff --git a/jRandomSkills - SRC Files/src/player/skills/Assassin.cs b/jRandomSkills - SRC Files/src/player/skills/Assassin.cs index 344dc56..2496648 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Assassin.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Assassin.cs @@ -8,13 +8,11 @@ namespace jRandomSkills public class Assassin : ISkill { private const Skills skillName = Skills.Assassin; - private static readonly float damageMultiplier = Config.GetValue(skillName, "damageMultiplier"); - private static readonly float toleranceDeg = Config.GetValue(skillName, "toleranceDeg"); private static readonly string[] nades = ["inferno", "flashbang", "smokegrenade", "decoy", "hegrenade"]; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerHurt(EventPlayerHurt @event) @@ -32,7 +30,7 @@ namespace jRandomSkills if (playerInfo?.Skill != skillName) return; if (IsBehind(attacker!, victim!)) - SkillUtils.TakeHealth(victim!.PlayerPawn.Value, (int)(damage * (damageMultiplier - 1f))); + SkillUtils.TakeHealth(victim!.PlayerPawn.Value, (int)(damage * (SkillsInfo.GetValue(skillName, "damageMultiplier") - 1f))); } private static bool IsBehind(CCSPlayerController attacker, CCSPlayerController victim) @@ -47,6 +45,7 @@ namespace jRandomSkills private static (float, float) GetAngleRange(float angle) { + var toleranceDeg = SkillsInfo.GetValue(skillName, "toleranceDeg"); float min = angle - toleranceDeg; float max = angle + toleranceDeg; @@ -63,7 +62,7 @@ namespace jRandomSkills return (target >= a || target <= b); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#d9d9d9", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float damageMultiplier = 2f, float toleranceDeg = 45f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#d9d9d9", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float damageMultiplier = 2f, float toleranceDeg = 45f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float DamageMultiplier { get; set; } = damageMultiplier; public float ToleranceDeg { get; set; } = toleranceDeg; diff --git a/jRandomSkills - SRC Files/src/player/skills/Astronaut.cs b/jRandomSkills - SRC Files/src/player/skills/Astronaut.cs index b41d016..3effa63 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Astronaut.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Astronaut.cs @@ -13,7 +13,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } public static void EnableSkill(CCSPlayerController player) @@ -43,13 +43,13 @@ namespace jRandomSkills var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo == null) return; - float gravityModifier = (float)Math.Round(Instance.Random.NextDouble() * (Config.GetValue(skillName, "ChanceTo") - Config.GetValue(skillName, "chanceFrom")) + Config.GetValue(skillName, "chanceFrom"), 1); + float gravityModifier = (float)Math.Round(Instance.Random.NextDouble() * (SkillsInfo.GetValue(skillName, "ChanceTo") - SkillsInfo.GetValue(skillName, "chanceFrom")) + SkillsInfo.GetValue(skillName, "chanceFrom"), 1); playerInfo.SkillChance = gravityModifier; - SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetTranslation("astronaut")}{ChatColors.Lime}: " + player.GetTranslation("astronaut_desc2", gravityModifier), false); + SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, gravityModifier)}", false); player.PlayerPawn.Value.ActualGravityScale = gravityModifier; } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#7E10AD", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float chanceFrom = .1f, float chanceTo = .7f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#7E10AD", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float chanceFrom = .1f, float chanceTo = .7f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float ChanceFrom { get; set; } = chanceFrom; public float ChanceTo { get; set; } = chanceTo; diff --git a/jRandomSkills - SRC Files/src/player/skills/Bankrupt.cs b/jRandomSkills - SRC Files/src/player/skills/Bankrupt.cs index 76f7f66..e500f20 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Bankrupt.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Bankrupt.cs @@ -4,6 +4,7 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { @@ -13,7 +14,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -33,7 +34,7 @@ namespace jRandomSkills if (playerInfo == null || playerInfo.Skill != skillName) continue; var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); - HashSet<(string, string)> menuItems = enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account)}$", e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account)}$", e.Index.ToString()))); SkillUtils.UpdateMenu(player, menuItems); } } @@ -74,7 +75,7 @@ namespace jRandomSkills var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); if (enemies.Length > 0) { - HashSet<(string, string)> menuItems = enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account)}$", e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account)}$", e.Index.ToString()))); SkillUtils.CreateMenu(player, menuItems); } else @@ -96,7 +97,7 @@ namespace jRandomSkills SkillUtils.CloseMenu(player); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#abab33", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#abab33", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Baseball.cs b/jRandomSkills - SRC Files/src/player/skills/Baseball.cs index 26dfbf9..8a21e90 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Baseball.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Baseball.cs @@ -4,20 +4,18 @@ using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Baseball : ISkill { private const Skills skillName = Skills.Baseball; - private static readonly float speedMultipier = Config.GetValue(skillName, "speedMultipier"); - private static readonly float maxSpeed = Config.GetValue(skillName, "maxSpeed"); - private static readonly int damageDeal = Config.GetValue(skillName, "damageDeal"); - private static readonly HashSet decoys = []; + private static readonly ConcurrentDictionary decoys = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerHurt(EventPlayerHurt @event) @@ -32,7 +30,7 @@ namespace jRandomSkills var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID); if (attackerInfo?.Skill != skillName) return; - SkillUtils.TakeHealth(victim!.PlayerPawn.Value, damageDeal); + SkillUtils.TakeHealth(victim!.PlayerPawn.Value, SkillsInfo.GetValue(skillName, "damageDeal")); } public static void OnEntitySpawned(CEntityInstance entity) @@ -52,7 +50,7 @@ namespace jRandomSkills var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo?.Skill != skillName) return; - decoys.Add(decoy); + decoys.TryAdd(decoy, 0); } public static void DecoyStarted(EventDecoyStarted @event) @@ -62,25 +60,25 @@ namespace jRandomSkills var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo?.Skill != skillName) return; - var decoy = decoys.FirstOrDefault(d => d.Index == @event.Entityid); + var decoy = decoys.FirstOrDefault(d => d.Key.Index == @event.Entityid).Key; if (decoy != null && decoy.IsValid) decoy.AcceptInput("Kill"); } public static void OnTick() { - foreach (var decoy in decoys) + foreach (var decoy in decoys.Keys) { if (!decoy.IsValid) { - decoys.Remove(decoy); + decoys.TryRemove(decoy, out _); continue; } decoy.Bounces = 0; if (Server.TickCount % 8 != 0) continue; var vel = decoy.AbsVelocity; float speed = vel.Length(); - float targetSpeed = Math.Min(speed * speedMultipier, maxSpeed); + float targetSpeed = Math.Min(speed * SkillsInfo.GetValue(skillName, "speedMultipier"), SkillsInfo.GetValue(skillName, "maxSpeed")); if (speed > .01f) { @@ -99,7 +97,7 @@ namespace jRandomSkills SkillUtils.TryGiveWeapon(player, CsItem.DecoyGrenade); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#2effc7", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float speedMultipier = 2f, float maxSpeed = 900f, int damageDeal = 9999) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#2effc7", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float speedMultipier = 2f, float maxSpeed = 900f, int damageDeal = 9999) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float SpeedMultipier { get; set; } = speedMultipier; public float MaxSpeed { get; set; } = maxSpeed; diff --git a/jRandomSkills - SRC Files/src/player/skills/Behind.cs b/jRandomSkills - SRC Files/src/player/skills/Behind.cs index 4cab3d5..d658b64 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Behind.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Behind.cs @@ -12,7 +12,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } public static void PlayerHurt(EventPlayerHurt @event) @@ -32,11 +32,11 @@ namespace jRandomSkills { var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo == null) return; - float newChance = (float)Instance.Random.NextDouble() * (Config.GetValue(skillName, "ChanceTo") - Config.GetValue(skillName, "ChanceFrom")) + Config.GetValue(skillName, "ChanceFrom"); + float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue(skillName, "ChanceTo") - SkillsInfo.GetValue(skillName, "ChanceFrom")) + SkillsInfo.GetValue(skillName, "ChanceFrom"); playerInfo.SkillChance = newChance; newChance = (float)Math.Round(newChance, 2) * 100; newChance = (float)Math.Round(newChance); - SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetTranslation("behind")}{ChatColors.Lime}: " + player.GetTranslation("behind_desc2", newChance), false); + SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", false); } private static void RotateEnemy(CCSPlayerController player) @@ -58,7 +58,7 @@ namespace jRandomSkills pawn.Teleport(currentPosition, newAngles, new Vector(0, 0, 0)); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#00FF00", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float chanceFrom = .2f, float chanceTo = .4f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#00FF00", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float chanceFrom = .2f, float chanceTo = .4f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float ChanceFrom { get; set; } = chanceFrom; public float ChanceTo { get; set; } = chanceTo; diff --git a/jRandomSkills - SRC Files/src/player/skills/BladeMaster.cs b/jRandomSkills - SRC Files/src/player/skills/BladeMaster.cs index 28fe9ce..fdd5054 100644 --- a/jRandomSkills - SRC Files/src/player/skills/BladeMaster.cs +++ b/jRandomSkills - SRC Files/src/player/skills/BladeMaster.cs @@ -10,12 +10,31 @@ namespace jRandomSkills { private const Skills skillName = Skills.BladeMaster; private static readonly string[] noReflectionWeapon = ["inferno", "flashbang", "smokegrenade", "decoy", "hegrenade", "knife", "taser"]; - private static readonly float torseReflectionChance = Config.GetValue(skillName, "torseReflectionChance") * 100; - private static readonly float legReflectionChance = Config.GetValue(skillName, "legReflectionChance") * 100; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); + } + + public static void OnTick() + { + 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; + + var playerPawn = player.PlayerPawn?.Value; + if (playerPawn == null || !playerPawn.IsValid || playerPawn.VelocityModifier == 0) continue; + + var weaponServices = playerPawn.WeaponServices; + if (weaponServices == null) return; + if (weaponServices.ActiveWeapon == null || !weaponServices.ActiveWeapon.IsValid || weaponServices.ActiveWeapon.Value == null || !weaponServices.ActiveWeapon.Value.IsValid || weaponServices.ActiveWeapon.Value.DesignerName != "weapon_knife") + return; + + playerPawn.VelocityModifier = SkillsInfo.GetValue(skillName, "velocityModifier"); + } } public static void PlayerHurt(EventPlayerHurt @event) @@ -32,11 +51,11 @@ namespace jRandomSkills int chance = Instance.Random.Next(0, 101); if (hitGroup == HitGroup_t.HITGROUP_LEFTLEG || hitGroup == HitGroup_t.HITGROUP_RIGHTLEG) { - if (chance > legReflectionChance) + if (chance > SkillsInfo.GetValue(skillName, "legReflectionChance") * 100) return; } else - if (chance > torseReflectionChance) + if (chance > SkillsInfo.GetValue(skillName, "torseReflectionChance") * 100) return; var pawn = victim!.PlayerPawn.Value; @@ -63,10 +82,11 @@ namespace jRandomSkills Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_iHealth"); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#cc7504", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float torseReflectionChance = .95f, float legReflectionChance = .80f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#cc7504", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float torseReflectionChance = .95f, float legReflectionChance = .80f, float velocityModifier = .85f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float TorseReflectionChance { get; set; } = torseReflectionChance; public float LegReflectionChance { get; set; } = legReflectionChance; + public float VelocityModifier { get; set; } = velocityModifier; } } } \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/BunnyHop.cs b/jRandomSkills - SRC Files/src/player/skills/BunnyHop.cs index c243ddf..6e12bc0 100644 --- a/jRandomSkills - SRC Files/src/player/skills/BunnyHop.cs +++ b/jRandomSkills - SRC Files/src/player/skills/BunnyHop.cs @@ -9,13 +9,10 @@ namespace jRandomSkills public class BunnyHop : ISkill { private const Skills skillName = Skills.BunnyHop; - private static readonly float maxSpeed = Config.GetValue(skillName, "maxSpeed"); - private static readonly float bunnyHopVelocity = Config.GetValue(skillName, "jumpVelocity"); - private static readonly float jumpBoost = Config.GetValue(skillName, "jumpBoost"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void OnTick() @@ -39,7 +36,8 @@ namespace jRandomSkills if (buttons.HasFlag(PlayerButtons.Jump) && flags.HasFlag(PlayerFlags.FL_ONGROUND) && !playerPawn.MoveType.HasFlag(MoveType_t.MOVETYPE_LADDER)) { - playerPawn.AbsVelocity.Z = bunnyHopVelocity; + playerPawn.AbsVelocity.Z = SkillsInfo.GetValue(skillName, "jumpVelocity"); + var maxSpeed = SkillsInfo.GetValue(skillName, "maxSpeed"); var vX = playerPawn.AbsVelocity.X; var vY = playerPawn.AbsVelocity.Y; @@ -48,7 +46,7 @@ namespace jRandomSkills if (speed2D < maxSpeed) { - var newSpeed = Math.Min(speed2D * jumpBoost, maxSpeed); + var newSpeed = Math.Min(speed2D * SkillsInfo.GetValue(skillName, "jumpBoost"), maxSpeed); scale = newSpeed / (speed2D == 0 ? 1 : speed2D); } else if (speed2D > maxSpeed) @@ -59,7 +57,7 @@ namespace jRandomSkills } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#d1430a", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float maxSpeed = 500f, float jumpVelocity = 300f, float jumpBoost = 2f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#d1430a", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float maxSpeed = 500f, float jumpVelocity = 300f, float jumpBoost = 2f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float MaxSpeed { get; set; } = maxSpeed; public float JumpVelocity { get; set; } = jumpVelocity; diff --git a/jRandomSkills - SRC Files/src/player/skills/C4Camouflage.cs b/jRandomSkills - SRC Files/src/player/skills/C4Camouflage.cs index af04d01..54035a0 100644 --- a/jRandomSkills - SRC Files/src/player/skills/C4Camouflage.cs +++ b/jRandomSkills - SRC Files/src/player/skills/C4Camouflage.cs @@ -5,17 +5,18 @@ using CounterStrikeSharp.API.Core.Attributes; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class C4Camouflage : ISkill { private const Skills skillName = Skills.C4Camouflage; - private static readonly Dictionary> invisibleEntities = []; + private static readonly ConcurrentDictionary> invisibleEntities = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void WeaponPickup(EventItemPickup @event) @@ -48,6 +49,16 @@ namespace jRandomSkills } } + public static void OnTick() + { + foreach (var player in Utilities.GetPlayers()) + { + if (!player.PawnIsAlive) + if (invisibleEntities.ContainsKey(player.SteamID)) + invisibleEntities.TryRemove(player.SteamID, out _); + } + } + public static void CheckTransmit([CastFrom(typeof(nint))] CCheckTransmitInfoList infoList) { foreach (var (info, player) in infoList) @@ -81,7 +92,7 @@ namespace jRandomSkills { SetPlayerVisibility(player, true); SetWeaponVisibility(player, true); - invisibleEntities.Remove(player.SteamID); + invisibleEntities.TryRemove(player.SteamID, out _); } private static void SetPlayerVisibility(CCSPlayerController player, bool enabled) @@ -101,7 +112,7 @@ namespace jRandomSkills var playerPawn = player.PlayerPawn.Value!; if (playerPawn.WeaponServices == null) return; - invisibleEntities.Remove(player.SteamID); + invisibleEntities.TryRemove(player.SteamID, out _); foreach (var weapon in playerPawn.WeaponServices.MyWeapons) { if (weapon != null && weapon.IsValid && weapon.Value != null && weapon.Value.IsValid) @@ -114,16 +125,16 @@ namespace jRandomSkills items.Add(weapon.Index); } else - invisibleEntities.Add(player.SteamID, [weapon.Index]); + invisibleEntities.TryAdd(player.SteamID, [weapon.Index]); } } } if (visible) - invisibleEntities.Remove(player.SteamID); + invisibleEntities.TryRemove(player.SteamID, out _); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#00911f", CsTeam onlyTeam = CsTeam.Terrorist, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#00911f", CsTeam onlyTeam = CsTeam.Terrorist, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Catapult.cs b/jRandomSkills - SRC Files/src/player/skills/Catapult.cs index 89953de..a0d24b6 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Catapult.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Catapult.cs @@ -12,7 +12,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } public static void PlayerHurt(EventPlayerHurt @event) @@ -36,14 +36,14 @@ namespace jRandomSkills { var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo == null) return; - float newChance = (float)Instance.Random.NextDouble() * (Config.GetValue(skillName, "chanceTo") - Config.GetValue(skillName, "chanceFrom")) + Config.GetValue(skillName, "chanceFrom"); + float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue(skillName, "chanceTo") - SkillsInfo.GetValue(skillName, "chanceFrom")) + SkillsInfo.GetValue(skillName, "chanceFrom"); playerInfo.SkillChance = newChance; newChance = (float)Math.Round(newChance, 2) * 100; newChance = (float)Math.Round(newChance); - SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetTranslation("catapult")}{ChatColors.Lime}: " + player.GetTranslation("catapult_desc2", newChance), false); + SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", false); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FF4500", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float chanceFrom = .2f, float chanceTo = .4f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FF4500", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float chanceFrom = .2f, float chanceTo = .4f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float ChanceFrom { get; set; } = chanceFrom; public float ChanceTo { get; set; } = chanceTo; diff --git a/jRandomSkills - SRC Files/src/player/skills/Chicken.cs b/jRandomSkills - SRC Files/src/player/skills/Chicken.cs index ec3cea2..ef7f1c2 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Chicken.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Chicken.cs @@ -5,7 +5,7 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using static jRandomSkills.jRandomSkills; using jRandomSkills.src.utils; -using CounterStrikeSharp.API.Core.Attributes; +using System.Collections.Concurrent; namespace jRandomSkills { @@ -22,17 +22,21 @@ namespace jRandomSkills "weapon_xm1014", "weapon_mag7", "weapon_sawedoff", "weapon_m249", "weapon_negev" ]; - private static readonly Dictionary chickens = []; + private static readonly ConcurrentDictionary chickens = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { foreach (var player in Utilities.GetPlayers()) SetWeaponAttack(player, false); + foreach (var valuePair in chickens) + if (valuePair.Value != null && valuePair.Value.IsValid) + valuePair.Value.AcceptInput("Kill"); + chickens.Clear(); } public static void WeaponPickup(EventItemPickup @event) @@ -44,17 +48,6 @@ namespace jRandomSkills SetWeaponAttack(player, true); } - public static void CheckTransmit([CastFrom(typeof(nint))] CCheckTransmitInfoList infoList) - { - foreach (var (info, player) in infoList) - { - if (player == null) continue; - if (chickens.TryGetValue(player, out var chicken)) - if (chicken != null && chicken.IsValid) - info.TransmitEntities.Remove(chicken.Index); - } - } - public static void EnableSkill(CCSPlayerController player) { var playerPawn = player.PlayerPawn?.Value; @@ -79,6 +72,7 @@ namespace jRandomSkills public static void DisableSkill(CCSPlayerController player) { + SkillUtils.ResetPrintHTML(player); var playerPawn = player.PlayerPawn?.Value; if (playerPawn != null) { @@ -100,7 +94,7 @@ namespace jRandomSkills { if (chicken != null && chicken.IsValid) chicken.AcceptInput("Kill"); - chickens.Remove(player); + chickens.TryRemove(player, out _); } } @@ -129,16 +123,21 @@ namespace jRandomSkills var chickenModel = Utilities.CreateEntityByName("prop_dynamic"); if (chickenModel == null) return; - Vector pos = new(0, 0, 0); - + chickenModel.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(chickenModel.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2)); chickenModel.SetModel("models/chicken/chicken.vmdl"); chickenModel.Render = Color.FromArgb(255, 255, 255, 255); - chickenModel.Teleport(pos, playerPawn.AbsRotation, null); + chickenModel.Teleport(playerPawn.AbsOrigin, playerPawn.AbsRotation, null); chickenModel.DispatchSpawn(); chickenModel.AcceptInput("InitializeSpawnFromWorld", playerPawn, playerPawn, ""); Utilities.SetStateChanged(chickenModel, "CBaseEntity", "m_CBodyComponent"); - Instance.AddTimer(1f, () => chickens.TryAdd(player, chickenModel)); + + chickenModel.CBodyComponent.SceneNode.GetSkeletonInstance().Scale = 1; + Utilities.SetStateChanged(chickenModel, "CBaseEntity", "m_CBodyComponent"); + Server.NextFrame(() => chickenModel.AcceptInput("SetScale", chickenModel, chickenModel, "1")); + + chickenModel.AcceptInput("SetParent", playerPawn, playerPawn, "!activator"); + chickens.TryAdd(player, chickenModel); } public static void OnTick() @@ -153,12 +152,6 @@ namespace jRandomSkills var pawn = player.PlayerPawn.Value; if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null || chicken.AbsOrigin == null) continue; - float X = (float)Math.Round(pawn.AbsOrigin.X, 2); - float Y = (float)Math.Round(pawn.AbsOrigin.Y, 2); - float Z = (float)Math.Round(pawn.AbsOrigin.Z, 2); - Vector pos = new(X, Y, Z); - if (chicken.AbsOrigin.X != pos.X || chicken.AbsOrigin.Y != pos.Y || chicken.AbsOrigin.Z != pos.Z) - chicken.Teleport(pos, pawn.AbsRotation, null); pawn.VelocityModifier = 1.1f; UpdateHUD(player); } @@ -170,21 +163,20 @@ namespace jRandomSkills var pawn = player.PlayerPawn.Value; if (pawn.WeaponServices == null || pawn.WeaponServices.ActiveWeapon == null || !pawn.WeaponServices.ActiveWeapon.IsValid || pawn.WeaponServices.ActiveWeapon.Value == null || !pawn.WeaponServices.ActiveWeapon.Value.IsValid) return; - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; var weapon = pawn.WeaponServices.ActiveWeapon.Value; - if (weapon == null || !disabledWeapons.Contains(weapon.DesignerName)) return; + if (weapon == null || !disabledWeapons.Contains(weapon.DesignerName)) + { + playerInfo.PrintHTML = null; + return; + } - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = $"{player.GetTranslation("disabled_weapon")}
"; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + playerInfo.PrintHTML = $"{player.GetTranslation("disabled_weapon")}"; } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FF8B42", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FF8B42", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/ChillOut.cs b/jRandomSkills - SRC Files/src/player/skills/ChillOut.cs index 864705e..3231113 100644 --- a/jRandomSkills - SRC Files/src/player/skills/ChillOut.cs +++ b/jRandomSkills - SRC Files/src/player/skills/ChillOut.cs @@ -9,11 +9,10 @@ namespace jRandomSkills public class ChillOut : ISkill { private const Skills skillName = Skills.ChillOut; - private static readonly float bombArmedTime = Config.GetValue(skillName, "bombArmedTime"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void BombBeginplant(EventBombBeginplant @event) @@ -29,12 +28,12 @@ namespace jRandomSkills { var bomb = bombEntities.FirstOrDefault(); if (bomb != null) - bomb.ArmedTime = Server.CurrentTime + bombArmedTime; + bomb.ArmedTime = Server.CurrentTime + SkillsInfo.GetValue(skillName, "bombArmedTime"); } } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#343deb", CsTeam onlyTeam = CsTeam.CounterTerrorist, bool needsTeammates = false, float bombArmedTime = 10f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#343deb", CsTeam onlyTeam = CsTeam.CounterTerrorist, bool disableOnFreezeTime = false, bool needsTeammates = false, float bombArmedTime = 10f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float BombArmedTime { get; set; } = bombArmedTime; } diff --git a/jRandomSkills - SRC Files/src/player/skills/Cutter.cs b/jRandomSkills - SRC Files/src/player/skills/Cutter.cs index 5403b4c..4a4ee5b 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Cutter.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Cutter.cs @@ -11,7 +11,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerHurt(EventPlayerHurt @event) @@ -29,7 +29,7 @@ namespace jRandomSkills SkillUtils.TakeHealth(victim!.PlayerPawn.Value, 9999); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#88a31a", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#88a31a", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Darkness.cs b/jRandomSkills - SRC Files/src/player/skills/Darkness.cs index 1effdb4..0feb39a 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Darkness.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Darkness.cs @@ -4,31 +4,35 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Darkness : ISkill { private const Skills skillName = Skills.Darkness; - private static readonly float brightness = Config.GetValue(skillName, "brightness"); - private static readonly Dictionary> defaultPostProcessings = []; - private static readonly List newPostProcessing = []; + private static readonly ConcurrentDictionary> defaultPostProcessings = []; + private static readonly ConcurrentBag newPostProcessing = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - foreach (var player in defaultPostProcessings.Keys) - DisableSkill(player); - foreach (var postProcessing in newPostProcessing) - if (postProcessing != null && postProcessing.IsValid) - postProcessing.AcceptInput("Kill"); - newPostProcessing.Clear(); - foreach (var player in Utilities.GetPlayers()) - SkillUtils.CloseMenu(player); + lock (setLock) + { + foreach (var player in defaultPostProcessings.Keys) + DisableSkill(player); + foreach (var postProcessing in newPostProcessing) + if (postProcessing != null && postProcessing.IsValid) + postProcessing.AcceptInput("Kill"); + newPostProcessing.Clear(); + foreach (var player in Utilities.GetPlayers()) + SkillUtils.CloseMenu(player); + } } public static void PlayerDeath(EventPlayerDeath @event) @@ -49,7 +53,7 @@ namespace jRandomSkills if (playerInfo == null || playerInfo.Skill != skillName) continue; var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); - HashSet<(string, string)> menuItems = enemies.Select(e => (e.PlayerName, e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); SkillUtils.UpdateMenu(player, menuItems); } } @@ -90,7 +94,7 @@ namespace jRandomSkills var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); if (enemies.Length > 0) { - HashSet<(string, string)> menuItems = enemies.Select(e => (e.PlayerName, e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); SkillUtils.CreateMenu(player, menuItems); } else @@ -99,8 +103,11 @@ namespace jRandomSkills public static void DisableSkill(CCSPlayerController player) { - SetUpPostProcessing(player, true); - SkillUtils.CloseMenu(player); + lock (setLock) + { + SetUpPostProcessing(player, true); + SkillUtils.CloseMenu(player); + } } private static void SetUpPostProcessing(CCSPlayerController player, bool dontCreateNew = false) @@ -109,8 +116,8 @@ namespace jRandomSkills var pawn = player.PlayerPawn.Value; if (pawn == null || !pawn.IsValid || pawn.CameraServices == null) return; - if (!defaultPostProcessings.TryGetValue(player, out _)) - defaultPostProcessings[player] = []; + if (!defaultPostProcessings.ContainsKey(player)) + defaultPostProcessings.TryAdd(player, []); int i = 0; foreach (var postProcessingVolume in pawn.CameraServices.PostProcessingVolumes) @@ -120,16 +127,18 @@ namespace jRandomSkills if (dontCreateNew) { - if (i < defaultPostProcessings[player].Count) - postProcessingVolume.Raw = defaultPostProcessings[player][i].EntityHandle.Raw; + if (defaultPostProcessings.TryGetValue(player, out var defaultList) && i < defaultList.Count) + postProcessingVolume.Raw = defaultList[i].EntityHandle.Raw; } else { - defaultPostProcessings[player].Add(postProcessingVolume.Value); + if (defaultPostProcessings.TryGetValue(player, out var defaultList)) + defaultList.Add(postProcessingVolume.Value); var postProcessing = Utilities.CreateEntityByName("post_processing_volume"); if (postProcessing == null) return; + var brightness = SkillsInfo.GetValue(skillName, "brightness"); postProcessing.ExposureControl = true; postProcessing.MaxExposure = brightness; postProcessing.MinExposure = brightness; @@ -142,10 +151,10 @@ namespace jRandomSkills Utilities.SetStateChanged(pawn, "CBasePlayerPawn", "m_pCameraServices"); if (dontCreateNew) - defaultPostProcessings.Remove(player); + defaultPostProcessings.TryRemove(player, out _); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#383838", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float brightness = .01f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#383838", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float brightness = .01f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Brightness { get; set; } = brightness; } diff --git a/jRandomSkills - SRC Files/src/player/skills/Dash.cs b/jRandomSkills - SRC Files/src/player/skills/Dash.cs index d005f83..a5039bd 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Dash.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Dash.cs @@ -13,12 +13,9 @@ namespace jRandomSkills private static readonly int?[] J = new int?[64]; private static readonly PlayerButtons[] LB = new PlayerButtons[64]; - private static readonly float jumpVelocity = Config.GetValue(skillName, "jumpVelocity"); - private static readonly float pushVelocity = Config.GetValue(skillName, "pushVelocity"); - public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void OnTick() @@ -28,11 +25,11 @@ namespace jRandomSkills if (!Instance.IsPlayerValid(player)) return; var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo?.Skill == skillName) - GiveAdditionalJump(player); + HandleDash(player); } } - private static void GiveAdditionalJump(CCSPlayerController player) + private static void HandleDash(CCSPlayerController player) { var playerPawn = player.PlayerPawn.Value; if (playerPawn == null || !playerPawn.IsValid) return; @@ -73,8 +70,8 @@ namespace jRandomSkills float moveAngle = MathF.Atan2(moveX, moveY) * (180f / MathF.PI); QAngle dashAngles = new(0, playerPawn.EyeAngles.Y + moveAngle, 0); - Vector newVelocity = SkillUtils.GetForwardVector(dashAngles) * pushVelocity; - newVelocity.Z = playerPawn.AbsVelocity.Z + jumpVelocity; + Vector newVelocity = SkillUtils.GetForwardVector(dashAngles) * SkillsInfo.GetValue(skillName, "pushVelocity"); + newVelocity.Z = playerPawn.AbsVelocity.Z + SkillsInfo.GetValue(skillName, "jumpVelocity"); playerPawn.AbsVelocity.X = newVelocity.X; playerPawn.AbsVelocity.Y = newVelocity.Y; @@ -85,7 +82,7 @@ namespace jRandomSkills LB[player.Slot] = buttons; } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#42bbfc", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float jumpVelocity = 150f, float pushVelocity = 600f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#42bbfc", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float jumpVelocity = 150f, float pushVelocity = 600f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float JumpVelocity { get; set; } = jumpVelocity; public float PushVelocity { get; set; } = pushVelocity; diff --git a/jRandomSkills - SRC Files/src/player/skills/Deactivator.cs b/jRandomSkills - SRC Files/src/player/skills/Deactivator.cs index 33e883d..627c38a 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Deactivator.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Deactivator.cs @@ -4,6 +4,7 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { @@ -13,7 +14,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -33,7 +34,7 @@ namespace jRandomSkills if (playerInfo == null || playerInfo.Skill != skillName) continue; var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); - HashSet<(string, string)> menuItems = []; + ConcurrentBag<(string, string)> menuItems = []; foreach (var enemy in enemies) { var enemyInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == enemy.SteamID); @@ -74,7 +75,7 @@ namespace jRandomSkills var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); if (enemies.Length > 0) { - HashSet<(string, string)> menuItems = []; + ConcurrentBag<(string, string)> menuItems = []; foreach (var enemy in enemies) { var enemyInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == enemy.SteamID); @@ -118,7 +119,7 @@ namespace jRandomSkills } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#919191", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#919191", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Deaf.cs b/jRandomSkills - SRC Files/src/player/skills/Deaf.cs index 35c1346..1d6501d 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Deaf.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Deaf.cs @@ -5,22 +5,23 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Deaf : ISkill { private const Skills skillName = Skills.Deaf; - private static readonly HashSet deafPlayers = []; + private static readonly ConcurrentDictionary deafPlayers = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - foreach (var player in deafPlayers) + foreach (var player in deafPlayers.Keys) DisableSkill(player); deafPlayers.Clear(); foreach (var player in Utilities.GetPlayers()) @@ -29,7 +30,7 @@ namespace jRandomSkills public static void PlayerMakeSound(UserMessage um) { - foreach (var player in deafPlayers) + foreach (var player in deafPlayers.Keys) um.Recipients.Remove(player); } @@ -44,7 +45,7 @@ namespace jRandomSkills if (playerInfo == null || playerInfo.Skill != skillName) continue; var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); - HashSet<(string, string)> menuItems = enemies.Select(e => (e.PlayerName, e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); SkillUtils.UpdateMenu(player, menuItems); } } @@ -70,7 +71,7 @@ namespace jRandomSkills return; } - deafPlayers.Add(enemy); + deafPlayers.TryAdd(enemy, 0); playerInfo.SkillChance = 1; player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("deaf_player_info", enemy.PlayerName)); enemy.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("deaf_enemy_info")); @@ -85,7 +86,7 @@ namespace jRandomSkills var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); if (enemies.Length > 0) { - HashSet<(string, string)> menuItems = enemies.Select(e => (e.PlayerName, e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); SkillUtils.CreateMenu(player, menuItems); } else @@ -94,11 +95,11 @@ namespace jRandomSkills public static void DisableSkill(CCSPlayerController player) { - deafPlayers.Remove(player); + deafPlayers.TryRemove(player, out _); SkillUtils.CloseMenu(player); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#dae01f", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#dae01f", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Disarmament.cs b/jRandomSkills - SRC Files/src/player/skills/Disarmament.cs index 952a72e..cb84648 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Disarmament.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Disarmament.cs @@ -12,7 +12,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } public static void PlayerHurt(EventPlayerHurt @event) @@ -32,8 +32,7 @@ namespace jRandomSkills var weaponName = weaponServices?.ActiveWeapon?.Value?.DesignerName; if (weaponName != null && !weaponName.Contains("weapon_knife") && !weaponName.Contains("weapon_c4")) - victim.ExecuteClientCommand("slot3"); - //victim.DropActiveWeapon(); + victim.DropActiveWeapon(); } } } @@ -42,14 +41,14 @@ namespace jRandomSkills { var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo == null) return; - float newChance = (float)Instance.Random.NextDouble() * (Config.GetValue(skillName, "chanceTo") - Config.GetValue(skillName, "chanceFrom")) + Config.GetValue(skillName, "chanceFrom"); + float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue(skillName, "chanceTo") - SkillsInfo.GetValue(skillName, "chanceFrom")) + SkillsInfo.GetValue(skillName, "chanceFrom"); playerInfo.SkillChance = newChance; newChance = (float)Math.Round(newChance, 2) * 100; newChance = (float)Math.Round(newChance); - SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetTranslation("disarmament")}{ChatColors.Lime}: " + player.GetTranslation("disarmament_desc2", newChance), false); + SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", false); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FF4500", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float chanceFrom = .2f, float chanceTo = .5f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FF4500", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float chanceFrom = .2f, float chanceTo = .35f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float ChanceFrom { get; set; } = chanceFrom; public float ChanceTo { get; set; } = chanceTo; diff --git a/jRandomSkills - SRC Files/src/player/skills/Distancer.cs b/jRandomSkills - SRC Files/src/player/skills/Distancer.cs index c4f3000..5e4a516 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Distancer.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Distancer.cs @@ -2,36 +2,45 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; -using jRandomSkills.src.utils; +using System.Collections.Concurrent; namespace jRandomSkills { public class Distancer : ISkill { private const Skills skillName = Skills.Distancer; - private static readonly HashSet distancerPlayers = []; + private static readonly ConcurrentDictionary distancerPlayers = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - distancerPlayers.Clear(); + lock (setLock) + distancerPlayers.Clear(); } public static void OnTick() { - foreach (var player in distancerPlayers) + if (SkillUtils.IsFreezeTime()) return; + foreach (var player in distancerPlayers.Keys) { + var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; + + if (playerInfo.SkillDescriptionHudExpired >= DateTime.Now) + { + playerInfo.PrintHTML = null; + return; + } + var playerPawn = player.PlayerPawn.Value; if (playerPawn == null || !playerPawn.IsValid) return; if (playerPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE) return; - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; - string closetEnemy = "Bot"; double closetDistance = double.MaxValue; @@ -47,27 +56,22 @@ namespace jRandomSkills } string distanceColor = closetDistance > 1500 ? "#00FF00" : closetDistance > 600 ? "#FFFF00" : "#FF0000"; - - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = $"{closetEnemy}: {closetDistance}
"; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + playerInfo.PrintHTML = $"{closetEnemy}: {closetDistance}"; } } public static void EnableSkill(CCSPlayerController player) { - distancerPlayers.Add(player); + distancerPlayers.TryAdd(player, 0); } public static void DisableSkill(CCSPlayerController player) { - distancerPlayers.Remove(player); + distancerPlayers.TryRemove(player, out _); + SkillUtils.ResetPrintHTML(player); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#00f2ff", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#00f2ff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Dracula.cs b/jRandomSkills - SRC Files/src/player/skills/Dracula.cs index 3fcb8c8..a49474e 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Dracula.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Dracula.cs @@ -9,11 +9,10 @@ namespace jRandomSkills public class Dracula : ISkill { private const Skills skillName = Skills.Dracula; - private static readonly float healthRegainScale = Config.GetValue(skillName, "healthRegainScale"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerHurt(EventPlayerHurt @event) @@ -33,7 +32,7 @@ namespace jRandomSkills var attackerPawn = attacker.PlayerPawn.Value; if (attackerPawn == null) return; - int newHealth = (int)(attackerPawn.Health + (damage * healthRegainScale)); + int newHealth = (int)(attackerPawn.Health + (damage * SkillsInfo.GetValue(skillName, "healthRegainScale"))); attackerPawn.MaxHealth = Math.Max(newHealth, 100); Utilities.SetStateChanged(attackerPawn, "CBaseEntity", "m_iMaxHealth"); @@ -42,7 +41,7 @@ namespace jRandomSkills Utilities.SetStateChanged(attackerPawn, "CBaseEntity", "m_iHealth"); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FA050D", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float healthRegainScale = .3f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FA050D", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float healthRegainScale = .3f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float HealthRegainScale { get; set; } = healthRegainScale; } diff --git a/jRandomSkills - SRC Files/src/player/skills/Duplicator.cs b/jRandomSkills - SRC Files/src/player/skills/Duplicator.cs index 834b621..7242187 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Duplicator.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Duplicator.cs @@ -4,6 +4,7 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { @@ -13,7 +14,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } public static void NewRound() @@ -33,7 +34,7 @@ namespace jRandomSkills if (playerInfo == null || playerInfo.Skill != skillName) continue; var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p != player && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); - HashSet<(string, string)> menuItems = []; + ConcurrentBag<(string, string)> menuItems = []; foreach (var enemy in enemies) { var enemyInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == enemy.SteamID); @@ -75,7 +76,7 @@ namespace jRandomSkills if (enemies.Length > 0) { List skills = []; - HashSet<(string, string)> menuItems = []; + ConcurrentBag<(string, string)> menuItems = []; foreach (var enemy in enemies) { var enemyInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == enemy.SteamID); @@ -135,12 +136,19 @@ namespace jRandomSkills playerInfo.Skill = enemySkill; playerInfo.SpecialSkill = skillName; SkillUtils.CloseMenu(player); - Instance.SkillAction(enemySkill.ToString(), "EnableSkill", [player]); + + if (SkillsInfo.GetValue(enemySkill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime()) + Instance?.AddTimer(Math.Max((float)(Event.freezeTimeEnd - DateTime.Now).TotalSeconds, 0), () => { + if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID && p.Skill == enemySkill) == null) return; + Instance?.SkillAction(enemySkill.ToString(), "EnableSkill", new[] { player }); + }); + else + Instance?.SkillAction(enemySkill.ToString(), "EnableSkill", new[] { player }); }); player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("duplicator_player_info", enemy.PlayerName)); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ffb73b", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ffb73b", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Dwarf.cs b/jRandomSkills - SRC Files/src/player/skills/Dwarf.cs index cb80ed8..389776c 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Dwarf.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Dwarf.cs @@ -13,7 +13,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } public static void NewRound() @@ -33,12 +33,12 @@ namespace jRandomSkills var playerPawn = player.PlayerPawn?.Value; if (playerPawn != null && player.IsValid) { - float newSize = (float)Instance.Random.NextDouble() * (Config.GetValue(skillName, "maxScale") - Config.GetValue(skillName, "minScale")) + Config.GetValue(skillName, "minScale"); + float newSize = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue(skillName, "maxScale") - SkillsInfo.GetValue(skillName, "minScale")) + SkillsInfo.GetValue(skillName, "minScale"); newSize = (float)Math.Round(newSize, 2); playerInfo.SkillChance = newSize; SkillUtils.ChangePlayerScale(player, newSize); - SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetTranslation("dwarf")}{ChatColors.Lime}: " + player.GetTranslation("dwarf_desc2", newSize), false); + SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newSize)}", false); } } @@ -56,7 +56,7 @@ namespace jRandomSkills } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ffff00", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float minScale = .6f, float maxScale = .95f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ffff00", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float minScale = .6f, float maxScale = .95f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float MinScale { get; set; } = minScale; public float MaxScale { get; set; } = maxScale; diff --git a/jRandomSkills - SRC Files/src/player/skills/Earthquake.cs b/jRandomSkills - SRC Files/src/player/skills/Earthquake.cs index b15e2bd..1c682df 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Earthquake.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Earthquake.cs @@ -4,42 +4,41 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Earthquake : ISkill { private const Skills skillName = Skills.Earthquake; - private static readonly float timerCooldown = Config.GetValue(skillName, "cooldown"); - private static readonly float amplitude = Config.GetValue(skillName, "amplitude"); - private static readonly float frequency = Config.GetValue(skillName, "frequency"); - private static readonly float duration = Config.GetValue(skillName, "duration"); - private static readonly float radius = Config.GetValue(skillName, "radius"); - private static readonly Dictionary SkillPlayerInfo = []; + private static readonly ConcurrentDictionary SkillPlayerInfo = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - SkillPlayerInfo.Clear(); + lock (setLock) + SkillPlayerInfo.Clear(); } public static void EnableSkill(CCSPlayerController player) { - SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo { SteamID = player.SteamID, CanUse = true, Cooldown = DateTime.MinValue, - }; + }); } public static void DisableSkill(CCSPlayerController player) { - SkillPlayerInfo.Remove(player.SteamID); + SkillPlayerInfo.TryRemove(player.SteamID, out _); + SkillUtils.ResetPrintHTML(player); } public static void PlayerDeath(EventPlayerDeath @event) @@ -48,7 +47,7 @@ namespace jRandomSkills if (player == null || !player.IsValid) return; var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo?.Skill == skillName) - SkillPlayerInfo.Remove(player.SteamID); + SkillPlayerInfo.TryRemove(player.SteamID, out _); } public static void OnTick() @@ -67,22 +66,20 @@ namespace jRandomSkills float cooldown = 0; if (skillInfo != null) { - float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "cooldown")) - DateTime.Now).TotalSeconds); cooldown = Math.Max(time, 0); if (cooldown == 0 && skillInfo?.CanUse == false) skillInfo.CanUse = true; } - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; + if (cooldown == 0) + return; - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = cooldown != 0 ? $"{player.GetTranslation("hud_info", $"{cooldown}")}
" : ""; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + string remainingLine = $"{player.GetTranslation("hud_info", $"{cooldown}")}"; } public static void UseSkill(CCSPlayerController player) @@ -119,10 +116,10 @@ namespace jRandomSkills shake.DispatchSpawn(); if (!shake.IsValid) return; - shake.Amplitude = amplitude; - shake.Frequency = frequency; - shake.Duration = duration; - shake.Radius = radius; + shake.Amplitude = SkillsInfo.GetValue(skillName, "amplitude"); + shake.Frequency = SkillsInfo.GetValue(skillName, "frequency"); + shake.Duration = SkillsInfo.GetValue(skillName, "duration"); + shake.Radius = SkillsInfo.GetValue(skillName, "radius"); shake.Teleport(new Vector(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z)); shake.AcceptInput("SetParent", pawn, pawn, "!activator"); @@ -136,7 +133,7 @@ namespace jRandomSkills public DateTime Cooldown { get; set; } } - public class SkillConfig(Skills skill = skillName, bool active = false, string color = "#42f59b", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float cooldown = 16f, float amplitude = 15f, float frequency = 500f, float duration = 8f, float radius = 50f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = false, string color = "#42f59b", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float cooldown = 16f, float amplitude = 15f, float frequency = 500f, float duration = 8f, float radius = 50f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Cooldown { get; set; } = cooldown; public float Amplitude { get; set; } = amplitude; diff --git a/jRandomSkills - SRC Files/src/player/skills/EnemySpawn.cs b/jRandomSkills - SRC Files/src/player/skills/EnemySpawn.cs index 6c8c6d9..e5c4768 100644 --- a/jRandomSkills - SRC Files/src/player/skills/EnemySpawn.cs +++ b/jRandomSkills - SRC Files/src/player/skills/EnemySpawn.cs @@ -4,27 +4,30 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class EnemySpawn : ISkill { private const Skills skillName = Skills.EnemySpawn; - private static readonly float timerCooldown = Config.GetValue(skillName, "cooldown"); - private static readonly Dictionary SkillPlayerInfo = []; + private static readonly ConcurrentDictionary SkillPlayerInfo = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - SkillPlayerInfo.Clear(); + lock (setLock) + SkillPlayerInfo.Clear(); } public static void OnTick() { + if (SkillUtils.IsFreezeTime()) return; foreach (var player in Utilities.GetPlayers()) { var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); @@ -36,17 +39,19 @@ namespace jRandomSkills public static void EnableSkill(CCSPlayerController player) { - SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + var cooldownBeforeUse = SkillsInfo.GetValue(skillName, "cooldownBeforeUse"); + SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo { SteamID = player.SteamID, - CanUse = true, - Cooldown = DateTime.MinValue, - }; + CanUse = false, + Cooldown = cooldownBeforeUse <= 0 ? DateTime.MinValue : Event.freezeTimeEnd.AddSeconds(cooldownBeforeUse - SkillsInfo.GetValue(skillName, "cooldown")), + }); } public static void DisableSkill(CCSPlayerController player) { - SkillPlayerInfo.Remove(player.SteamID); + SkillPlayerInfo.TryRemove(player.SteamID, out _); + SkillUtils.ResetPrintHTML(player); } private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) @@ -54,22 +59,20 @@ namespace jRandomSkills float cooldown = 0; if (skillInfo != null) { - float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "cooldown")) - DateTime.Now).TotalSeconds); cooldown = Math.Max(time, 0); if (cooldown == 0 && skillInfo?.CanUse == false) skillInfo.CanUse = true; } - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = cooldown != 0 ? $"{player.GetTranslation("hud_info", $"{cooldown}")}
" : ""; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + if (cooldown == 0) + playerInfo.PrintHTML = null; + else + playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"{cooldown}")}"; } public static void UseSkill(CCSPlayerController player) @@ -109,9 +112,10 @@ namespace jRandomSkills public DateTime Cooldown { get; set; } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff8c92", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float cooldown = 15f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff8c92", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, float cooldown = 15f, float cooldownBeforeUse = 10f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Cooldown { get; set; } = cooldown; + public float CooldownBeforeUse { get; set; } = cooldownBeforeUse; } } } \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/ExplosiveShot.cs b/jRandomSkills - SRC Files/src/player/skills/ExplosiveShot.cs index 09dd2a8..0030720 100644 --- a/jRandomSkills - SRC Files/src/player/skills/ExplosiveShot.cs +++ b/jRandomSkills - SRC Files/src/player/skills/ExplosiveShot.cs @@ -5,49 +5,66 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using Vector = CounterStrikeSharp.API.Modules.Utils.Vector; namespace jRandomSkills { public class ExplosiveShot : ISkill { private const Skills skillName = Skills.ExplosiveShot; - private static readonly float damage = Config.GetValue(skillName, "damage"); - private static readonly float damageRadius = Config.GetValue(skillName, "damageRadius"); + + private static readonly QAngle angle = new(5, 10, -4); + private static int lastTick = 0; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } public static void EnableSkill(CCSPlayerController player) { var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo == null) return; - float newChance = (float)Instance.Random.NextDouble() * (Config.GetValue(skillName, "ChanceTo") - Config.GetValue(skillName, "ChanceFrom")) + Config.GetValue(skillName, "ChanceFrom"); + float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue(skillName, "ChanceTo") - SkillsInfo.GetValue(skillName, "ChanceFrom")) + SkillsInfo.GetValue(skillName, "ChanceFrom"); playerInfo.SkillChance = newChance; newChance = (float)Math.Round(newChance, 2) * 100; newChance = (float)Math.Round(newChance); - SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetTranslation("explosiveshot")}{ChatColors.Lime}: " + player.GetTranslation("explosiveshot_desc2", newChance), false); + SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", false); } private static void SpawnExplosion(Vector vector) { - var heProjectile = Utilities.CreateEntityByName("hegrenade_projectile"); - if (heProjectile == null || !heProjectile.IsValid) return; - - Vector pos = vector; - heProjectile.TicksAtZeroVelocity = 100; - heProjectile.TeamNum = (byte)CsTeam.None; - heProjectile.Damage = damage; - heProjectile.DmgRadius = damageRadius; - heProjectile.Teleport(pos, null, new Vector(0, 0, -10)); - heProjectile.DispatchSpawn(); - heProjectile.AcceptInput("InitializeSpawnFromWorld", null, null, ""); - heProjectile.DetonateTime = 0; + lastTick = Server.TickCount; + SkillUtils.CreateHEGrenadeProjectile(vector, angle, new Vector(0, 0, 0), 0); } + public static void OnEntitySpawned(CEntityInstance entity) + { + if (entity.DesignerName != "hegrenade_projectile") return; + + var heProjectile = entity.As(); + if (heProjectile == null || !heProjectile.IsValid || heProjectile.AbsRotation == null) return; + + Server.NextFrame(() => + { + if (heProjectile == null || !heProjectile.IsValid) return; + if (!(NearlyEquals(angle.X, heProjectile.AbsRotation.X) && NearlyEquals(angle.Y, heProjectile.AbsRotation.Y) && NearlyEquals(angle.Z, heProjectile.AbsRotation.Z))) + return; + + heProjectile.TicksAtZeroVelocity = 100; + heProjectile.TeamNum = (byte)CsTeam.None; + heProjectile.Damage = SkillsInfo.GetValue(skillName, "damage"); + heProjectile.DmgRadius = SkillsInfo.GetValue(skillName, "damageRadius"); + heProjectile.DetonateTime = 0; + }); + } + + private static bool NearlyEquals(float a, float b, float epsilon = 0.001f) => Math.Abs(a -b) < epsilon; + public static void OnTakeDamage(DynamicHook h) { + if (lastTick == Server.TickCount) return; + CEntityInstance param = h.GetParam(0); CTakeDamageInfo param2 = h.GetParam(1); @@ -69,7 +86,7 @@ namespace jRandomSkills SpawnExplosion(param2.DamagePosition); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#9c0000", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float damage = 25f, float damageRadius = 210f, float chanceFrom = .15f, float chanceTo = .3f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#9c0000", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float damage = 25f, float damageRadius = 210f, float chanceFrom = .15f, float chanceTo = .3f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Damage { get; set; } = damage; public float DamageRadius { get; set; } = damageRadius; diff --git a/jRandomSkills - SRC Files/src/player/skills/FalconEye.cs b/jRandomSkills - SRC Files/src/player/skills/FalconEye.cs index bebd74b..59cc02e 100644 --- a/jRandomSkills - SRC Files/src/player/skills/FalconEye.cs +++ b/jRandomSkills - SRC Files/src/player/skills/FalconEye.cs @@ -4,18 +4,18 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using System.Drawing; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class FalconEye : ISkill { private const Skills skillName = Skills.FalconEye; - private static readonly float distance = Config.GetValue(skillName, "distance"); - private static readonly Dictionary cameras = []; + private static readonly ConcurrentDictionary cameras = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -65,7 +65,7 @@ namespace jRandomSkills ChangeCamera(player, true); continue; } - Vector pos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + 1000); + Vector pos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + SkillsInfo.GetValue(skillName, "distance")); QAngle angle = new(90, 0, -pawn.V_angle.Y); cameraInfo.Item2.Teleport(pos, angle); } @@ -104,12 +104,12 @@ namespace jRandomSkills var pawn = player.PlayerPawn.Value; if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return 0; - Vector pos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + distance); + Vector pos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + SkillsInfo.GetValue(skillName, "distance")); camera.Render = Color.FromArgb(0, 255, 255, 255); camera.Teleport(pos, new QAngle(90, 0, 0)); camera.DispatchSpawn(); - cameras[player.SteamID] = (pawn.CameraServices!.ViewEntity.Raw, camera); + cameras.AddOrUpdate(player.SteamID, (pawn.CameraServices!.ViewEntity.Raw, camera), (k, v) => (pawn.CameraServices!.ViewEntity.Raw, camera)); return camera.EntityHandle.Raw; } @@ -132,7 +132,7 @@ namespace jRandomSkills } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#d1f542", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float distance = 1000f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#d1f542", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float distance = 1000f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Distance { get; set; } = distance; } diff --git a/jRandomSkills - SRC Files/src/player/skills/FastReload.cs b/jRandomSkills - SRC Files/src/player/skills/FastReload.cs index efbb244..64edfdc 100644 --- a/jRandomSkills - SRC Files/src/player/skills/FastReload.cs +++ b/jRandomSkills - SRC Files/src/player/skills/FastReload.cs @@ -12,7 +12,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void UseSkill(CCSPlayerController player) @@ -40,7 +40,7 @@ namespace jRandomSkills Utilities.SetStateChanged(activeWeapon, "CBasePlayerWeapon", "m_iClip1"); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ffc061", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ffc061", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Flash.cs b/jRandomSkills - SRC Files/src/player/skills/Flash.cs index 971f9f0..50c0583 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Flash.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Flash.cs @@ -5,17 +5,18 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Flash : ISkill { private const Skills skillName = Skills.Flash; - public static readonly Dictionary jumpedPlayers = []; + public static readonly ConcurrentDictionary jumpedPlayers = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } public static void NewRound() @@ -46,7 +47,7 @@ namespace jRandomSkills var player = @event.Userid; if (player == null || !player.IsValid) return; if (!jumpedPlayers.TryGetValue(player.SteamID, out _)) return; - jumpedPlayers[player.SteamID] = Server.TickCount + 20; + jumpedPlayers.AddOrUpdate(player.SteamID, Server.TickCount + 20, (k, v) => Server.TickCount + 20); } public static void EnableSkill(CCSPlayerController player) @@ -55,16 +56,13 @@ namespace jRandomSkills var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerPawn == null || playerInfo == null) return; - var skillConfig = Config.LoadedConfig.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString()); - if (skillConfig == null) return; - - float newSpeed = (float)Instance.Random.NextDouble() * (Config.GetValue(skillName, "ChanceTo") - Config.GetValue(skillName, "ChanceFrom")) + Config.GetValue(skillName, "ChanceFrom"); + float newSpeed = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue(skillName, "ChanceTo") - SkillsInfo.GetValue(skillName, "ChanceFrom")) + SkillsInfo.GetValue(skillName, "ChanceFrom"); newSpeed = (float)Math.Round(newSpeed, 2); playerInfo.SkillChance = newSpeed; jumpedPlayers.TryAdd(player.SteamID, 0); playerPawn.VelocityModifier = newSpeed; - SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetTranslation("flash")}{ChatColors.Lime}: " + player.GetTranslation("flash_desc2", newSpeed), false); + SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newSpeed)}", false); } public static void DisableSkill(CCSPlayerController player) @@ -72,7 +70,7 @@ namespace jRandomSkills var playerPawn = player.PlayerPawn.Value; if (playerPawn == null) return; playerPawn.VelocityModifier = 1; - jumpedPlayers.Remove(player.SteamID); + jumpedPlayers.TryRemove(player.SteamID, out _); } public static void OnTick() @@ -100,7 +98,7 @@ namespace jRandomSkills } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#A31912", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float chanceFrom = 1.2f, float chanceTo = 3.0f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#A31912", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float chanceFrom = 1.2f, float chanceTo = 3.0f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float ChanceFrom { get; set; } = chanceFrom; public float ChanceTo { get; set; } = chanceTo; diff --git a/jRandomSkills - SRC Files/src/player/skills/Fortnite.cs b/jRandomSkills - SRC Files/src/player/skills/Fortnite.cs index 69d952e..799360a 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Fortnite.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Fortnite.cs @@ -6,29 +6,30 @@ using jRandomSkills.src.player; using jRandomSkills.src.utils; using static CounterStrikeSharp.API.Core.Listeners; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Fortnite : ISkill { private const Skills skillName = Skills.Fortnite; - private static readonly float timerCooldown = Config.GetValue(skillName, "cooldown"); - private static readonly int barricadeHealth = Config.GetValue(skillName, "barricadeHealth"); - private static readonly string propModel = Config.GetValue(skillName, "propModel"); - - private static readonly Dictionary SkillPlayerInfo = []; - private static readonly Dictionary barricades = []; + private static readonly ConcurrentDictionary SkillPlayerInfo = []; + private static readonly ConcurrentDictionary barricades = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); - Instance.RegisterListener((ResourceManifest manifest) => manifest.AddResource(propModel)); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); + Instance.RegisterListener((ResourceManifest manifest) => manifest.AddResource(SkillsInfo.GetValue(skillName, "propModel"))); } public static void NewRound() { - SkillPlayerInfo.Clear(); - barricades.Clear(); + lock (setLock) + { + SkillPlayerInfo.Clear(); + barricades.Clear(); + } } public static void OnTick() @@ -44,17 +45,18 @@ namespace jRandomSkills public static void EnableSkill(CCSPlayerController player) { - SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo { SteamID = player.SteamID, CanUse = true, Cooldown = DateTime.MinValue, - }; + }); } public static void DisableSkill(CCSPlayerController player) { - SkillPlayerInfo.Remove(player.SteamID); + SkillPlayerInfo.TryRemove(player.SteamID, out _); + SkillUtils.ResetPrintHTML(player); } private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) @@ -62,22 +64,20 @@ namespace jRandomSkills float cooldown = 0; if (skillInfo != null) { - float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "cooldown")) - DateTime.Now).TotalSeconds); cooldown = Math.Max(time, 0); if (cooldown == 0 && skillInfo?.CanUse == false) skillInfo.CanUse = true; } - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = cooldown != 0 ? $"{player.GetTranslation("hud_info", $"{cooldown}")}
" : ""; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + if (cooldown == 0) + playerInfo.PrintHTML = null; + else + playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"{cooldown}")}"; } public static void UseSkill(CCSPlayerController player) @@ -111,10 +111,10 @@ namespace jRandomSkills box.Collision.SolidType = SolidType_t.SOLID_VPHYSICS; box.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(box.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2)); box.DispatchSpawn(); - barricades.Add(box.Index, barricadeHealth); + barricades.TryAdd(box.Index, SkillsInfo.GetValue(skillName, "barricadeHealth")); Server.NextFrame(() => { - box.SetModel(propModel); + box.SetModel(SkillsInfo.GetValue(skillName, "propModel")); box.Teleport(pos, angle, null); }); } @@ -137,7 +137,7 @@ namespace jRandomSkills if (barricades.TryGetValue(box.Index, out int health)) { health -= (int)param2.Damage; - barricades[box.Index] = health; + barricades.AddOrUpdate(box.Index, health, (k, v) => health); if (health <= 0) box.AcceptInput("Kill"); } else box.AcceptInput("Kill"); @@ -150,7 +150,7 @@ namespace jRandomSkills public DateTime Cooldown { get; set; } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1b04cc", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float cooldown = 2f, int barricadeHealth = 115, string propModel = "models/props/de_aztec/hr_aztec/aztec_scaffolding/aztec_scaffold_wall_support_128.vmdl") : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1b04cc", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, float cooldown = 2f, int barricadeHealth = 115, string propModel = "models/props/de_aztec/hr_aztec/aztec_scaffolding/aztec_scaffold_wall_support_128.vmdl") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Cooldown { get; set; } = cooldown; public int BarricadeHealth { get; set; } = barricadeHealth; diff --git a/jRandomSkills - SRC Files/src/player/skills/FragileBomb.cs b/jRandomSkills - SRC Files/src/player/skills/FragileBomb.cs index c4ee45f..a4db055 100644 --- a/jRandomSkills - SRC Files/src/player/skills/FragileBomb.cs +++ b/jRandomSkills - SRC Files/src/player/skills/FragileBomb.cs @@ -12,20 +12,21 @@ namespace jRandomSkills public class FragileBomb : ISkill { private const Skills skillName = Skills.FragileBomb; - private static int bombHealth = Config.GetValue(skillName, "maxBombHealth"); - private static readonly int maxBombHealth = Config.GetValue(skillName, "maxBombHealth"); + private static int bombHealth = 1000; + private static int maxBombHealth = 1000; private static CPlantedC4? plantedC4; private static CTriggerMultiple? triggerC4; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - bombHealth = maxBombHealth; + bombHealth = SkillsInfo.GetValue(skillName, "maxBombHealth"); + maxBombHealth = SkillsInfo.GetValue(skillName, "maxBombHealth"); plantedC4 = null; triggerC4 = null; } @@ -110,7 +111,7 @@ namespace jRandomSkills Localization.PrintTranslationToChatAll($" {ChatColors.Gold}{{0}}: {ChatColors.Red}{bombHealth}{ChatColors.Gold}/{ChatColors.Green}{maxBombHealth}", ["fragilebomb_bomb_health"]); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#5d00ff", CsTeam onlyTeam = CsTeam.CounterTerrorist, bool needsTeammates = false, int maxBombHealth = 1000) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#5d00ff", CsTeam onlyTeam = CsTeam.CounterTerrorist, bool disableOnFreezeTime = false, bool needsTeammates = false, int maxBombHealth = 1000) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int MaxBombHealth { get; set; } = maxBombHealth; } diff --git a/jRandomSkills - SRC Files/src/player/skills/FriendlyFire.cs b/jRandomSkills - SRC Files/src/player/skills/FriendlyFire.cs index 464c496..c399433 100644 --- a/jRandomSkills - SRC Files/src/player/skills/FriendlyFire.cs +++ b/jRandomSkills - SRC Files/src/player/skills/FriendlyFire.cs @@ -9,12 +9,11 @@ namespace jRandomSkills public class FriendlyFire : ISkill { private const Skills skillName = Skills.FriendlyFire; - private static readonly float healthMultiplier = Config.GetValue(skillName, "healthMultiplier"); private static readonly string[] nades = ["inferno", "flashbang", "smokegrenade", "decoy", "hegrenade"]; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerHurt(EventPlayerHurt @event) @@ -35,10 +34,10 @@ namespace jRandomSkills var pawn = victim.PlayerPawn.Value; if (pawn == null || !pawn.IsValid) return; - SkillUtils.AddHealth(pawn, damage + (int)(damage * healthMultiplier), pawn.MaxHealth); + SkillUtils.AddHealth(pawn, damage + (int)(damage * SkillsInfo.GetValue(skillName, "healthMultiplier")), pawn.MaxHealth); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff0000", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = true, float healthMultiplier = 1.5f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff0000", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = true, float healthMultiplier = 1.5f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float HealthMultiplier { get; set; } = healthMultiplier; } diff --git a/jRandomSkills - SRC Files/src/player/skills/FrozenDecoy.cs b/jRandomSkills - SRC Files/src/player/skills/FrozenDecoy.cs index cd80bec..2719d45 100644 --- a/jRandomSkills - SRC Files/src/player/skills/FrozenDecoy.cs +++ b/jRandomSkills - SRC Files/src/player/skills/FrozenDecoy.cs @@ -10,13 +10,11 @@ namespace jRandomSkills public class FrozenDecoy : ISkill { private const Skills skillName = Skills.FrozenDecoy; - private static readonly float decoyRadius = Config.GetValue(skillName, "triggerRadius"); - private static readonly int slownessMultiplier = Config.GetValue(skillName, "slownessMultiplier"); private static readonly List decoys = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -47,13 +45,14 @@ namespace jRandomSkills foreach (Vector decoyPos in decoys) foreach (var player in Utilities.GetPlayers().Where(p => p.Team == CsTeam.Terrorist || p.Team == CsTeam.CounterTerrorist)) { + var decoyRadius = SkillsInfo.GetValue(skillName, "triggerRadius"); var pawn = player.PlayerPawn.Value; if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return; double distance = SkillUtils.GetDistance(decoyPos, pawn.AbsOrigin); if (distance <= decoyRadius) { double modifier = Math.Clamp(distance / decoyRadius, 0f, 1f); - pawn.VelocityModifier = (float)Math.Pow(modifier, slownessMultiplier); + pawn.VelocityModifier = (float)Math.Pow(modifier, SkillsInfo.GetValue(skillName, "slownessMultiplier")); } } } @@ -63,7 +62,7 @@ namespace jRandomSkills SkillUtils.TryGiveWeapon(player, CsItem.DecoyGrenade); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#00eaff", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float triggerRadius = 180, int slownessMultiplier = 5) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#00eaff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float triggerRadius = 180, int slownessMultiplier = 5) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float TriggerRadius { get; set; } = triggerRadius; public int SlownessMultiplier { get; set; } = slownessMultiplier; diff --git a/jRandomSkills - SRC Files/src/player/skills/Gambler.cs b/jRandomSkills - SRC Files/src/player/skills/Gambler.cs index f096292..178f60c 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Gambler.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Gambler.cs @@ -4,17 +4,17 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Gambler : ISkill { private const Skills skillName = Skills.Gambler; - private static readonly int refreshPrice = Config.GetValue(skillName, "refreshPrice"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -50,7 +50,14 @@ namespace jRandomSkills if (skill.Skill != skillName) playerInfo.SpecialSkill = skillName; playerInfo.SkillChance = 1; - Instance.SkillAction(skill.Skill.ToString(), "EnableSkill", [player]); + + if (SkillsInfo.GetValue(skill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime()) + Instance?.AddTimer(Math.Max((float)(Event.freezeTimeEnd - DateTime.Now).TotalSeconds, 0), () => { + if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID && p.Skill == skill.Skill) == null) return; + Instance?.SkillAction(skill.Skill.ToString(), "EnableSkill", new[] { player }); + }); + else + Instance?.SkillAction(skill.Skill.ToString(), "EnableSkill", new[] { player }); }); } @@ -58,7 +65,7 @@ namespace jRandomSkills { if (player == null || !player.IsValid || player.InGameMoneyServices == null) return; var account = player.InGameMoneyServices.Account; - player.InGameMoneyServices.Account = Math.Max(0, account - refreshPrice); + player.InGameMoneyServices.Account = Math.Max(0, account - SkillsInfo.GetValue(skillName, "refreshPrice")); Utilities.SetStateChanged(player, "CCSPlayerController", "m_pInGameMoneyServices"); } @@ -73,10 +80,9 @@ namespace jRandomSkills skills.Remove(firstSkill); var secondSkill = skills[Instance.Random.Next(skills.Count)]; - HashSet<(string, string)> menuItems = [(player.GetSkillName(firstSkill.Skill), firstSkill.Skill.ToString()), - (player.GetSkillName(secondSkill.Skill), secondSkill.Skill.ToString()), - (player.GetTranslation("gambler_more", refreshPrice), skillName.ToString())]; - SkillUtils.CreateMenu(player, menuItems); + ConcurrentBag<(string, string)> menuItems = [(player.GetSkillName(firstSkill.Skill), firstSkill.Skill.ToString()), + (player.GetSkillName(secondSkill.Skill), secondSkill.Skill.ToString())]; + SkillUtils.CreateMenu(player, menuItems, (player.GetTranslation("gambler_more", SkillsInfo.GetValue(skillName, "refreshPrice")), skillName.ToString())); } public static void DisableSkill(CCSPlayerController player) @@ -94,7 +100,7 @@ namespace jRandomSkills if (Utilities.GetPlayers().FindAll(p => p.Team == player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator).Count == 1) { - Config.DefaultSkillInfo[] skillsNeedsTeammates = Config.LoadedConfig.SkillsInfo.Where(s => s.NeedsTeammates).ToArray(); + SkillsInfo.DefaultSkillInfo[] skillsNeedsTeammates = SkillsInfo.LoadedConfig.Where(s => s.NeedsTeammates).ToArray(); skillList.RemoveAll(s => skillsNeedsTeammates.Any(s2 => s2.Name == s.Skill.ToString())); } @@ -106,7 +112,7 @@ namespace jRandomSkills return skillList.Count == 0 ? [Event.noneSkill] : skillList; } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#7eff47", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, int refreshPrice = 150) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#7eff47", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, int refreshPrice = 150) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int RefreshPrice { get; set; } = refreshPrice; } diff --git a/jRandomSkills - SRC Files/src/player/skills/Ghost.cs b/jRandomSkills - SRC Files/src/player/skills/Ghost.cs index b60e47c..544be29 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Ghost.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Ghost.cs @@ -7,6 +7,7 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { @@ -25,14 +26,14 @@ namespace jRandomSkills "weapon_g3sg1", "weapon_nova", "weapon_xm1014", "weapon_mag7", "weapon_sawedoff", "weapon_m249", "weapon_negev" ]; - private static readonly Dictionary> invisibleEntities = []; + private static readonly ConcurrentDictionary> invisibleEntities = []; public static void LoadSkill() { - if (Config.LoadedConfig.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + if (SkillsInfo.LoadedConfig.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) return; - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -85,10 +86,11 @@ namespace jRandomSkills public static void DisableSkill(CCSPlayerController player) { + SkillUtils.ResetPrintHTML(player); SetPlayerVisibility(player, true); SetWeaponVisibility(player, true); SetWeaponAttack(player, false); - invisibleEntities.Remove(player.SteamID); + invisibleEntities.TryRemove(player.SteamID, out _); } public static void OnTick() @@ -98,6 +100,9 @@ namespace jRandomSkills var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo?.Skill == skillName) UpdateHUD(player); + if (!player.PawnIsAlive) + if (invisibleEntities.ContainsKey(player.SteamID)) + invisibleEntities.TryRemove(player.SteamID, out _); } } @@ -121,10 +126,7 @@ namespace jRandomSkills var playerPawn = player.PlayerPawn.Value!; if (playerPawn.WeaponServices == null) return; - // var color = visible ? Color.FromArgb(255, 255, 255, 255) : Color.FromArgb(0, 255, 255, 255); - // var shadowStrength = visible ? 1.0f : 0.0f; - - invisibleEntities.Remove(player.SteamID); + invisibleEntities.TryRemove(player.SteamID, out _); foreach (var weapon in playerPawn.WeaponServices.MyWeapons) { if (weapon != null && weapon.IsValid && weapon.Value != null && weapon.Value.IsValid) @@ -137,17 +139,13 @@ namespace jRandomSkills items.Add(weapon.Index); } else - invisibleEntities.Add(player.SteamID, [weapon.Index]); + invisibleEntities.TryAdd(player.SteamID, [weapon.Index]); } - /* - weapon.Value.Render = color; - weapon.Value.ShadowStrength = shadowStrength; - Utilities.SetStateChanged(weapon.Value, "CBaseModelEntity", "m_clrRender");*/ } } if (visible) - invisibleEntities.Remove(player.SteamID); + invisibleEntities.TryRemove(player.SteamID, out _); } private static void SetWeaponAttack(CCSPlayerController player, bool disableWeapon) @@ -174,21 +172,20 @@ namespace jRandomSkills var pawn = player.PlayerPawn.Value; if (pawn == null || !pawn.IsValid || pawn.WeaponServices == null) return; - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; var weapon = pawn.WeaponServices.ActiveWeapon.Value; - if (weapon == null || !weapon.IsValid || !disabledWeapons.Contains(weapon.DesignerName)) return; + if (weapon == null || !weapon.IsValid || !disabledWeapons.Contains(weapon.DesignerName)) + { + playerInfo.PrintHTML = null; + return; + } - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = $"{player.GetTranslation("disabled_weapon")}
"; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + playerInfo.PrintHTML = $"{player.GetTranslation("disabled_weapon")}"; } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FFFFFF", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FFFFFF", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Glaz.cs b/jRandomSkills - SRC Files/src/player/skills/Glaz.cs index 6104f50..97199df 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Glaz.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Glaz.cs @@ -4,6 +4,7 @@ using CounterStrikeSharp.API.Core.Attributes; using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; +using System.Collections.Concurrent; using static jRandomSkills.jRandomSkills; namespace jRandomSkills @@ -11,26 +12,28 @@ namespace jRandomSkills public class Glaz : ISkill { private const Skills skillName = Skills.Glaz; - private readonly static List smokes = []; + private readonly static ConcurrentDictionary smokes = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - smokes.Clear(); + lock (setLock) + smokes.Clear(); } public static void SmokegrenadeDetonate(EventSmokegrenadeDetonate @event) { - smokes.Add(@event.Entityid); + smokes.TryAdd(@event.Entityid, 0); } public static void SmokegrenadeExpired(EventSmokegrenadeExpired @event) { - smokes.Remove(@event.Entityid); + smokes.TryRemove(@event.Entityid, out _); } public static void CheckTransmit([CastFrom(typeof(nint))] CCheckTransmitInfoList infoList) @@ -44,7 +47,7 @@ namespace jRandomSkills var observerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == observedPlayer?.SteamID); if (playerInfo?.Skill != skillName && observerInfo?.Skill != skillName) continue; - foreach (var smoke in smokes) + foreach (var smoke in smokes.Keys) info.TransmitEntities.Remove(smoke); } } @@ -55,7 +58,7 @@ namespace jRandomSkills SkillUtils.TryGiveWeapon(player, CsItem.SmokeGrenade); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#5d00ff", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#5d00ff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Glitch.cs b/jRandomSkills - SRC Files/src/player/skills/Glitch.cs index a47b7a0..ad3563e 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Glitch.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Glitch.cs @@ -4,22 +4,25 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Glitch : ISkill { private const Skills skillName = Skills.Glitch; - private static readonly HashSet glitchedPlayers = []; + private static readonly ConcurrentDictionary glitchedPlayers = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - glitchedPlayers.Clear(); + lock (setLock) + glitchedPlayers.Clear(); foreach (var player in Utilities.GetPlayers()) { DisableSkill(player); @@ -44,7 +47,7 @@ namespace jRandomSkills if (playerInfo == null || playerInfo.Skill != skillName) continue; var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); - HashSet<(string, string)> menuItems = enemies.Select(e => (e.PlayerName, e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); SkillUtils.UpdateMenu(player, menuItems); } } @@ -70,7 +73,7 @@ namespace jRandomSkills return; } - glitchedPlayers.Add(enemy); + glitchedPlayers.TryAdd(enemy, 0); enemy.ReplicateConVar("sv_disable_radar", "1"); playerInfo.SkillChance = 1; player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("glitch_player_info", enemy.PlayerName)); @@ -86,7 +89,7 @@ namespace jRandomSkills var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); if (enemies.Length > 0) { - HashSet<(string, string)> menuItems = enemies.Select(e => (e.PlayerName, e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); SkillUtils.CreateMenu(player, menuItems); } else @@ -96,11 +99,11 @@ namespace jRandomSkills public static void DisableSkill(CCSPlayerController player) { player.ReplicateConVar("sv_disable_radar", "0"); - glitchedPlayers.Remove(player); + glitchedPlayers.TryRemove(player, out _); SkillUtils.CloseMenu(player); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#f542ef", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#f542ef", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Glue.cs b/jRandomSkills - SRC Files/src/player/skills/Glue.cs index 3bed166..746e01a 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Glue.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Glue.cs @@ -11,7 +11,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void OnEntitySpawned(CEntityInstance entity) @@ -34,7 +34,7 @@ namespace jRandomSkills grenade.Bounces = 555; } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#fff52e", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#fff52e", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/GodMode.cs b/jRandomSkills - SRC Files/src/player/skills/GodMode.cs index eca08c2..e1db45a 100644 --- a/jRandomSkills - SRC Files/src/player/skills/GodMode.cs +++ b/jRandomSkills - SRC Files/src/player/skills/GodMode.cs @@ -4,34 +4,35 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class GodMode : ISkill { private const Skills skillName = Skills.GodMode; - private static readonly float timerCooldown = Config.GetValue(skillName, "cooldown"); - private static readonly float duration = Config.GetValue(skillName, "duration"); - private static readonly Dictionary SkillPlayerInfo = []; + private static readonly ConcurrentDictionary SkillPlayerInfo = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - SkillPlayerInfo.Clear(); + lock (setLock) + SkillPlayerInfo.Clear(); } public static void EnableSkill(CCSPlayerController player) { - SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo { SteamID = player.SteamID, CanUse = true, Cooldown = DateTime.MinValue, - }; + }); } public static void OnTick() @@ -47,7 +48,8 @@ namespace jRandomSkills public static void DisableSkill(CCSPlayerController player) { - SkillPlayerInfo.Remove(player.SteamID); + SkillPlayerInfo.TryRemove(player.SteamID, out _); + SkillUtils.ResetPrintHTML(player); } private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) @@ -55,22 +57,20 @@ namespace jRandomSkills float cooldown = 0; if (skillInfo != null) { - float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "cooldown")) - DateTime.Now).TotalSeconds); cooldown = Math.Max(time, 0); if (cooldown == 0 && skillInfo?.CanUse == false) skillInfo.CanUse = true; } - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = cooldown != 0 ? $"{player.GetTranslation("hud_info", $"{cooldown}")}
" : ""; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + if (cooldown == 0) + playerInfo.PrintHTML = null; + else + playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"{cooldown}")}"; } public static void UseSkill(CCSPlayerController player) @@ -89,7 +89,7 @@ namespace jRandomSkills player.PrintToChat($" {ChatColors.Green} {player.GetTranslation("godmode_on")}"); player.PlayerPawn.Value.TakesDamage = false; - Instance.AddTimer(duration, () => { + Instance.AddTimer(SkillsInfo.GetValue(skillName, "duration"), () => { if (player.IsValid && player.PawnIsAlive) { player.PlayerPawn.Value.TakesDamage = true; @@ -107,7 +107,7 @@ namespace jRandomSkills public DateTime Cooldown { get; set; } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#e0d83a", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float cooldown = 30f, float duration = 2f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#e0d83a", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, float cooldown = 30f, float duration = 2f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Cooldown { get; set; } = cooldown; public float Duration { get; set; } = duration; diff --git a/jRandomSkills - SRC Files/src/player/skills/Grenadier.cs b/jRandomSkills - SRC Files/src/player/skills/Grenadier.cs index 51df178..83fcdfb 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Grenadier.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Grenadier.cs @@ -12,7 +12,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void EnableSkill(CCSPlayerController player) @@ -32,7 +32,7 @@ namespace jRandomSkills player!.GiveNamedItem($"weapon_{weapon}"); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#4a6e21", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#4a6e21", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/HealingSmoke.cs b/jRandomSkills - SRC Files/src/player/skills/HealingSmoke.cs index 6520f20..590843b 100644 --- a/jRandomSkills - SRC Files/src/player/skills/HealingSmoke.cs +++ b/jRandomSkills - SRC Files/src/player/skills/HealingSmoke.cs @@ -10,13 +10,11 @@ namespace jRandomSkills public class HealingSmoke : ISkill { private const Skills skillName = Skills.HealingSmoke; - private static readonly int smokeHeal = Config.GetValue(skillName, "smokeHeal"); - private static readonly float smokeRadius = Config.GetValue(skillName, "smokeRadius"); private static readonly List smokes = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -74,8 +72,8 @@ namespace jRandomSkills foreach (var player in Utilities.GetPlayers()) if (Server.TickCount % 17 == 0) if (player.PlayerPawn.Value != null && player.PlayerPawn.Value.IsValid && player.PlayerPawn.Value.AbsOrigin != null) - if (SkillUtils.GetDistance(smokePos, player.PlayerPawn.Value.AbsOrigin) <= smokeRadius) - AddHealth(player.PlayerPawn.Value, smokeHeal); + if (SkillUtils.GetDistance(smokePos, player.PlayerPawn.Value.AbsOrigin) <= SkillsInfo.GetValue(skillName, "smokeRadius")) + AddHealth(player.PlayerPawn.Value, SkillsInfo.GetValue(skillName, "smokeHeal")); } public static void EnableSkill(CCSPlayerController player) @@ -95,7 +93,7 @@ namespace jRandomSkills Utilities.SetStateChanged(player, "CBaseEntity", "m_iHealth"); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1fe070", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, int smokeHeal = 1, float smokeRadius = 180) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1fe070", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, int smokeHeal = 1, float smokeRadius = 180) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int SmokeHeal { get; set; } = smokeHeal; public float SmokeRadius { get; set; } = smokeRadius; diff --git a/jRandomSkills - SRC Files/src/player/skills/Hermit.cs b/jRandomSkills - SRC Files/src/player/skills/Hermit.cs index 307f802..7a92ecc 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Hermit.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Hermit.cs @@ -3,31 +3,30 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Hermit : ISkill { private const Skills skillName = Skills.Hermit; - private static readonly Dictionary dictionary = new() - { - { "weapon_glock", 120 }, { "weapon_usp_silencer", 24 }, { "weapon_hkp2000", 52 }, { "weapon_p250", 26 }, - { "weapon_cz75", 12 }, { "weapon_deagle", 35 }, { "weapon_fiveseven", 100 }, { "weapon_elite", 120 }, - { "weapon_tec9", 90 }, { "weapon_revolver", 8 }, { "weapon_mac10", 100 }, { "weapon_mp9", 120 }, - { "weapon_mp7", 120 }, { "weapon_mp5", 120 }, { "weapon_mp5sd", 120 }, { "weapon_ump45", 100 }, - { "weapon_p90", 100 }, { "weapon_bizon", 120 }, { "weapon_ak47", 90 }, { "weapon_m4a1", 90 }, - { "weapon_m4a1_silencer", 80 }, { "weapon_galilar", 90 }, { "weapon_famas", 90 }, { "weapon_aug", 90 }, - { "weapon_sg556", 90 }, { "weapon_ssg08", 90 }, { "weapon_awp", 30 }, { "weapon_scar20", 90 }, - { "weapon_g3sg1", 90 }, { "weapon_nova", 32 }, { "weapon_xm1014", 32 }, { "weapon_sawedoff", 32 }, - { "weapon_mag7", 32 }, { "weapon_m249", 200 }, { "weapon_negev", 300 } - }; - private static readonly Dictionary maxReserveAmmo = dictionary; - - private static readonly int healthToAdd = Config.GetValue(skillName, "healthToAdd"); + private static readonly ConcurrentDictionary ConcurrentDictionary = new( + [ + new KeyValuePair("weapon_glock", 120), new KeyValuePair("weapon_usp_silencer", 24), new KeyValuePair("weapon_hkp2000", 52), new KeyValuePair("weapon_p250", 26), + new KeyValuePair("weapon_cz75", 12), new KeyValuePair("weapon_deagle", 35), new KeyValuePair("weapon_fiveseven", 100), new KeyValuePair("weapon_elite", 120), + new KeyValuePair("weapon_tec9", 90), new KeyValuePair("weapon_revolver", 8), new KeyValuePair("weapon_mac10", 100), new KeyValuePair("weapon_mp9", 120), + new KeyValuePair("weapon_mp7", 120), new KeyValuePair("weapon_mp5", 120), new KeyValuePair("weapon_mp5sd", 120), new KeyValuePair("weapon_ump45", 100), + new KeyValuePair("weapon_p90", 100), new KeyValuePair("weapon_bizon", 120), new KeyValuePair("weapon_ak47", 90), new KeyValuePair("weapon_m4a1", 90), + new KeyValuePair("weapon_m4a1_silencer", 80), new KeyValuePair("weapon_galilar", 90), new KeyValuePair("weapon_famas", 90), new KeyValuePair("weapon_aug", 90), + new KeyValuePair("weapon_sg556", 90), new KeyValuePair("weapon_ssg08", 90), new KeyValuePair("weapon_awp", 30), new KeyValuePair("weapon_scar20", 90), + new KeyValuePair("weapon_g3sg1", 90), new KeyValuePair("weapon_nova", 32), new KeyValuePair("weapon_xm1014", 32), new KeyValuePair("weapon_sawedoff", 32), + new KeyValuePair("weapon_mag7", 32), new KeyValuePair("weapon_m249", 200), new KeyValuePair("weapon_negev", 300) + ]); + private static readonly ConcurrentDictionary maxReserveAmmo = ConcurrentDictionary; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerDeath(EventPlayerDeath @event) @@ -50,10 +49,10 @@ namespace jRandomSkills Utilities.SetStateChanged(weapon, "CBasePlayerWeapon", "m_iClip1"); Utilities.SetStateChanged(weapon, "CBasePlayerWeapon", "m_pReserveAmmo"); - SkillUtils.AddHealth(pawn, healthToAdd); + SkillUtils.AddHealth(pawn, SkillsInfo.GetValue(skillName, "healthToAdd")); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ded678", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, int healthToAdd = 25) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ded678", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, int healthToAdd = 25) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int HealthToAdd { get; set; } = healthToAdd; } diff --git a/jRandomSkills - SRC Files/src/player/skills/HolyHandGrenade.cs b/jRandomSkills - SRC Files/src/player/skills/HolyHandGrenade.cs index 8bd53c0..5458b32 100644 --- a/jRandomSkills - SRC Files/src/player/skills/HolyHandGrenade.cs +++ b/jRandomSkills - SRC Files/src/player/skills/HolyHandGrenade.cs @@ -10,12 +10,10 @@ namespace jRandomSkills public class HolyHandGrenade : ISkill { private const Skills skillName = Skills.HolyHandGrenade; - private static readonly float damageMultiplier = Config.GetValue(skillName, "damageMultiplier"); - private static readonly float damageRadiusMultiplier = Config.GetValue(skillName, "damageRadiusMultiplier"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void OnEntitySpawned(CEntityInstance @event) @@ -36,8 +34,8 @@ namespace jRandomSkills var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); if (playerInfo?.Skill != skillName) return; - hegrenade.Damage *= damageMultiplier; - hegrenade.DmgRadius *= damageRadiusMultiplier; + hegrenade.Damage *= SkillsInfo.GetValue(skillName, "damageMultiplier"); + hegrenade.DmgRadius *= SkillsInfo.GetValue(skillName, "damageRadiusMultiplier"); }); } @@ -46,7 +44,7 @@ namespace jRandomSkills SkillUtils.TryGiveWeapon(player, CsItem.HEGrenade); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ffdd00", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float damageMultiplier = 2f, float damageRadiusMultiplier = 2f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ffdd00", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float damageMultiplier = 2f, float damageRadiusMultiplier = 2f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float DamageMultiplier { get; set; } = damageMultiplier; public float DamageRadiusMultiplier { get; set; } = damageRadiusMultiplier; diff --git a/jRandomSkills - SRC Files/src/player/skills/Impostor.cs b/jRandomSkills - SRC Files/src/player/skills/Impostor.cs index 39956b9..7008a15 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Impostor.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Impostor.cs @@ -15,7 +15,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void EnableSkill(CCSPlayerController player) @@ -58,7 +58,7 @@ namespace jRandomSkills }); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#99140B", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#99140B", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/InfiniteAmmo.cs b/jRandomSkills - SRC Files/src/player/skills/InfiniteAmmo.cs index 805b9dd..452d4d0 100644 --- a/jRandomSkills - SRC Files/src/player/skills/InfiniteAmmo.cs +++ b/jRandomSkills - SRC Files/src/player/skills/InfiniteAmmo.cs @@ -11,7 +11,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void WeaponFire(EventWeaponFire @event) @@ -53,7 +53,7 @@ namespace jRandomSkills activeWeaponHandle.Value.Clip1 = 100; } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#0000FF", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#0000FF", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Jackal.cs b/jRandomSkills - SRC Files/src/player/skills/Jackal.cs index d648a62..fda9c6f 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Jackal.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Jackal.cs @@ -5,18 +5,18 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using System.Drawing; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Jackal : ISkill { private const Skills skillName = Skills.Jackal; - private static readonly int maxStepBeam = Config.GetValue(skillName, "maxStepBeam"); - private static readonly Dictionary> stepBeams = []; + private static readonly ConcurrentDictionary> stepBeams = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -36,7 +36,7 @@ namespace jRandomSkills var player = step.Key; if (!player.IsValid) { - stepBeams.Remove(player); + stepBeams.TryRemove(player, out _); continue; } @@ -51,7 +51,7 @@ namespace jRandomSkills if (newBeam != null) step.Value.Add(newBeam); - if (beams?.Count >= maxStepBeam) + if (beams?.Count >= SkillsInfo.GetValue(skillName, "maxStepBeam")) { beams[0].AcceptInput("Kill"); step.Value.RemoveAt(0); @@ -104,9 +104,9 @@ namespace jRandomSkills public static void EnableSkill(CCSPlayerController _) { SkillUtils.EnableTransmit(); - foreach (var _player in Utilities.GetPlayers().Where(p => p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator)) + foreach (var _player in Utilities.GetPlayers().Where(p => p.IsValid && !p.IsBot && !p.IsHLTV && p.PawnIsAlive && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist)) if (!stepBeams.ContainsKey(_player)) - stepBeams.Add(_player, []); + stepBeams.TryAdd(_player, []); } public static void DisableSkill(CCSPlayerController player) @@ -119,7 +119,7 @@ namespace jRandomSkills NewRound(); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#f542ef", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, int maxStepBeam = 100) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#f542ef", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, int maxStepBeam = 100) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int MaxStepBeam { get; set; } = maxStepBeam; } diff --git a/jRandomSkills - SRC Files/src/player/skills/Jammer.cs b/jRandomSkills - SRC Files/src/player/skills/Jammer.cs index 79e01b4..341b68e 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Jammer.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Jammer.cs @@ -4,24 +4,29 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Jammer : ISkill { private const Skills skillName = Skills.Jammer; - private static readonly HashSet jammedPlayers = []; + private static readonly ConcurrentDictionary jammedPlayers = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } public static void NewRound() { - foreach (var player in jammedPlayers) - SetCrosshair(player, true); - jammedPlayers.Clear(); + lock (setLock) + { + foreach (var player in jammedPlayers.Keys) + SetCrosshair(player, true); + jammedPlayers.Clear(); + } foreach (var player in Utilities.GetPlayers()) SkillUtils.CloseMenu(player); } @@ -37,7 +42,7 @@ namespace jRandomSkills if (playerInfo == null || playerInfo.Skill != skillName) continue; var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); - HashSet<(string, string)> menuItems = enemies.Select(e => (e.PlayerName, e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); SkillUtils.UpdateMenu(player, menuItems); } } @@ -63,7 +68,7 @@ namespace jRandomSkills return; } - jammedPlayers.Add(enemy); + jammedPlayers.TryAdd(enemy, 0); SetCrosshair(enemy, false); playerInfo.SkillChance = 1; player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("jammer_player_info", enemy.PlayerName)); @@ -89,7 +94,7 @@ namespace jRandomSkills var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); if (enemies.Length > 0) { - HashSet<(string, string)> menuItems = enemies.Select(e => (e.PlayerName, e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); SkillUtils.CreateMenu(player, menuItems); } else @@ -99,11 +104,11 @@ namespace jRandomSkills public static void DisableSkill(CCSPlayerController player) { SetCrosshair(player, true); - jammedPlayers.Remove(player); + jammedPlayers.TryRemove(player, out _); SkillUtils.CloseMenu(player); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#42f5a7", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#42f5a7", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Jester.cs b/jRandomSkills - SRC Files/src/player/skills/Jester.cs index 292c802..e65c3bf 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Jester.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Jester.cs @@ -13,12 +13,10 @@ namespace jRandomSkills private const Skills skillName = Skills.Jester; private static bool jesterMode = false; private static bool jesterStarted = false; - private static readonly float minTime = Config.GetValue(skillName, "minTime"); - private static readonly float maxTime = Config.GetValue(skillName, "maxTime"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -26,6 +24,11 @@ namespace jRandomSkills jesterStarted = false; } + public static void DisableSkill(CCSPlayerController player) + { + SkillUtils.ResetPrintHTML(player); + } + public static void PlayerHurt(EventPlayerHurt @event) { if (!jesterMode) return; @@ -57,6 +60,8 @@ namespace jRandomSkills { if (!jesterStarted) { + var minTime = SkillsInfo.GetValue(skillName, "minTime"); + var maxTime = SkillsInfo.GetValue(skillName, "maxTime"); float wait = (float)Instance.Random.NextDouble() * (maxTime - minTime) + minTime; Instance.AddTimer(wait, ChangeMode); jesterStarted = true; @@ -78,6 +83,8 @@ namespace jRandomSkills player.ExecuteClientCommand("play sounds/weapons/taser/taser_charge_ready"); } } + var minTime = SkillsInfo.GetValue(skillName, "minTime"); + var maxTime = SkillsInfo.GetValue(skillName, "maxTime"); float wait = (float)Instance.Random.NextDouble() * (maxTime - minTime) + minTime; Instance.AddTimer(wait, ChangeMode); } @@ -92,6 +99,7 @@ namespace jRandomSkills public static void OnTick() { + if (SkillUtils.IsFreezeTime()) return; foreach (var player in Utilities.GetPlayers().Where(p => !p.IsBot && p.PawnIsAlive)) { if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) continue; @@ -103,18 +111,12 @@ namespace jRandomSkills private static void UpdateHUD(CCSPlayerController player) { - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; - - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = $"{player.GetTranslation("jester_mode")}: {player.GetTranslation(jesterMode ? "jester_on" : "jester_off")}
"; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; + playerInfo.PrintHTML = $"{player.GetTranslation("jester_mode")}: {player.GetTranslation(jesterMode ? "jester_on" : "jester_off")}"; } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8f108f", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float minTime = 10f, float maxTime = 25f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8f108f", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float minTime = 10f, float maxTime = 25f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float MinTime { get; set; } = minTime; public float MaxTime { get; set; } = maxTime; diff --git a/jRandomSkills - SRC Files/src/player/skills/JumpBan.cs b/jRandomSkills - SRC Files/src/player/skills/JumpBan.cs index 2b3ebd3..7761588 100644 --- a/jRandomSkills - SRC Files/src/player/skills/JumpBan.cs +++ b/jRandomSkills - SRC Files/src/player/skills/JumpBan.cs @@ -4,17 +4,18 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class JumpBan : ISkill { private const Skills skillName = Skills.JumpBan; - public static readonly Dictionary bannedPlayers = []; + public static readonly ConcurrentDictionary bannedPlayers = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -29,7 +30,7 @@ namespace jRandomSkills var player = @event.Userid; if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return; if (!bannedPlayers.TryGetValue(player.PlayerPawn.Value, out _)) return; - bannedPlayers[player.PlayerPawn.Value] = Server.TickCount + 10; + bannedPlayers.AddOrUpdate(player.PlayerPawn.Value, Server.TickCount + 10, (k, v) => Server.TickCount + 10); } public static void OnTick() @@ -52,7 +53,7 @@ namespace jRandomSkills if (playerInfo == null || playerInfo.Skill != skillName) continue; var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); - HashSet<(string, string)> menuItems = enemies.Select(e => (e.PlayerName, e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); SkillUtils.UpdateMenu(player, menuItems); } } @@ -78,7 +79,7 @@ namespace jRandomSkills return; } - bannedPlayers[enemy.PlayerPawn.Value] = 0; + bannedPlayers.AddOrUpdate(enemy.PlayerPawn.Value, 0, (k, v) => 0); playerInfo.SkillChance = 1; player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("jumpban_player_info", enemy.PlayerName)); enemy.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("jumpban_enemy_info")); @@ -93,7 +94,7 @@ namespace jRandomSkills var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); if (enemies.Length > 0) { - HashSet<(string, string)> menuItems = enemies.Select(e => (e.PlayerName, e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); SkillUtils.CreateMenu(player, menuItems); } else @@ -103,11 +104,11 @@ namespace jRandomSkills public static void DisableSkill(CCSPlayerController player) { if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return; - bannedPlayers.Remove(player.PlayerPawn.Value); + bannedPlayers.TryRemove(player.PlayerPawn.Value, out _); SkillUtils.CloseMenu(player); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#b01e5d", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#b01e5d", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/JumpingJack.cs b/jRandomSkills - SRC Files/src/player/skills/JumpingJack.cs index f7fd383..bed8eb9 100644 --- a/jRandomSkills - SRC Files/src/player/skills/JumpingJack.cs +++ b/jRandomSkills - SRC Files/src/player/skills/JumpingJack.cs @@ -8,11 +8,10 @@ namespace jRandomSkills public class JumpingJack : ISkill { private const Skills skillName = Skills.JumpingJack; - private static readonly int addHealth = Config.GetValue(skillName, "healthToAdd"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerJump(EventPlayerJump @event) @@ -21,10 +20,10 @@ namespace jRandomSkills if (player == null || !player.IsValid) return; var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo?.Skill != skillName) return; - SkillUtils.AddHealth(player.PlayerPawn.Value, addHealth); + SkillUtils.AddHealth(player.PlayerPawn.Value, SkillsInfo.GetValue(skillName, "healthToAdd")); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a86eff", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, int healthToAdd = 3) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a86eff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, int healthToAdd = 3) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int HealthToAdd { get; set; } = healthToAdd; } diff --git a/jRandomSkills - SRC Files/src/player/skills/KillerFlash.cs b/jRandomSkills - SRC Files/src/player/skills/KillerFlash.cs index b85ec6d..bce8de5 100644 --- a/jRandomSkills - SRC Files/src/player/skills/KillerFlash.cs +++ b/jRandomSkills - SRC Files/src/player/skills/KillerFlash.cs @@ -1,9 +1,7 @@ -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; -using Microsoft.Extensions.Logging; using static jRandomSkills.jRandomSkills; namespace jRandomSkills @@ -11,11 +9,10 @@ namespace jRandomSkills public class KillerFlash : ISkill { private const Skills skillName = Skills.KillerFlash; - private static readonly float flashDuration = Config.GetValue(skillName, "flashDuration"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerBlind(EventPlayerBlind @event) @@ -27,7 +24,7 @@ namespace jRandomSkills var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID); - if (attackerInfo?.Skill == skillName && playerInfo?.Skill != Skills.AntyFlash && player!.PlayerPawn.Value!.FlashDuration >= flashDuration) + if (attackerInfo?.Skill == skillName && playerInfo?.Skill != Skills.AntyFlash && player!.PlayerPawn.Value!.FlashDuration >= SkillsInfo.GetValue(skillName, "flashDuration")) player?.PlayerPawn?.Value?.CommitSuicide(false, true); } @@ -36,7 +33,7 @@ namespace jRandomSkills SkillUtils.TryGiveWeapon(player, CsItem.FlashbangGrenade); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#57bcff", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float flashDuration = 1f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#57bcff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float flashDuration = 1f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float FlashDuration { get; set; } = flashDuration; } diff --git a/jRandomSkills - SRC Files/src/player/skills/LifeSwap.cs b/jRandomSkills - SRC Files/src/player/skills/LifeSwap.cs index 228d00c..fd46fb6 100644 --- a/jRandomSkills - SRC Files/src/player/skills/LifeSwap.cs +++ b/jRandomSkills - SRC Files/src/player/skills/LifeSwap.cs @@ -4,6 +4,7 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { @@ -13,7 +14,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -33,7 +34,7 @@ namespace jRandomSkills if (playerInfo == null || playerInfo.Skill != skillName) continue; var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); - HashSet<(string, string)> menuItems = enemies.Select(e => ($"{e.PlayerName} : {e.PawnHealth} HP", e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"{e.PlayerName} : {e.PawnHealth} HP", e.Index.ToString()))); SkillUtils.UpdateMenu(player, menuItems); } } @@ -74,7 +75,7 @@ namespace jRandomSkills var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); if (enemies.Length > 0) { - HashSet<(string, string)> menuItems = enemies.Select(e => ($"{e.PlayerName} : {e.PawnHealth} HP", e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"{e.PlayerName} : {e.PawnHealth} HP", e.Index.ToString()))); SkillUtils.CreateMenu(player, menuItems); } else @@ -99,7 +100,7 @@ namespace jRandomSkills SkillUtils.CloseMenu(player); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a3651a", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a3651a", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/LongKnife.cs b/jRandomSkills - SRC Files/src/player/skills/LongKnife.cs index a41f6bc..0aa9f2b 100644 --- a/jRandomSkills - SRC Files/src/player/skills/LongKnife.cs +++ b/jRandomSkills - SRC Files/src/player/skills/LongKnife.cs @@ -1,6 +1,7 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Entities.Constants; +using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CounterStrikeSharp.API.Modules.Utils; using CS2TraceRay.Class; using CS2TraceRay.Enum; @@ -16,14 +17,63 @@ namespace jRandomSkills public class LongKnife : ISkill { private const Skills skillName = Skills.LongKnife; - private static readonly float maxDistance = Config.GetValue(skillName, "maxDistance"); + + private static bool hooked = false; + private const int actionCode = 503; + private static readonly MemoryFunctionVoid Shoot_Secondary = new(GameData.GetSignature("Shoot_Secondary")); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } - public unsafe static void WeaponFire(EventWeaponFire @event) + public static void NewRound() + { + Shoot_Secondary.Unhook(ShootSecondary, HookMode.Pre); + } + + public static void EnableSkill(CCSPlayerController _) + { + if (hooked) return; + hooked = true; + Shoot_Secondary.Hook(ShootSecondary, HookMode.Pre); + } + + public static void DisableSkill(CCSPlayerController player) + { + var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo == null) return; + + playerInfo.Skill = Skills.None; + if (!Instance.SkillPlayer.Any(p => p.Skill == skillName)) + { + Shoot_Secondary.Unhook(ShootSecondary, HookMode.Pre); + hooked = false; + } + } + + public static HookResult ShootSecondary(DynamicHook hook) + { + var weapon = hook.GetParam(0); + var action = hook.GetParam(1); + + if (action != actionCode || weapon?.DesignerName != "weapon_knife") return HookResult.Continue; + if (weapon.OwnerEntity.Value == null || !weapon.OwnerEntity.Value.IsValid) return HookResult.Continue; + + var pawn = weapon.OwnerEntity.Value.As(); + if (pawn == null || !pawn.IsValid || pawn.Controller.Value == null || !pawn.Controller.Value.IsValid) return HookResult.Continue; + + var player = pawn.Controller.Value.As(); + if (player == null || !player.IsValid) return HookResult.Continue; + + var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo == null || playerInfo.Skill != skillName) return HookResult.Continue; + + KnifeHit(player, true); + return HookResult.Continue; + } + + public static void WeaponFire(EventWeaponFire @event) { var player = @event.Userid; if (!Instance.IsPlayerValid(player)) return; @@ -37,8 +87,16 @@ namespace jRandomSkills var activeWeapon = pawn.WeaponServices.ActiveWeapon.Value; if (activeWeapon == null || !activeWeapon.IsValid || activeWeapon.DesignerName != "weapon_knife") return; + KnifeHit(player, false); + } + + private unsafe static void KnifeHit(CCSPlayerController player, bool heavyHit) + { + var pawn = player!.PlayerPawn.Value; + if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return; + Vector eyePos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z); - Vector endPos = eyePos + SkillUtils.GetForwardVector(pawn.EyeAngles) * maxDistance; + Vector endPos = eyePos + SkillUtils.GetForwardVector(pawn.EyeAngles) * SkillsInfo.GetValue(skillName, "maxDistance"); Ray ray = new(Vector3.Zero); CTraceFilter filter = new(pawn.Index, pawn.Index) @@ -55,9 +113,9 @@ namespace jRandomSkills filter.m_nHierarchyIds[0] = pawn.GetHierarchyId(); filter.m_nHierarchyIds[1] = 0; - CGameTrace trace = TraceRay.TraceHull(eyePos, endPos, filter, ray); + CGameTrace trace = TraceRay.TraceHull(eyePos, endPos, filter, ray); - if (Config.LoadedConfig.Settings.CS2TraceRayDebug) + if (Config.LoadedConfig.CS2TraceRayDebug) { CreateLine(eyePos, endPos, Color.FromArgb(255, 255, 255, 0)); CreateLine(new Vector(trace.StartPos.X, trace.StartPos.Y, trace.StartPos.Z), new Vector(trace.EndPos.X, trace.EndPos.Y, trace.EndPos.Z), Color.FromArgb(255, 255, 0, 0)); @@ -77,7 +135,7 @@ namespace jRandomSkills if (target.Handle == player.Handle || target.PlayerPawn.Value == null || !target.PlayerPawn.Value.IsValid || trace.Distance() <= 70) return; target.PlayerPawn.Value.EmitSound("Player.DamageBody.Onlooker"); - SkillUtils.TakeHealth(target.PlayerPawn.Value, Instance.Random.Next(21, 34)); + SkillUtils.TakeHealth(target.PlayerPawn.Value, heavyHit ? Instance.Random.Next(45, 55) : Instance.Random.Next(21, 34)); } private static void CreateLine(Vector start, Vector end, Color color) @@ -98,7 +156,7 @@ namespace jRandomSkills beam.AcceptInput("FollowEntity", beam, null!, ""); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#c9f8ff", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float maxDistance = 4096f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#c9f8ff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float maxDistance = 4096f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float MaxDistance { get; set; } = maxDistance; } diff --git a/jRandomSkills - SRC Files/src/player/skills/LongZeus.cs b/jRandomSkills - SRC Files/src/player/skills/LongZeus.cs index 7c66009..c6fdcdd 100644 --- a/jRandomSkills - SRC Files/src/player/skills/LongZeus.cs +++ b/jRandomSkills - SRC Files/src/player/skills/LongZeus.cs @@ -16,11 +16,10 @@ namespace jRandomSkills public class LongZeus : ISkill { private const Skills skillName = Skills.LongZeus; - private static readonly float maxDistance = Config.GetValue(skillName, "maxDistance"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public unsafe static void WeaponFire(EventWeaponFire @event) @@ -38,7 +37,7 @@ namespace jRandomSkills if (activeWeapon == null || !activeWeapon.IsValid || activeWeapon.DesignerName != "weapon_taser") return; Vector eyePos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z); - Vector endPos = eyePos + SkillUtils.GetForwardVector(pawn.EyeAngles) * maxDistance; + Vector endPos = eyePos + SkillUtils.GetForwardVector(pawn.EyeAngles) * SkillsInfo.GetValue(skillName, "maxDistance"); Ray ray = new(Vector3.Zero); CTraceFilter filter = new(pawn.Index, pawn.Index) @@ -57,7 +56,7 @@ namespace jRandomSkills filter.m_nHierarchyIds[1] = 0; CGameTrace trace = TraceRay.TraceHull(eyePos, endPos, filter, ray); - if (Config.LoadedConfig.Settings.CS2TraceRayDebug) + if (Config.LoadedConfig.CS2TraceRayDebug) { CreateLine(eyePos, endPos, Color.FromArgb(255, 255, 255, 0)); CreateLine(new Vector(trace.StartPos.X, trace.StartPos.Y, trace.StartPos.Z), new Vector(trace.EndPos.X, trace.EndPos.Y, trace.EndPos.Z), Color.FromArgb(255, 255, 0, 0)); @@ -102,7 +101,7 @@ namespace jRandomSkills beam.AcceptInput("FollowEntity", beam, null!, ""); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#6effc7", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float maxDistance = 4096f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#6effc7", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float maxDistance = 4096f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float MaxDistance { get; set; } = maxDistance; } diff --git a/jRandomSkills - SRC Files/src/player/skills/Magnifier.cs b/jRandomSkills - SRC Files/src/player/skills/Magnifier.cs index f3336b0..e3b939d 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Magnifier.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Magnifier.cs @@ -4,18 +4,18 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Magnifier : ISkill { private const Skills skillName = Skills.Magnifier; - private static readonly uint customFOV = Config.GetValue(skillName, "customFOV"); - private static readonly Dictionary playersFOV = []; + private static readonly ConcurrentDictionary playersFOV = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -45,7 +45,7 @@ namespace jRandomSkills if (playerInfo == null || playerInfo.Skill != skillName) continue; var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); - HashSet<(string, string)> menuItems = enemies.Select(e => (e.PlayerName, e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); SkillUtils.UpdateMenu(player, menuItems); } } @@ -72,8 +72,8 @@ namespace jRandomSkills } if (!playersFOV.ContainsKey(enemy)) - playersFOV.Add(enemy, enemy.DesiredFOV); - enemy.DesiredFOV = customFOV; + playersFOV.TryAdd(enemy, enemy.DesiredFOV); + enemy.DesiredFOV = SkillsInfo.GetValue(skillName, "customFOV"); Utilities.SetStateChanged(enemy, "CBasePlayerController", "m_iDesiredFOV"); playerInfo.SkillChance = 1; @@ -90,7 +90,7 @@ namespace jRandomSkills var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); if (enemies.Length > 0) { - HashSet<(string, string)> menuItems = enemies.Select(e => (e.PlayerName, e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); SkillUtils.CreateMenu(player, menuItems); } else @@ -104,11 +104,11 @@ namespace jRandomSkills player.DesiredFOV = fov; Utilities.SetStateChanged(player, "CBasePlayerController", "m_iDesiredFOV"); } - playersFOV.Remove(player); + playersFOV.TryRemove(player, out _); SkillUtils.CloseMenu(player); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#9ba882", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, uint customFOV = 50) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#9ba882", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, uint customFOV = 50) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public uint CustomFOV { get; set; } = customFOV; } diff --git a/jRandomSkills - SRC Files/src/player/skills/Medic.cs b/jRandomSkills - SRC Files/src/player/skills/Medic.cs index 2708ac2..502912b 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Medic.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Medic.cs @@ -4,29 +4,30 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Medic : ISkill { private const Skills skillName = Skills.Medic; - private static readonly int healthToAdd = Config.GetValue(skillName, "healthToAdd"); - private static readonly int healthShotLimit = Config.GetValue(skillName, "healthShotLimit"); - private static readonly float timerCooldown = Config.GetValue(skillName, "cooldown"); - private static readonly Dictionary SkillPlayerInfo = []; + private static readonly ConcurrentDictionary SkillPlayerInfo = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - SkillPlayerInfo.Clear(); + lock (setLock) + SkillPlayerInfo.Clear(); } public static void OnTick() { + if (SkillUtils.IsFreezeTime()) return; foreach (var player in Utilities.GetPlayers()) { var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); @@ -38,18 +39,19 @@ namespace jRandomSkills public static void EnableSkill(CCSPlayerController player) { - SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo { SteamID = player.SteamID, CanUse = true, Cooldown = DateTime.MinValue, - Count = healthShotLimit, - }; + Count = SkillsInfo.GetValue(skillName, "healthShotLimit"), + }); } public static void DisableSkill(CCSPlayerController player) { - SkillPlayerInfo.Remove(player.SteamID); + SkillPlayerInfo.TryRemove(player.SteamID, out _); + SkillUtils.ResetPrintHTML(player); } private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) @@ -57,7 +59,7 @@ namespace jRandomSkills float cooldown = 0; if (skillInfo != null) { - float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "cooldown")) - DateTime.Now).TotalSeconds); cooldown = Math.Max(time, 0); if (cooldown == 0 && skillInfo?.CanUse == false) @@ -67,14 +69,14 @@ namespace jRandomSkills var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); if (skillData == null) return; - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = cooldown != 0 - ? $"{player.GetTranslation("hud_info", $"{cooldown}")}
" - : $"{(skillInfo == null ? 0 : skillInfo.Count)}/{healthShotLimit}
"; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + string remainingLine = cooldown != 0 + ? $"{player.GetTranslation("hud_info", $"{cooldown}")}" + : $"{(skillInfo == null ? 0 : skillInfo.Count)}/{SkillsInfo.GetValue(skillName, "healthShotLimit")}"; + + playerInfo.PrintHTML = remainingLine; } public static void UseSkill(CCSPlayerController player) @@ -90,7 +92,7 @@ namespace jRandomSkills skillInfo.CanUse = false; skillInfo.Cooldown = DateTime.Now; skillInfo.Count -= 1; - SkillUtils.AddHealth(playerPawn, healthToAdd); + SkillUtils.AddHealth(playerPawn, SkillsInfo.GetValue(skillName, "healthToAdd")); player.EmitSound("Healthshot.Success"); } } @@ -104,7 +106,7 @@ namespace jRandomSkills public DateTime Cooldown { get; set; } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#10c212", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, int healthToAdd = 50, int healthShotLimit = 3, float cooldown = 1f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#10c212", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, int healthToAdd = 50, int healthShotLimit = 3, float cooldown = 1f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int HealthToAdd { get; set; } = healthToAdd; public int HealthShotLimit { get; set; } = healthShotLimit; diff --git a/jRandomSkills - SRC Files/src/player/skills/MoneySwap.cs b/jRandomSkills - SRC Files/src/player/skills/MoneySwap.cs index 90962ba..98b7559 100644 --- a/jRandomSkills - SRC Files/src/player/skills/MoneySwap.cs +++ b/jRandomSkills - SRC Files/src/player/skills/MoneySwap.cs @@ -4,6 +4,7 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { @@ -13,7 +14,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -33,7 +34,7 @@ namespace jRandomSkills if (playerInfo == null || playerInfo.Skill != skillName) continue; var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); - HashSet<(string, string)> menuItems = enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account)}$", e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account)}$", e.Index.ToString()))); SkillUtils.UpdateMenu(player, menuItems); } } @@ -74,7 +75,7 @@ namespace jRandomSkills var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); if (enemies.Length > 0) { - HashSet<(string, string)> menuItems = enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account)}$", e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account)}$", e.Index.ToString()))); SkillUtils.CreateMenu(player, menuItems); } else @@ -102,7 +103,7 @@ namespace jRandomSkills SkillUtils.CloseMenu(player); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#52f54c", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#52f54c", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Muhammed.cs b/jRandomSkills - SRC Files/src/player/skills/Muhammed.cs index 1df3178..89ce837 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Muhammed.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Muhammed.cs @@ -1,23 +1,21 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Modules.Entities; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; -using Microsoft.Extensions.Logging; using static jRandomSkills.jRandomSkills; +using Vector = CounterStrikeSharp.API.Modules.Utils.Vector; namespace jRandomSkills { public class Muhammed : ISkill { private const Skills skillName = Skills.Muhammed; - private static readonly float explosionRadius = Config.GetValue(skillName, "explosionRadius"); - private static readonly int explosionDamage = Config.GetValue(skillName, "explosionDamage"); + private static readonly QAngle angle = new(10, -5, 9); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerDeath(EventPlayerDeath @event) @@ -32,39 +30,50 @@ namespace jRandomSkills private static void SpawnExplosion(CCSPlayerController player) { - var heProjectile = Utilities.CreateEntityByName("hegrenade_projectile"); - if (heProjectile == null || !heProjectile.IsValid) return; - var pawn = player.PlayerPawn.Value; if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return; Vector pos = pawn.AbsOrigin; pos.Z += 10; - heProjectile.TicksAtZeroVelocity = 100; - heProjectile.TeamNum = player.TeamNum; - heProjectile.Damage = explosionDamage; - heProjectile.DmgRadius = (int)explosionRadius; - heProjectile.Teleport(pos, null, new Vector(0, 0, -10)); - heProjectile.DispatchSpawn(); - heProjectile.AcceptInput("InitializeSpawnFromWorld", player.PlayerPawn.Value, player.PlayerPawn.Value, ""); - heProjectile.DetonateTime = 0; - Server.PrintToChatAll($" {ChatColors.DarkRed}► {ChatColors.Green}[{ChatColors.DarkRed} jRandomSkills {ChatColors.Green}] {ChatColors.DarkRed}{player.PlayerName}: {ChatColors.Lime}ALLAHU AKBAR!!!"); + SkillUtils.CreateHEGrenadeProjectile(pos, angle, new Vector(0, 0, -10), player.TeamNum); + + foreach (var _p in Utilities.GetPlayers().Where(p => p.IsValid && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist && !p.IsBot)) + SkillUtils.PrintToChat(_p, $"{ChatColors.DarkRed}{player.PlayerName}: {ChatColors.Lime}{_p.GetTranslation("muhammed_explosion")}", false); var fileNames = new[] { "radiobotfallback01", "radiobotfallback02", "radiobotfallback04" }; - Instance.AddTimer(0.1f, () => + var randomFile = fileNames[new Random().Next(fileNames.Length)]; + player.ExecuteClientCommand($"play vo/agents/balkan/{randomFile}.vsnd"); + } + + public static void OnEntitySpawned(CEntityInstance entity) + { + if (entity.DesignerName != "hegrenade_projectile") return; + + var heProjectile = entity.As(); + if (heProjectile == null || !heProjectile.IsValid || heProjectile.AbsRotation == null) return; + + Server.NextFrame(() => { - var randomFile = fileNames[new Random().Next(fileNames.Length)]; - player.ExecuteClientCommand($"play vo/agents/balkan/{randomFile}.vsnd"); + if (heProjectile == null || !heProjectile.IsValid) return; + if (!(NearlyEquals(angle.X, heProjectile.AbsRotation.X) && NearlyEquals(angle.Y, heProjectile.AbsRotation.Y) && NearlyEquals(angle.Z, heProjectile.AbsRotation.Z))) + return; + + heProjectile.TicksAtZeroVelocity = 100; + heProjectile.Damage = SkillsInfo.GetValue(skillName, "explosionDamage"); + heProjectile.DmgRadius = SkillsInfo.GetValue(skillName, "explosionRadius"); + heProjectile.DetonateTime = 0; }); } + private static bool NearlyEquals(float a, float b, float epsilon = 0.001f) => Math.Abs(a - b) < epsilon; + private static bool IsDeadPlayerValid(CCSPlayerController? player) { return player != null && player.IsValid && player.PlayerPawn?.Value != null; } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#F5CB42", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float explosionRadius = 500.0f, int explosionDamage = 999) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#F5CB42", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float explosionRadius = 500.0f, int explosionDamage = 999) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float ExplosionRadius { get; set; } = explosionRadius; public int ExplosionDamage { get; set; } = explosionDamage; diff --git a/jRandomSkills - SRC Files/src/player/skills/Ninja.cs b/jRandomSkills - SRC Files/src/player/skills/Ninja.cs index e10b33d..b5f9f89 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Ninja.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Ninja.cs @@ -5,26 +5,26 @@ using CounterStrikeSharp.API.Core.Attributes; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Ninja : ISkill { private const Skills skillName = Skills.Ninja; - private static readonly float idlePercentInvisibility = Config.GetValue(skillName, "idlePercentInvisibility"); - private static readonly float duckPercentInvisibility = Config.GetValue(skillName, "duckPercentInvisibility"); - private static readonly float knifePercentInvisibility = Config.GetValue(skillName, "knifePercentInvisibility"); - private static readonly Dictionary invisibilityChanged = []; - private static readonly Dictionary> invisibleEntities = []; + private static readonly ConcurrentDictionary invisibilityChanged = []; + private static readonly ConcurrentDictionary> invisibleEntities = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - invisibilityChanged.Clear(); + lock (setLock) + invisibilityChanged.Clear(); } public static void WeaponEquip(EventItemEquip @event) @@ -66,6 +66,9 @@ namespace jRandomSkills var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo?.Skill == skillName) UpdateNinja(player); + if (!player.PawnIsAlive) + if (invisibleEntities.ContainsKey(player.SteamID)) + invisibleEntities.TryRemove(player.SteamID, out _); } } @@ -78,7 +81,7 @@ namespace jRandomSkills { SetPlayerVisibility(player, 0); SetWeaponVisibility(player, 0); - invisibleEntities.Remove(player.SteamID); + invisibleEntities.TryRemove(player.SteamID, out _); } private static void UpdateNinja(CCSPlayerController? player) @@ -97,18 +100,18 @@ namespace jRandomSkills float percentInvisibility = 0; if (buttons.HasFlag(PlayerButtons.Duck)) - percentInvisibility += duckPercentInvisibility; + percentInvisibility += SkillsInfo.GetValue(skillName, "duckPercentInvisibility"); if (activeWeapon != null && activeWeapon.DesignerName == "weapon_knife") - percentInvisibility += knifePercentInvisibility; + percentInvisibility += SkillsInfo.GetValue(skillName, "knifePercentInvisibility"); if (!buttons.HasFlag(PlayerButtons.Moveleft) && !buttons.HasFlag(PlayerButtons.Moveright) && !buttons.HasFlag(PlayerButtons.Forward) && !buttons.HasFlag(PlayerButtons.Back) && flags.HasFlag(PlayerFlags.FL_ONGROUND)) - percentInvisibility += idlePercentInvisibility; + percentInvisibility += SkillsInfo.GetValue(skillName, "idlePercentInvisibility"); SetWeaponVisibility(player, percentInvisibility); if (invisibilityChanged.TryGetValue(player.Handle, out float oldInvisibility)) if (percentInvisibility == oldInvisibility) return; - invisibilityChanged[player.Handle] = percentInvisibility; + invisibilityChanged.TryAdd(player.Handle, percentInvisibility); SetPlayerVisibility(player, percentInvisibility); } @@ -131,7 +134,7 @@ namespace jRandomSkills var color = Color.FromArgb(Math.Max(255 - (int)(255 * percentInvisibility * 2), 0), 255, 255, 255); - invisibleEntities.Remove(player.SteamID); + invisibleEntities.TryRemove(player.SteamID, out _); if (color.A != 0) return; foreach (var weapon in playerPawn.WeaponServices.MyWeapons) @@ -144,12 +147,12 @@ namespace jRandomSkills items.Add(weapon.Index); } else - invisibleEntities.Add(player.SteamID, [weapon.Index]); + invisibleEntities.TryAdd(player.SteamID, [weapon.Index]); } } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#dedede", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float idlePercentInvisibility = .3f, float duckPercentInvisibility = .3f, float knifePercentInvisibility = .3f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#dedede", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float idlePercentInvisibility = .3f, float duckPercentInvisibility = .3f, float knifePercentInvisibility = .3f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float IdlePercentInvisibility { get; set; } = idlePercentInvisibility; public float DuckPercentInvisibility { get; set; } = duckPercentInvisibility; diff --git a/jRandomSkills - SRC Files/src/player/skills/NoNades.cs b/jRandomSkills - SRC Files/src/player/skills/NoNades.cs index 98a56ba..5d47669 100644 --- a/jRandomSkills - SRC Files/src/player/skills/NoNades.cs +++ b/jRandomSkills - SRC Files/src/player/skills/NoNades.cs @@ -11,7 +11,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerHurt(EventPlayerHurt @event) @@ -28,7 +28,7 @@ namespace jRandomSkills SkillUtils.AddHealth(player!.PlayerPawn.Value, damage); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a38c1a", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a38c1a", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/NoRecoil.cs b/jRandomSkills - SRC Files/src/player/skills/NoRecoil.cs index f7520c0..644f686 100644 --- a/jRandomSkills - SRC Files/src/player/skills/NoRecoil.cs +++ b/jRandomSkills - SRC Files/src/player/skills/NoRecoil.cs @@ -12,7 +12,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -49,7 +49,7 @@ namespace jRandomSkills } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8a42f5", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8a42f5", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Noclip.cs b/jRandomSkills - SRC Files/src/player/skills/Noclip.cs index 4aa3a15..9655772 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Noclip.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Noclip.cs @@ -4,24 +4,25 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Noclip : ISkill { private const Skills skillName = Skills.Noclip; - private static readonly float timerCooldown = Config.GetValue(skillName, "cooldown"); - private static readonly float duration = Config.GetValue(skillName, "duration"); - private static readonly Dictionary SkillPlayerInfo = []; + private static readonly ConcurrentDictionary SkillPlayerInfo = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - SkillPlayerInfo.Clear(); + lock (setLock) + SkillPlayerInfo.Clear(); } public static void OnTick() @@ -37,17 +38,20 @@ namespace jRandomSkills public static void EnableSkill(CCSPlayerController player) { - SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo { SteamID = player.SteamID, CanUse = true, + IsFlying = false, Cooldown = DateTime.MinValue, - }; + LastPosition = null, + }); } public static void DisableSkill(CCSPlayerController player) { - SkillPlayerInfo.Remove(player.SteamID); + SkillPlayerInfo.TryRemove(player.SteamID, out _); + SkillUtils.ResetPrintHTML(player); } private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) @@ -56,35 +60,35 @@ namespace jRandomSkills float flying = 0; if (skillInfo != null) { - float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "cooldown")) - DateTime.Now).TotalSeconds); cooldown = Math.Max(time, 0); - float flyingTime = (int)(skillInfo.Cooldown.AddSeconds(duration) - DateTime.Now).TotalMilliseconds; + float flyingTime = (int)(skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "duration")) - DateTime.Now).TotalMilliseconds; flying = Math.Max(flyingTime, 0); if (cooldown == 0 && skillInfo?.CanUse == false) skillInfo.CanUse = true; } - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = cooldown != 0 - ? ( - flying != 0 - ? $"{player.GetTranslation("active_hud_info", $"{Math.Round(flying / 100, 2)}")}
" - : $"{player.GetTranslation("hud_info", $"{cooldown}")}
" - ) : ""; + if (cooldown == 0) + { + playerInfo.PrintHTML = null; + return; + } - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + playerInfo.PrintHTML = + skillInfo?.IsFlying == true + ? $"{player.GetTranslation("active_hud_info", $"{Math.Round(flying / 100, 2)}")}" + : $"{player.GetTranslation("hud_info", $"{cooldown}")}"; } public static void UseSkill(CCSPlayerController player) { var playerPawn = player.PlayerPawn.Value; + var duration = SkillsInfo.GetValue(skillName, "duration"); if (playerPawn?.CBodyComponent == null) return; if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) @@ -93,10 +97,39 @@ namespace jRandomSkills if (skillInfo.CanUse) { skillInfo.CanUse = false; + skillInfo.IsFlying = true; skillInfo.Cooldown = DateTime.Now; + skillInfo.LastPosition = playerPawn.AbsOrigin == null ? null : new Vector(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z); playerPawn.ActualMoveType = MoveType_t.MOVETYPE_NOCLIP; - Instance.AddTimer(duration, () => playerPawn.ActualMoveType = MoveType_t.MOVETYPE_WALK); + Instance.AddTimer(duration, () => { + if (playerPawn == null || !playerPawn.IsValid || !skillInfo.IsFlying) return; + skillInfo.IsFlying = false; + playerPawn.ActualMoveType = MoveType_t.MOVETYPE_WALK; + }); + + Instance.AddTimer(duration + 4, () => { + if (playerPawn == null || !playerPawn.IsValid || !player.PawnIsAlive || skillInfo.IsFlying) return; + if (skillInfo.LastPosition == null || playerPawn.AbsOrigin == null) return; + skillInfo.IsFlying = false; + var diff = Math.Abs(playerPawn.AbsOrigin.Z - skillInfo.LastPosition.Z); + if (diff > 3000 && playerPawn.AbsOrigin.Z < skillInfo.LastPosition.Z) + playerPawn.Teleport(skillInfo.LastPosition, null, new Vector(0,0,0)); + }); + } + else if (skillInfo.IsFlying) + { + skillInfo.IsFlying = false; + playerPawn.ActualMoveType = MoveType_t.MOVETYPE_WALK; + + Instance.AddTimer(4, () => { + if (playerPawn == null || !playerPawn.IsValid || !player.PawnIsAlive || skillInfo.IsFlying) return; + if (skillInfo.LastPosition == null || playerPawn.AbsOrigin == null) return; + skillInfo.IsFlying = false; + var diff = Math.Abs(playerPawn.AbsOrigin.Z - skillInfo.LastPosition.Z); + if (diff > 3000 && playerPawn.AbsOrigin.Z < skillInfo.LastPosition.Z) + playerPawn.Teleport(skillInfo.LastPosition, null, new Vector(0, 0, 0)); + }); } } } @@ -105,10 +138,12 @@ namespace jRandomSkills { public ulong SteamID { get; set; } public bool CanUse { get; set; } + public bool IsFlying { get; set; } public DateTime Cooldown { get; set; } + public Vector? LastPosition { get; set; } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#44ebd4", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float cooldown = 30f, float duration = 2f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#44ebd4", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, float cooldown = 30f, float duration = 2f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Cooldown { get; set; } = cooldown; public float Duration { get; set; } = duration; diff --git a/jRandomSkills - SRC Files/src/player/skills/None.cs b/jRandomSkills - SRC Files/src/player/skills/None.cs index 16995fe..d77ddbe 100644 --- a/jRandomSkills - SRC Files/src/player/skills/None.cs +++ b/jRandomSkills - SRC Files/src/player/skills/None.cs @@ -9,10 +9,10 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FFFFFF", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FFFFFF", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/OneShot.cs b/jRandomSkills - SRC Files/src/player/skills/OneShot.cs index 5c57689..dd57557 100644 --- a/jRandomSkills - SRC Files/src/player/skills/OneShot.cs +++ b/jRandomSkills - SRC Files/src/player/skills/OneShot.cs @@ -12,7 +12,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void OnTakeDamage(DynamicHook h) @@ -42,7 +42,7 @@ namespace jRandomSkills param2.Damage = 1000f; } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff5CD9", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff5CD9", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/OnlyHead.cs b/jRandomSkills - SRC Files/src/player/skills/OnlyHead.cs index 7009f5b..4b81485 100644 --- a/jRandomSkills - SRC Files/src/player/skills/OnlyHead.cs +++ b/jRandomSkills - SRC Files/src/player/skills/OnlyHead.cs @@ -12,7 +12,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerHurt(EventPlayerHurt @event) @@ -44,7 +44,7 @@ namespace jRandomSkills Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_iHealth"); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#3c47de", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#3c47de", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/PawelJumper.cs b/jRandomSkills - SRC Files/src/player/skills/PawelJumper.cs index 99c2613..b702514 100644 --- a/jRandomSkills - SRC Files/src/player/skills/PawelJumper.cs +++ b/jRandomSkills - SRC Files/src/player/skills/PawelJumper.cs @@ -10,16 +10,13 @@ namespace jRandomSkills public class PawelJumper : ISkill { private const Skills skillName = Skills.PawelJumper; - private static readonly int extraJumpsMin = Config.GetValue(skillName, "extraJumpsMin"); - private static readonly int extraJumpsMax = Config.GetValue(skillName, "extraJumpsMax"); - private static readonly PlayerFlags[] LF = new PlayerFlags[64]; private static readonly int?[] J = new int?[64]; private static readonly PlayerButtons[] LB = new PlayerButtons[64]; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } public static void OnTick() @@ -39,12 +36,12 @@ namespace jRandomSkills var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerPawn == null || playerInfo == null) return; - var skillConfig = Config.LoadedConfig.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString()); + var skillConfig = SkillsInfo.LoadedConfig.FirstOrDefault(s => s.Name == skillName.ToString()); if (skillConfig == null) return; - float extraJumps = (float)Instance.Random.Next(extraJumpsMin, extraJumpsMax + 1); + float extraJumps = (float)Instance.Random.Next(SkillsInfo.GetValue(skillName, "extraJumpsMin"), SkillsInfo.GetValue(skillName, "extraJumpsMax") + 1); playerInfo.SkillChance = extraJumps; - SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetTranslation("paweljumper")}{ChatColors.Lime}: " + player.GetTranslation("paweljumper_desc2", extraJumps), false); + SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, extraJumps)}", false); } private static void GiveAdditionalJump(CCSPlayerController player) @@ -76,7 +73,7 @@ namespace jRandomSkills LB[player.Slot] = buttons; } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FFA500", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, int extraJumpsMin = 1, int extraJumpsMax = 4) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FFA500", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, int extraJumpsMin = 1, int extraJumpsMax = 4) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int ExtraJumpsMin { get; set; } = extraJumpsMin; public int ExtraJumpsMax { get; set; } = extraJumpsMax; diff --git a/jRandomSkills - SRC Files/src/player/skills/Phoenix.cs b/jRandomSkills - SRC Files/src/player/skills/Phoenix.cs index ecb88b5..3e443be 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Phoenix.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Phoenix.cs @@ -9,10 +9,11 @@ namespace jRandomSkills public class Phoenix : ISkill { private const Skills skillName = Skills.Phoenix; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } public static void PlayerDeath(EventPlayerDeath @event) @@ -25,9 +26,12 @@ namespace jRandomSkills { if (Instance.Random.NextDouble() <= playerInfo.SkillChance) { - player.Respawn(); - Instance.AddTimer(.2f, () => player.Respawn()); - SkillUtils.PrintToChat(player, player.GetTranslation("phoenix_respawn"), false); ; + lock (setLock) + { + player.Respawn(); + Instance.AddTimer(.2f, () => player.Respawn()); + SkillUtils.PrintToChat(player, player.GetTranslation("phoenix_respawn"), false); + } } } } @@ -36,19 +40,14 @@ namespace jRandomSkills { var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo == null) return; - float newChance = (float)Instance.Random.NextDouble() * (Config.GetValue(skillName, "ChanceTo") - Config.GetValue(skillName, "ChanceFrom")) + Config.GetValue(skillName, "ChanceFrom"); + float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue(skillName, "ChanceTo") - SkillsInfo.GetValue(skillName, "ChanceFrom")) + SkillsInfo.GetValue(skillName, "ChanceFrom"); playerInfo.SkillChance = newChance; newChance = (float)Math.Round(newChance, 2) * 100; newChance = (float)Math.Round(newChance); - SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetTranslation("phoenix")}{ChatColors.Lime}: " + player.GetTranslation("phoenix_desc2", newChance), false); + SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", false); } - private static bool IsDeadPlayerValid(CCSPlayerController player) - { - return player != null && player.IsValid && player.PlayerPawn?.Value != null; - } - - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff5C0A", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float chanceFrom = .2f, float chanceTo = .4f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff5C0A", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float chanceFrom = .2f, float chanceTo = .4f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float ChanceFrom { get; set; } = chanceFrom; public float ChanceTo { get; set; } = chanceTo; diff --git a/jRandomSkills - SRC Files/src/player/skills/Pilot.cs b/jRandomSkills - SRC Files/src/player/skills/Pilot.cs index ad8926b..f7633eb 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Pilot.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Pilot.cs @@ -4,20 +4,18 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Pilot : ISkill { private const Skills skillName = Skills.Pilot; - private static readonly float maximumFuel = Config.GetValue(skillName, "maximumFuel"); - private static readonly float fuelConsumption = Config.GetValue(skillName, "fuelConsumption"); - private static readonly float refuelling = Config.GetValue(skillName, "refuelling"); - private static readonly Dictionary PlayerPilotInfo = []; + private static readonly ConcurrentDictionary PlayerPilotInfo = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -37,24 +35,26 @@ namespace jRandomSkills public static void EnableSkill(CCSPlayerController player) { - PlayerPilotInfo[player.SteamID] = new Pilot_PlayerInfo + PlayerPilotInfo.TryAdd(player.SteamID, new Pilot_PlayerInfo { SteamID = player.SteamID, - Fuel = maximumFuel, - }; + Fuel = SkillsInfo.GetValue(skillName, "maximumFuel"), + }); } public static void DisableSkill(CCSPlayerController player) { - PlayerPilotInfo.Remove(player.SteamID); + PlayerPilotInfo.TryRemove(player.SteamID, out _); + SkillUtils.ResetPrintHTML(player); } private static void HandlePilot(CCSPlayerController player) { var buttons = player.Buttons; + var maximumFuel = SkillsInfo.GetValue(skillName, "maximumFuel"); if (PlayerPilotInfo.TryGetValue(player.SteamID, out var pilotInfo)) { - pilotInfo.Fuel = Math.Min(Math.Max(0, pilotInfo.Fuel - (buttons.HasFlag(PlayerButtons.Use) ? fuelConsumption : -refuelling)), maximumFuel); + pilotInfo.Fuel = Math.Min(Math.Max(0, pilotInfo.Fuel - (buttons.HasFlag(PlayerButtons.Use) ? SkillsInfo.GetValue(skillName, "fuelConsumption") : -SkillsInfo.GetValue(skillName, "refuelling"))), maximumFuel); if (buttons.HasFlag(PlayerButtons.Use)) if (pilotInfo.Fuel > 0 && player.PlayerPawn.Value != null && player.PlayerPawn.Value.IsValid && !player.PlayerPawn.Value.IsDefusing) ApplyPilotEffect(player); @@ -64,23 +64,27 @@ namespace jRandomSkills private static void UpdateHUD(CCSPlayerController player, Pilot_PlayerInfo pilotInfo) { + if (pilotInfo == null) return; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; + + var maximumFuel = SkillsInfo.GetValue(skillName, "maximumFuel"); + if (pilotInfo.Fuel == maximumFuel && playerInfo.SkillDescriptionHudExpired >= DateTime.Now) + { + playerInfo.PrintHTML = null; + return; + } + var buttons = player.Buttons; float fuelPercentage = maximumFuel; - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; - string fuelColor = GetFuelColor(pilotInfo.Fuel); - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = $"{player.GetTranslation("pilot_hud_info")}: {(pilotInfo.Fuel/maximumFuel)*100:F0}%
"; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + playerInfo.PrintHTML = $"{player.GetTranslation("pilot_hud_info")}: {(pilotInfo.Fuel/maximumFuel)*100:F0}%"; } private static string GetFuelColor(float fuelPercentage) { + var maximumFuel = SkillsInfo.GetValue(skillName, "maximumFuel"); if (fuelPercentage > (maximumFuel/2f)) return "#00FF00"; if (fuelPercentage > (maximumFuel/4f)) return "#FFFF00"; return "#FF0000"; @@ -120,7 +124,7 @@ namespace jRandomSkills public float Fuel { get; set; } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1466F5", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float maximumFuel = 150f, float fuelConsumption = .64f, float refuelling = .1f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1466F5", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, float maximumFuel = 150f, float fuelConsumption = .64f, float refuelling = .1f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float MaximumFuel { get; set; } = maximumFuel; public float FuelConsumption { get; set; } = fuelConsumption; diff --git a/jRandomSkills - SRC Files/src/player/skills/Planter.cs b/jRandomSkills - SRC Files/src/player/skills/Planter.cs index 5fffe7b..b9133b8 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Planter.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Planter.cs @@ -10,11 +10,10 @@ namespace jRandomSkills public class Planter : ISkill { private const Skills skillName = Skills.Planter; - private static readonly int extraC4BlowTime = Config.GetValue(skillName, "extraC4BlowTime"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void BombPlanted(EventBombPlanted @event) @@ -27,7 +26,7 @@ namespace jRandomSkills var plantedBomb = Utilities.FindAllEntitiesByDesignerName("planted_c4").FirstOrDefault(); if (plantedBomb != null) - Server.NextFrame(() => plantedBomb.C4Blow = (float)Server.EngineTime + extraC4BlowTime); + Server.NextFrame(() => plantedBomb.C4Blow = (float)Server.EngineTime + SkillsInfo.GetValue(skillName, "extraC4BlowTime")); } public static void DisableSkill(CCSPlayerController player) @@ -43,12 +42,12 @@ namespace jRandomSkills if (!Instance.IsPlayerValid(player)) continue; var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == skillName && Instance?.GameRules?.FreezePeriod == false) + if (playerInfo?.Skill == skillName) Schema.SetSchemaValue(player!.PlayerPawn.Value!.Handle, "CCSPlayerPawn", "m_bInBombZone", true); } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#7d7d7d", CsTeam onlyTeam = CsTeam.Terrorist, bool needsTeammates = false, int extraC4BlowTime = 60) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#7d7d7d", CsTeam onlyTeam = CsTeam.Terrorist, bool disableOnFreezeTime = true, bool needsTeammates = false, int extraC4BlowTime = 60) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int ExtraC4BlowTime { get; set; } = extraC4BlowTime; } diff --git a/jRandomSkills - SRC Files/src/player/skills/Poison.cs b/jRandomSkills - SRC Files/src/player/skills/Poison.cs index e56f53c..308df12 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Poison.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Poison.cs @@ -4,35 +4,36 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Poison : ISkill { private const Skills skillName = Skills.Poison; - private static readonly float cooldown = Config.GetValue(skillName, "Cooldown"); - private static readonly int healthToDamage = Config.GetValue(skillName, "Damage"); - private static readonly HashSet poisonedPlayers = []; + private static readonly ConcurrentDictionary poisonedPlayers = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } public static void NewRound() { - poisonedPlayers.Clear(); + lock (setLock) + poisonedPlayers.Clear(); } public static void OnTick() { - if (Server.TickCount % (int)(64 * cooldown) == 0) + if (Server.TickCount % (int)(64 * SkillsInfo.GetValue(skillName, "Cooldown")) == 0) { - foreach (var player in poisonedPlayers) + foreach (var player in poisonedPlayers.Keys) { var pawn = player.PlayerPawn.Value; if (pawn == null || !pawn.IsValid) continue; - SkillUtils.TakeHealth(pawn, healthToDamage); + SkillUtils.TakeHealth(pawn, SkillsInfo.GetValue(skillName, "Damage")); } } @@ -45,7 +46,7 @@ namespace jRandomSkills if (playerInfo == null || playerInfo.Skill != skillName) continue; var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); - HashSet<(string, string)> menuItems = enemies.Select(e => (e.PlayerName, e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); SkillUtils.UpdateMenu(player, menuItems); } } @@ -71,7 +72,7 @@ namespace jRandomSkills return; } - poisonedPlayers.Add(enemy); + poisonedPlayers.TryAdd(enemy, 0); playerInfo.SkillChance = 1; player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("poison_player_info", enemy.PlayerName)); enemy.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("poison_enemy_info")); @@ -86,7 +87,7 @@ namespace jRandomSkills var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); if (enemies.Length > 0) { - HashSet<(string, string)> menuItems = enemies.Select(e => (e.PlayerName, e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); SkillUtils.CreateMenu(player, menuItems); } else @@ -95,11 +96,11 @@ namespace jRandomSkills public static void DisableSkill(CCSPlayerController player) { - poisonedPlayers.Remove(player); + poisonedPlayers.TryRemove(player, out _); SkillUtils.CloseMenu(player); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#902eff", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float cooldown = 1, int damage = 1) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#902eff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, float cooldown = 1, int damage = 1) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int Damage { get; set; } = damage; public float Cooldown { get; set; } = cooldown; diff --git a/jRandomSkills - SRC Files/src/player/skills/PrimaryBan.cs b/jRandomSkills - SRC Files/src/player/skills/PrimaryBan.cs index b3c9cb4..e0c9c7c 100644 --- a/jRandomSkills - SRC Files/src/player/skills/PrimaryBan.cs +++ b/jRandomSkills - SRC Files/src/player/skills/PrimaryBan.cs @@ -4,13 +4,15 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class PrimaryBan : ISkill { private const Skills skillName = Skills.PrimaryBan; - private static readonly HashSet bannedPlayers = []; + private static readonly ConcurrentDictionary bannedPlayers = []; + private static readonly object setLock = new(); private static readonly string[] disabledWeapons = [ "ak47", "m4a1", "m4a4", "m4a1_silencer", "famas", "galilar", "aug", "sg553", "mp9", "mac10", "bizon", "mp7", "ump45", @@ -19,14 +21,17 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - bannedPlayers.Clear(); - foreach (var player in Utilities.GetPlayers()) - SkillUtils.CloseMenu(player); + lock (setLock) + { + bannedPlayers.Clear(); + foreach (var player in Utilities.GetPlayers()) + SkillUtils.CloseMenu(player); + } } public static void WeaponEquip(EventItemEquip @event) @@ -34,7 +39,7 @@ namespace jRandomSkills var player = @event.Userid; var weapon = @event.Item; if (player == null || !player.IsValid) return; - if (!bannedPlayers.Contains(player.SteamID) || !disabledWeapons.Contains(weapon)) return; + if (!bannedPlayers.ContainsKey(player.SteamID) || !disabledWeapons.Contains(weapon)) return; player.ExecuteClientCommand("slot3"); } @@ -49,7 +54,7 @@ namespace jRandomSkills if (playerInfo == null || playerInfo.Skill != skillName) continue; var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); - HashSet<(string, string)> menuItems = enemies.Select(e => (e.PlayerName, e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); SkillUtils.UpdateMenu(player, menuItems); } } @@ -75,7 +80,7 @@ namespace jRandomSkills return; } - bannedPlayers.Add(enemy.SteamID); + bannedPlayers.TryAdd(enemy.SteamID, 0); CheckWeapon(enemy); playerInfo.SkillChance = 1; player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("primaryban_player_info", enemy.PlayerName)); @@ -88,7 +93,7 @@ namespace jRandomSkills if (activeWeapon == null || !activeWeapon.IsValid) return; if (activeWeapon.DesignerName == null || string.IsNullOrEmpty(activeWeapon.DesignerName)) return; - if (!bannedPlayers.Contains(player.SteamID) || !disabledWeapons.Contains(activeWeapon.DesignerName?.Replace("weapon_", ""))) return; + if (!bannedPlayers.ContainsKey(player.SteamID) || !disabledWeapons.Contains(activeWeapon.DesignerName?.Replace("weapon_", ""))) return; player.ExecuteClientCommand("slot3"); } @@ -101,7 +106,7 @@ namespace jRandomSkills var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); if (enemies.Length > 0) { - HashSet<(string, string)> menuItems = enemies.Select(e => (e.PlayerName, e.Index.ToString())).ToHashSet(); + ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); SkillUtils.CreateMenu(player, menuItems); } else @@ -110,11 +115,11 @@ namespace jRandomSkills public static void DisableSkill(CCSPlayerController player) { - bannedPlayers.Remove(player.SteamID); + bannedPlayers.TryRemove(player.SteamID, out _); SkillUtils.CloseMenu(player); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ffc061", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ffc061", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Prosthesis.cs b/jRandomSkills - SRC Files/src/player/skills/Prosthesis.cs index 9f4a9c7..d20c3e7 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Prosthesis.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Prosthesis.cs @@ -12,7 +12,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerHurt(EventPlayerHurt @event) @@ -44,7 +44,7 @@ namespace jRandomSkills Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_iHealth"); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#9c9c9c", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#9c9c9c", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/PsychicDefusing.cs b/jRandomSkills - SRC Files/src/player/skills/PsychicDefusing.cs index e8a643b..1dbf0e2 100644 --- a/jRandomSkills - SRC Files/src/player/skills/PsychicDefusing.cs +++ b/jRandomSkills - SRC Files/src/player/skills/PsychicDefusing.cs @@ -4,27 +4,30 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class PsychicDefusing : ISkill { private const Skills skillName = Skills.PsychicDefusing; - private static readonly Dictionary SkillPlayerInfo = []; + private static readonly ConcurrentDictionary 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; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - SkillPlayerInfo.Clear(); - bombLocation = null; + lock (setLock) + { + SkillPlayerInfo.Clear(); + bombLocation = null; + } } public static void PlayerDeath(EventPlayerDeath @event) @@ -37,7 +40,7 @@ namespace jRandomSkills var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo?.Skill == skillName) - SkillPlayerInfo.Remove(pawn); + SkillPlayerInfo.TryRemove(pawn, out _); } public static void BombPlanted(EventBombPlanted _) @@ -52,18 +55,25 @@ namespace jRandomSkills if (bombLocation == null) return; foreach (var skillInfo in SkillPlayerInfo) { - var player = skillInfo.Key; + var pawn = skillInfo.Key; var info = skillInfo.Value; - if (player.AbsOrigin == null || SkillUtils.GetDistance(player.AbsOrigin, bombLocation) > maxDefusingRange) + var playerController = pawn.Controller.Value; + if (playerController == null || !pawn.Controller.IsValid) return; + + var player = playerController.As(); + if (player == null || !player.IsValid) return; + + if (pawn.AbsOrigin == null || SkillUtils.GetDistance(pawn.AbsOrigin, bombLocation) > SkillsInfo.GetValue(skillName, "maxDefusingRange")) { info.Defusing = false; - info.DefusingTime = defusingTime; + info.DefusingTime = SkillsInfo.GetValue(skillName, "defusingTime"); + SkillUtils.ResetPrintHTML(player); continue; } if (!info.Defusing) - player.EmitSound("c4.disarmstart"); + pawn.EmitSound("c4.disarmstart"); info.Defusing = true; info.DefusingTime -= (1f / tickRate); @@ -75,13 +85,11 @@ namespace jRandomSkills plantedBomb.AcceptInput("Kill"); SkillUtils.TerminateRound(CsTeam.CounterTerrorist); } - + SkillUtils.ResetPrintHTML(player); SkillPlayerInfo.Clear(); } - var playerController = player.Controller.Value; - if (playerController == null || !player.Controller.IsValid) return; - UpdateHUD(playerController.As(), info); + UpdateHUD(player, info); } } @@ -89,35 +97,34 @@ namespace jRandomSkills { var pawn = player.PlayerPawn.Value; if (pawn == null || !pawn.IsValid) return; - SkillPlayerInfo[pawn] = new PlayerSkillInfo + SkillPlayerInfo.TryAdd(pawn, new PlayerSkillInfo { SteamID = player.SteamID, Defusing = false, - DefusingTime = defusingTime, - }; + DefusingTime = SkillsInfo.GetValue(skillName, "defusingTime"), + }); } public static void DisableSkill(CCSPlayerController player) { + SkillUtils.ResetPrintHTML(player); var pawn = player.PlayerPawn.Value; if (pawn == null || !pawn.IsValid) return; - SkillPlayerInfo.Remove(pawn); + SkillPlayerInfo.TryRemove(pawn, out _); } private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) { if (!skillInfo.Defusing) return; - int cooldown = (int)skillInfo.DefusingTime + 1; + int cooldown = (int)Math.Ceiling(skillInfo.DefusingTime); - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = cooldown != 0 ? $"{player.GetTranslation("psychicdefusing_hud_info", $"{cooldown}")}
" : ""; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + if (cooldown == 0) + playerInfo.PrintHTML = null; + else + playerInfo.PrintHTML = $"{player.GetTranslation("psychicdefusing_hud_info", $"{cooldown}")}"; } public class PlayerSkillInfo { @@ -126,7 +133,7 @@ namespace jRandomSkills 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 class SkillConfig(Skills skill = skillName, bool active = true, string color = "#507529", CsTeam onlyTeam = CsTeam.CounterTerrorist, bool disableOnFreezeTime = false, bool needsTeammates = false, float maxDefusingRange = 80f, float defusingTime = 10f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float MaxDefusingRange { get; set; } = maxDefusingRange; public float DefusingTime { get; set; } = defusingTime; diff --git a/jRandomSkills - SRC Files/src/player/skills/Push.cs b/jRandomSkills - SRC Files/src/player/skills/Push.cs index ea02564..440b205 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Push.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Push.cs @@ -9,12 +9,10 @@ namespace jRandomSkills public class Push : ISkill { private const Skills skillName = Skills.Push; - private static readonly float jumpVelocity = Config.GetValue(skillName, "jumpVelocity"); - private static readonly float pushVelocity = Config.GetValue(skillName, "pushVelocity"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } public static void PlayerHurt(EventPlayerHurt @event) @@ -38,11 +36,11 @@ namespace jRandomSkills { var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo == null) return; - float newChance = (float)Instance.Random.NextDouble() * (Config.GetValue(skillName, "ChanceTo") - Config.GetValue(skillName, "ChanceFrom")) + Config.GetValue(skillName, "ChanceFrom"); + float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue(skillName, "ChanceTo") - SkillsInfo.GetValue(skillName, "ChanceFrom")) + SkillsInfo.GetValue(skillName, "ChanceFrom"); playerInfo.SkillChance = newChance; newChance = (float)Math.Round(newChance, 2) * 100; newChance = (float)Math.Round(newChance); - SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetTranslation("push")}{ChatColors.Lime}: " + player.GetTranslation("push_desc2", newChance), false); + SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", false); } private static void PushEnemy(CCSPlayerController player, QAngle attackerAngle) @@ -53,13 +51,13 @@ namespace jRandomSkills var currentPosition = player.PlayerPawn.Value.AbsOrigin; var currentAngles = player.PlayerPawn.Value.EyeAngles; - Vector newVelocity = SkillUtils.GetForwardVector(attackerAngle) * pushVelocity; - newVelocity.Z = player.PlayerPawn.Value.AbsVelocity.Z + jumpVelocity; + Vector newVelocity = SkillUtils.GetForwardVector(attackerAngle) * SkillsInfo.GetValue(skillName, "pushVelocity"); + newVelocity.Z = player.PlayerPawn.Value.AbsVelocity.Z + SkillsInfo.GetValue(skillName, "jumpVelocity"); player.PlayerPawn.Value.Teleport(currentPosition, currentAngles, newVelocity); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1e9ab0", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float chanceFrom = 1f, float chanceTo = 1f, float jumpVelocity = 300f, float pushVelocity = 400f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1e9ab0", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float chanceFrom = 1f, float chanceTo = 1f, float jumpVelocity = 300f, float pushVelocity = 400f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float ChanceFrom { get; set; } = chanceFrom; public float ChanceTo { get; set; } = chanceTo; diff --git a/jRandomSkills - SRC Files/src/player/skills/Pyro.cs b/jRandomSkills - SRC Files/src/player/skills/Pyro.cs index 0c54dd0..0f28b55 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Pyro.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Pyro.cs @@ -10,11 +10,10 @@ namespace jRandomSkills public class Pyro : ISkill { private const Skills skillName = Skills.Pyro; - private static readonly float regenerationMultiplier = Config.GetValue(skillName, "regenerationMultiplier"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerHurt(EventPlayerHurt @event) @@ -27,7 +26,7 @@ namespace jRandomSkills var victimInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == victim?.SteamID); if (victimInfo == null || victimInfo.Skill != skillName) return ; - RestoreHealth(victim!, damage * regenerationMultiplier); + RestoreHealth(victim!, damage * SkillsInfo.GetValue(skillName, "regenerationMultiplier")); } public static void EnableSkill(CCSPlayerController player) @@ -48,7 +47,7 @@ namespace jRandomSkills Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_iHealth"); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#3c47de", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float regenerationMultiplier = 1.5f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#3c47de", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float regenerationMultiplier = 1.5f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float RegenerationMultiplier { get; set; } = regenerationMultiplier; } diff --git a/jRandomSkills - SRC Files/src/player/skills/QuickShot.cs b/jRandomSkills - SRC Files/src/player/skills/QuickShot.cs index dbc44d7..d2aa2d0 100644 --- a/jRandomSkills - SRC Files/src/player/skills/QuickShot.cs +++ b/jRandomSkills - SRC Files/src/player/skills/QuickShot.cs @@ -12,7 +12,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void OnTick() @@ -42,7 +42,7 @@ namespace jRandomSkills } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8a42f5", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8a42f5", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/RadarHack.cs b/jRandomSkills - SRC Files/src/player/skills/RadarHack.cs index 954d159..c0d26b7 100644 --- a/jRandomSkills - SRC Files/src/player/skills/RadarHack.cs +++ b/jRandomSkills - SRC Files/src/player/skills/RadarHack.cs @@ -12,7 +12,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void OnTick() @@ -51,9 +51,9 @@ namespace jRandomSkills } } - public class SkillConfig : Config.DefaultSkillInfo + public class SkillConfig : SkillsInfo.DefaultSkillInfo { - public SkillConfig(Skills skill = skillName, bool active = true, string color = "#2effcb", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : base(skill, active, color, onlyTeam, needsTeammates) + public SkillConfig(Skills skill = skillName, bool active = true, string color = "#2effcb", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : base(skill, active, color, onlyTeam, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Rambo.cs b/jRandomSkills - SRC Files/src/player/skills/Rambo.cs index b5f3990..f2a0082 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Rambo.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Rambo.cs @@ -9,17 +9,15 @@ namespace jRandomSkills public class Rambo : ISkill { private const Skills skillName = Skills.Rambo; - private static readonly int minExtraHealth = Config.GetValue(skillName, "minExtraHealth"); - private static readonly int maxExtraHealth = Config.GetValue(skillName, "maxExtraHealth"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void EnableSkill(CCSPlayerController player) { - int healthBonus = Instance.Random.Next(minExtraHealth, maxExtraHealth); + int healthBonus = Instance.Random.Next(SkillsInfo.GetValue(skillName, "minExtraHealth"), SkillsInfo.GetValue(skillName, "maxExtraHealth")); AddHealth(player, healthBonus); } @@ -52,7 +50,7 @@ namespace jRandomSkills Utilities.SetStateChanged(pawn, "CBaseEntity", "m_iHealth"); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#009905", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, int minExtraHealth = 50, int maxExtraHealth = 501) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#009905", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, int minExtraHealth = 50, int maxExtraHealth = 501) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int MinExtraHealth { get; set; } = minExtraHealth; public int MaxExtraHealth { get; set; } = maxExtraHealth; diff --git a/jRandomSkills - SRC Files/src/player/skills/RandomWeapon.cs b/jRandomSkills - SRC Files/src/player/skills/RandomWeapon.cs index 042d4f1..afcd260 100644 --- a/jRandomSkills - SRC Files/src/player/skills/RandomWeapon.cs +++ b/jRandomSkills - SRC Files/src/player/skills/RandomWeapon.cs @@ -5,14 +5,15 @@ using jRandomSkills.src.player; using jRandomSkills.src.utils; using System.Collections.Immutable; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class RandomWeapon : ISkill { private const Skills skillName = Skills.RandomWeapon; - private static readonly float timerCooldown = Config.GetValue(skillName, "cooldown"); - private static readonly Dictionary SkillPlayerInfo = []; + private static readonly ConcurrentDictionary SkillPlayerInfo = []; + private static readonly object setLock = new(); private static readonly string[] pistols = [ "weapon_deagle", "weapon_revolver", "weapon_glock", "weapon_usp_silencer", "weapon_cz75a", "weapon_fiveseven", "weapon_p250", "weapon_tec9", "weapon_elite", "weapon_hkp2000" ]; @@ -24,12 +25,13 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - SkillPlayerInfo.Clear(); + lock (setLock) + SkillPlayerInfo.Clear(); } public static void OnTick() @@ -45,17 +47,18 @@ namespace jRandomSkills public static void EnableSkill(CCSPlayerController player) { - SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo { SteamID = player.SteamID, CanUse = true, Cooldown = DateTime.MinValue, - }; + }); } public static void DisableSkill(CCSPlayerController player) { - SkillPlayerInfo.Remove(player.SteamID); + SkillPlayerInfo.TryRemove(player.SteamID, out _); + SkillUtils.ResetPrintHTML(player); } private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) @@ -63,22 +66,20 @@ namespace jRandomSkills float cooldown = 0; if (skillInfo != null) { - float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "cooldown")) - DateTime.Now).TotalSeconds); cooldown = Math.Max(time, 0); if (cooldown == 0 && skillInfo?.CanUse == false) skillInfo.CanUse = true; } - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = cooldown != 0 ? $"{player.GetTranslation("hud_info", $"{cooldown}")}
" : ""; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + if (cooldown == 0) + playerInfo.PrintHTML = null; + else + playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"{cooldown}")}"; } public static void UseSkill(CCSPlayerController player) @@ -145,7 +146,7 @@ namespace jRandomSkills public DateTime Cooldown { get; set; } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#e0873a", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float cooldown = 15f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#e0873a", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float cooldown = 15f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Cooldown { get; set; } = cooldown; } diff --git a/jRandomSkills - SRC Files/src/player/skills/ReZombie.cs b/jRandomSkills - SRC Files/src/player/skills/ReZombie.cs index 739f96b..deafdb3 100644 --- a/jRandomSkills - SRC Files/src/player/skills/ReZombie.cs +++ b/jRandomSkills - SRC Files/src/player/skills/ReZombie.cs @@ -4,29 +4,30 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using System.Drawing; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class ReZombie : ISkill { private const Skills skillName = Skills.ReZombie; - private static readonly int zombieHealth = Config.GetValue(skillName, "zombieHealth"); - private static readonly HashSet zombies = []; + private static readonly ConcurrentDictionary zombies = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void EnableSkill(CCSPlayerController player) { - zombies.Remove(player); + zombies.TryRemove(player, out _); } public static void DisableSkill(CCSPlayerController player) { if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return; - zombies.Remove(player); + zombies.TryRemove(player, out _); SetPlayerColor(player.PlayerPawn.Value, true); } @@ -35,13 +36,13 @@ namespace jRandomSkills var player = @event.Userid; var weapon = @event.Item; if (player == null || !player.IsValid) return; - if (!zombies.Contains(player) || weapon == "c4") return; + if (!zombies.ContainsKey(player) || weapon == "c4") return; player.ExecuteClientCommand("slot3"); } public static void NewRound() { - foreach (var player in zombies) + foreach (var player in zombies.Keys) DisableSkill(player); zombies.Clear(); } @@ -49,7 +50,7 @@ namespace jRandomSkills public static void PlayerDeath(EventPlayerDeath @event) { var player = @event.Userid; - if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid || zombies.Contains(player)) return; + if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid || zombies.ContainsKey(player)) return; var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo?.Skill != skillName) return; @@ -61,13 +62,17 @@ namespace jRandomSkills player.Respawn(); Instance.AddTimer(.2f, () => { - player.Respawn(); - zombies.Add(player); - SetPlayerColor(pawn, false); - SkillUtils.AddHealth(pawn, zombieHealth - 100, zombieHealth); - pawn.Teleport(deadPosition, deadRotation); - player.ExecuteClientCommand("slot3"); - Instance.AddTimer(1, () => player.ExecuteClientCommand("slot3")); + lock (setLock) + { + var zombieHealth = SkillsInfo.GetValue(skillName, "zombieHealth"); + player.Respawn(); + zombies.TryAdd(player, 0); + SetPlayerColor(pawn, false); + SkillUtils.AddHealth(pawn, zombieHealth - 100, zombieHealth); + pawn.Teleport(deadPosition, deadRotation); + player.ExecuteClientCommand("slot3"); + Instance.AddTimer(1, () => player.ExecuteClientCommand("slot3")); + } }); } @@ -78,7 +83,7 @@ namespace jRandomSkills Utilities.SetStateChanged(pawn, "CBaseModelEntity", "m_clrRender"); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff5C0A", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, int zombieHealth = 200) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff5C0A", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, int zombieHealth = 200) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int ZombieHealth { get; set; } = zombieHealth; } diff --git a/jRandomSkills - SRC Files/src/player/skills/ReactiveArmor.cs b/jRandomSkills - SRC Files/src/player/skills/ReactiveArmor.cs index 6a951d1..b81da13 100644 --- a/jRandomSkills - SRC Files/src/player/skills/ReactiveArmor.cs +++ b/jRandomSkills - SRC Files/src/player/skills/ReactiveArmor.cs @@ -4,23 +4,25 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class ReactiveArmor : ISkill { private const Skills skillName = Skills.ReactiveArmor; - private static readonly float timerCooldown = Config.GetValue(skillName, "cooldown"); - private static readonly Dictionary SkillPlayerInfo = []; + private static readonly ConcurrentDictionary SkillPlayerInfo = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - SkillPlayerInfo.Clear(); + lock (setLock) + SkillPlayerInfo.Clear(); } public static void OnTick() @@ -52,17 +54,18 @@ namespace jRandomSkills public static void EnableSkill(CCSPlayerController player) { - SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo { SteamID = player.SteamID, CanUse = true, Cooldown = DateTime.MinValue, - }; + }); } public static void DisableSkill(CCSPlayerController player) { - SkillPlayerInfo.Remove(player.SteamID); + SkillPlayerInfo.TryRemove(player.SteamID, out _); + SkillUtils.ResetPrintHTML(player); } private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) @@ -70,22 +73,20 @@ namespace jRandomSkills float cooldown = 0; if (skillInfo != null) { - float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "cooldown")) - DateTime.Now).TotalSeconds); cooldown = Math.Max(time, 0); if (cooldown == 0 && skillInfo?.CanUse == false) skillInfo.CanUse = true; } - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = cooldown != 0 ? $"{player.GetTranslation("hud_info", $"{cooldown}")}
" : ""; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + if (cooldown == 0) + playerInfo.PrintHTML = null; + else + playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"{cooldown}")}"; } private static void RestoreHealth(CCSPlayerController victim, float damage) @@ -108,7 +109,7 @@ namespace jRandomSkills public DateTime Cooldown { get; set; } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#3cded3", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float cooldown = 15) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#3cded3", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float cooldown = 15) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Cooldown { get; set; } = cooldown; } diff --git a/jRandomSkills - SRC Files/src/player/skills/Regeneration.cs b/jRandomSkills - SRC Files/src/player/skills/Regeneration.cs index 7710f44..495d96e 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Regeneration.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Regeneration.cs @@ -8,17 +8,15 @@ namespace jRandomSkills public class Regeneration : ISkill { private const Skills skillName = Skills.Regeneration; - private static float cooldown = Config.GetValue(skillName, "cooldown"); - private static int healthToAdd = Config.GetValue(skillName, "healthToAdd"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void OnTick() { - if (Server.TickCount % (int)(64 * cooldown) != 0) return; + if (Server.TickCount % (int)(64 * SkillsInfo.GetValue(skillName, "cooldown")) != 0) return; foreach (var player in Utilities.GetPlayers()) { var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); @@ -26,15 +24,15 @@ namespace jRandomSkills var pawn = player.PlayerPawn.Value; if (pawn == null || !pawn.IsValid) continue; - SkillUtils.AddHealth(pawn, healthToAdd); + SkillUtils.AddHealth(pawn, SkillsInfo.GetValue(skillName, "healthToAdd")); } } - public class SkillConfig : Config.DefaultSkillInfo + public class SkillConfig : SkillsInfo.DefaultSkillInfo { public int HealthToAdd { get; set; } public float Cooldown { get; set; } - public SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff462e", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, int healthToAdd = 1, float cooldown = .25f) : base(skill, active, color, onlyTeam, needsTeammates) + public SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff462e", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, int healthToAdd = 1, float cooldown = .25f) : base(skill, active, color, onlyTeam, needsTeammates) { HealthToAdd = healthToAdd; Cooldown = cooldown; diff --git a/jRandomSkills - SRC Files/src/player/skills/Replicator.cs b/jRandomSkills - SRC Files/src/player/skills/Replicator.cs index 2d2b3ff..2a9abd9 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Replicator.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Replicator.cs @@ -5,23 +5,25 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Replicator : ISkill { private const Skills skillName = Skills.Replicator; - private static readonly float timerCooldown = Config.GetValue(skillName, "cooldown"); - private static readonly Dictionary SkillPlayerInfo = []; + private static readonly ConcurrentDictionary SkillPlayerInfo = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - SkillPlayerInfo.Clear(); + lock (setLock) + SkillPlayerInfo.Clear(); } public static void OnTick() @@ -37,17 +39,18 @@ namespace jRandomSkills public static void EnableSkill(CCSPlayerController player) { - SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo { SteamID = player.SteamID, CanUse = true, Cooldown = DateTime.MinValue, - }; + }); } public static void DisableSkill(CCSPlayerController player) { - SkillPlayerInfo.Remove(player.SteamID); + SkillPlayerInfo.TryRemove(player.SteamID, out _); + SkillUtils.ResetPrintHTML(player); } private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) @@ -55,22 +58,20 @@ namespace jRandomSkills float cooldown = 0; if (skillInfo != null) { - float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "cooldown")) - DateTime.Now).TotalSeconds); cooldown = Math.Max(time, 0); if (cooldown == 0 && skillInfo?.CanUse == false) skillInfo.CanUse = true; } - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = cooldown != 0 ? $"{player.GetTranslation("hud_info", $"{cooldown}")}
" : ""; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + if (cooldown == 0) + playerInfo.PrintHTML = null; + else + playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"{cooldown}")}"; } public static void UseSkill(CCSPlayerController player) @@ -142,7 +143,7 @@ namespace jRandomSkills public DateTime Cooldown { get; set; } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a3000b", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float cooldown = 15f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a3000b", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, float cooldown = 15f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Cooldown { get; set; } = cooldown; } diff --git a/jRandomSkills - SRC Files/src/player/skills/Retreat.cs b/jRandomSkills - SRC Files/src/player/skills/Retreat.cs index 4604c45..f7f9b2e 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Retreat.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Retreat.cs @@ -4,23 +4,25 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Retreat : ISkill { private const Skills skillName = Skills.Retreat; - private static readonly float timerCooldown = Config.GetValue(skillName, "cooldown"); - private static readonly Dictionary SkillPlayerInfo = []; + private static readonly ConcurrentDictionary SkillPlayerInfo = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - SkillPlayerInfo.Clear(); + lock (setLock) + SkillPlayerInfo.Clear(); } public static void OnTick() @@ -36,17 +38,18 @@ namespace jRandomSkills public static void EnableSkill(CCSPlayerController player) { - SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo { SteamID = player.SteamID, CanUse = true, Cooldown = DateTime.MinValue, - }; + }); } public static void DisableSkill(CCSPlayerController player) { - SkillPlayerInfo.Remove(player.SteamID); + SkillPlayerInfo.TryRemove(player.SteamID, out _); + SkillUtils.ResetPrintHTML(player); } private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) @@ -54,22 +57,20 @@ namespace jRandomSkills float cooldown = 0; if (skillInfo != null) { - float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "cooldown")) - DateTime.Now).TotalSeconds); cooldown = Math.Max(time, 0); if (cooldown == 0 && skillInfo?.CanUse == false) skillInfo.CanUse = true; } - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = cooldown != 0 ? $"{player.GetTranslation("hud_info", $"{cooldown}")}
" : ""; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + if (cooldown == 0) + playerInfo.PrintHTML = null; + else + playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"{cooldown}")}"; } public static void UseSkill(CCSPlayerController player) @@ -107,7 +108,7 @@ namespace jRandomSkills public DateTime Cooldown { get; set; } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a86eff", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float cooldown = 15f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a86eff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, float cooldown = 15f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Cooldown { get; set; } = cooldown; } diff --git a/jRandomSkills - SRC Files/src/player/skills/ReturnToSender.cs b/jRandomSkills - SRC Files/src/player/skills/ReturnToSender.cs index 1535400..37cc42b 100644 --- a/jRandomSkills - SRC Files/src/player/skills/ReturnToSender.cs +++ b/jRandomSkills - SRC Files/src/player/skills/ReturnToSender.cs @@ -3,17 +3,18 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class ReturnToSender : ISkill { private const Skills skillName = Skills.ReturnToSender; - private static readonly HashSet playersToSender = []; + private static readonly ConcurrentDictionary playersToSender = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -31,18 +32,18 @@ namespace jRandomSkills var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID); if (attackerInfo == null || attackerInfo.Skill != skillName) return; - if (playersToSender.TryGetValue(victim!.Handle, out _)) + if (playersToSender.ContainsKey(victim!.Handle)) return; var spawn = GetSpawnVector(victim); if (spawn == null) return; victim!.PlayerPawn!.Value!.Teleport(spawn); - playersToSender.Add(victim.Handle); + playersToSender.TryAdd(victim.Handle, 0); } public static void DisableSkill(CCSPlayerController player) { - playersToSender.Remove(player.Handle); + playersToSender.TryRemove(player.Handle, out _); } private static Vector? GetSpawnVector(CCSPlayerController player) @@ -56,7 +57,7 @@ namespace jRandomSkills return null; } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a68132", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a68132", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/RichBoy.cs b/jRandomSkills - SRC Files/src/player/skills/RichBoy.cs index ef1dc2c..7cacadc 100644 --- a/jRandomSkills - SRC Files/src/player/skills/RichBoy.cs +++ b/jRandomSkills - SRC Files/src/player/skills/RichBoy.cs @@ -9,19 +9,17 @@ namespace jRandomSkills public class RichBoy : ISkill { private const Skills skillName = Skills.RichBoy; - private static readonly int minMoney = Config.GetValue(skillName, "minMoney"); - private static readonly int maxMoney = Config.GetValue(skillName, "maxMoney"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void EnableSkill(CCSPlayerController player) { var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo == null) return; - int moneyBonus = Instance.Random.Next(minMoney, maxMoney); + int moneyBonus = Instance.Random.Next(SkillsInfo.GetValue(skillName, "minMoney"), SkillsInfo.GetValue(skillName, "maxMoney")); playerInfo.SkillChance = moneyBonus; AddMoney(player, moneyBonus); } @@ -44,7 +42,7 @@ namespace jRandomSkills Utilities.SetStateChanged(player, "CCSPlayerController", "m_pInGameMoneyServices"); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#D4AF37", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, int minMoney = 5000, int maxMoney = 15000) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#D4AF37", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, int minMoney = 5000, int maxMoney = 15000) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int MinMoney { get; set; } = minMoney; public int MaxMoney { get; set; } = maxMoney; diff --git a/jRandomSkills - SRC Files/src/player/skills/RobinHood.cs b/jRandomSkills - SRC Files/src/player/skills/RobinHood.cs index f4bfbd9..cd9fda1 100644 --- a/jRandomSkills - SRC Files/src/player/skills/RobinHood.cs +++ b/jRandomSkills - SRC Files/src/player/skills/RobinHood.cs @@ -9,11 +9,10 @@ namespace jRandomSkills public class RobinHood : ISkill { private const Skills skillName = Skills.RobinHood; - private static readonly int moneyMultiplier = Config.GetValue(skillName, "moneyMultiplier"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerHurt(EventPlayerHurt @event) @@ -26,7 +25,7 @@ namespace jRandomSkills var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID); if (attackerInfo?.Skill != skillName) return; - int moneyToSteal = damage * moneyMultiplier; + int moneyToSteal = damage * SkillsInfo.GetValue(skillName, "moneyMultiplier"); StealMoney(victim!, attacker!, moneyToSteal); } @@ -44,7 +43,7 @@ namespace jRandomSkills Utilities.SetStateChanged(attacker!, "CCSPlayerController", "m_pInGameMoneyServices"); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#119125", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, int moneyMultiplier = 35) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#119125", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, int moneyMultiplier = 35) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int MoneyMultiplier { get; set; } = moneyMultiplier; } diff --git a/jRandomSkills - SRC Files/src/player/skills/Rubber.cs b/jRandomSkills - SRC Files/src/player/skills/Rubber.cs index 48bd1d4..4baa918 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Rubber.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Rubber.cs @@ -3,20 +3,18 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Rubber: ISkill { private const Skills skillName = Skills.Rubber; - private static readonly float rubberTime = Config.GetValue(skillName, "slownessTime"); - private static readonly float rubberModifier = Config.GetValue(skillName, "slownessModifier"); - - private static readonly Dictionary playersToSlow = []; + private static readonly ConcurrentDictionary playersToSlow = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -35,11 +33,9 @@ namespace jRandomSkills var victimPawn = victim!.PlayerPawn.Value; if (victimPawn == null || !victimPawn.IsValid) return; + var rubberTime = SkillsInfo.GetValue(skillName, "slownessTime"); if (attackerInfo?.Skill == skillName) - if (playersToSlow.ContainsKey(victimPawn)) - playersToSlow[victimPawn] = Server.TickCount + (64 * rubberTime); - else playersToSlow.TryAdd(victimPawn, Server.TickCount + (64 * rubberTime)); - + playersToSlow.AddOrUpdate(victimPawn, Server.TickCount + (64 * rubberTime), (k, v) => Server.TickCount + (64 * rubberTime)); } public static void OnTick() @@ -51,17 +47,17 @@ namespace jRandomSkills if (time >= Server.TickCount) ChangeVelocity(pawn); else - playersToSlow.Remove(item.Key); + playersToSlow.TryRemove(item.Key, out _); } } private static void ChangeVelocity(CCSPlayerPawn pawn) { if (pawn == null || !pawn.IsValid) return; - pawn.VelocityModifier = rubberModifier; + pawn.VelocityModifier = SkillsInfo.GetValue(skillName, "slownessModifier"); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8B4513", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float slownessTime = 2f, float slownessModifier = .2f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8B4513", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float slownessTime = 2f, float slownessModifier = .2f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float SlownessTime { get; set; } = slownessTime; public float SlownessModifier { get; set; } = slownessModifier; diff --git a/jRandomSkills - SRC Files/src/player/skills/Saper.cs b/jRandomSkills - SRC Files/src/player/skills/Saper.cs index 2798f72..23c1040 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Saper.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Saper.cs @@ -12,7 +12,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void BombBegindefuse(EventBombBegindefuse @event) @@ -51,7 +51,7 @@ namespace jRandomSkills } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8A2BE2", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8A2BE2", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/SecondLife.cs b/jRandomSkills - SRC Files/src/player/skills/SecondLife.cs index 06aaefe..8f00647 100644 --- a/jRandomSkills - SRC Files/src/player/skills/SecondLife.cs +++ b/jRandomSkills - SRC Files/src/player/skills/SecondLife.cs @@ -3,18 +3,19 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class SecondLife : ISkill { private const Skills skillName = Skills.SecondLife; - private static readonly int secondLifeHealth = Config.GetValue(skillName, "startHealth"); - private static readonly HashSet secondLifePlayers = []; + private static readonly ConcurrentDictionary secondLifePlayers = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -32,26 +33,29 @@ namespace jRandomSkills if (victimInfo == null || victimInfo.Skill != skillName) return; var victimPawn = victim!.PlayerPawn.Value; - if (victimPawn!.Health > 0 || secondLifePlayers.TryGetValue(victim.Handle, out _) == true) + if (victimPawn!.Health > 0 || secondLifePlayers.ContainsKey(victim.Handle)) return; - secondLifePlayers.Add(victim.Handle); - SetHealth(victim, secondLifeHealth); - var spawn = GetSpawnVector(victim); - if (spawn != null) - victimPawn.Teleport(spawn, victimPawn.AbsRotation, null); + lock (setLock) + { + secondLifePlayers.TryAdd(victim.Handle, 0); + SetHealth(victim, SkillsInfo.GetValue(skillName, "startHealth")); + var spawn = GetSpawnVector(victim); + if (spawn != null) + victimPawn.Teleport(spawn, victimPawn.AbsRotation, null); + } } public static void EnableSkill(CCSPlayerController player) { - SetHealth(player, secondLifeHealth); + SetHealth(player, SkillsInfo.GetValue(skillName, "startHealth")); } public static void DisableSkill(CCSPlayerController player) { - secondLifePlayers.Remove(player.Handle); + secondLifePlayers.TryRemove(player.Handle, out _); if (player.PlayerPawn.Value == null) return; - SetHealth(player, Math.Min(player.PlayerPawn.Value.Health + secondLifeHealth, 100)); + SetHealth(player, Math.Min(player.PlayerPawn.Value.Health + SkillsInfo.GetValue(skillName, "startHealth"), 100)); } private static void SetHealth(CCSPlayerController player, int health) @@ -81,7 +85,7 @@ namespace jRandomSkills return abs == null ? null : new Vector(abs.X, abs.Y, abs.Z); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#d41c1c", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, int startHealth = 50) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#d41c1c", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, int startHealth = 50) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int StartHealth { get; set; } = startHealth; } diff --git a/jRandomSkills - SRC Files/src/player/skills/Shade.cs b/jRandomSkills - SRC Files/src/player/skills/Shade.cs index 43ad32e..fb4403a 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Shade.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Shade.cs @@ -9,18 +9,18 @@ using jRandomSkills.src.utils; using System.Numerics; using static jRandomSkills.jRandomSkills; using Vector = CounterStrikeSharp.API.Modules.Utils.Vector; +using System.Collections.Concurrent; namespace jRandomSkills { public class Shade : ISkill { private const Skills skillName = Skills.Shade; - private static readonly float teleportDistance = Config.GetValue(skillName, "teleportDistance"); - private static readonly Dictionary noSpace = []; + private static readonly ConcurrentDictionary noSpace = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -44,7 +44,8 @@ namespace jRandomSkills public static void DisableSkill(CCSPlayerController player) { - noSpace.Remove(player); + noSpace.TryRemove(player, out _); + SkillUtils.ResetPrintHTML(player); } public static void OnTick() @@ -56,14 +57,9 @@ namespace jRandomSkills private static void UpdateHUD(CCSPlayerController player) { - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; - - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = $"{player.GetTranslation("shade_nospace")}
"; - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; + playerInfo.PrintHTML = $"{player.GetTranslation("shade_nospace")}"; } private unsafe static bool CheckTeleport(CCSPlayerController player, Vector startPos, Vector endPos) @@ -104,17 +100,17 @@ namespace jRandomSkills foreach (int extraAngle in angles) { QAngle newAngle = new(victimAngles.X, victimAngles.Y + extraAngle, victimAngles.Z); - Vector behindPosition = victimEyePos - SkillUtils.GetForwardVector(newAngle) * teleportDistance; + Vector behindPosition = victimEyePos - SkillUtils.GetForwardVector(newAngle) * SkillsInfo.GetValue(skillName, "teleportDistance"); if (!CheckTeleport(victim, victimEyePos, behindPosition)) continue; attackerPawn.Teleport(behindPosition, newAngle, new(0, 0, 0)); teleported = true; break; } if (!teleported) - noSpace[attacker] = Server.TickCount + (64 * 2); + noSpace.AddOrUpdate(attacker, Server.TickCount + (64 * 2), (k, v) => Server.TickCount + (64 * 2)); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#4d4d4d", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float teleportDistance = 100f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#4d4d4d", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float teleportDistance = 100f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float TeleportDistance { get; set; } = teleportDistance; } diff --git a/jRandomSkills - SRC Files/src/player/skills/ShortBomb.cs b/jRandomSkills - SRC Files/src/player/skills/ShortBomb.cs index 966e14a..21cfd85 100644 --- a/jRandomSkills - SRC Files/src/player/skills/ShortBomb.cs +++ b/jRandomSkills - SRC Files/src/player/skills/ShortBomb.cs @@ -9,11 +9,10 @@ namespace jRandomSkills public class ShortBomb : ISkill { private const Skills skillName = Skills.ShortBomb; - private static readonly int detonationTime = Config.GetValue(skillName, "detonationTime"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void BombPlanted(EventBombPlanted @event) @@ -26,10 +25,10 @@ namespace jRandomSkills var plantedBomb = Utilities.FindAllEntitiesByDesignerName("planted_c4").FirstOrDefault(); if (plantedBomb != null) - Server.NextFrame(() => plantedBomb.C4Blow = (float)Server.EngineTime + detonationTime); + Server.NextFrame(() => plantedBomb.C4Blow = (float)Server.EngineTime + SkillsInfo.GetValue(skillName, "detonationTime")); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#f5b74c", CsTeam onlyTeam = CsTeam.Terrorist, bool needsTeammates = false, int detonationTime = 20) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#f5b74c", CsTeam onlyTeam = CsTeam.Terrorist, bool disableOnFreezeTime = false, bool needsTeammates = false, int detonationTime = 20) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int DetonationTime { get; set; } = detonationTime; } diff --git a/jRandomSkills - SRC Files/src/player/skills/Silent.cs b/jRandomSkills - SRC Files/src/player/skills/Silent.cs index 79df00e..78845cf 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Silent.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Silent.cs @@ -12,7 +12,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerMakeSound(UserMessage um) @@ -33,7 +33,7 @@ namespace jRandomSkills um.Recipients.Clear(); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#333333", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#333333", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/SniperElite.cs b/jRandomSkills - SRC Files/src/player/skills/SniperElite.cs index 309df2c..e880a0a 100644 --- a/jRandomSkills - SRC Files/src/player/skills/SniperElite.cs +++ b/jRandomSkills - SRC Files/src/player/skills/SniperElite.cs @@ -3,14 +3,16 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class SniperElite : ISkill { private const Skills skillName = Skills.SniperElite; - private static readonly Dictionary> playerAWPs = []; - private static readonly Dictionary sniperElites = []; + private static readonly ConcurrentDictionary> playerAWPs = []; + private static readonly ConcurrentDictionary sniperElites = []; + private static readonly object setLock = new(); private static readonly string[] rifles = [ "weapon_mp9", "weapon_mac10", "weapon_bizon", "weapon_mp7", "weapon_ump45", "weapon_p90", "weapon_mp5sd", "weapon_famas", "weapon_galilar", "weapon_m4a1", "weapon_m4a1_silencer", "weapon_ak47", @@ -19,13 +21,17 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - sniperElites.Clear(); - playerAWPs.Clear(); + + lock (setLock) + { + sniperElites.Clear(); + playerAWPs.Clear(); + } } public static void PlayerDeath(EventPlayerDeath @event) @@ -53,8 +59,8 @@ namespace jRandomSkills public static void DisableSkill(CCSPlayerController player) { - sniperElites.Remove(player.SteamID); - playerAWPs.Remove(player.SteamID); + sniperElites.TryRemove(player.SteamID, out _); + playerAWPs.TryRemove(player.SteamID, out _); } public static void UseSkill(CCSPlayerController player) @@ -79,7 +85,7 @@ namespace jRandomSkills if (activeRifle != null && activeRifle.IsValid) RemoveWeapon(player, activeRifle.DesignerName); - sniperElites[player.SteamID] = (activeRifle != null && activeRifle.IsValid) ? SkillUtils.GetDesignerName(activeRifle) : "weapon_awp"; + sniperElites.TryAdd(player.SteamID, (activeRifle != null && activeRifle.IsValid) ? SkillUtils.GetDesignerName(activeRifle) : "weapon_awp"); Server.NextFrame(() => { string weapon = holdedWeapon ?? "weapon_awp"; if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return; @@ -90,7 +96,7 @@ namespace jRandomSkills if (playerAWPs.TryGetValue(player.SteamID, out List? value)) value.Add(createdWeapon); else - playerAWPs.Add(player.SteamID, [createdWeapon]); + playerAWPs.TryAdd(player.SteamID, [createdWeapon]); } DeleteDroppedAWP(player); }); @@ -149,7 +155,7 @@ namespace jRandomSkills item.Value.AcceptInput("Kill"); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#e0873a", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#e0873a", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Soldier.cs b/jRandomSkills - SRC Files/src/player/skills/Soldier.cs index 7a3c59b..7e1aec2 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Soldier.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Soldier.cs @@ -13,17 +13,17 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } public static void EnableSkill(CCSPlayerController player) { var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo == null) return; - float newScale = (float)Instance.Random.NextDouble() * (Config.GetValue(skillName, "ChanceTo") - Config.GetValue(skillName, "ChanceFrom")) + Config.GetValue(skillName, "ChanceFrom"); + float newScale = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue(skillName, "ChanceTo") - SkillsInfo.GetValue(skillName, "ChanceFrom")) + SkillsInfo.GetValue(skillName, "ChanceFrom"); playerInfo.SkillChance = newScale; newScale = (float)Math.Round(newScale, 2); - SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetTranslation("soldier")}{ChatColors.Lime}: " + player.GetTranslation("soldier_desc2", newScale), false); + SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newScale)}", false); } public static void OnTakeDamage(DynamicHook h) @@ -56,7 +56,7 @@ namespace jRandomSkills } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#09ba00", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float chanceFrom = 1.15f, float chanceTo = 1.35f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#09ba00", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float chanceFrom = 1.15f, float chanceTo = 1.35f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float ChanceFrom { get; set; } = chanceFrom; public float ChanceTo { get; set; } = chanceTo; diff --git a/jRandomSkills - SRC Files/src/player/skills/SoundMaker.cs b/jRandomSkills - SRC Files/src/player/skills/SoundMaker.cs index 5b10cd3..ca1ce89 100644 --- a/jRandomSkills - SRC Files/src/player/skills/SoundMaker.cs +++ b/jRandomSkills - SRC Files/src/player/skills/SoundMaker.cs @@ -4,38 +4,41 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class SoundMaker : ISkill { private const Skills skillName = Skills.SoundMaker; - private static readonly float timerCooldown = Config.GetValue(skillName, "Cooldown"); - private static readonly Dictionary SkillPlayerInfo = []; + private static readonly ConcurrentDictionary SkillPlayerInfo = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - SkillPlayerInfo.Clear(); + lock (setLock) + SkillPlayerInfo.Clear(); } public static void EnableSkill(CCSPlayerController player) { - SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo { SteamID = player.SteamID, CanUse = true, Cooldown = DateTime.MinValue, - }; + }); } public static void DisableSkill(CCSPlayerController player) { - SkillPlayerInfo.Remove(player.SteamID); + SkillPlayerInfo.TryRemove(player.SteamID, out _); + SkillUtils.ResetPrintHTML(player); } public static void PlayerDeath(EventPlayerDeath @event) @@ -44,7 +47,7 @@ namespace jRandomSkills if (player == null || !player.IsValid) return; var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo?.Skill == skillName) - SkillPlayerInfo.Remove(player.SteamID); + SkillPlayerInfo.TryRemove(player.SteamID, out _); } public static void OnTick() @@ -63,22 +66,20 @@ namespace jRandomSkills float cooldown = 0; if (skillInfo != null) { - float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "Cooldown")) - DateTime.Now).TotalSeconds); cooldown = Math.Max(time, 0); if (cooldown == 0 && skillInfo?.CanUse == false) skillInfo.CanUse = true; } - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = cooldown != 0 ? $"{player.GetTranslation("hud_info", $"{cooldown}")}
" : ""; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + if (cooldown == 0) + playerInfo.PrintHTML = null; + else + playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"{cooldown}")}"; } public static void UseSkill(CCSPlayerController player) @@ -112,7 +113,7 @@ namespace jRandomSkills public DateTime Cooldown { get; set; } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#e3ed8c", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float cooldown = 5f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#e3ed8c", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float cooldown = 5f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Cooldown { get; set; } = cooldown; } diff --git a/jRandomSkills - SRC Files/src/player/skills/Spectator.cs b/jRandomSkills - SRC Files/src/player/skills/Spectator.cs index 7fa842d..75774c2 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Spectator.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Spectator.cs @@ -4,18 +4,18 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using System.Drawing; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class Spectator : ISkill { private const Skills skillName = Skills.Spectator; - private static readonly float distance = Config.GetValue(skillName, "distance"); - private static readonly Dictionary cameras = []; + private static readonly ConcurrentDictionary cameras = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -58,14 +58,7 @@ namespace jRandomSkills { var pawn = cameraInfo.Item3; if (pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE) - { ChangeCamera(player, true); - continue; - } - if (pawn.AbsOrigin == null) continue; - var pos = pawn.AbsOrigin - SkillUtils.GetForwardVector(pawn.EyeAngles) * distance; - pos.Z += pawn.ViewOffset.Z; - cameraInfo.Item2.Teleport(pos, pawn.V_angle); } } @@ -106,15 +99,20 @@ namespace jRandomSkills var enemy = enemies[Instance.Random.Next(enemies.Count)]; var pawn = enemy.PlayerPawn.Value; - if (pawn == null || !pawn.IsValid || pawn.CameraServices == null) return 0; + if (pawn == null || !pawn.IsValid || pawn.CameraServices == null || pawn.AbsOrigin == null) return 0; + + var pos = pawn.AbsOrigin - SkillUtils.GetForwardVector(pawn.EyeAngles) * SkillsInfo.GetValue(skillName, "distance"); + pos.Z += pawn.ViewOffset.Z; camera.Render = Color.FromArgb(0, 255, 255, 255); - camera.Teleport(pawn!.AbsOrigin, pawn.EyeAngles); + camera.Teleport(pos, new QAngle(0, pawn.EyeAngles.Y, 0)); camera.DispatchSpawn(); + camera.AcceptInput("SetParent", pawn, pawn, "!activator"); + if (cameras.TryGetValue(player.SteamID, out var cameraInfo)) - cameras[player.SteamID] = (cameraInfo.Item1, camera, pawn); + cameras.AddOrUpdate(player.SteamID, (cameraInfo.Item1, camera, pawn), (k, v) => (cameraInfo.Item1, camera, pawn)); else - cameras[player.SteamID] = (pawn.CameraServices.ViewEntity.Raw, camera, pawn); + cameras.AddOrUpdate(player.SteamID, (pawn.CameraServices.ViewEntity.Raw, camera, pawn), (k, v) => (pawn.CameraServices.ViewEntity.Raw, camera, pawn)); return camera.EntityHandle.Raw; } @@ -135,7 +133,7 @@ namespace jRandomSkills } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#42f5da", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float distance = 100f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#42f5da", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float distance = 100f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Distance { get; set; } = distance; } diff --git a/jRandomSkills - SRC Files/src/player/skills/SwapPosition.cs b/jRandomSkills - SRC Files/src/player/skills/SwapPosition.cs index 6fcafd1..d9c3ea5 100644 --- a/jRandomSkills - SRC Files/src/player/skills/SwapPosition.cs +++ b/jRandomSkills - SRC Files/src/player/skills/SwapPosition.cs @@ -4,27 +4,30 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class SwapPosition : ISkill { private const Skills skillName = Skills.SwapPosition; - private static readonly float timerCooldown = Config.GetValue(skillName, "cooldown"); - private static readonly Dictionary SkillPlayerInfo = []; + private static readonly ConcurrentDictionary SkillPlayerInfo = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - SkillPlayerInfo.Clear(); + lock (setLock) + SkillPlayerInfo.Clear(); } public static void OnTick() { + if (SkillUtils.IsFreezeTime()) return; foreach (var player in Utilities.GetPlayers()) { var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); @@ -39,19 +42,21 @@ namespace jRandomSkills public static void EnableSkill(CCSPlayerController player) { - SkillPlayerInfo[player.SteamID] = new ZamianaMiejsc_PlayerInfo + var cooldownBeforeUse = SkillsInfo.GetValue(skillName, "cooldownBeforeUse"); + SkillPlayerInfo.TryAdd(player.SteamID, new ZamianaMiejsc_PlayerInfo { SteamID = player.SteamID, - CanUse = true, - Cooldown = DateTime.MinValue, + CanUse = false, + Cooldown = cooldownBeforeUse <= 0 ? DateTime.MinValue : Event.freezeTimeEnd.AddSeconds(cooldownBeforeUse - SkillsInfo.GetValue(skillName, "cooldown")), LastClick = DateTime.MinValue, FindedEnemy = false, - }; + }); } public static void DisableSkill(CCSPlayerController player) { - SkillPlayerInfo.Remove(player.SteamID); + SkillPlayerInfo.TryRemove(player.SteamID, out _); + SkillUtils.ResetPrintHTML(player); } private static void UpdateHUD(CCSPlayerController player, ZamianaMiejsc_PlayerInfo skillInfo, bool showInfo) @@ -59,29 +64,27 @@ namespace jRandomSkills float cooldown = 0; if (skillInfo != null) { - float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "cooldown")) - DateTime.Now).TotalSeconds); cooldown = Math.Max(time, 0); if (cooldown == 0 && skillInfo?.CanUse == false) skillInfo.CanUse = true; } - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = ""; + if (cooldown == 0) + { + if (showInfo) + playerInfo.PrintHTML = skillInfo != null && !skillInfo.FindedEnemy + ? $"{player.GetTranslation("hud_info_no_enemy")}" : null; + else + SkillUtils.ResetPrintHTML(player); + return; + } - if (showInfo) - remainingLine = cooldown != 0 ? $"{player.GetTranslation("hud_info", $"{cooldown}")}
" - : skillInfo != null && !skillInfo.FindedEnemy ? $"{player.GetTranslation("hud_info_no_enemy")}
" - : ""; - else - remainingLine = cooldown != 0 ? $"{player.GetTranslation("hud_info", $"{cooldown}")}
" : ""; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"{cooldown}")}"; } public static void UseSkill(CCSPlayerController player) @@ -141,9 +144,10 @@ namespace jRandomSkills public bool FindedEnemy { get; set; } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1466F5", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float cooldown = 30f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1466F5", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, float cooldown = 30f, float cooldownBeforeUse = 10f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Cooldown { get; set; } = cooldown; + public float CooldownBeforeUse { get; set; } = cooldownBeforeUse; } } } \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Teleporter.cs b/jRandomSkills - SRC Files/src/player/skills/Teleporter.cs index 0a32317..6919582 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Teleporter.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Teleporter.cs @@ -12,7 +12,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerHurt(EventPlayerHurt @event) @@ -46,7 +46,7 @@ namespace jRandomSkills attackerPawn.Teleport(victimPosition, victimAngles, victimVelocity); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8A2BE2", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8A2BE2", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Thief.cs b/jRandomSkills - SRC Files/src/player/skills/Thief.cs index 7d49d7b..ceb88e0 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Thief.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Thief.cs @@ -4,6 +4,7 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { @@ -13,7 +14,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color"), false); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"), false); } public static void OnTick() @@ -27,7 +28,7 @@ namespace jRandomSkills if (playerInfo == null || playerInfo.Skill != skillName) continue; var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); - HashSet<(string, string)> menuItems = []; + ConcurrentBag<(string, string)> menuItems = []; foreach (var enemy in enemies) { var enemyInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == enemy.SteamID); @@ -75,7 +76,7 @@ namespace jRandomSkills if (enemies.Length > 0) { List skills = []; - HashSet<(string, string)> menuItems = []; + ConcurrentBag<(string, string)> menuItems = []; foreach (var enemy in enemies) { var enemyInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == enemy.SteamID); @@ -137,6 +138,14 @@ namespace jRandomSkills SkillUtils.CloseMenu(player); Instance.SkillAction(enemySkill.ToString(), "EnableSkill", [player]); player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("thief_player_info", enemy.PlayerName)); + + if (SkillsInfo.GetValue(enemySkill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime()) + Instance?.AddTimer(Math.Max((float)(Event.freezeTimeEnd - DateTime.Now).TotalSeconds, 0), () => { + if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID && p.Skill == enemySkill) == null) return; + Instance?.SkillAction(enemySkill.ToString(), "EnableSkill", new[] { player }); + }); + else + Instance?.SkillAction(enemySkill.ToString(), "EnableSkill", new[] { player }); }); Instance.AddTimer(.1f, () => @@ -148,7 +157,7 @@ namespace jRandomSkills }); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#adaec7", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#adaec7", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/ThirdEye.cs b/jRandomSkills - SRC Files/src/player/skills/ThirdEye.cs index 190f8ba..d093621 100644 --- a/jRandomSkills - SRC Files/src/player/skills/ThirdEye.cs +++ b/jRandomSkills - SRC Files/src/player/skills/ThirdEye.cs @@ -3,18 +3,19 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using System.Drawing; +using System.Collections.Concurrent; namespace jRandomSkills { public class ThirdEye : ISkill { private const Skills skillName = Skills.ThirdEye; - private static readonly float distance = Config.GetValue(skillName, "distance"); - private static readonly Dictionary cameras = []; + private static readonly ConcurrentDictionary cameras = []; + private static readonly object setLock = new(); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -22,7 +23,8 @@ namespace jRandomSkills foreach (var camera in cameras) if (camera.Value.Item2 != null && camera.Value.Item2.IsValid) camera.Value.Item2.AcceptInput("Kill"); - cameras.Clear(); + lock (setLock) + cameras.Clear(); } public static void UseSkill(CCSPlayerController player) @@ -49,9 +51,13 @@ namespace jRandomSkills ChangeCamera(player, true); continue; } - var pos = pawn.AbsOrigin - SkillUtils.GetForwardVector(pawn.EyeAngles) * distance; + + var pos = pawn.AbsOrigin - SkillUtils.GetForwardVector(pawn.EyeAngles) * SkillsInfo.GetValue(skillName, "distance"); pos.Z += pawn.ViewOffset.Z; - cameraInfo.Item2.Teleport(pos, pawn.V_angle); + + var cam = cameraInfo.Item2; + if (cam == null || cam.AbsOrigin == null || cam.AbsRotation == null) continue; + cam.Teleport(pos, pawn.V_angle); } } @@ -92,11 +98,12 @@ namespace jRandomSkills camera.Render = Color.FromArgb(0, 255, 255, 255); camera.Teleport(pawn!.AbsOrigin, pawn.EyeAngles); camera.DispatchSpawn(); - cameras[player.SteamID] = (pawn.CameraServices!.ViewEntity.Raw, camera); + + cameras.AddOrUpdate(player.SteamID, (pawn.CameraServices!.ViewEntity.Raw, camera), (v,k) => (pawn.CameraServices!.ViewEntity.Raw, camera)); return camera.EntityHandle.Raw; } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1b04cc", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float distance = 100f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1b04cc", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float distance = 100f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Distance { get; set; } = distance; } diff --git a/jRandomSkills - SRC Files/src/player/skills/Thorns.cs b/jRandomSkills - SRC Files/src/player/skills/Thorns.cs index 2c09c30..2e13ede 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Thorns.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Thorns.cs @@ -8,11 +8,10 @@ namespace jRandomSkills public class Thorns : ISkill { private const Skills skillName = Skills.Thorns; - private static readonly float healthTakenScale = Config.GetValue(skillName, "healthTakenScale"); public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void PlayerHurt(EventPlayerHurt @event) @@ -24,12 +23,12 @@ namespace jRandomSkills var victimInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == victim?.SteamID); if (victimInfo?.Skill == skillName && victim!.PawnIsAlive && attacker!.PawnIsAlive) { - SkillUtils.TakeHealth(attacker.PlayerPawn.Value, (int)(@event.DmgHealth * healthTakenScale)); + SkillUtils.TakeHealth(attacker.PlayerPawn.Value, (int)(@event.DmgHealth * SkillsInfo.GetValue(skillName, "healthTakenScale"))); attacker.EmitSound("Player.DamageBody.Onlooker"); } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#962631", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float healthTakenScale = .3f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#962631", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float healthTakenScale = .3f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float HealthTakenScale { get; set; } = healthTakenScale; } diff --git a/jRandomSkills - SRC Files/src/player/skills/ToxicSmoke.cs b/jRandomSkills - SRC Files/src/player/skills/ToxicSmoke.cs index 151124a..366b9b4 100644 --- a/jRandomSkills - SRC Files/src/player/skills/ToxicSmoke.cs +++ b/jRandomSkills - SRC Files/src/player/skills/ToxicSmoke.cs @@ -10,13 +10,11 @@ namespace jRandomSkills public class ToxicSmoke : ISkill { private const Skills skillName = Skills.ToxicSmoke; - private static readonly int smokeDamage = Config.GetValue(skillName, "smokeDamage"); - private static readonly float smokeRadius = Config.GetValue(skillName, "smokeRadius"); private static readonly List smokes = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -93,11 +91,11 @@ namespace jRandomSkills if (Server.TickCount % 17 == 0) if (player != null && player.IsValid && player.PlayerPawn.Value != null && player.PlayerPawn.Value.IsValid) if (player.PlayerPawn.Value.LifeState == (byte)LifeState_t.LIFE_ALIVE && player.PlayerPawn.Value.AbsOrigin != null) - if (SkillUtils.GetDistance(smokePos, player.PlayerPawn.Value.AbsOrigin) <= smokeRadius) - AddHealth(player.PlayerPawn.Value, -smokeDamage); + if (SkillUtils.GetDistance(smokePos, player.PlayerPawn.Value.AbsOrigin) <= SkillsInfo.GetValue(skillName, "smokeRadius")) + AddHealth(player.PlayerPawn.Value, -SkillsInfo.GetValue(skillName, "smokeDamage")); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#507529", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, int smokeDamage = 2, float smokeRadius = 180) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#507529", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, int smokeDamage = 2, float smokeRadius = 180) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int SmokeDamage { get; set; } = smokeDamage; public float SmokeRadius { get; set; } = smokeRadius; diff --git a/jRandomSkills - SRC Files/src/player/skills/Wallhack.cs b/jRandomSkills - SRC Files/src/player/skills/Wallhack.cs index 77e9977..406055b 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Wallhack.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Wallhack.cs @@ -11,11 +11,11 @@ namespace jRandomSkills public class Wallhack : ISkill { private const Skills skillName = Skills.Wallhack; - private static readonly List<(CDynamicProp, CDynamicProp)> glows = []; + private static readonly List<(CDynamicProp, CDynamicProp, CsTeam)> glows = []; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void CheckTransmit([CastFrom(typeof(nint))] CCheckTransmitInfoList infoList) @@ -28,11 +28,11 @@ namespace jRandomSkills var observedPlayer = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == player?.Pawn?.Value?.ObserverServices?.ObserverTarget?.Value?.Handle); var observerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == observedPlayer?.SteamID); - if (playerInfo?.Skill == skillName || (observerInfo != null && observerInfo?.Skill == skillName)) - continue; - foreach (var glow in glows) { + if (glow.Item3 != player.Team && (playerInfo?.Skill == skillName || (observerInfo != null && observerInfo?.Skill == skillName))) + continue; + info.TransmitEntities.Remove(glow.Item1); info.TransmitEntities.Remove(glow.Item2); } @@ -51,10 +51,11 @@ namespace jRandomSkills glows.Clear(); } - public static void EnableSkill(CCSPlayerController player) + public static void EnableSkill(CCSPlayerController _) { SkillUtils.EnableTransmit(); - SetGlowEffectForEnemies(player); + if (glows.Count == 0) + SetGlowEffectForAll(); } public static void DisableSkill(CCSPlayerController player) @@ -67,10 +68,9 @@ namespace jRandomSkills NewRound(); } - private static void SetGlowEffectForEnemies(CCSPlayerController player) + private static void SetGlowEffectForAll() { - CsTeam originalTeam = player.Team; - foreach (var enemy in Utilities.GetPlayers().FindAll(p => p.Team != originalTeam && p.PawnIsAlive)) + foreach (var enemy in Utilities.GetPlayers().FindAll(p => p.PawnIsAlive && p.Team is CsTeam.Terrorist or CsTeam.CounterTerrorist)) { var enemyInfo = Instance.SkillPlayer.FirstOrDefault(e => e.SteamID == enemy.SteamID); if (enemyInfo?.Skill == Skills.Ghost) @@ -103,11 +103,11 @@ namespace jRandomSkills modelRelay.AcceptInput("FollowEntity", enemyPawn, modelRelay, "!activator"); modelGlow.AcceptInput("FollowEntity", modelRelay, modelGlow, "!activator"); - glows.Add((modelRelay, modelGlow)); + glows.Add((modelRelay, modelGlow, enemy.Team)); } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#5d00ff", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#5d00ff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/player/skills/Watchmaker.cs b/jRandomSkills - SRC Files/src/player/skills/Watchmaker.cs index abe7823..5c0bdb1 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Watchmaker.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Watchmaker.cs @@ -10,12 +10,11 @@ namespace jRandomSkills public class Watchmaker : ISkill { private const Skills skillName = Skills.Watchmaker; - private static readonly int roundTime = Config.GetValue(skillName, "changeRoundTime"); private static bool bombPlanted = false; public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() @@ -23,6 +22,11 @@ namespace jRandomSkills bombPlanted = false; } + public static void DisableSkill(CCSPlayerController player) + { + SkillUtils.ResetPrintHTML(player); + } + public static void BombPlanted(EventBombPlanted _) { bombPlanted = true; @@ -45,6 +49,7 @@ namespace jRandomSkills var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (playerInfo?.Skill != skillName || Instance.GameRules == null) return; + var roundTime = SkillsInfo.GetValue(skillName, "changeRoundTime"); Instance.GameRules.RoundTime += player.Team == CsTeam.Terrorist ? roundTime : -roundTime; if (player.Team == CsTeam.Terrorist) Localization.PrintTranslationToChatAll($" {ChatColors.Orange}{{0}}", ["watchmaker_tt"], [roundTime]); @@ -55,6 +60,7 @@ namespace jRandomSkills public static void OnTick() { if (bombPlanted) return; + if (SkillUtils.IsFreezeTime()) return; foreach (var player in Utilities.GetPlayers()) { var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); @@ -69,16 +75,13 @@ namespace jRandomSkills if (skillData == null || Instance?.GameRules == null || Instance?.GameRules?.RoundTime == null || Instance.GameRules?.RoundStartTime == null) return; int seconds = 1 + (int)(Instance.GameRules.RoundTime - (Server.CurrentTime - Instance.GameRules.RoundStartTime)); - - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = $"{SkillUtils.SecondsToTimer(seconds)}
"; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; + playerInfo.PrintHTML = SkillUtils.SecondsToTimer(seconds); } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff462e", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, int changeRoundTime = 10) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff462e", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, int changeRoundTime = 10) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public int ChangeRoundTime { get; set; } = changeRoundTime; } diff --git a/jRandomSkills - SRC Files/src/player/skills/WeaponsSwap.cs b/jRandomSkills - SRC Files/src/player/skills/WeaponsSwap.cs index c55bcd1..f6370df 100644 --- a/jRandomSkills - SRC Files/src/player/skills/WeaponsSwap.cs +++ b/jRandomSkills - SRC Files/src/player/skills/WeaponsSwap.cs @@ -4,14 +4,15 @@ using CounterStrikeSharp.API.Modules.Utils; using jRandomSkills.src.player; using jRandomSkills.src.utils; using static jRandomSkills.jRandomSkills; +using System.Collections.Concurrent; namespace jRandomSkills { public class WeaponsSwap : ISkill { private const Skills skillName = Skills.WeaponsSwap; - private static readonly float timerCooldown = Config.GetValue(skillName, "cooldown"); - private static readonly Dictionary SkillPlayerInfo = []; + private static readonly ConcurrentDictionary SkillPlayerInfo = []; + private static readonly object setLock = new(); private static readonly string[] weapons = [ "weapon_deagle", "weapon_revolver", "weapon_glock", "weapon_usp_silencer", "weapon_cz75a", "weapon_fiveseven", "weapon_p250", "weapon_tec9", "weapon_elite", "weapon_hkp2000", @@ -22,17 +23,18 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void NewRound() { - SkillPlayerInfo.Clear(); + lock (setLock) + SkillPlayerInfo.Clear(); } public static void EnableSkill(CCSPlayerController player) { - SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo { SteamID = player.SteamID, CanUse = true, @@ -40,12 +42,13 @@ namespace jRandomSkills LastClick = DateTime.MinValue, FindedEnemy = true, HaveWeapon = true, - }; + }); } public static void DisableSkill(CCSPlayerController player) { - SkillPlayerInfo.Remove(player.SteamID); + SkillPlayerInfo.TryRemove(player.SteamID, out _); + SkillUtils.ResetPrintHTML(player); } public static void OnTick() @@ -67,30 +70,29 @@ namespace jRandomSkills float cooldown = 0; if (skillInfo != null) { - float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "cooldown")) - DateTime.Now).TotalSeconds); cooldown = Math.Max(time, 0); if (cooldown == 0 && skillInfo?.CanUse == false) skillInfo.CanUse = true; } - var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); - if (skillData == null) return; + var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; - string remainingLine = ""; + if (cooldown == 0) + { + if (showInfo) + playerInfo.PrintHTML = + skillInfo != null && !skillInfo.FindedEnemy + ? $"{player.GetTranslation("hud_info_no_enemy")}" + : skillInfo != null && !skillInfo.HaveWeapon ? $"{player.GetTranslation("weaponsswap_hud_info2")}" : null; + else + SkillUtils.ResetPrintHTML(player); + return; + } - if (showInfo) - remainingLine = cooldown != 0 ? $"{player.GetTranslation("hud_info", $"{cooldown}")}
" - : skillInfo != null && !skillInfo.FindedEnemy ? $"{player.GetTranslation("hud_info_no_enemy")}
" - : skillInfo != null && !skillInfo.HaveWeapon ? $"{player.GetTranslation("weaponsswap_hud_info2")}
" - : ""; - else - remainingLine = cooldown != 0 ? $"{player.GetTranslation("hud_info", $"{cooldown}")}
" : ""; - - var hudContent = infoLine + skillLine + remainingLine; - player.PrintToCenterHtml(hudContent); + playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"{cooldown}")}"; } public static void UseSkill(CCSPlayerController player) @@ -193,7 +195,7 @@ namespace jRandomSkills public bool HaveWeapon { get; set; } } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#c7e03a", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false, float cooldown = 30f) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#c7e03a", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, float cooldown = 30f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { public float Cooldown { get; set; } = cooldown; } diff --git a/jRandomSkills - SRC Files/src/player/skills/Zeus.cs b/jRandomSkills - SRC Files/src/player/skills/Zeus.cs index 80c182f..2547b3b 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Zeus.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Zeus.cs @@ -12,7 +12,7 @@ namespace jRandomSkills public static void LoadSkill() { - SkillUtils.RegisterSkill(skillName, Config.GetValue(skillName, "color")); + SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color")); } public static void EnableSkill(CCSPlayerController player) @@ -48,7 +48,7 @@ namespace jRandomSkills } - public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#fbff00", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) : Config.DefaultSkillInfo(skill, active, color, onlyTeam, needsTeammates) + public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#fbff00", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates) { } } diff --git a/jRandomSkills - SRC Files/src/utils/Config.cs b/jRandomSkills - SRC Files/src/utils/Config.cs index e04aec4..be089e9 100644 --- a/jRandomSkills - SRC Files/src/utils/Config.cs +++ b/jRandomSkills - SRC Files/src/utils/Config.cs @@ -1,9 +1,5 @@ -using CounterStrikeSharp.API.Modules.Utils; -using jRandomSkills.src.player; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System.Reflection; using static jRandomSkills.jRandomSkills; namespace jRandomSkills @@ -12,111 +8,67 @@ namespace jRandomSkills { private static readonly string configsFolder = Path.Combine(Instance.ModuleDirectory, "configs"); private static readonly string configPath = Path.Combine(configsFolder, "config.json"); - private static ConfigModel config = LoadConfig(); + private static readonly object fileLock = new(); - public static ConfigModel LoadedConfig => config; + private static SettingsModel config = LoadConfig(); + public static SettingsModel LoadedConfig => config; - public static ConfigModel LoadConfig() + public static SettingsModel LoadConfig() { - if (!File.Exists(configPath)) + lock (fileLock) { - Instance.Logger.LogInformation("Config file does not exist. Create a new config file..."); - var defaultConfig = new ConfigModel(); - SaveConfig(defaultConfig); - return defaultConfig; - } + var newConfig = new SettingsModel(); - string json = File.ReadAllText(configPath); - var config = new ConfigModel(); + if (!File.Exists(configPath)) + { + Instance.Logger.LogInformation("Config file does not exist. Create a new config file..."); + SaveConfig(newConfig); + return config = newConfig; + } - try - { - var root = JsonConvert.DeserializeObject(json); - if (root == null) return config; + try + { + string json; + using (var fs = new FileStream(configPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + using (var sr = new StreamReader(fs)) + json = sr.ReadToEnd(); + newConfig = JsonConvert.DeserializeObject(json) ?? new SettingsModel(); + } + catch + { + Instance.Logger.LogError("Error when loading the config file."); + } - var settings = root["Settings"]; - if (settings != null) JsonConvert.PopulateObject(settings.ToString(), config.Settings); - - var skillsArray = (JArray?)root["SkillsInfo"]; - if (skillsArray != null) - foreach (var skillObj in skillsArray) - { - var name = skillObj["Name"]; - if (name == null) continue; - var instance = config.SkillsInfo.FirstOrDefault(x => x.Name == name.ToString()); - if (instance != null) JsonConvert.PopulateObject(skillObj.ToString(), instance); - } - } - catch - { - Instance.Logger.LogError("Error when loading the config file."); - } - - return config; - } - - public static void SaveConfig(ConfigModel config) - { - try - { - Directory.CreateDirectory(configsFolder); - string json = JsonConvert.SerializeObject(config, Formatting.Indented); - File.WriteAllText(configPath, json); - } - catch - { - Instance.Logger.LogError("Error when saving the config file."); + if (newConfig.DisplayAlwaysDescription) + newConfig.SkillDescriptionDuration = 9999; + return config = newConfig; } } - public static T GetValue(object skill, string key) + public static void SaveConfig(SettingsModel config) { - var skillConfig = config.SkillsInfo.FirstOrDefault(s => s.Name == skill.ToString()); - if (skillConfig == null) return default!; - - var prop = skillConfig.GetType().GetProperty(key, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); - if (prop != null) + lock (fileLock) { - var value = prop.GetValue(skillConfig); - if (value == null) return default!; - else return (T)Convert.ChangeType(value, typeof(T)); - } + try + { + Directory.CreateDirectory(configsFolder); + string json = JsonConvert.SerializeObject(config, Formatting.Indented); - var field = skillConfig.GetType().GetField(key, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); - if (field != null) - { - var value = field.GetValue(skillConfig); - if (value == null) return default!; - else return (T)Convert.ChangeType(value, typeof(T)); - } + string tempPath = $"{configPath}.temp"; + File.WriteAllText(tempPath, json); - return default!; - } - - public class ConfigModel - { - public Settings Settings { get; set; } = new Settings(); - public DefaultSkillInfo[] SkillsInfo { get; set; } - - public ConfigModel() - { - SkillsInfo = Assembly.GetExecutingAssembly().GetTypes() - .Where(t => typeof(DefaultSkillInfo).IsAssignableFrom(t) && t.Name == "SkillConfig") - .Select(t => - { - var ctor = t.GetConstructors().FirstOrDefault(c => c.GetParameters().All(p => p.IsOptional)); - if (ctor == null) return null; - var args = ctor.GetParameters().Select(p => Type.Missing).ToArray(); - return ctor.Invoke(args) as DefaultSkillInfo; - }) - .Where(instance => instance != null) - .ToArray()!; + File.Copy(tempPath, configPath, overwrite: true); + File.Delete(tempPath); + } + catch + { + Instance.Logger.LogError("Error when saving the config file."); + } } } - public class Settings + public class SettingsModel { - public string LangCode { get; set; } public int GameMode { get; set; } public bool KillerSkillInfo { get; set; } public bool TeamMateSkillInfo { get; set; } @@ -125,28 +77,17 @@ namespace jRandomSkills public string? AlternativeSkillButton { get; set; } public float SkillTimeBeforeStart { get; set; } public float SkillDescriptionDuration { get; set; } + public bool DisplayAlwaysDescription { get; set; } public bool DisableSpectateHUD { get; set; } public bool FlashingHtmlHudFix { get; set; } public bool CS2TraceRayDebug { get; set; } + public LanguageSystem LanguageSystem { get; set; } + public HtmlHudCustomisation HtmlHudCustomisation { get; set; } + public NormalCommands NormalCommands { get; set; } + public VotingCommands VotingCommands { get; set; } - public NormalCommand SetSkillCommands { get; set; } - public NormalCommand SkillsListCommands { get; set; } - public NormalCommand UseSkillCommands { get; set; } - public NormalCommand HealCommands { get; set; } - public NormalCommand ConsoleCommands { get; set; } - public NormalCommand SetStaticSkillCommands { get; set; } - public NormalCommand ChangeLanguageCommands { get; set; } - public NormalCommand ReloadCommands { get; set; } - public VotingCommand StartGameCommands { get; set; } - public VotingCommand ChangeMapCommands { get; set; } - public VotingCommand SwapCommands { get; set; } - public VotingCommand ShuffleCommands { get; set; } - public VotingCommand PauseCommands { get; set; } - public VotingCommand SetScoreCommands { get; set; } - - public Settings() + public SettingsModel() { - LangCode = "en"; GameMode = (int)GameModes.NoRepeat; KillerSkillInfo = true; TeamMateSkillInfo = true; @@ -155,27 +96,100 @@ namespace jRandomSkills AlternativeSkillButton = null; SkillTimeBeforeStart = 7; SkillDescriptionDuration = 7; + DisplayAlwaysDescription = false; FlashingHtmlHudFix = true; CS2TraceRayDebug = false; DisableSpectateHUD = false; - SetSkillCommands = new NormalCommand("ustawskill, ustaw_skill, setskill, set_skill, definirhabilidade, configurarhabilidade, 设置技能, 配置技能", "@jRandmosSkills/admin"); - SkillsListCommands = new NormalCommand("supermoc, skille, listamocy, supermoce, skills, listaHabilidades, habilidades, 技能列表, 超能力列表", "@jRandmosSkills/admin"); - UseSkillCommands = new NormalCommand("t, useSkill, usarHabilidade, 技能使用, 使用技能", "@jRandmosSkills/admin"); - HealCommands = new NormalCommand("heal, ulecz, curar, tratar, 治疗, 治愈", "@jRandmosSkills/admin"); - ConsoleCommands = new NormalCommand("console, sv, 控制台, 服务器", "@jRandmosSkills/root"); - SetStaticSkillCommands = new NormalCommand("ustawstatycznyskill, ustaw_statyczny_skill, setstaticskill, set_static_skill", "@jRandmosSkills/admin"); - ChangeLanguageCommands = new NormalCommand("lang, language, changelang, change_lang, jezyk, język", ""); - ReloadCommands = new NormalCommand("reload, refresh", "@jRandmosSkills/admin"); + LanguageSystem = new LanguageSystem + { + DefaultLangCode = "en", + DisableGeoLite = false, + LanguageInfos = + [ + new LanguageInfo("CN, TW, HK, MO, SG", "pt-br"), + new LanguageInfo("PT, BR, AO, CV, GW, MZ, ST, TL", "zh"), + new LanguageInfo("FR, MC, HT", "fr"), + new LanguageInfo("PL", "pl"), + new LanguageInfo("GB, US", "en") + ] + }; - StartGameCommands = new VotingCommand(true, "start, go, começar, iniciar, 开始, 启动", "@jRandmosSkills/admin", 15, 60, 15, 500, 2); - ChangeMapCommands = new VotingCommand( true, "map, mapa, changemap, zmienmape, zmienmape, mudarMapa, trocarMapa, 更换地图, 更改地图", "@jRandmosSkills/admin", 25, 90, 15, 500, 2); - SwapCommands = new VotingCommand(true, "swap, zmiana, trocar, 交换, 切换", "@jRandmosSkills/admin", 15, 90, 15, 20, 2); - ShuffleCommands = new VotingCommand(true, "shuffle, embaralhar, 随机排序, 洗牌", "@jRandmosSkills/admin", 15, 90, 15, 20, 2); - PauseCommands = new VotingCommand(true, "pause, unpause, pausar, despausar, 暂停, 恢复", "@jRandmosSkills/admin", 15, 60, 15, 2, 2); - SetScoreCommands = new VotingCommand(true, "setscore, wynik, definirPontuacao, configurarPontos, 设置分数, 调整分数", "@jRandmosSkills/root", 15, 90, 15, 90, 2); + HtmlHudCustomisation = new HtmlHudCustomisation + { + HeaderLineColor = "#FFFFFF", + HeaderLineSize = "ml", + SkillLineSize = "l", + InfoLineColor = "#FFFFFF", + InfoLineSize = "sm", + SkillDescriptionLineColor = "#999999", + SkillDescriptionLineSize = "sm", + WSADMenuSelectInfoLineColor = "#999999", + WSADMenuSelectInfoLineSize = "sm", + WSADMenuItemLineColor = "white", + WSADMenuItemHoverLineColor = "orange", + WSADMenuItemLineSize = "sm", + WSADMenuControllsLineSize = "sm", + WSADMenuControllsLineColor1 = "cyan", + WSADMenuControllsLineColor2 = "white", + WSADMenuControllsLineColor3 = "green", + }; + + NormalCommands = new NormalCommands + { + SetSkillCommand = new NormalCommand("ustawskill, ustaw_skill, setskill, set_skill, definirhabilidade, configurarhabilidade, 设置技能, 配置技能", "@jRandmosSkills/admin"), + SkillsListCommand = new NormalCommand("supermoc, skille, listamocy, supermoce, skills, listaHabilidades, habilidades, 技能列表, 超能力列表", "@jRandmosSkills/admin"), + UseSkillCommand = new NormalCommand("t, useSkill, usarHabilidade, 技能使用, 使用技能", "@jRandmosSkills/admin"), + HealCommand = new NormalCommand("heal, ulecz, curar, tratar, 治疗, 治愈", "@jRandmosSkills/admin"), + ConsoleCommand = new NormalCommand("console, sv, 控制台, 服务器", "@jRandmosSkills/root"), + SetStaticSkillCommand = new NormalCommand("ustawstatycznyskill, ustaw_statyczny_skill, setstaticskill, set_static_skill", "@jRandmosSkills/admin"), + ChangeLanguageCommand = new NormalCommand("lang, language, changelang, change_lang, jezyk, język", ""), + ReloadCommand = new NormalCommand("reload, refresh", "@jRandmosSkills/admin"), + }; + + VotingCommands = new VotingCommands + { + StartGameCommand = new StartGameCommand(true, "start, go, começar, iniciar, 开始, 启动", "@jRandmosSkills/admin", "mp_freezetime 15; mp_forcecamera 0; mp_overtime_enable 1; sv_cheats 0", "mp_freezetime 0; mp_forcecamera 0; mp_overtime_enable 1; sv_cheats 1", 15, 60, 15, 500, 2), + ChangeMapCommand = new VotingCommand(true, "map, mapa, changemap, zmienmape, zmienmape, mudarMapa, trocarMapa, 更换地图, 更改地图", "@jRandmosSkills/admin", 25, 90, 15, 500, 2), + SwapCommand = new VotingCommand(true, "swap, zmiana, trocar, 交换, 切换", "@jRandmosSkills/admin", 15, 90, 15, 20, 2), + ShuffleCommand = new VotingCommand(true, "shuffle, embaralhar, 随机排序, 洗牌", "@jRandmosSkills/admin", 15, 90, 15, 20, 2), + PauseCommand = new VotingCommand(true, "pause, unpause, pausar, despausar, 暂停, 恢复", "@jRandmosSkills/admin", 15, 60, 15, 2, 2), + SetScoreCommand = new VotingCommand(true, "setscore, wynik, definirPontuacao, configurarPontos, 设置分数, 调整分数", "@jRandmosSkills/root", 15, 90, 15, 90, 2), + }; } + } + public class HtmlHudCustomisation + { + public required string HeaderLineColor { get; set; } + public required string HeaderLineSize { get; set; } + public required string SkillLineSize { get; set; } + public required string InfoLineColor { get; set; } + public required string InfoLineSize { get; set; } + public required string SkillDescriptionLineColor { get; set; } + public required string SkillDescriptionLineSize { get; set; } + public required string WSADMenuSelectInfoLineColor { get; set; } + public required string WSADMenuSelectInfoLineSize { get; set; } + public required string WSADMenuItemLineColor { get; set; } + public required string WSADMenuItemHoverLineColor { get; set; } + public required string WSADMenuItemLineSize { get; set; } + public required string WSADMenuControllsLineSize { get; set; } + public required string WSADMenuControllsLineColor1 { get; set; } + public required string WSADMenuControllsLineColor2 { get; set; } + public required string WSADMenuControllsLineColor3 { get; set; } + } + + public class LanguageSystem + { + public required string DefaultLangCode { get; set; } + public required bool DisableGeoLite { get; set; } + public required LanguageInfo[] LanguageInfos { get; set; } + } + + public class LanguageInfo(string isoCodes, string fileName) + { + public string IsoCodes { get; set; } = isoCodes; + public string FileName { get; set; } = fileName; } public class NormalCommand(string alias, string permissions) @@ -184,6 +198,18 @@ namespace jRandomSkills public string Permissions { get; set; } = permissions; } + public class NormalCommands + { + public required NormalCommand SetSkillCommand { get; set; } + public required NormalCommand SkillsListCommand { get; set; } + public required NormalCommand UseSkillCommand { get; set; } + public required NormalCommand HealCommand { get; set; } + public required NormalCommand ConsoleCommand { get; set; } + public required NormalCommand SetStaticSkillCommand { get; set; } + public required NormalCommand ChangeLanguageCommand { get; set; } + public required NormalCommand ReloadCommand { get; set; } + } + public class VotingCommand(bool enableVoting, string alias, string permissions, float timeToVote, float percentagesToSuccess, float timeToNextVoting, float timeToNextSameVoting, int minimumPlayersToStartVoting) : NormalCommand(alias, permissions) { public bool EnableVoting { get; set; } = enableVoting; @@ -194,13 +220,28 @@ namespace jRandomSkills public int MinimumPlayersToStartVoting { get; set; } = minimumPlayersToStartVoting; } - public class DefaultSkillInfo(Skills skill, bool active = true, string color = "#ffffff", CsTeam onlyTeam = CsTeam.None, bool needsTeammates = false) + public class StartGameCommand(bool enableVoting, string alias, string permissions, string startParams, string svStartParams, float timeToVote, float percentagesToSuccess, float timeToNextVoting, float timeToNextSameVoting, int minimumPlayersToStartVoting) { - public bool NeedsTeammates { get; set; } = needsTeammates; - public int OnlyTeam { get; set; } = (int)onlyTeam; - public string Color { get; set; } = color; - public bool Active { get; set; } = active; - public string Name { get; set; } = skill.ToString(); + public bool EnableVoting { get; set; } = enableVoting; + public string Alias { get; set; } = alias; + public string Permissions { get; set; } = permissions; + public string StartParams { get; set; } = startParams; + public string SVStartParams { get; set; } = svStartParams; + public float TimeToVote { get; set; } = timeToVote; + public float PercentagesToSuccess { get; set; } = percentagesToSuccess; + public float TimeToNextVoting { get; set; } = timeToNextVoting; + public float TimeToNextSameVoting { get; set; } = timeToNextSameVoting; + public int MinimumPlayersToStartVoting { get; set; } = minimumPlayersToStartVoting; + } + + public class VotingCommands + { + public required StartGameCommand StartGameCommand { get; set; } + public required VotingCommand ChangeMapCommand { get; set; } + public required VotingCommand SwapCommand { get; set; } + public required VotingCommand ShuffleCommand { get; set; } + public required VotingCommand PauseCommand { get; set; } + public required VotingCommand SetScoreCommand { get; set; } } public enum GameModes diff --git a/jRandomSkills - SRC Files/src/utils/Localization.cs b/jRandomSkills - SRC Files/src/utils/Localization.cs index 8d6d276..55e38d2 100644 --- a/jRandomSkills - SRC Files/src/utils/Localization.cs +++ b/jRandomSkills - SRC Files/src/utils/Localization.cs @@ -5,21 +5,20 @@ using jRandomSkills.src.player; using MaxMind.Db; using Newtonsoft.Json; using System.Net; +using System.Collections.Concurrent; +using System.Text.RegularExpressions; namespace jRandomSkills.src.utils { public static class Localization { private static readonly string languagesFolderPath = Path.Combine(jRandomSkills.Instance.ModuleDirectory, "languages"); - private static readonly Dictionary> _translations = []; + private static readonly ConcurrentDictionary> _translations = []; private static readonly string playersLanguageFileName = "playersLanguage.json"; private static readonly string configsFolderPath = Path.Combine(jRandomSkills.Instance.ModuleDirectory, "configs"); - private static Dictionary _playersLanguage = []; + private static ConcurrentDictionary _playersLanguage = []; private static readonly string geoliteFilePath = Path.Combine(jRandomSkills.Instance.ModuleDirectory, "packages", "GeoLite2-Country.mmdb"); - public static readonly string[] chinaIsoCodes = ["CN", "TW", "HK", "MO", "SG"]; - public static readonly string[] portugalIsoCodes = ["PT", "BR", "AO", "CV", "GW", "MZ", "ST", "TL"]; - public static readonly string[] frenchIsoCodes = ["FR", "MC", "HT"]; private static string defaultLangCode = "en"; @@ -34,7 +33,7 @@ namespace jRandomSkills.src.utils private static void SetLangCode() { - defaultLangCode = Config.LoadedConfig.Settings.LangCode; + defaultLangCode = Config.LoadedConfig.LanguageSystem.DefaultLangCode; } private static void LoadAllLanguages() @@ -51,29 +50,67 @@ namespace jRandomSkills.src.utils if (!File.Exists(langPath)) return; - var code = Path.GetFileNameWithoutExtension(langPath); + var code = Path.GetFileNameWithoutExtension(langPath).ToLower(); var jsonText = File.ReadAllText(langPath); - var translations = JsonConvert.DeserializeObject>(jsonText); + var translations = JsonConvert.DeserializeObject>(jsonText); if (translations != null) - _translations[code] = translations; + _translations.AddOrUpdate(code, translations, (k, v) => translations); } public static bool HasTranslation(string code) { - return _translations.ContainsKey(code); + return _translations.ContainsKey(code.ToLower()); } - public static string GetSkillName(this CCSPlayerController player, Skills skill) + public static string GetSkillName(this CCSPlayerController player, Skills skill, float? chance = null) { string langCode = GetLangCode(player); - return GetTranslation(skill.ToString().ToLower(), langCode); + if (chance == null) + { + var translation = GetTranslation(skill.ToString().ToLower(), langCode); + if (!translation.Contains("{0}")) + return translation; + + if (!translation.Contains(' ')) + return translation.Replace("{0}", "").Trim(); + + var parts = translation.Split(' ', StringSplitOptions.RemoveEmptyEntries); + var filtered = parts.Where(p => !p.Contains("{0}")); + return string.Join(' ', filtered); + } + + var value = Math.Round((double)(chance ?? 1), 2); + var skillNameText = GetTranslation(skill.ToString().ToLower(), langCode, value); + if (skillNameText.Contains('%')) skillNameText = skillNameText.Replace(value.ToString(), Math.Round(value * 100, 0).ToString()); + return skillNameText; } - public static string GetSkillDescription(this CCSPlayerController player, Skills skill) + public static string GetSkillDescription(this CCSPlayerController player, Skills skill, float? chance = null) { string langCode = GetLangCode(player); - return GetTranslation($"{skill.ToString().ToLower()}_desc", langCode); + if (chance == null) + { + var translation = GetTranslation($"{skill.ToString().ToLower()}_desc", langCode); + if (!translation.Contains("{0}")) + return translation; + + if (!translation.Contains(' ')) + return translation.Replace("{0}", "").Trim(); + + var parts = translation.Split(' ', StringSplitOptions.RemoveEmptyEntries); + var filtered = parts.Where(p => !p.Contains("{0}")); + return string.Join(' ', filtered); + } + + var skillName = $"{skill.ToString().ToLower()}_desc2"; + var value = Math.Round((double)(chance ?? 1), 2); + var desc2 = GetTranslation(skillName, langCode, value); + + var skilLDescription = desc2 == skillName + ? player.GetTranslation($"{skill.ToString().ToLower()}_desc") + : (desc2.Contains('%') ? desc2.Replace(value.ToString(), Math.Round(value * 100, 0).ToString()) : desc2); + return skilLDescription; } public static void PrintTranslationToChatAll(string message, string[]? key, params object[][]? args) @@ -112,9 +149,10 @@ namespace jRandomSkills.src.utils return translation; else { - string output = string.Format(translation, args).Replace("CHATCOLORS.RED", ChatColors.Red.ToString()); - if (Config.LoadedConfig.Settings.AlternativeSkillButton != null) - output = output.Replace("css_useSkill", $"css_useSkill/{Config.LoadedConfig.Settings.AlternativeSkillButton}"); + string output = args.Length == 0 ? translation : string.Format(translation, args); + output = output.Replace("CHATCOLORS.RED", ChatColors.Red.ToString()); + if (Config.LoadedConfig.AlternativeSkillButton != null) + output = output.Replace("css_useSkill", $"css_useSkill/{Config.LoadedConfig.AlternativeSkillButton}"); return output; } @@ -129,6 +167,9 @@ namespace jRandomSkills.src.utils if (!string.IsNullOrEmpty(fileLangCode)) return fileLangCode; + if (Config.LoadedConfig.LanguageSystem.DisableGeoLite == true) + return defaultLangCode; + string? geoliteLandCode = GetLangCodeFromDatabase(GetPlayerIP(player)) ?? defaultLangCode; ChangePlayerLanguage(player, geoliteLandCode); return geoliteLandCode; @@ -149,21 +190,18 @@ namespace jRandomSkills.src.utils if (!File.Exists(geoliteFilePath)) return null; using var reader = new Reader(geoliteFilePath); var ip = IPAddress.Parse(playerIP); - var data = reader.Find>(ip); - if (data == null || data.Count == 0) return null; + var data = reader.Find>(ip); + if (data == null || data.IsEmpty) return null; - if (data.TryGetValue("country", out var _country) && _country is Dictionary country) + if (data.TryGetValue("country", out var _country) && _country is ConcurrentDictionary country) if (country.TryGetValue("iso_code", out var _isoCode) && _isoCode is string isoCode) { - if (portugalIsoCodes.Contains(isoCode)) - isoCode = "pt-br"; - if (chinaIsoCodes.Contains(isoCode)) - isoCode = "zh"; - if (frenchIsoCodes.Contains(isoCode)) - isoCode = "fr"; - isoCode = isoCode.ToLower(); - if (_translations.ContainsKey(isoCode)) - return isoCode; + string fileName = Config.LoadedConfig.LanguageSystem.DefaultLangCode; + foreach (var langInfo in Config.LoadedConfig.LanguageSystem.LanguageInfos) + if (langInfo.IsoCodes.Contains(isoCode)) + fileName = langInfo.FileName; + if (_translations.ContainsKey(fileName)) + return fileName; } return null; } @@ -175,7 +213,7 @@ namespace jRandomSkills.src.utils return; var jsonText = File.ReadAllText(filePath); - _playersLanguage = JsonConvert.DeserializeObject>(jsonText) ?? []; + _playersLanguage = JsonConvert.DeserializeObject>(jsonText) ?? []; } private static void SavePlayersLanguage() @@ -198,7 +236,7 @@ namespace jRandomSkills.src.utils public static void ChangePlayerLanguage(CCSPlayerController? player, string language) { if (player == null || !player.IsValid) return; - _playersLanguage[player.SteamID] = language; + _playersLanguage.AddOrUpdate(player.SteamID, language, (k,v) => language); SavePlayersLanguage(); } } diff --git a/jRandomSkills - SRC Files/src/utils/SkillUtils.cs b/jRandomSkills - SRC Files/src/utils/SkillUtils.cs index 08bba31..6f7d2e4 100644 --- a/jRandomSkills - SRC Files/src/utils/SkillUtils.cs +++ b/jRandomSkills - SRC Files/src/utils/SkillUtils.cs @@ -11,17 +11,27 @@ using System.Runtime.InteropServices; using WASDMenuAPI.Classes; using WASDSharedAPI; using static CounterStrikeSharp.API.Core.Listeners; +using System.Collections.Concurrent; +using System; +using static System.Net.Mime.MediaTypeNames; +using System.Drawing; namespace jRandomSkills { public static class SkillUtils { + private static readonly MemoryFunctionWithReturn HEGrenadeProjectile_CreateFunc = new(GameData.GetSignature("HEGrenadeProjectile_CreateFunc")); private static readonly MemoryFunctionVoid TerminateRoundFunc = new(GameData.GetSignature("CCSGameRules_TerminateRound")); public static void PrintToChat(CCSPlayerController player, string msg, bool isError) { string checkIcon = isError ? $"{ChatColors.DarkRed}✖{ChatColors.LightRed}" : $"{ChatColors.Green}✔{ChatColors.Lime}"; - player.PrintToChat($" {ChatColors.DarkRed}► {ChatColors.Green}[{ChatColors.DarkRed} jRadnomSkills {ChatColors.Green}] {checkIcon} {msg}"); + player.PrintToChat($" {ChatColors.DarkRed}► {ChatColors.Green}[{ChatColors.DarkRed} {jRandomSkills.Tag} {ChatColors.Green}] {checkIcon} {msg}"); + } + + public static bool IsFreezeTime() + { + return jRandomSkills.Instance?.GameRules?.FreezePeriod == true; } public static void RegisterSkill(Skills skill, string color, bool display = true) @@ -76,10 +86,14 @@ namespace jRandomSkills var playerPawn = player.PlayerPawn.Value; if (playerPawn == null || !playerPawn.IsValid || playerPawn.CBodyComponent == null || playerPawn.CBodyComponent.SceneNode == null) return; - playerPawn.CBodyComponent.SceneNode.Scale = scale; playerPawn.CBodyComponent.SceneNode.GetSkeletonInstance().Scale = scale; - playerPawn.AcceptInput("SetScale", null, null, scale.ToString()); - Server.NextFrame(() => Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_CBodyComponent")); + Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_CBodyComponent"); + Server.NextFrame(() => playerPawn.AcceptInput("SetScale", playerPawn, playerPawn, scale.ToString())); + } + + public static void CreateHEGrenadeProjectile(Vector pos, QAngle angle, Vector vel, int teamNum) + { + HEGrenadeProjectile_CreateFunc.Invoke(pos.Handle, angle.Handle, vel.Handle, vel.Handle, IntPtr.Zero, 44, teamNum); } public static void TakeHealth(CCSPlayerPawn? pawn, int damage) @@ -98,6 +112,13 @@ namespace jRandomSkills }); } + public static void ResetPrintHTML(CCSPlayerController? player) + { + var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); + if (playerInfo == null) return; + playerInfo.PrintHTML = null; + } + public static void AddHealth(CCSPlayerPawn? pawn, int extraHealth, int maxHealth = 100) { if (pawn == null || !pawn.IsValid || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE) @@ -159,7 +180,7 @@ namespace jRandomSkills return manager.HasMenu(player); } - public static void UpdateMenu(CCSPlayerController? player, HashSet<(string, string)> items) + public static void UpdateMenu(CCSPlayerController? player, ConcurrentBag<(string, string)> items) { if (player == null) return; @@ -171,7 +192,7 @@ namespace jRandomSkills Dictionary> list = []; foreach (var item in items) - list.Add(item.Item1, (p, option) => + list.TryAdd(item.Item1, (p, option) => { jRandomSkills.Instance.SkillAction(playerInfo.Skill.ToString(), "TypeSkill", [p, new[] { item.Item2 }]); manager.CloseMenu(p); @@ -180,7 +201,7 @@ namespace jRandomSkills manager.UpdateActiveMenu(player, list); } - public static void CreateMenu(CCSPlayerController? player, HashSet<(string, string)> enemies) + public static void CreateMenu(CCSPlayerController? player, ConcurrentBag<(string, string)> enemies, (string, string)? lastElement = null) { if (player == null || !player.IsValid) return; @@ -190,20 +211,47 @@ namespace jRandomSkills var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == playerInfo.Skill); if (skillData == null) return; - string infoLine = $"{player.GetTranslation("your_skill")}:
"; - string skillLine = $"{player.GetSkillName(skillData.Skill)}
" - + $"{player.GetTranslation($"{playerInfo.Skill.ToString().ToLower()}_select_info")}"; - var manager = GetMenuManager(); if (manager == null) return; - IWasdMenu menu = manager.CreateMenu(infoLine + skillLine, "W/S - Scroll | E - Select
"); + var config = Config.LoadedConfig.HtmlHudCustomisation; + var your_skill = player.GetTranslation("your_skill"); + var emptySymbol = $" "; + + string infoLine = string.IsNullOrEmpty(your_skill) + ? "" + : $"{your_skill}:
"; + + string skillLine = $"{player.GetSkillName(skillData.Skill)}
"; + + var skill_select_info = player.GetTranslation($"{playerInfo.Skill.ToString().ToLower()}_select_info"); + string remainingLine = string.IsNullOrWhiteSpace(skill_select_info) + ? "" + : $"{skill_select_info}
"; + + var hudContent = infoLine + skillLine + remainingLine; + + string controllsLine = + $"{emptySymbol}{player.GetTranslation($"menu_controlls_scroll")}" + + $"{player.GetTranslation($"menu_controlls_padding")}" + + $"{player.GetTranslation($"menu_controlls_select")}{emptySymbol}"; + + string itemText = $"{{0}}
"; + string itemHoverText = $"[ {{0}} ]
"; + + IWasdMenu menu = manager.CreateMenu(hudContent, itemText, itemHoverText, controllsLine); foreach (var enemy in enemies) menu.Add(enemy.Item1, (p, option) => { jRandomSkills.Instance.SkillAction(playerInfo.Skill.ToString(), "TypeSkill", [p, new[] { enemy.Item2 }]); manager.CloseMenu(p); }); + if (lastElement != null) + menu.Add(lastElement.Value.Item1, (p, option) => + { + jRandomSkills.Instance.SkillAction(playerInfo.Skill.ToString(), "TypeSkill", [p, new[] { lastElement.Value.Item2 }]); + manager.CloseMenu(p); + }); manager.OpenMainMenu(player, menu); } diff --git a/jRandomSkills - SRC Files/src/utils/SkillsInfo.cs b/jRandomSkills - SRC Files/src/utils/SkillsInfo.cs new file mode 100644 index 0000000..d803fbb --- /dev/null +++ b/jRandomSkills - SRC Files/src/utils/SkillsInfo.cs @@ -0,0 +1,139 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System.Reflection; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public static class SkillsInfo + { + private static readonly string configsFolder = Path.Combine(Instance.ModuleDirectory, "configs"); + private static readonly string configPath = Path.Combine(configsFolder, "skillsInfo.json"); + private static readonly object fileLock = new(); + + private static SkillsInfoModel config = LoadSkillsInfo(); + public static SkillsInfoModel LoadedConfig => config; + + public static SkillsInfoModel LoadSkillsInfo() + { + lock (fileLock) + { + var newConfig = new SkillsInfoModel(); + + if (!File.Exists(configPath)) + { + Instance.Logger.LogInformation("Config file does not exist. Create a new skills info file..."); + SaveConfig(newConfig); + return config = newConfig; + } + + try + { + string json; + using (var fs = new FileStream(configPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + using (var sr = new StreamReader(fs)) + json = sr.ReadToEnd(); + + var root = JsonConvert.DeserializeObject(json); + if (root != null) + foreach (var skillObj in root) + { + var name = skillObj["Name"]?.ToString(); + if (string.IsNullOrEmpty(name)) continue; + + var instance = newConfig.FirstOrDefault(x => x.Name == name.ToString()); + if (instance != null) JsonConvert.PopulateObject(skillObj.ToString(), instance); + } + } + catch + { + Instance.Logger.LogError("Error when loading the skills info file."); + } + + return config = newConfig; + } + } + + public static void SaveConfig(SkillsInfoModel config) + { + lock (fileLock) + { + try + { + Directory.CreateDirectory(configsFolder); + string json = JsonConvert.SerializeObject(config, Formatting.Indented); + + string tempPath = $"{configPath}.temp"; + File.WriteAllText(tempPath, json); + + File.Copy(tempPath, configPath, overwrite: true); + File.Delete(tempPath); + } + catch + { + Instance.Logger.LogError("Error when saving the skills info file."); + } + } + } + + public static T GetValue(object skill, string key) + { + if (config == null) return default!; + + var skillConfig = LoadedConfig.FirstOrDefault(s => s.Name == skill.ToString()); + if (skillConfig == null) return default!; + + var prop = skillConfig.GetType().GetProperty(key, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); + if (prop != null) + { + var value = prop.GetValue(skillConfig); + if (value == null) return default!; + else return (T)Convert.ChangeType(value, typeof(T)); + } + + var field = skillConfig.GetType().GetField(key, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); + if (field != null) + { + var value = field.GetValue(skillConfig); + if (value == null) return default!; + else return (T)Convert.ChangeType(value, typeof(T)); + } + + return default!; + } + + public class SkillsInfoModel : List + { + public SkillsInfoModel() + { + AddRange( + Assembly.GetExecutingAssembly().GetTypes() + .Where(t => typeof(DefaultSkillInfo).IsAssignableFrom(t) && t.Name == "SkillConfig") + .Select(t => + { + var ctor = t.GetConstructors().FirstOrDefault(c => c.GetParameters().All(p => p.IsOptional)); + if (ctor == null) return null; + var args = ctor.GetParameters().Select(p => Type.Missing).ToArray(); + return ctor.Invoke(args) as DefaultSkillInfo; + }) + .Where(instance => instance != null) + .Cast() + ); + } + } + + public class DefaultSkillInfo(Skills skill, bool active = true, string color = "#ffffff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false) + { + public bool NeedsTeammates { get; set; } = needsTeammates; + public bool DisableOnFreezeTime { get; set; } = disableOnFreezeTime; + public int OnlyTeam { get; set; } = (int)onlyTeam; + public string Color { get; set; } = color; + public bool Active { get; set; } = active; + public string Name { get; set; } = skill.ToString(); + } + } +} \ No newline at end of file diff --git a/jRandomSkills - Server Files/gamedata/jRandomSkills.gamedata.json b/jRandomSkills - Server Files/gamedata/jRandomSkills.gamedata.json new file mode 100644 index 0000000..d5325b2 --- /dev/null +++ b/jRandomSkills - Server Files/gamedata/jRandomSkills.gamedata.json @@ -0,0 +1,16 @@ +{ + "HEGrenadeProjectile_CreateFunc": { + "signatures": { + "library": "server", + "windows": "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 40 48 8B 6C 24", + "linux": "55 4C 89 C1 48 89 E5 41 57 49 89 FF 41 56 49 89" + } + }, + "Shoot_Secondary": { + "signatures": { + "library": "server", + "windows": "48 89 5C 24 ? 57 48 83 EC 20 44 0F BF C2", + "linux": "55 48 89 E5 41 54 53 48 89 FB 66 83 FE 65" + } + } +} \ No newline at end of file diff --git a/jRandomSkills - Server Files/plugins/!jRandomSkills/!jRandomSkills.dll b/jRandomSkills - Server Files/plugins/!jRandomSkills/!jRandomSkills.dll index 0b4edf6..d58ab4f 100644 Binary files a/jRandomSkills - Server Files/plugins/!jRandomSkills/!jRandomSkills.dll and b/jRandomSkills - Server Files/plugins/!jRandomSkills/!jRandomSkills.dll differ diff --git a/jRandomSkills - Server Files/plugins/!jRandomSkills/WASDMenuAPI.dll b/jRandomSkills - Server Files/plugins/!jRandomSkills/WASDMenuAPI.dll index cd9a908..e18b762 100644 Binary files a/jRandomSkills - Server Files/plugins/!jRandomSkills/WASDMenuAPI.dll and b/jRandomSkills - Server Files/plugins/!jRandomSkills/WASDMenuAPI.dll differ diff --git a/jRandomSkills - Server Files/plugins/!jRandomSkills/configs/config.json b/jRandomSkills - Server Files/plugins/!jRandomSkills/configs/config.json index 13349a6..bc28c42 100644 --- a/jRandomSkills - Server Files/plugins/!jRandomSkills/configs/config.json +++ b/jRandomSkills - Server Files/plugins/!jRandomSkills/configs/config.json @@ -1,60 +1,108 @@ { - "Settings": { - "LangCode": "en", - "GameMode": 3, - "KillerSkillInfo": true, - "TeamMateSkillInfo": true, - "SummaryAfterTheRound": true, - "DebugMode": true, - "AlternativeSkillButton": null, - "SkillTimeBeforeStart": 7.0, - "SkillDescriptionDuration": 7.0, - "DisableSpectateHUD": false, - "FlashingHtmlHudFix": true, - "CS2TraceRayDebug": false, - "SetSkillCommands": { + "GameMode": 3, + "KillerSkillInfo": true, + "TeamMateSkillInfo": true, + "SummaryAfterTheRound": true, + "DebugMode": true, + "AlternativeSkillButton": null, + "SkillTimeBeforeStart": 7.0, + "SkillDescriptionDuration": 7.0, + "DisplayAlwaysDescription": false, + "DisableSpectateHUD": false, + "FlashingHtmlHudFix": true, + "CS2TraceRayDebug": false, + "LanguageSystem": { + "DefaultLangCode": "en", + "DisableGeoLite": false, + "LanguageInfos": [ + { + "IsoCodes": "CN, TW, HK, MO, SG", + "FileName": "pt-br" + }, + { + "IsoCodes": "PT, BR, AO, CV, GW, MZ, ST, TL", + "FileName": "zh" + }, + { + "IsoCodes": "FR, MC, HT", + "FileName": "fr" + }, + { + "IsoCodes": "PL", + "FileName": "pl" + }, + { + "IsoCodes": "GB, US", + "FileName": "en" + } + ] + }, + "HtmlHudCustomisation": { + "HeaderLineColor": "#FFFFFF", + "HeaderLineSize": "ml", + "SkillLineSize": "l", + "InfoLineColor": "#FFFFFF", + "InfoLineSize": "sm", + "SkillDescriptionLineColor": "#999999", + "SkillDescriptionLineSize": "sm", + "WSADMenuSelectInfoLineColor": "#999999", + "WSADMenuSelectInfoLineSize": "sm", + "WSADMenuItemLineColor": "white", + "WSADMenuItemHoverLineColor": "orange", + "WSADMenuItemLineSize": "sm", + "WSADMenuControllsLineSize": "sm", + "WSADMenuControllsLineColor1": "cyan", + "WSADMenuControllsLineColor2": "white", + "WSADMenuControllsLineColor3": "green" + }, + "NormalCommands": { + "SetSkillCommand": { "Alias": "ustawskill, ustaw_skill, setskill, set_skill, definirhabilidade, configurarhabilidade, 设置技能, 配置技能", "Permissions": "@jRandmosSkills/admin" }, - "SkillsListCommands": { + "SkillsListCommand": { "Alias": "supermoc, skille, listamocy, supermoce, skills, listaHabilidades, habilidades, 技能列表, 超能力列表", "Permissions": "@jRandmosSkills/admin" }, - "UseSkillCommands": { + "UseSkillCommand": { "Alias": "t, useSkill, usarHabilidade, 技能使用, 使用技能", "Permissions": "@jRandmosSkills/admin" }, - "HealCommands": { + "HealCommand": { "Alias": "heal, ulecz, curar, tratar, 治疗, 治愈", "Permissions": "@jRandmosSkills/admin" }, - "ConsoleCommands": { + "ConsoleCommand": { "Alias": "console, sv, 控制台, 服务器", "Permissions": "@jRandmosSkills/root" }, - "SetStaticSkillCommands": { + "SetStaticSkillCommand": { "Alias": "ustawstatycznyskill, ustaw_statyczny_skill, setstaticskill, set_static_skill", "Permissions": "@jRandmosSkills/admin" }, - "ChangeLanguageCommands": { + "ChangeLanguageCommand": { "Alias": "lang, language, changelang, change_lang, jezyk, język", "Permissions": "" }, - "ReloadCommands": { + "ReloadCommand": { "Alias": "reload, refresh", "Permissions": "@jRandmosSkills/admin" - }, - "StartGameCommands": { + } + }, + "VotingCommands": { + "StartGameCommand": { "EnableVoting": true, + "Alias": "start, go, começar, iniciar, 开始, 启动", + "Permissions": "@jRandmosSkills/admin", + "StartParams": "mp_freezetime 15; mp_forcecamera 0; mp_overtime_enable 1; sv_cheats 0", + "SVStartParams": "mp_freezetime 0; mp_forcecamera 0; mp_overtime_enable 1; sv_cheats 1", "TimeToVote": 15.0, "PercentagesToSuccess": 60.0, "TimeToNextVoting": 15.0, "TimeToNextSameVoting": 500.0, - "MinimumPlayersToStartVoting": 2, - "Alias": "start, go, começar, iniciar, 开始, 启动", - "Permissions": "@jRandmosSkills/admin" + "MinimumPlayersToStartVoting": 2 }, - "ChangeMapCommands": { + "ChangeMapCommand": { "EnableVoting": true, "TimeToVote": 25.0, "PercentagesToSuccess": 90.0, @@ -64,7 +112,7 @@ "Alias": "map, mapa, changemap, zmienmape, zmienmape, mudarMapa, trocarMapa, 更换地图, 更改地图", "Permissions": "@jRandmosSkills/admin" }, - "SwapCommands": { + "SwapCommand": { "EnableVoting": true, "TimeToVote": 15.0, "PercentagesToSuccess": 90.0, @@ -74,7 +122,7 @@ "Alias": "swap, zmiana, trocar, 交换, 切换", "Permissions": "@jRandmosSkills/admin" }, - "ShuffleCommands": { + "ShuffleCommand": { "EnableVoting": true, "TimeToVote": 15.0, "PercentagesToSuccess": 90.0, @@ -84,7 +132,7 @@ "Alias": "shuffle, embaralhar, 随机排序, 洗牌", "Permissions": "@jRandmosSkills/admin" }, - "PauseCommands": { + "PauseCommand": { "EnableVoting": true, "TimeToVote": 15.0, "PercentagesToSuccess": 60.0, @@ -94,7 +142,7 @@ "Alias": "pause, unpause, pausar, despausar, 暂停, 恢复", "Permissions": "@jRandmosSkills/admin" }, - "SetScoreCommands": { + "SetScoreCommand": { "EnableVoting": true, "TimeToVote": 15.0, "PercentagesToSuccess": 90.0, @@ -104,904 +152,5 @@ "Alias": "setscore, wynik, definirPontuacao, configurarPontos, 设置分数, 调整分数", "Permissions": "@jRandmosSkills/root" } - }, - "SkillsInfo": [ - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#ff0000", - "Active": true, - "Name": "Aimbot" - }, - { - "SecondsInBack": 5, - "Cooldown": 15.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#a86eff", - "Active": true, - "Name": "Anomaly" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#D6E6FF", - "Active": true, - "Name": "AntyFlash" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#8B4513", - "Active": true, - "Name": "AntyHead" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 3, - "Color": "#edf5b5", - "Active": true, - "Name": "AreaReaper" - }, - { - "ChanceFrom": 0.65, - "ChanceTo": 0.85, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#d1430a", - "Active": true, - "Name": "Armored" - }, - { - "DamageMultiplier": 2.0, - "ToleranceDeg": 45.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#d9d9d9", - "Active": true, - "Name": "Assassin" - }, - { - "ChanceFrom": 0.1, - "ChanceTo": 0.7, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#7E10AD", - "Active": true, - "Name": "Astronaut" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#abab33", - "Active": true, - "Name": "Bankrupt" - }, - { - "SpeedMultipier": 2.0, - "MaxSpeed": 900.0, - "DamageDeal": 9999.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#2effc7", - "Active": true, - "Name": "Baseball" - }, - { - "ChanceFrom": 0.2, - "ChanceTo": 0.4, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#00FF00", - "Active": true, - "Name": "Behind" - }, - { - "TorseReflectionChance": 0.95, - "LegReflectionChance": 0.8, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#cc7504", - "Active": true, - "Name": "BladeMaster" - }, - { - "MaxSpeed": 500.0, - "JumpVelocity": 300.0, - "JumpBoost": 2.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#d1430a", - "Active": true, - "Name": "BunnyHop" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 2, - "Color": "#00911f", - "Active": true, - "Name": "C4Camouflage" - }, - { - "ChanceFrom": 0.2, - "ChanceTo": 0.4, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#FF4500", - "Active": true, - "Name": "Catapult" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#FF8B42", - "Active": true, - "Name": "Chicken" - }, - { - "BombArmedTime": 10.0, - "NeedsTeammates": false, - "OnlyTeam": 3, - "Color": "#343deb", - "Active": true, - "Name": "ChillOut" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#88a31a", - "Active": true, - "Name": "Cutter" - }, - { - "Brightness": 0.01, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#383838", - "Active": true, - "Name": "Darkness" - }, - { - "JumpVelocity": 150.0, - "PushVelocity": 600.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#42bbfc", - "Active": true, - "Name": "Dash" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#919191", - "Active": true, - "Name": "Deactivator" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#dae01f", - "Active": true, - "Name": "Deaf" - }, - { - "ChanceFrom": 0.2, - "ChanceTo": 0.5, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#FF4500", - "Active": true, - "Name": "Disarmament" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#00f2ff", - "Active": true, - "Name": "Distancer" - }, - { - "HealthRegainScale": 0.3, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#FA050D", - "Active": true, - "Name": "Dracula" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#ffb73b", - "Active": true, - "Name": "Duplicator" - }, - { - "MinScale": 0.6, - "MaxScale": 0.95, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#ffff00", - "Active": true, - "Name": "Dwarf" - }, - { - "Cooldown": 16.0, - "Amplitude": 15.0, - "Frequency": 500.0, - "Duration": 8.0, - "Radius": 50.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#42f59b", - "Active": false, - "Name": "Earthquake" - }, - { - "Cooldown": 15.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#ff8c92", - "Active": true, - "Name": "EnemySpawn" - }, - { - "Damage": 25.0, - "DamageRadius": 210.0, - "ChanceFrom": 0.15, - "ChanceTo": 0.3, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#9c0000", - "Active": true, - "Name": "ExplosiveShot" - }, - { - "Distance": 1000.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#d1f542", - "Active": true, - "Name": "FalconEye" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#ffc061", - "Active": true, - "Name": "FastReload" - }, - { - "ChanceFrom": 1.2, - "ChanceTo": 3.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#A31912", - "Active": true, - "Name": "Flash" - }, - { - "Cooldown": 2.0, - "BarricadeHealth": 115, - "PropModel": "models/props/de_aztec/hr_aztec/aztec_scaffolding/aztec_scaffold_wall_support_128.vmdl", - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#1b04cc", - "Active": true, - "Name": "Fortnite" - }, - { - "MaxBombHealth": 1000, - "NeedsTeammates": false, - "OnlyTeam": 3, - "Color": "#5d00ff", - "Active": true, - "Name": "FragileBomb" - }, - { - "HealthMultiplier": 1.5, - "NeedsTeammates": true, - "OnlyTeam": 0, - "Color": "#ff0000", - "Active": true, - "Name": "FriendlyFire" - }, - { - "TriggerRadius": 180.0, - "SlownessMultiplier": 5, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#00eaff", - "Active": true, - "Name": "FrozenDecoy" - }, - { - "RefreshPrice": 150, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#7eff47", - "Active": true, - "Name": "Gambler" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#FFFFFF", - "Active": true, - "Name": "Ghost" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#5d00ff", - "Active": true, - "Name": "Glaz" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#f542ef", - "Active": true, - "Name": "Glitch" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#fff52e", - "Active": true, - "Name": "Glue" - }, - { - "Cooldown": 30.0, - "Duration": 2.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#e0d83a", - "Active": true, - "Name": "GodMode" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#4a6e21", - "Active": true, - "Name": "Grenadier" - }, - { - "SmokeHeal": 1, - "SmokeRadius": 180.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#1fe070", - "Active": true, - "Name": "HealingSmoke" - }, - { - "HealthToAdd": 25, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#ded678", - "Active": true, - "Name": "Hermit" - }, - { - "DamageMultiplier": 2.0, - "DamageRadiusMultiplier": 2.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#ffdd00", - "Active": true, - "Name": "HolyHandGrenade" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#99140B", - "Active": true, - "Name": "Impostor" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#0000FF", - "Active": true, - "Name": "InfiniteAmmo" - }, - { - "MaxStepBeam": 100, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#f542ef", - "Active": true, - "Name": "Jackal" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#42f5a7", - "Active": true, - "Name": "Jammer" - }, - { - "MinTime": 10.0, - "MaxTime": 25.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#8f108f", - "Active": true, - "Name": "Jester" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#b01e5d", - "Active": true, - "Name": "JumpBan" - }, - { - "HealthToAdd": 3, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#a86eff", - "Active": true, - "Name": "JumpingJack" - }, - { - "FlashDuration": 1.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#57bcff", - "Active": true, - "Name": "KillerFlash" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#a3651a", - "Active": true, - "Name": "LifeSwap" - }, - { - "MaxDistance": 4096.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#c9f8ff", - "Active": true, - "Name": "LongKnife" - }, - { - "MaxDistance": 4096.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#6effc7", - "Active": true, - "Name": "LongZeus" - }, - { - "CustomFOV": 50, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#9ba882", - "Active": true, - "Name": "Magnifier" - }, - { - "HealthToAdd": 50, - "HealthShotLimit": 3, - "Cooldown": 1.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#10c212", - "Active": true, - "Name": "Medic" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#52f54c", - "Active": true, - "Name": "MoneySwap" - }, - { - "ExplosionRadius": 500.0, - "ExplosionDamage": 999, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#F5CB42", - "Active": true, - "Name": "Muhammed" - }, - { - "IdlePercentInvisibility": 0.3, - "DuckPercentInvisibility": 0.3, - "KnifePercentInvisibility": 0.3, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#dedede", - "Active": true, - "Name": "Ninja" - }, - { - "Cooldown": 30.0, - "Duration": 2.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#44ebd4", - "Active": true, - "Name": "Noclip" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#a38c1a", - "Active": true, - "Name": "NoNades" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#FFFFFF", - "Active": true, - "Name": "None" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#8a42f5", - "Active": true, - "Name": "NoRecoil" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#ff5CD9", - "Active": true, - "Name": "OneShot" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#3c47de", - "Active": true, - "Name": "OnlyHead" - }, - { - "ExtraJumpsMin": 1, - "ExtraJumpsMax": 4, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#FFA500", - "Active": true, - "Name": "PawelJumper" - }, - { - "ChanceFrom": 0.2, - "ChanceTo": 0.4, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#ff5C0A", - "Active": true, - "Name": "Phoenix" - }, - { - "MaximumFuel": 150.0, - "FuelConsumption": 0.64, - "Refuelling": 0.1, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#1466F5", - "Active": true, - "Name": "Pilot" - }, - { - "ExtraC4BlowTime": 60, - "NeedsTeammates": false, - "OnlyTeam": 2, - "Color": "#7d7d7d", - "Active": true, - "Name": "Planter" - }, - { - "Damage": 1, - "Cooldown": 1.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#902eff", - "Active": true, - "Name": "Poison" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#ffc061", - "Active": true, - "Name": "PrimaryBan" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#9c9c9c", - "Active": true, - "Name": "Prosthesis" - }, - { - "MaxDefusingRange": 80.0, - "DefusingTime": 10.0, - "NeedsTeammates": false, - "OnlyTeam": 3, - "Color": "#507529", - "Active": true, - "Name": "PsychicDefusing" - }, - { - "ChanceFrom": 1.0, - "ChanceTo": 1.0, - "JumpVelocity": 300.0, - "PushVelocity": 400.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#1e9ab0", - "Active": true, - "Name": "Push" - }, - { - "RegenerationMultiplier": 1.5, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#3c47de", - "Active": true, - "Name": "Pyro" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#8a42f5", - "Active": true, - "Name": "QuickShot" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#2effcb", - "Active": true, - "Name": "RadarHack" - }, - { - "MinExtraHealth": 50, - "MaxExtraHealth": 501, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#009905", - "Active": true, - "Name": "Rambo" - }, - { - "Cooldown": 15.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#e0873a", - "Active": true, - "Name": "RandomWeapon" - }, - { - "Cooldown": 15.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#3cded3", - "Active": true, - "Name": "ReactiveArmor" - }, - { - "HealthToAdd": 1, - "Cooldown": 0.25, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#ff462e", - "Active": true, - "Name": "Regeneration" - }, - { - "Cooldown": 15.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#a3000b", - "Active": true, - "Name": "Replicator" - }, - { - "Cooldown": 15.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#a86eff", - "Active": true, - "Name": "Retreat" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#a68132", - "Active": true, - "Name": "ReturnToSender" - }, - { - "ZombieHealth": 200, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#ff5C0A", - "Active": true, - "Name": "ReZombie" - }, - { - "MinMoney": 5000, - "MaxMoney": 15000, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#D4AF37", - "Active": true, - "Name": "RichBoy" - }, - { - "MoneyMultiplier": 35, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#119125", - "Active": true, - "Name": "RobinHood" - }, - { - "SlownessTime": 2.0, - "SlownessModifier": 0.2, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#8B4513", - "Active": true, - "Name": "Rubber" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#8A2BE2", - "Active": true, - "Name": "Saper" - }, - { - "StartHealth": 50, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#d41c1c", - "Active": true, - "Name": "SecondLife" - }, - { - "TeleportDistance": 100.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#4d4d4d", - "Active": true, - "Name": "Shade" - }, - { - "DetonationTime": 20, - "NeedsTeammates": false, - "OnlyTeam": 2, - "Color": "#f5b74c", - "Active": true, - "Name": "ShortBomb" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#333333", - "Active": true, - "Name": "Silent" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#e0873a", - "Active": true, - "Name": "SniperElite" - }, - { - "ChanceFrom": 1.15, - "ChanceTo": 1.35, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#09ba00", - "Active": true, - "Name": "Soldier" - }, - { - "Cooldown": 5.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#e3ed8c", - "Active": true, - "Name": "SoundMaker" - }, - { - "Distance": 100.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#42f5da", - "Active": true, - "Name": "Spectator" - }, - { - "Cooldown": 30.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#1466F5", - "Active": true, - "Name": "SwapPosition" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#8A2BE2", - "Active": true, - "Name": "Teleporter" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#adaec7", - "Active": true, - "Name": "Thief" - }, - { - "Distance": 100.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#1b04cc", - "Active": true, - "Name": "ThirdEye" - }, - { - "HealthTakenScale": 0.3, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#962631", - "Active": true, - "Name": "Thorns" - }, - { - "SmokeDamage": 2, - "SmokeRadius": 180.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#507529", - "Active": true, - "Name": "ToxicSmoke" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#5d00ff", - "Active": true, - "Name": "Wallhack" - }, - { - "ChangeRoundTime": 10, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#ff462e", - "Active": true, - "Name": "Watchmaker" - }, - { - "Cooldown": 30.0, - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#c7e03a", - "Active": true, - "Name": "WeaponsSwap" - }, - { - "NeedsTeammates": false, - "OnlyTeam": 0, - "Color": "#fbff00", - "Active": true, - "Name": "Zeus" - } - ] + } } \ No newline at end of file diff --git a/jRandomSkills - Server Files/plugins/!jRandomSkills/configs/skillsInfo.json b/jRandomSkills - Server Files/plugins/!jRandomSkills/configs/skillsInfo.json new file mode 100644 index 0000000..1b2a293 --- /dev/null +++ b/jRandomSkills - Server Files/plugins/!jRandomSkills/configs/skillsInfo.json @@ -0,0 +1,1014 @@ +[ + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#ff0000", + "Active": true, + "Name": "Aimbot" + }, + { + "SecondsInBack": 5, + "Cooldown": 15.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": true, + "OnlyTeam": 0, + "Color": "#a86eff", + "Active": true, + "Name": "Anomaly" + }, + { + "FlashDuration": 7.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#D6E6FF", + "Active": true, + "Name": "AntyFlash" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#8B4513", + "Active": true, + "Name": "AntyHead" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 3, + "Color": "#edf5b5", + "Active": true, + "Name": "AreaReaper" + }, + { + "ChanceFrom": 0.65, + "ChanceTo": 0.85, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#d1430a", + "Active": true, + "Name": "Armored" + }, + { + "DamageMultiplier": 2.0, + "ToleranceDeg": 45.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#d9d9d9", + "Active": true, + "Name": "Assassin" + }, + { + "ChanceFrom": 0.1, + "ChanceTo": 0.7, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#7E10AD", + "Active": true, + "Name": "Astronaut" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#abab33", + "Active": true, + "Name": "Bankrupt" + }, + { + "SpeedMultipier": 2.0, + "MaxSpeed": 900.0, + "DamageDeal": 9999.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#2effc7", + "Active": true, + "Name": "Baseball" + }, + { + "ChanceFrom": 0.2, + "ChanceTo": 0.4, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#00FF00", + "Active": true, + "Name": "Behind" + }, + { + "TorseReflectionChance": 0.95, + "LegReflectionChance": 0.8, + "VelocityModifier": 0.85, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#cc7504", + "Active": true, + "Name": "BladeMaster" + }, + { + "MaxSpeed": 500.0, + "JumpVelocity": 300.0, + "JumpBoost": 2.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#d1430a", + "Active": true, + "Name": "BunnyHop" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 2, + "Color": "#00911f", + "Active": true, + "Name": "C4Camouflage" + }, + { + "ChanceFrom": 0.2, + "ChanceTo": 0.4, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#FF4500", + "Active": true, + "Name": "Catapult" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#FF8B42", + "Active": true, + "Name": "Chicken" + }, + { + "BombArmedTime": 10.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 3, + "Color": "#343deb", + "Active": true, + "Name": "ChillOut" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#88a31a", + "Active": true, + "Name": "Cutter" + }, + { + "Brightness": 0.01, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#383838", + "Active": true, + "Name": "Darkness" + }, + { + "JumpVelocity": 150.0, + "PushVelocity": 600.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#42bbfc", + "Active": true, + "Name": "Dash" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#919191", + "Active": true, + "Name": "Deactivator" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#dae01f", + "Active": true, + "Name": "Deaf" + }, + { + "ChanceFrom": 0.2, + "ChanceTo": 0.35, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#FF4500", + "Active": true, + "Name": "Disarmament" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#00f2ff", + "Active": true, + "Name": "Distancer" + }, + { + "HealthRegainScale": 0.3, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#FA050D", + "Active": true, + "Name": "Dracula" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#ffb73b", + "Active": true, + "Name": "Duplicator" + }, + { + "MinScale": 0.6, + "MaxScale": 0.95, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#ffff00", + "Active": true, + "Name": "Dwarf" + }, + { + "Cooldown": 16.0, + "Amplitude": 15.0, + "Frequency": 500.0, + "Duration": 8.0, + "Radius": 50.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#42f59b", + "Active": false, + "Name": "Earthquake" + }, + { + "Cooldown": 15.0, + "CooldownBeforeUse": 10.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": true, + "OnlyTeam": 0, + "Color": "#ff8c92", + "Active": true, + "Name": "EnemySpawn" + }, + { + "Damage": 25.0, + "DamageRadius": 210.0, + "ChanceFrom": 0.15, + "ChanceTo": 0.3, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#9c0000", + "Active": true, + "Name": "ExplosiveShot" + }, + { + "Distance": 1000.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#d1f542", + "Active": true, + "Name": "FalconEye" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#ffc061", + "Active": true, + "Name": "FastReload" + }, + { + "ChanceFrom": 1.2, + "ChanceTo": 3.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#A31912", + "Active": true, + "Name": "Flash" + }, + { + "Cooldown": 2.0, + "BarricadeHealth": 115, + "PropModel": "models/props/de_aztec/hr_aztec/aztec_scaffolding/aztec_scaffold_wall_support_128.vmdl", + "NeedsTeammates": false, + "DisableOnFreezeTime": true, + "OnlyTeam": 0, + "Color": "#1b04cc", + "Active": true, + "Name": "Fortnite" + }, + { + "MaxBombHealth": 1000, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 3, + "Color": "#5d00ff", + "Active": true, + "Name": "FragileBomb" + }, + { + "HealthMultiplier": 1.5, + "NeedsTeammates": true, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#ff0000", + "Active": true, + "Name": "FriendlyFire" + }, + { + "TriggerRadius": 180.0, + "SlownessMultiplier": 5, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#00eaff", + "Active": true, + "Name": "FrozenDecoy" + }, + { + "RefreshPrice": 150, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#7eff47", + "Active": true, + "Name": "Gambler" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#FFFFFF", + "Active": true, + "Name": "Ghost" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#5d00ff", + "Active": true, + "Name": "Glaz" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#f542ef", + "Active": true, + "Name": "Glitch" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#fff52e", + "Active": true, + "Name": "Glue" + }, + { + "Cooldown": 30.0, + "Duration": 2.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": true, + "OnlyTeam": 0, + "Color": "#e0d83a", + "Active": true, + "Name": "GodMode" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#4a6e21", + "Active": true, + "Name": "Grenadier" + }, + { + "SmokeHeal": 1, + "SmokeRadius": 180.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#1fe070", + "Active": true, + "Name": "HealingSmoke" + }, + { + "HealthToAdd": 25, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#ded678", + "Active": true, + "Name": "Hermit" + }, + { + "DamageMultiplier": 2.0, + "DamageRadiusMultiplier": 2.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#ffdd00", + "Active": true, + "Name": "HolyHandGrenade" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#99140B", + "Active": true, + "Name": "Impostor" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#0000FF", + "Active": true, + "Name": "InfiniteAmmo" + }, + { + "MaxStepBeam": 100, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#f542ef", + "Active": true, + "Name": "Jackal" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#42f5a7", + "Active": true, + "Name": "Jammer" + }, + { + "MinTime": 10.0, + "MaxTime": 25.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#8f108f", + "Active": true, + "Name": "Jester" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#b01e5d", + "Active": true, + "Name": "JumpBan" + }, + { + "HealthToAdd": 3, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#a86eff", + "Active": true, + "Name": "JumpingJack" + }, + { + "FlashDuration": 1.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#57bcff", + "Active": true, + "Name": "KillerFlash" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#a3651a", + "Active": true, + "Name": "LifeSwap" + }, + { + "MaxDistance": 4096.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#c9f8ff", + "Active": true, + "Name": "LongKnife" + }, + { + "MaxDistance": 4096.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#6effc7", + "Active": true, + "Name": "LongZeus" + }, + { + "CustomFOV": 50, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#9ba882", + "Active": true, + "Name": "Magnifier" + }, + { + "HealthToAdd": 50, + "HealthShotLimit": 3, + "Cooldown": 1.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": true, + "OnlyTeam": 0, + "Color": "#10c212", + "Active": true, + "Name": "Medic" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#52f54c", + "Active": true, + "Name": "MoneySwap" + }, + { + "ExplosionRadius": 500.0, + "ExplosionDamage": 999, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#F5CB42", + "Active": true, + "Name": "Muhammed" + }, + { + "IdlePercentInvisibility": 0.3, + "DuckPercentInvisibility": 0.3, + "KnifePercentInvisibility": 0.3, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#dedede", + "Active": true, + "Name": "Ninja" + }, + { + "Cooldown": 30.0, + "Duration": 2.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": true, + "OnlyTeam": 0, + "Color": "#44ebd4", + "Active": true, + "Name": "Noclip" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#a38c1a", + "Active": true, + "Name": "NoNades" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#FFFFFF", + "Active": true, + "Name": "None" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#8a42f5", + "Active": true, + "Name": "NoRecoil" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#ff5CD9", + "Active": true, + "Name": "OneShot" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#3c47de", + "Active": true, + "Name": "OnlyHead" + }, + { + "ExtraJumpsMin": 1, + "ExtraJumpsMax": 4, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#FFA500", + "Active": true, + "Name": "PawelJumper" + }, + { + "ChanceFrom": 0.2, + "ChanceTo": 0.4, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#ff5C0A", + "Active": true, + "Name": "Phoenix" + }, + { + "MaximumFuel": 150.0, + "FuelConsumption": 0.64, + "Refuelling": 0.1, + "NeedsTeammates": false, + "DisableOnFreezeTime": true, + "OnlyTeam": 0, + "Color": "#1466F5", + "Active": true, + "Name": "Pilot" + }, + { + "ExtraC4BlowTime": 60, + "NeedsTeammates": false, + "DisableOnFreezeTime": true, + "OnlyTeam": 2, + "Color": "#7d7d7d", + "Active": true, + "Name": "Planter" + }, + { + "Damage": 1, + "Cooldown": 1.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": true, + "OnlyTeam": 0, + "Color": "#902eff", + "Active": true, + "Name": "Poison" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#ffc061", + "Active": true, + "Name": "PrimaryBan" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#9c9c9c", + "Active": true, + "Name": "Prosthesis" + }, + { + "MaxDefusingRange": 80.0, + "DefusingTime": 10.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 3, + "Color": "#507529", + "Active": true, + "Name": "PsychicDefusing" + }, + { + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "JumpVelocity": 300.0, + "PushVelocity": 400.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#1e9ab0", + "Active": true, + "Name": "Push" + }, + { + "RegenerationMultiplier": 1.5, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#3c47de", + "Active": true, + "Name": "Pyro" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#8a42f5", + "Active": true, + "Name": "QuickShot" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#2effcb", + "Active": true, + "Name": "RadarHack" + }, + { + "MinExtraHealth": 50, + "MaxExtraHealth": 501, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#009905", + "Active": true, + "Name": "Rambo" + }, + { + "Cooldown": 15.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#e0873a", + "Active": true, + "Name": "RandomWeapon" + }, + { + "Cooldown": 15.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#3cded3", + "Active": true, + "Name": "ReactiveArmor" + }, + { + "HealthToAdd": 1, + "Cooldown": 0.25, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#ff462e", + "Active": true, + "Name": "Regeneration" + }, + { + "Cooldown": 15.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": true, + "OnlyTeam": 0, + "Color": "#a3000b", + "Active": true, + "Name": "Replicator" + }, + { + "Cooldown": 15.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": true, + "OnlyTeam": 0, + "Color": "#a86eff", + "Active": true, + "Name": "Retreat" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#a68132", + "Active": true, + "Name": "ReturnToSender" + }, + { + "ZombieHealth": 200, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#ff5C0A", + "Active": true, + "Name": "ReZombie" + }, + { + "MinMoney": 5000, + "MaxMoney": 15000, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#D4AF37", + "Active": true, + "Name": "RichBoy" + }, + { + "MoneyMultiplier": 35, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#119125", + "Active": true, + "Name": "RobinHood" + }, + { + "SlownessTime": 2.0, + "SlownessModifier": 0.2, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#8B4513", + "Active": true, + "Name": "Rubber" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#8A2BE2", + "Active": true, + "Name": "Saper" + }, + { + "StartHealth": 50, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#d41c1c", + "Active": true, + "Name": "SecondLife" + }, + { + "TeleportDistance": 100.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#4d4d4d", + "Active": true, + "Name": "Shade" + }, + { + "DetonationTime": 20, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 2, + "Color": "#f5b74c", + "Active": true, + "Name": "ShortBomb" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#333333", + "Active": true, + "Name": "Silent" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#e0873a", + "Active": true, + "Name": "SniperElite" + }, + { + "ChanceFrom": 1.15, + "ChanceTo": 1.35, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#09ba00", + "Active": true, + "Name": "Soldier" + }, + { + "Cooldown": 5.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#e3ed8c", + "Active": true, + "Name": "SoundMaker" + }, + { + "Distance": 100.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#42f5da", + "Active": true, + "Name": "Spectator" + }, + { + "Cooldown": 30.0, + "CooldownBeforeUse": 10.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": true, + "OnlyTeam": 0, + "Color": "#1466F5", + "Active": true, + "Name": "SwapPosition" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#8A2BE2", + "Active": true, + "Name": "Teleporter" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#adaec7", + "Active": true, + "Name": "Thief" + }, + { + "Distance": 100.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#1b04cc", + "Active": true, + "Name": "ThirdEye" + }, + { + "HealthTakenScale": 0.3, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#962631", + "Active": true, + "Name": "Thorns" + }, + { + "SmokeDamage": 2, + "SmokeRadius": 180.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#507529", + "Active": true, + "Name": "ToxicSmoke" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#5d00ff", + "Active": true, + "Name": "Wallhack" + }, + { + "ChangeRoundTime": 10, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#ff462e", + "Active": true, + "Name": "Watchmaker" + }, + { + "Cooldown": 30.0, + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#c7e03a", + "Active": true, + "Name": "WeaponsSwap" + }, + { + "NeedsTeammates": false, + "DisableOnFreezeTime": false, + "OnlyTeam": 0, + "Color": "#fbff00", + "Active": true, + "Name": "Zeus" + } +] \ No newline at end of file diff --git a/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/en.json b/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/en.json index 1cb54d3..d3b93e4 100644 --- a/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/en.json +++ b/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/en.json @@ -215,7 +215,7 @@ "lifeswap_select_info": "Swap health with player:", "longknife": "Long Knife", - "longknife_desc": "A primary knife attack deals damage regardless of distance", + "longknife_desc": "A knife attack deals damage regardless of distance", "longzeus": "Long Zeus", "longzeus_desc": "Zeus deals damage regardless of distance", @@ -237,6 +237,7 @@ "muhammed": "Muhammed", "muhammed_desc": "You explode upon death, killing nearby players", + "muhammed_explosion": "ALLAHU AKBAR!!!", "ninja": "Ninja", "ninja_desc": "Standing still increases your invisibility by 33%, crouching by 33%, and holding a knife by 33%", @@ -452,5 +453,7 @@ "summary_start": "======SUMMARY=OF=THE=LAST=ROUND======", "summary_end": "=======================================", - "menu_controlls": "W/S - Scroll | E - Select
" + "menu_controlls_scroll": "W/S - Scroll", + "menu_controlls_padding": " | ", + "menu_controlls_select": "E - Select" } \ No newline at end of file diff --git a/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/fr.json b/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/fr.json index 8131605..d5548be 100644 --- a/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/fr.json +++ b/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/fr.json @@ -215,7 +215,7 @@ "lifeswap_select_info": "Échanger la santé avec le joueur :", "longknife": "Couteau Long", - "longknife_desc": "Une attaque primaire au couteau inflige des dégâts quelle que soit la distance", + "longknife_desc": "Une attaque au couteau inflige des dégâts quelle que soit la distance", "longzeus": "Zeus Longue Portée", "longzeus_desc": "Le Zeus inflige des dégâts quelle que soit la distance", @@ -237,6 +237,7 @@ "muhammed": "Bombe", "muhammed_desc": "Vous explosez à votre mort, tuant les joueurs proches", + "muhammed_explosion": "ALLAHU AKBAR!!!", "ninja": "Ninja", "ninja_desc": "Rester immobile augmente votre invisibilité de 33%, s’accroupir de 33%, et tenir un couteau de 33%", @@ -452,5 +453,7 @@ "summary_start": "======RÉSUMÉ=DU=DERNIER=ROUND======", "summary_end": "===================================", - "menu_controlls": "W/S - Défilement | E - Sélectionner
" -} \ No newline at end of file + "menu_controlls_scroll": "W/S - Défilement", + "menu_controlls_padding": " | ", + "menu_controlls_select": "E - Sélectionner" +} diff --git a/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/pl.json b/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/pl.json index b84c5ac..60a9b5f 100644 --- a/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/pl.json +++ b/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/pl.json @@ -215,7 +215,7 @@ "lifeswap_select_info": "Zamień się zdrowiem z graczem:", "longknife": "Długi Nóż", - "longknife_desc": "Podstawowy atak nożem zadaje obrażenia niezależnie od odległości", + "longknife_desc": "Atak nożem zadaje obrażenia niezależnie od odległości", "longzeus": "Długi Zeus", "longzeus_desc": "Zeus zadaje obrażenia niezależnie od odległości", @@ -237,6 +237,7 @@ "muhammed": "Muhammed", "muhammed_desc": "Po śmierci eksplodujesz i zabijasz graczy znajdujących się w zasięgu", + "muhammed_explosion": "ALLAHU AKBAR!!!", "ninja": "Ninja", "ninja_desc": "Stojąc nieruchomo zwiększasz swoją niewidzialność o 33%, kucając o 33%, a trzymając nóż o 33%", @@ -452,5 +453,7 @@ "summary_start": "======PODSUMOWANIE=Z=OSTATNIEJ=RUNDY======", "summary_end": "============================================", - "menu_controlls": "W/S – Przewijanie | E - Wybierz
" + "menu_controlls_scroll": "W/S – Przewijanie", + "menu_controlls_padding": " | ", + "menu_controlls_select": "E - Wybierz" } \ No newline at end of file diff --git a/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/pt-br.json b/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/pt-br.json index fb05ea3..180a374 100644 --- a/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/pt-br.json +++ b/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/pt-br.json @@ -215,7 +215,7 @@ "lifeswap_select_info": "Trocar vida com jogador:", "longknife": "Faca Longa", - "longknife_desc": "Um ataque com faca primária causa dano independentemente da distância", + "longknife_desc": "Um ataque com faca causa danos independentemente da distância", "longzeus": "Zeus Longo", "longzeus_desc": "Zeus causa dano independentemente da distância", @@ -237,6 +237,7 @@ "muhammed": "Muhammed", "muhammed_desc": "Você explode ao morrer, matando jogadores próximos", + "muhammed_explosion": "ALLAHU AKBAR!!!", "ninja": "Ninja", "ninja_desc": "Ficar parado aumenta sua invisibilidade em 33%, agachar em 33%, e segurar uma faca em 33%", @@ -452,5 +453,7 @@ "summary_start": "=======RESUMO=DA=ÚLTIMA=RODADA=======", "summary_end": "=======================================", - "menu_controlls": "W/S - Rolar | E - Selecionar
" + "menu_controlls_scroll": "W/S - Rolar", + "menu_controlls_padding": " | ", + "menu_controlls_select": "E - Selecionar" } \ No newline at end of file diff --git a/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/test.json b/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/test.json new file mode 100644 index 0000000..98be7e8 --- /dev/null +++ b/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/test.json @@ -0,0 +1,458 @@ +{ + "none": "Brak", + "none_desc": "Nie posiadasz żadnej supermocy", + + "aimbot": "Aimbot", + "aimbot_desc": "Każdy twój trafiony pocisk liczy się jako strzał w głowę", + + "anomaly": "Anomalia", + "anomaly_desc": "Cofasz się o kilka sekund do tyłu", + + "antyflash": "Anty Flash", + "antyflash_desc": "Posiadasz odporność na flash'e, a twoje flash'e trwają 7 sekund", + + "antyhead": "Żelazna Głowa", + "antyhead_desc": "Nie otrzymujesz obrażeń w głowę", + + "areareaper": "Niszczyciel Stref", + "areareaper_desc": "Możesz wybrać strefę detonacji, którą chcesz dezaktywować", + "areareaper_incorrect_site": "Nie znaleziono takiej strefy detonacji.", + "areareaper_no_site": "Nie znaleziono żadnej strefy detonacji.", + "areareaper_select_info": "Wybierz strefę do dezaktyw.:", + "areareaper_site_disabled": "Strefa detonacji {0} została dezaktywowana - nie można na niej podłożyć bomby!", + "areareaper_used_info": "Twoja moc została już wykorzystana.", + + "armored": "Gruby", + "armored_desc": "Masz losowy mnożnik otrzymywanych obrażeń", + "armored_desc2": "Twój mnożnik otrzymywanych obrażeń wynosi: {0}x", + + "assassin": "Skrytobójca", + "assassin_desc": "Zadajesz większe obrażenia przeciwnikowi od tyłu", + + "astronaut": "Astronauta", + "astronaut_desc": "Na początku rundy otrzymujesz losową wartość grawitacji", + "astronaut_desc2": "Twoja losowa grawitacja wynosi: {0}x", + + "bankrupt": "Bankrut", + "bankrupt_desc": "Wybierz gracza, który straci wszystkie swoje pieniądze", + "bankrupt_enemy_info": "Stałeś się bankrutem.", + "bankrupt_player_info": "Gracz '{0}' zbankrutował.", + "bankrupt_select_info": "Wybierz gracza do bankrucji:", + + "baseball": "Bejsbolista", + "baseball_desc": "Twój wabik odbija się od ścian i natychmiastowo zabija wroga po trafieniu", + + "behind": "Obrót Wroga", + "behind_desc": "Masz losową szansę na obrócenie wroga o 180 stopni po trafieniu go", + "behind_desc2": "Twoje szanse na obrócenie wroga po trafieniu to: {0}%", + + "blademaster": "Mistrz Ostrza", + "blademaster_desc": "Trzymając nóż, masz duże szanse na odparcie strzału", + + "bunnyhop": "Królik", + "bunnyhop_desc": "Otrzymujesz auto \"BunnyHopa\"", + + "c4camouflage": "C4 Kamuflaż", + "c4camouflage_desc": "Kiedy trzymasz bombę, jesteś niewidzialny", + + "catapult": "Katapulta", + "catapult_desc": "Masz losową szanse na podrzucenie wroga", + "catapult_desc2": "Twoje szanse na podrzucenie wroga po trafieniu to: {0}%", + + "chicken": "Kurczak", + "chicken_desc": "Otrzymujesz model kurczaka + jesteś o 10% szybszy - 50hp", + + "chillout": "Wyluzowany", + "chillout_desc": "Podłożenie bomby zajmuje znacznie więcej czasu", + + "cutter": "Scyzoryk", + "cutter_desc": "Natychmiastowe zabójstwo nożem", + + "darkness": "Mrok", + "darkness_desc": "Nadaje efekt ciemności wybranemu przeciwnikowi", + "darkness_enemy_info": "Niech zgasną światła.", + "darkness_player_info": "Ciemność opanowała gracza '{0}'.", + "darkness_select_info": "Nałóż efekt ciemności:", + + "deactivator": "Deaktywator", + "deactivator_desc": "Wybierasz gracza, którego supermoc chcesz wyłączyć", + "deactivator_enemy_info": "Twoja supermoc została wyłączona.", + "deactivator_player_info": "Moc gracza '{0}' została wyłączona.", + "deactivator_select_info": "Wyłącz moc gracza:", + + "deaf": "Głuchy", + "deaf_desc": "Wybierasz gracza, dla którego chcesz wyłączyć wszystkie dźwięki", + "deaf_enemy_info": "Słuchawki opuściły grę.", + "deaf_player_info": "Dźwięk został wyłączony dla gracza '{0}'.", + "deaf_select_info": "Wycisz dźwięki gracza:", + + "disarmament": "Rozbrojenie", + "disarmament_desc": "Masz losową szanse na wyrzucenie broni wroga po trafieniu", + "disarmament_desc2": "Twoje szanse na wyrzucenie broni wroga to: {0}%", + + "distancer": "Odległościomierz", + "distancer_desc": "Możesz zobaczyć odległość do najbliższego przeciwnika", + + "dash": "Doskok", + "dash_desc": "Wykonaj drugi skok, aby wykonać doskok", + + "dracula": "Drakula", + "dracula_desc": "Po trafieniu ofiary odzyskujesz zdrowie równe pewnemu procentowi zadanych obrażeń", + + "duplicator": "Duplikator", + "duplicator_desc": "Wybierasz gracza, od którego chcesz skopiować supermoc", + "duplicator_player_info": "Moc gracza '{0}' została skopiowana.", + "duplicator_select_info": "Skopiuj moc gracza:", + + "dwarf": "Mini Majk ({0}%)", + "dwarf_desc": "Losowa wielkość postaci na początku rundy", + "dwarf_desc2": "Twój mnożnik wielkości to {0}%", + + "enemyspawn": "Resp Wroga", + "enemyspawn_desc": "Kliknij [css_useSkill], aby teleportować się na resp wroga", + + "explosiveshot": "Strzał Wybuchowy", + "explosiveshot_desc": "Losowa szansa wystrzelenia pocisku wybuchowego podczas strzelania", + "explosiveshot_desc2": "Twoja szansa na wystrzelenie pocisku wybuchowego: {0}%", + + "falconeye": "Oko Sokoła", + "falconeye_desc": "Kliknij [css_useSkill], aby aktywować kamerę z lotu ptaka", + + "fastreload": "Szybkie Rączki", + "fastreload_desc": "Kliknij [css_useSkill], aby przeładować broń, którą obecnie trzymasz", + + "flash": "Flash", + "flash_desc": "Losowa prędkośc postaci na początku rundy", + "flash_desc2": "Twój mnożnik prędkości to {0}x", + + "fortnite": "Fortnite", + "fortnite_desc": "Kliknij [css_useSkill], aby stworzyć barykadę, którą można zniszczyć", + + "fragilebomb": "Krucha Bomba", + "fragilebomb_desc": "Strzelanie do bomby powoduje jej uszkodzenie", + "fragilebomb_bomb_health": "Zdrowie bomby", + + "friendlyfire": "Ogień Przyjacielski", + "friendlyfire_desc": "Strzelanie do członków drużyny leczy ich", + + "frozendecoy": "Zamrażający Wabik", + "frozendecoy_desc": "Twój decoy zamraża wszystkich graczy w pobliżu", + + "gambler": "Hazardzista", + "gambler_desc": "Wybierz umiejętność z podanej listy.", + "gambler_select_info": "Wybierz umiejętność:", + "gambler_more": "#00FF00|Odśwież za ${0}", + + "ghost": "Duszek", + "ghost_desc": "Jesteś całkowicie niewidzialny", + + "glaz": "Glaz", + "glaz_desc": "Nie widzisz granatów dymnych", + + "glitch": "Glitch", + "glitch_desc": "Wyłączasz radar wybranemu przeciwnikowi", + "glitch_enemy_info": "Twój radar został wyłączony.", + "glitch_player_info": "Radar gracza '{0}' został wyłączony.", + "glitch_select_info": "Wyłącz radar dla gracza:", + + "glue": "Klej", + "glue_desc": "Twoje granaty przyklejają się do ścian", + + "godmode": "Nieśmiertelność", + "godmode_desc": "Kliknij [css_useSkill], aby stać się nieśmiertelnym na krótką chwilę", + "godmode_off": "Nieśmiertelność wyłączona", + "godmode_on": "Nieśmiertelność włączona", + + "grenadier": "Granatnik", + "grenadier_desc": "Masz nieskończone granaty odłamkowe", + + "healingsmoke": "Leczący Dym", + "healingsmoke_desc": "Twoje granaty dymne leczą", + + "hermit": "Pustelnik", + "hermit_desc": "Zabijanie przywraca amunicję i część zdrowia", + + "holyhandgrenade": "Święty Granat Ręczny", + "holyhandgrenade_desc": "Twoje granaty uderzeniowe zadają podwójne obrażenia i mają podwójny zasięg", + + "impostor": "Szpieg", + "impostor_desc": "Na początku rundy otrzymujesz model postaci przeciwnika", + + "infiniteammo": "Nieskończone Ammo", + "infiniteammo_desc": "Otrzymujesz nieskończoną ilość amunicji do wszystkich broni", + + "jackal": "Stópkarz", + "jackal_desc": "Każdy przeciwnik pozostawia za sobą ślad", + + "jammer": "Zakłócacz", + "jammer_desc": "Wybierasz gracza, dla którego chcesz wyłączyć celownik", + "jammer_enemy_info": "Twój celownik został wyłączony.", + "jammer_player_info": "Celownik gracza '{0}' została wyłączona.", + "jammer_select_info": "Wyłącz celownik dla gracza:", + + "jester": "Błazen", + "jester_desc": "W trybie błazna nie możesz zadawać ani otrzymywać obrażeń. Tryb zmienia się co kilka sekund.", + "jester_mode": "Tryb Błazna", + "jester_on": "WŁ.", + "jester_off": "WYŁ.", + + "jumpban": "Beznogi", + "jumpban_desc": "Wybierasz gracza, który nie będzie mógł skakać", + "jumpban_enemy_info": "Ktoś odciął ci nogi.", + "jumpban_player_info": "Gracz '{0}' nie może teraz skakać.", + "jumpban_select_info": "Zablokuj skok dla gracza:", + + "jumpingjack": "Pajacyk", + "jumpingjack_desc": "Skakanie przywraca zdrowie", + + "killerflash": "Zabójczy Flash", + "killerflash_desc": "Każdy całkowicie oślepiony twoim granatem umiera (również ty)", + + "lifeswap": "Zamiana Żyć", + "lifeswap_desc": "Wybierasz gracza, z którym chcesz wymienić się zdrowiem", + "lifeswap_enemy_info": "Ktoś pożyczył sobie twoje zdrowie.", + "lifeswap_player_info": "Wymieniłeś się zdrowiem z graczem '{0}'.", + "lifeswap_select_info": "Zamień się zdrowiem z graczem:", + + "longknife": "Długi Nóż", + "longknife_desc": "Podstawowy atak nożem zadaje obrażenia niezależnie od odległości", + + "longzeus": "Długi Zeus", + "longzeus_desc": "Zeus zadaje obrażenia niezależnie od odległości", + + "magnifier": "Lupa", + "magnifier_desc": "Przybiżasz ekran wybranemu przeciwnikowi", + "magnifier_enemy_info": "Twoje pole widzenia zostało zniekształcone!", + "magnifier_player_info": "Gracz '{0}' został zmuszony do przejścia w tryb powiększenia.", + "magnifier_select_info": "Powiększ ekran gracza:", + + "medic": "Medyk", + "medic_desc": "Kliknij [css_useSkill], aby użyć ładunku leczniczego, który przywraca 50 punktów zdrowia", + + "moneyswap": "Skarbówka", + "moneyswap_desc": "Wybierasz gracza, z którym chcesz zamienić się pieniędzmi", + "moneyswap_enemy_info": "Urząd skarbowy cię dopadł.", + "moneyswap_player_info": "Wymieniłeś swoje pieniądze z graczem '{0}'.", + "moneyswap_select_info": "Zamień się kasą z graczem:", + + "muhammed": "Muhammed", + "muhammed_desc": "Po śmierci eksplodujesz i zabijasz graczy znajdujących się w zasięgu", + + "ninja": "Ninja", + "ninja_desc": "Stojąc nieruchomo zwiększasz swoją niewidzialność o 33%, kucając o 33%, a trzymając nóż o 33%", + + "nonades": "Pancernik", + "nonades_desc": "Granaty nie zadają Ci obrażeń", + + "norecoil": "Skupienie", + "norecoil_desc": "Brak odrzutu podczas strzelania", + + "noclip": "NoClip", + "noclip_desc": "Kliknij [css_useSkill], aby włączyć noclip na krótki czas", + + "oneshot": "Jednostrzałowiec", + "oneshot_desc": "Po trafieniu natychmiast zabijasz przeciwnika", + + "onlyhead": "Tylko Głowa", + "onlyhead_desc": "Otrzymujesz obrażenia tylko w głowę", + + "paweljumper": "Pawel Jumper", + "paweljumper_desc": "Otrzymujesz losową liczbę dodatkowych skoków", + "paweljumper_desc2": "Otrzymujesz {0} dodatkowych skoków", + + "phoenix": "Feniks", + "phoenix_desc": "Masz losową szans na odrodzenie się po śmierci", + "phoenix_desc2": "Twoje szanse na odrodzenie się po śmierci: {0}%", + "phoenix_respawn": "Zostałeś odrodzony z popiołów dzięki mocy: CHATCOLORS.REDPhoenix", + + "psychicdefusing": "Zdalne Rozbrajanie", + "psychicdefusing_desc": "Kiedy jesteś blisko bomby, zaczynasz ją rozbrajać", + "psychicdefusing_hud_info": "Pozostało {0} sekund do rozbrojenia", + + "pilot": "Pilot", + "pilot_desc": "Latanie przez określony czas. Przytrzymaj [USE - E], aby latać", + "pilot_hud_info": "Paliwo", + + "planter": "Samowolka", + "planter_desc": "Bombę można podłożyć w dowolnym miejscu, a czas detonacji wynosi 60 sekund.", + + "poison": "Trutka", + "poison_desc": "Wybierasz gracza, który co kilka sekund będzie otrzymywał obrażenia", + "poison_enemy_info": "Zostałeś otruty.", + "poison_player_info": "Gracz '{0}' został otruty.", + "poison_select_info": "Zatruj gracza:", + + "primaryban": "Brak Karabinów", + "primaryban_desc": "Wybierasz gracza, który nie może używać karabinów", + "primaryban_enemy_info": "Nie możesz już używać karabinów.", + "primaryban_player_info": "Gracz '{0}' nie może już używać karabinów.", + "primaryban_select_info": "Zablokuj karabiny dla gracza:", + + "prosthesis": "Proteza", + "prosthesis_desc": "Ramiona i nogi są kuloodporne", + + "push": "Odpychacz", + "push_desc": "Masz losową szansę na odepchnięcie wroga po trafieniu go", + "push_desc2": "Twoje szanse na odepchnięcie wroga to: {0}%", + + "pyro": "Pyro", + "pyro_desc": "Molotow przywraca zdrowie", + + "quickshot": "Szybkostrzelność", + "quickshot_desc": "Wszystkie pociski są wystrzeliwane bardzo szybko", + + "radarhack": "Radarowiec", + "radarhack_desc": "Na radarze widać wrogów", + + "rambo": "Rambo", + "rambo_desc": "Na początku rundy otrzymujesz losową ilość zdrowia", + + "randomweapon": "Losowa Broń", + "randomweapon_desc": "Kliknij [css_useSkill], aby otrzymać losową broń", + + "rezombie": "Re-Zombie", + "rezombie_desc": "Po śmierci odradzasz się jako zombie z większym zdrowiem i bez broni", + + "reactivearmor": "Pancerz Reaktywny", + "reactivearmor_desc": "Pancerz pochłania pierwsze otrzymane obrażenia", + + "regeneration": "Regeneracja", + "regeneration_desc": "Co kilka sekund odnawiasz zdrowie", + + "replicator": "Replikator", + "replicator_desc": "Kliknij [css_useSkill], aby stworzyć swoją replikę, która zadaje obrażenia po trafieniu", + + "retreat": "Odwrót", + "retreat_desc": "Kliknij [css_useSkill], aby powrócić na resp", + + "returntosender": "Zwrot do Nadawcy", + "returntosender_desc": "Pierwsze trafienie wroga powoduje, że wraca on na swój resp", + + "richboy": "Bogacz", + "richboy_desc": "Na początku rundy otrzymujesz losową kwotę gotówki", + + "robinhood": "Robin Hood", + "robinhood_desc": "Zadanie obrażeń przeciwnikowi powoduje kradzież jego pieniędzy", + + "rubber": "Gumowe Kule", + "rubber_desc": "Twoje pociski znacznie spowalniają graczy", + + "saper": "Saper", + "saper_desc": "Możesz szybciej podłożyć bombę i ją rozbroić", + + "secondlife": "Druga Szansa", + "secondlife_desc": "Po śmierci odradzasz się z taką samą ilością zdrowia", + + "shade": "Cień", + "shade_desc": "Teleportujesz się za plecy trafionego wroga", + "shade_nospace": "Brak miejsca", + + "shortbomb": "Krótka Bomba", + "shortbomb_desc": "Bomba wybucha znacznie szybciej", + + "silent": "Cichociemny", + "silent_desc": "Twoje kroki i skoki są niesłyszalne dla INNYCH graczy", + + "sniperelite": "SzeliS", + "sniperelite_desc": "Kliknij [css_useSkill], aby zamienić aktualną broń na AWP", + + "soldier": "Żołnierz {0}%", + "soldier_desc": "Masz losowy mnożnik obrażeń", + "soldier_desc2": "A AAAAAAAAAAAAAAAAAAAAAA", + + "soundmaker": "Dźwiękowiec", + "soundmaker_desc": "Kliknij [css_useSkill], aby wywołać dzwięk u każdego przeciwnika", + + "spectator": "Obserwator", + "spectator_desc": "Kliknij [css_useSkill], aby obserwować losowego przeciwnika", + + "swapposition": "Zamiana Miejsc", + "swapposition_desc": "Kliknij [css_useSkill], aby zamienić się miejscami z losowym przeciwnikiem", + + "teleporter": "Teleporter", + "teleporter_desc": "Zamieniasz się miejscami z trafionym przeciwnikiem", + + "thief": "Złodziej", + "thief_desc": "Możesz ukraść supermoc wybranemu graczowi", + "thief_enemy_info": "Twoja supermoc została skradziona.", + "thief_player_info": "Moc gracza '{0}' została skradziona.", + "thief_select_info": "Ukradnij moc gracza:", + "thief_incorrect_skill": "Tej umiejętności nie można wybrać!", + + "thirdeye": "Trzecie Oko", + "thirdeye_desc": "Kliknij [css_useSkill], aby aktywować trzecią osobę", + + "thorns": "Ciernie", + "thorns_desc": "Twój przeciwnik otrzymuje część obrażeń, które zadał ci", + + "toxicsmoke": "Toksyczny Dym", + "toxicsmoke_desc": "Twoje granaty dymny zadają obrażenia", + + "wallhack": "Wallhack", + "wallhack_desc": "Widzisz wrogów przez ściany", + + "watchmaker": "Zegarmistrz", + "watchmaker_desc": "Każdy rzut granatem zmienia czas rundy", + "watchmaker_ct": "Czas rundy został skrócony o {0} sekund.", + "watchmaker_tt": "Czas rundy został wydłużony o {0} sekund", + + "weaponsswap": "Zamiana Broni", + "weaponsswap_desc": "Kliknij [css_useSkill], aby zamienić się bronią z losowym przeciwnikiem", + "weaponsswap_hud_info2": "Nie posiadasz broni na zamiane", + + "zeus": "Zeus", + "zeus_desc": "Zeus x27 natychmiastowo się odnawia", + + "your_skill": "", + "enemy_skill": "Supermoc przeciwnika", + "observer_skill": "Moc gracza", + "welcome_message": "Witaj {PLAYER} na serwerze {SERVER_NAME}!\nAktualna wersja jRandomSkills: {VERSION} ({SKILLS_COUNT} supermocy).\n\nPierwotnie plugin stworzona przez:\n{AUTHOR1}\nZmodyfikowany i ulepszony przez:\n{AUTHOR2}\nOficjalny discord: https://discord.gg/9H8EZYBpPF", + "drawing_skill": "", + "disabled_weapon": "Nie możesz używać tej broni", + + "hud_info": "Poczekaj jeszcze {0} sekund", + "hud_info_no_enemy": "Nie znaleziono przeciwnika", + "active_hud_info": "Działa jeszcze przez {0} milisekund", + + "skills_menu": "Lista Super Mocy", + "no_player": "Nie znaleziono pasującego gracza.", + "duplicate_player": "Znaleziono więcej niż jednego gracza o tej samej nazwie.", + "selectplayerskill_command": "Wpisz /t", + "selectplayerskill_incorrect_enemy_index": "Nie znaleziono graczy do wyboru.", + + "skill_not_found_setskill": "Nie znaleziono takiej CHATCOLORS.REDsupermocy", + "player_not_found_setskill": "Nie znaleziono takiego CHATCOLORS.REDgracza", + "correct_form_setskill": "Poprawne użycie: CHATCOLORS.RED!setskill ", + "correct_form_setscore": "Poprawne użycie: CHATCOLORS.RED!setscore ", + "done_setskill": "Ustawiono Supermoc", + "error_setskill": "Nie udało się ustawić CHATCOLORS.REDsupermocy", + "for_setskill": "dla", + + "invalid_map": "Nazwa mapy została wprowadzona nieprawidłowo!", + "loading_map": "Ładowanie nowej mapy", + + "pause": "Mecz został wstrzymany.", + "unpause": "Mecz został wznowiony.", + "healed": "Zostałeś uleczony.", + "game_start": "Gra rozpoczęta!", + "reload": "Tłumaczenia i konfigi zostały ponownie załadowane.", + + "vote_started": "Głosowanie rozpoczęte: '{0}'", + "vote_timeout": "Głosowanie '{0}' przekroczyło limit czasu!", + "vote_wait": "Musisz poczekać, zanim rozpoczniesz kolejne głosowanie!", + "vote_same_wait": "Musisz poczekać, zanim ponownie rozpoczniesz to samo głosowanie!", + "vote_not_enough_players": "Za mało graczy, aby rozpocząć głosowanie!", + "vote_alredy_voted": "Już zagłosowałeś!", + "vote_vote": "Głosowanie", + + "bombsite_a": "Strefa detonacji A", + "bombsite_b": "Strefa detonacji B", + + "teammate_skills": "Supermoce twoich sojuszników", + "summary_start": "======PODSUMOWANIE=Z=OSTATNIEJ=RUNDY======", + "summary_end": "============================================", + + "menu_controlls_scroll": "W/S - Scroll", + "menu_controlls_padding": " | ", + "menu_controlls_select": "E - Select" +} \ No newline at end of file diff --git a/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/zh.json b/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/zh.json index b6263c9..7b51cba 100644 --- a/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/zh.json +++ b/jRandomSkills - Server Files/plugins/!jRandomSkills/languages/zh.json @@ -215,7 +215,7 @@ "lifeswap_select_info": "选择你想与之交换生命值的玩家:", "longknife": "长刀", - "longknife_desc": "近战刀具攻击无论距离远近均可造成伤害", + "longknife_desc": "刀具攻击造成的伤害与距离无关", "longzeus": "长宙斯", "longzeus_desc": "宙斯电击枪无论距离多远都能造成伤害", @@ -237,6 +237,7 @@ "muhammed": "穆罕默德", "muhammed_desc": "你死亡时会爆炸,杀死附近的玩家", + "muhammed_explosion": "真主至大!!!", "ninja": "忍者", "ninja_desc": "站立不动增加33%隐形,蹲下增加33%,持刀增加33%", @@ -452,5 +453,7 @@ "summary_start": "=============上一回合总结==============", "summary_end": "=======================================", - "menu_controlls": "W/S - 滚动 | E - 选择
" + "menu_controlls_scroll": "W/S - 滚动", + "menu_controlls_padding": " | ", + "menu_controlls_select": "E - 选择" } \ No newline at end of file