From d68896f18157aba1ed34d83bba7532aa3047eec5 Mon Sep 17 00:00:00 2001 From: Juzlus Date: Thu, 25 Sep 2025 04:06:00 +0200 Subject: [PATCH] v1.1.8 --- .../src/command/Command.cs | 30 ++- .../src/jRandomSkills.cs | 3 +- jRandomSkills - SRC Files/src/lang/en.json | 2 + jRandomSkills - SRC Files/src/lang/fr.json | 2 + jRandomSkills - SRC Files/src/lang/pl.json | 2 + jRandomSkills - SRC Files/src/lang/pt-br.json | 2 + jRandomSkills - SRC Files/src/lang/zh.json | 2 + .../src/player/PlayerEvents.cs | 21 ++ .../src/player/PlayerOnTick.cs | 5 +- .../src/player/skills/Chicken.cs | 2 +- .../src/player/skills/Replicator.cs | 13 +- jRandomSkills - SRC Files/src/utils/Config.cs | 10 +- .../src/utils/SkillUtils.cs | 2 +- .../plugins/!jRandomSkills/!jRandomSkills.dll | Bin 406016 -> 409088 bytes .../!jRandomSkills/configs/config.json | 10 +- .../plugins/!jRandomSkills/languages/en.json | 2 + .../plugins/!jRandomSkills/languages/fr.json | 2 + .../plugins/!jRandomSkills/languages/pl.json | 2 + .../!jRandomSkills/languages/pt-br.json | 2 + .../plugins/!jRandomSkills/languages/zh.json | 2 + readme-pl.md | 198 ++++++++++++++---- readme.md | 130 ++++++++---- 22 files changed, 338 insertions(+), 106 deletions(-) diff --git a/jRandomSkills - SRC Files/src/command/Command.cs b/jRandomSkills - SRC Files/src/command/Command.cs index 1bfdd03..f008354 100644 --- a/jRandomSkills - SRC Files/src/command/Command.cs +++ b/jRandomSkills - SRC Files/src/command/Command.cs @@ -40,6 +40,7 @@ namespace src.command { 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.HudCommand.Alias), ("Enable/Disable HUD", Command_HUD) }, { 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) }, @@ -324,6 +325,21 @@ namespace src.command player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("healed")}"); } + [CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)] + private static void Command_HUD(CCSPlayerController? player, CommandInfo command) + { + Debug.WriteToDebug($"Player {player?.PlayerPawn} used the css_hud {command.ArgString} command."); + if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return; + if (!AdminManager.PlayerHasPermissions(player, config.NormalCommands.HudCommand.Permissions)) return; + + var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo == null) return; + + playerInfo.DisplayHUD = !playerInfo.DisplayHUD; + SkillUtils.CloseMenu(player); + player.PrintToChat($" {(playerInfo.DisplayHUD ? ChatColors.Green : ChatColors.Red)}{player.GetTranslation(playerInfo.DisplayHUD ? "hud_on" : "hud_off")}"); + } + [CommandHelper(minArgs: 2, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)] private static void Command_SetScore(CCSPlayerController? player, CommandInfo command) { @@ -485,13 +501,23 @@ namespace src.command Localization.Load(); Load(); - foreach (var skill in SkillData.Skills) - skill.Color = SkillsInfo.GetValue(skill.Skill, "color"); + SkillData.Skills.Clear(); + foreach (var skill in Enum.GetValues(typeof(Skills))) + if (SkillsInfo.GetValue(skill, "active")) + Instance.SkillAction(skill.ToString()!, "LoadSkill"); if (player != null && player.IsValid) player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("reload")}"); else Server.PrintToConsole($" {ChatColors.Green}{Localization.GetTranslation("reload")}"); + + foreach (var target in Instance.SkillPlayer) + { + if (SkillsInfo.GetValue(target.Skill, "active") == false) + target.Skill = Event.noneSkill.Skill; + if (SkillsInfo.GetValue(target.SpecialSkill, "active") == false) + target.SpecialSkill = Event.noneSkill.Skill; + } } } } diff --git a/jRandomSkills - SRC Files/src/jRandomSkills.cs b/jRandomSkills - SRC Files/src/jRandomSkills.cs index 41b5729..7a0f18c 100644 --- a/jRandomSkills - SRC Files/src/jRandomSkills.cs +++ b/jRandomSkills - SRC Files/src/jRandomSkills.cs @@ -25,7 +25,7 @@ namespace src 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.7"; + public override string ModuleVersion => "1.1.8"; public override void Load(bool hotReload) { @@ -104,6 +104,7 @@ namespace src public bool IsDrawing { get; set; } public DateTime SkillDescriptionHudExpired { get; set; } public string? PrintHTML { get; set; } + public bool DisplayHUD { get; set; } } public class jSkill_SkillInfo(Skills skill, string color, bool display) diff --git a/jRandomSkills - SRC Files/src/lang/en.json b/jRandomSkills - SRC Files/src/lang/en.json index 4ed4dc9..745900b 100644 --- a/jRandomSkills - SRC Files/src/lang/en.json +++ b/jRandomSkills - SRC Files/src/lang/en.json @@ -438,6 +438,8 @@ "healed": "You have been healed.", "game_start": "Game started!", "reload": "Languages and configs have been reloaded.", + "hud_on": "HUD has been enabled.", + "hud_off": "HUD has been disabled.", "vote_started": "Vote started: '{0}'", "vote_timeout": "Vote '{0}' timed out!", diff --git a/jRandomSkills - SRC Files/src/lang/fr.json b/jRandomSkills - SRC Files/src/lang/fr.json index bd95294..56e1401 100644 --- a/jRandomSkills - SRC Files/src/lang/fr.json +++ b/jRandomSkills - SRC Files/src/lang/fr.json @@ -438,6 +438,8 @@ "healed": "Vous avez été soigné.", "game_start": "La partie a commencé !", "reload": "Les langues et configurations ont été rechargées.", + "hud_on": "Le HUD a été activé.", + "hud_off": "Le HUD a été désactivé.", "vote_started": "Vote lancé : « {0} »", "vote_timeout": "Le vote « {0} » a expiré !", diff --git a/jRandomSkills - SRC Files/src/lang/pl.json b/jRandomSkills - SRC Files/src/lang/pl.json index 946e5dc..2897792 100644 --- a/jRandomSkills - SRC Files/src/lang/pl.json +++ b/jRandomSkills - SRC Files/src/lang/pl.json @@ -438,6 +438,8 @@ "healed": "Zostałeś uleczony.", "game_start": "Gra rozpoczęta!", "reload": "Tłumaczenia i konfigi zostały ponownie załadowane.", + "hud_on": "HUD został włączony.", + "hud_off": "HUD został wyłączony.", "vote_started": "Głosowanie rozpoczęte: '{0}'", "vote_timeout": "Głosowanie '{0}' przekroczyło limit czasu!", diff --git a/jRandomSkills - SRC Files/src/lang/pt-br.json b/jRandomSkills - SRC Files/src/lang/pt-br.json index 0e05369..4f0e9da 100644 --- a/jRandomSkills - SRC Files/src/lang/pt-br.json +++ b/jRandomSkills - SRC Files/src/lang/pt-br.json @@ -438,6 +438,8 @@ "healed": "Você foi curado.", "game_start": "Jogo iniciado!", "reload": "Os idiomas e as configurações foram recarregados.", + "hud_on": "O HUD foi ativado.", + "hud_off": "O HUD foi desativado.", "vote_started": "Votação iniciada: '{0}'", "vote_timeout": "Votação '{0}' expirou!", diff --git a/jRandomSkills - SRC Files/src/lang/zh.json b/jRandomSkills - SRC Files/src/lang/zh.json index 7a149a9..99d6be0 100644 --- a/jRandomSkills - SRC Files/src/lang/zh.json +++ b/jRandomSkills - SRC Files/src/lang/zh.json @@ -438,6 +438,8 @@ "healed": "你已被治疗。", "game_start": "游戏开始!", "reload": "语言和配置已重新加载。", + "hud_on": "HUD已启用。", + "hud_off": "HUD已禁用。", "vote_started": "投票开始:'{0}'", "vote_timeout": "投票'{0}'超时!", diff --git a/jRandomSkills - SRC Files/src/player/PlayerEvents.cs b/jRandomSkills - SRC Files/src/player/PlayerEvents.cs index 37bac8f..41fbe5f 100644 --- a/jRandomSkills - SRC Files/src/player/PlayerEvents.cs +++ b/jRandomSkills - SRC Files/src/player/PlayerEvents.cs @@ -283,6 +283,8 @@ namespace src.player SpecialSkill = Skills.None, IsDrawing = false, SkillChance = 1, + PrintHTML = null, + DisplayHUD = true, }); string welcomeMsg = player.GetTranslation("welcome_message", "welcome"); @@ -385,6 +387,24 @@ namespace src.player } }); } + + if (Config.LoadedConfig.DisableSkillsOnRoundEnd) + { + isTransmitRegistered = false; + Instance.AddTimer(1f, () => + { + DisableAll(); + foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid && !p.IsBot && !p.IsHLTV && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist)) + { + var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (skillPlayer == null) continue; + skillPlayer.Skill = noneSkill.Skill; + skillPlayer.SpecialSkill = noneSkill.Skill; + skillPlayer.PrintHTML = null; + } + }); + Instance.RemoveListener(CheckTransmit); + } return HookResult.Continue; } } @@ -559,6 +579,7 @@ namespace src.player if (randomSkill.Display) SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(randomSkill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(randomSkill.Skill)}", false); + Instance?.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [player]); skillPlayer.Skill = randomSkill.Skill; skillPlayer.SpecialSkill = Skills.None; diff --git a/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs b/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs index 1a3061d..418ff40 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.Admin; using CounterStrikeSharp.API.Modules.Utils; using src.utils; using static CounterStrikeSharp.API.Core.Listeners; @@ -48,7 +49,7 @@ namespace src.player { if (player == null) return; var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (skillPlayer == null) return; + if (skillPlayer == null || !skillPlayer.DisplayHUD) return; string infoLine = ""; string skillLine = ""; @@ -86,7 +87,7 @@ namespace src.player } } else if (player?.IsValid == true) { - if (player.Team is CsTeam.Spectator or CsTeam.None && Config.LoadedConfig.DisableSpectateHUD) + if ((player.Team is CsTeam.Spectator or CsTeam.None && Config.LoadedConfig.DisableSpectateHUD) || AdminManager.PlayerHasPermissions(player, Config.LoadedConfig.DisableHUDOnDeathPermission)) return; var pawn = player.Pawn.Value; diff --git a/jRandomSkills - SRC Files/src/player/skills/Chicken.cs b/jRandomSkills - SRC Files/src/player/skills/Chicken.cs index 8f24ab8..76bf6b7 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Chicken.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Chicken.cs @@ -112,7 +112,7 @@ namespace src.player.skills { if (string.IsNullOrEmpty(model)) model = player.Team == CsTeam.Terrorist ? defaultTModel : defaultCTModel; - + pawn.SetModel(model); var originalRender = pawn.Render; pawn.Render = Color.FromArgb(255, originalRender.R, originalRender.G, originalRender.B); diff --git a/jRandomSkills - SRC Files/src/player/skills/Replicator.cs b/jRandomSkills - SRC Files/src/player/skills/Replicator.cs index 6a535c7..1275c30 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Replicator.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Replicator.cs @@ -93,7 +93,7 @@ namespace src.player.skills private static void CreateReplica(CCSPlayerController player) { var playerPawn = player.PlayerPawn.Value; - var replica = Utilities.CreateEntityByName("prop_dynamic"); + var replica = Utilities.CreateEntityByName("prop_dynamic_override"); if (replica == null || playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null || playerPawn.AbsRotation == null) return; @@ -105,12 +105,12 @@ namespace src.player.skills replica.Flags = playerPawn.Flags; replica.Flags |= (uint)Flags_t.FL_DUCKING; + replica.Collision.SolidType = SolidType_t.SOLID_VPHYSICS; replica.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(replica.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2)); replica.SetModel(playerPawn!.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.ModelName); replica.Entity!.Name = replica.Globalname = $"Replica_{Server.TickCount}_{(player.Team == CsTeam.CounterTerrorist ? "CT" : "TT")}"; replica.Teleport(pos, playerPawn.AbsRotation, null); replica.DispatchSpawn(); - replica.AcceptInput("EnableCollision"); } public static void OnTakeDamage(DynamicHook h) @@ -121,18 +121,21 @@ namespace src.player.skills if (param == null || param.Entity == null || param2 == null || param2.Attacker == null || param2.Attacker.Value == null) return; - CCSPlayerPawn attackerPawn = new(param2.Attacker.Value.Handle); if (string.IsNullOrEmpty(param.Entity.Name)) return; if (!param.Entity.Name.StartsWith("Replica_")) return; var replica = param.As(); if (replica == null || !replica.IsValid) return; replica.EmitSound("GlassBottle.BulletImpact", volume: 1f); - + replica.AcceptInput("Kill"); + + CCSPlayerPawn attackerPawn = new(param2.Attacker.Value.Handle); + if (attackerPawn.DesignerName != "player") + return; + var attackerTeam = attackerPawn.TeamNum; var replicaTeam = replica.Globalname.EndsWith("CT") ? 3 : 2; SkillUtils.TakeHealth(attackerPawn, attackerTeam != replicaTeam ? 15 : 5); - replica.AcceptInput("Kill"); } public class PlayerSkillInfo diff --git a/jRandomSkills - SRC Files/src/utils/Config.cs b/jRandomSkills - SRC Files/src/utils/Config.cs index 0fae3f4..5649ced 100644 --- a/jRandomSkills - SRC Files/src/utils/Config.cs +++ b/jRandomSkills - SRC Files/src/utils/Config.cs @@ -81,6 +81,8 @@ namespace src.utils public bool DisableSpectateHUD { get; set; } public bool FlashingHtmlHudFix { get; set; } public bool CS2TraceRayDebug { get; set; } + public string DisableHUDOnDeathPermission { get; set; } + public bool DisableSkillsOnRoundEnd { get; set; } public LanguageSystem LanguageSystem { get; set; } public HtmlHudCustomisation HtmlHudCustomisation { get; set; } public NormalCommands NormalCommands { get; set; } @@ -100,6 +102,8 @@ namespace src.utils FlashingHtmlHudFix = true; CS2TraceRayDebug = false; DisableSpectateHUD = false; + DisableHUDOnDeathPermission = "@jRandmosSkills/death"; + DisableSkillsOnRoundEnd = false; LanguageSystem = new LanguageSystem { @@ -141,7 +145,8 @@ namespace src.utils 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"), + ConsoleCommand = new NormalCommand("console, sv, 控制台, 服务器", "@jRandmosSkills/owner"), + HudCommand = new NormalCommand("hud, hood", ""), 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"), @@ -154,7 +159,7 @@ namespace src.utils 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), + SetScoreCommand = new VotingCommand(true, "setscore, wynik, definirPontuacao, configurarPontos, 设置分数, 调整分数", "@jRandmosSkills/owner", 15, 90, 15, 90, 2), }; } } @@ -205,6 +210,7 @@ namespace src.utils public required NormalCommand UseSkillCommand { get; set; } public required NormalCommand HealCommand { get; set; } public required NormalCommand ConsoleCommand { get; set; } + public required NormalCommand HudCommand { get; set; } public required NormalCommand SetStaticSkillCommand { get; set; } public required NormalCommand ChangeLanguageCommand { get; set; } public required NormalCommand ReloadCommand { get; set; } diff --git a/jRandomSkills - SRC Files/src/utils/SkillUtils.cs b/jRandomSkills - SRC Files/src/utils/SkillUtils.cs index 1cba23b..4da1dc6 100644 --- a/jRandomSkills - SRC Files/src/utils/SkillUtils.cs +++ b/jRandomSkills - SRC Files/src/utils/SkillUtils.cs @@ -201,7 +201,7 @@ namespace src.utils if (player == null || !player.IsValid) return; var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo == null) return; + if (playerInfo == null || !playerInfo.DisplayHUD) return; var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == playerInfo.Skill); if (skillData == null) return; diff --git a/jRandomSkills - Server Files/plugins/!jRandomSkills/!jRandomSkills.dll b/jRandomSkills - Server Files/plugins/!jRandomSkills/!jRandomSkills.dll index 87f1aec052ac95707d729706c0e5a8e0b34668ae..7f06bffd43f3681304bbdb027996f151e7cb51e6 100644 GIT binary patch literal 409088 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