This commit is contained in:
Juzlus 2025-09-23 04:53:25 +02:00
parent a36fdbf92d
commit 04a4fdce0d
143 changed files with 3565 additions and 2344 deletions

View file

@ -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;

View file

@ -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<IWasdMenuOption>? Options { get; set; } = new();
public LinkedListNode<IWasdMenuOption>? Prev { get; set; } = null;

View file

@ -123,11 +123,19 @@ public class WasdMenuPlayer
return;
StringBuilder builder = new();
string itemText = "";
string itemHoverText = "";
string endControl = "";
LinkedListNode<IWasdMenuOption>? option = MenuStart;
if (!string.IsNullOrEmpty(option?.Value?.Parent?.Title))
builder.AppendLine($"{option.Value.Parent?.Title}</u><font class='fontSize-m' color='white'><br>");
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 ?? "";
@ -176,10 +184,10 @@ public class WasdMenuPlayer
else
text = SafeSubstring(text, 0, maxLength);
builder.AppendLine($"</font><font color='purple'>[ </font><font color='orange'>{text}</font><font color='purple'> ]</font><font color='white'> <br>");
builder.AppendLine(string.Format(itemHoverText, text));
}
else
builder.AppendLine($"<font color='{color ?? "white"}'>{SafeSubstring(text, 0, maxLength)}</font> <br>");
builder.AppendLine(string.Format(itemText, $"<font {(string.IsNullOrEmpty(color) ? "" : $"color='{color}'")}'>{SafeSubstring(text, 0, maxLength)}</font>"));
option = option.Next;
shown++;
@ -188,7 +196,6 @@ public class WasdMenuPlayer
if (!string.IsNullOrEmpty(endControl))
builder.AppendLine(endControl);
builder.AppendLine("</div>");
CenterHtml = builder.ToString();
}

View file

@ -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<IWasdMenuOption>? Options { get; set; }
// previous option node

View file

@ -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<string, Action<CCSPlayerController, IWasdMenuOption>> list);
}

View file

@ -14,8 +14,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.339" />
<PackageReference Include="CS2TraceRay" Version="1.0.7" />
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.340" />
<PackageReference Include="CS2TraceRay" Version="1.0.8" />
<PackageReference Include="MaxMind.Db" Version="4.2.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

View file

@ -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<string, CommandInfo.CommandCallback> oldCommands = [];
private static readonly object setLock = new();
public static void Load()
{
config = Config.LoadedConfig;
if (config == null || config == null) return;
lock (setLock)
{
if (oldCommands.Count != 0)
{
foreach (var command in oldCommands)
Instance.RemoveCommand(command.Key, command.Value);
oldCommands.Clear();
}
var commands = new Dictionary<IEnumerable<string>, (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) },
{ 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<string> 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,29 +456,36 @@ 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;
lock (setLock)
{
Config.LoadConfig();
SkillsInfo.LoadSkillsInfo();
Localization.Load();
Command.Load();
foreach (var skill in SkillData.Skills)
skill.Color = SkillsInfo.GetValue<string>(skill.Skill, "color");
if (player != null && player.IsValid)
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("reload")}");
else
@ -467,3 +493,4 @@ namespace jRandomSkills
}
}
}
}

View file

@ -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<VoteData> votes = [];
private static readonly ConcurrentDictionary<VoteData, byte> 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<ulong> PlayersVoted { get; set; } = [];
public ConcurrentDictionary<ulong, byte> PlayersVoted { get; set; } = [];
private DateTime CreatedTime { get; set; } = DateTime.Now;
@ -138,15 +139,15 @@ namespace jRandomSkills
public static class VoteTypeCommands
{
private static readonly Dictionary<VoteType, string> 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<VoteType, string> names = new(
[
new KeyValuePair<VoteType, string>(VoteType.StartGame, "css_start"),
new KeyValuePair<VoteType, string>(VoteType.PauseGame, "css_pause"),
new KeyValuePair<VoteType, string>(VoteType.ShuffleTeam, "css_shuffle"),
new KeyValuePair<VoteType, string>(VoteType.SwapTeam, "css_swap"),
new KeyValuePair<VoteType, string>(VoteType.ChangeMap, "css_map"),
new KeyValuePair<VoteType, string>(VoteType.SetScore, "css_setscore"),
]);
public static string GetCommand(VoteType type) => names[type];
}

View file

@ -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<bool>(skill, "active"))
if (SkillsInfo.GetValue<bool>(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)

View file

@ -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": "<font class='fontSize-m' color='cyan'>W/S - Scroll</font> <font class='fontSize-m' color='white'> | </font> <font class='fontSize-m' color='green'>E - Select</font> <br>"
"menu_controlls_scroll": "W/S - Scroll",
"menu_controlls_padding": " | ",
"menu_controlls_select": "E - Select"
}

View file

@ -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": "<font class='fontSize-m' color='cyan'>W/S - Défilement</font> <font class='fontSize-m' color='white'> | </font> <font class='fontSize-m' color='green'>E - Sélectionner</font> <br>"
"menu_controlls_scroll": "W/S - Défilement",
"menu_controlls_padding": " | ",
"menu_controlls_select": "E - Sélectionner"
}

View file

@ -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": "<font class='fontSize-m' color='cyan'>W/S – Przewijanie</font> <font class='fontSize-m' color='white'> | </font> <font class='fontSize-m' color='green'>E - Wybierz</font> <br>"
"menu_controlls_scroll": "W/S – Przewijanie",
"menu_controlls_padding": " | ",
"menu_controlls_select": "E - Wybierz"
}

View file

@ -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": "<font class='fontSize-m' color='cyan'>W/S - Rolar</font> <font class='fontSize-m' color='white'> | </font> <font class='fontSize-m' color='green'>E - Selecionar</font> <br>"
"menu_controlls_scroll": "W/S - Rolar",
"menu_controlls_padding": " | ",
"menu_controlls_select": "E - Selecionar"
}

View file

@ -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": "<font class='fontSize-m' color='cyan'>W/S - 滚动</font> <font class='fontSize-m' color='white'> | </font> <font class='fontSize-m' color='green'>E - 选择</font> <br>"
"menu_controlls_scroll": "W/S - 滚动",
"menu_controlls_padding": " | ",
"menu_controlls_select": "E - 选择"
}

View file

@ -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";

View file

@ -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<string>(Skills.None, "color"), false);
public static readonly jSkill_SkillInfo noneSkill = new(Skills.None, SkillsInfo.GetValue<string>(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<jSkill_SkillInfo> 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<ulong, List<jSkill_SkillInfo>> playersSkills = [];
public static readonly Dictionary<ulong, jSkill_SkillInfo> staticSkills = [];
private static readonly ConcurrentDictionary<ulong, List<jSkill_SkillInfo>> playersSkills = [];
public static readonly ConcurrentDictionary<ulong, jSkill_SkillInfo> staticSkills = [];
private static readonly object setLock = new object();
public static void Load()
{
@ -171,12 +174,15 @@ namespace jRandomSkills
}
private static HookResult PlayerHurt(EventPlayerHurt @event, GameEventInfo info)
{
lock (setLock)
{
foreach (var playerSkill in Instance.SkillPlayer)
if (!playerSkill.IsDrawing)
Instance.SkillAction(playerSkill.Skill.ToString(), "PlayerHurt", [@event]);
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)
if (SkillsInfo.GetValue<bool>(playerSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
return;
else
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));
}
}
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>(CheckTransmit);
int freezetime = ConVar.Find("mp_freezetime")?.GetPrimitiveValue<Int32>() ?? 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")}");
@ -318,6 +322,8 @@ namespace jRandomSkills
}
private static HookResult PlayerDeath(EventPlayerDeath @event, GameEventInfo info)
{
lock (setLock)
{
foreach (var playerSkill in Instance.SkillPlayer)
if (!playerSkill.IsDrawing)
@ -332,7 +338,7 @@ namespace jRandomSkills
Instance.SkillAction(playerInfo.Skill.ToString(), "DisableSkill", [victim]);
if (victim == attacker) return HookResult.Continue;
if (Config.LoadedConfig.Settings.KillerSkillInfo)
if (Config.LoadedConfig.KillerSkillInfo)
{
var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID);
if (attackerInfo != null)
@ -348,10 +354,11 @@ namespace jRandomSkills
}
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<PlayerButtons>(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<bool>(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<jSkill_SkillInfo> 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<jSkill_SkillInfo> 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<jSkill_SkillInfo>? 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<bool>(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<jSkill_SkillInfo> 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<jSkill_SkillInfo>? 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;
if (SkillsInfo.GetValue<bool>(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 = $"<font class='fontSize-{(string.IsNullOrEmpty(headerLine) ? "l" : "ml")}'> </font>";
var emptySymbol2 = $"<font class='fontSize-ml'> </font>";
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo == null) return;
string infoLine = string.IsNullOrEmpty(headerLine)
? ""
: $"<font class='fontWeight-Bold fontSize-{config.HeaderLineSize}' color='{config.HeaderLineColor}'>{headerLine}:</font><br>";
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == playerInfo.Skill);
if (skillData == null) return;
string skillLine = $"{emptySymbol2}<font class='fontWeight-Bold fontSize-{config.SkillLineSize}'>{centerLine}</font>{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 = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
string skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{skillData.Color}'>{player.GetSkillName(skillData.Skill)}</font> <br>";
string remainingLine = $"<font size='0.2' color='#999999'>{skilLDescription} <br>";
string remainingLine = string.IsNullOrWhiteSpace(extraLine)
? ""
: $"<br>{emptySymbol}<font class='fontSize-{(isDescription ? config.SkillDescriptionLineSize : config.InfoLineSize)}' color='{(isDescription ? config.SkillDescriptionLineColor : config.InfoLineColor)}'>{extraLine}</font>{emptySymbol}";
var hudContent = infoLine + skillLine + remainingLine;
player.PrintToCenterHtml(hudContent);

View file

@ -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 = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("none")}</font> <br>";
infoLine = player.GetTranslation("your_skill");
skillLine = player.GetTranslation("none");
}
else if (skillPlayer.IsDrawing)
{
var randomSkill = SkillData.Skills[Instance.Random.Next(SkillData.Skills.Count)];
infoLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("drawing_skill")}:</font> <br>";
skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{randomSkill.Color}'>{player.GetSkillName(randomSkill.Skill)}</font> <br>";
infoLine = player.GetTranslation("drawing_skill");
skillLine = $"<font color='{randomSkill.Color}'>{player.GetSkillName(randomSkill.Skill)}</font>";
}
else if (!skillPlayer.IsDrawing)
{
@ -71,11 +75,21 @@ namespace jRandomSkills
var skillInfo = SkillData.Skills.FirstOrDefault(s => s.Skill == skillPlayer.Skill);
if (skillInfo != null)
{
infoLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{skillInfo.Color}'>{player.GetSkillName(skillInfo.Skill)}</font> <br>";
}
} else if (player?.IsValid == true && Config.LoadedConfig.Settings.DisableSpectateHUD)
infoLine = player.GetTranslation("your_skill");
skillLine = $"<font color='{skillInfo.Color}'>{player.GetSkillName(skillInfo.Skill, skillPlayer.SkillChance)}</font>";
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)
{
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 = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("observer_skill")} {pName}:</font> <br>";
skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{observeredPlayerSkillInfo.Color}'>{(observeredPlayerSkill.SpecialSkill == Skills.None ? player.GetSkillName(observeredPlayerSkillInfo.Skill) : $"{player.GetSkillName(observeredPlayerSpecialSkillInfo.Skill)}({player.GetSkillName(observeredPlayerSkillInfo.Skill)})")}</font> <br>";
var observerSkill = player.GetTranslation("observer_skill");
infoLine = string.IsNullOrEmpty(observerSkill) ? pName : $"{observerSkill} {pName}";
skillLine = $"<font color='{observeredPlayerSkillInfo.Color}'>{(observeredPlayerSkill.SpecialSkill == Skills.None
? player.GetSkillName(observeredPlayerSkillInfo.Skill, observeredPlayerSkill.SkillChance)
: $"{player.GetSkillName(observeredPlayerSpecialSkillInfo.Skill)}({player.GetSkillName(observeredPlayerSkillInfo.Skill)})")}</font>";
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);
}
}
}

View file

@ -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<nint, int> hitGroups = [];
private static readonly ConcurrentDictionary<nint, int> hitGroups = [];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -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,18 +11,18 @@ namespace jRandomSkills
public class Anomaly : ISkill
{
private const Skills skillName = Skills.Anomaly;
private static readonly int maxSize = Config.GetValue<int>(skillName, "secondsInBack");
private static readonly float tickRate = 64;
private static readonly float timerCooldown = Config.GetValue<float>(skillName, "cooldown");
private static readonly Dictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
lock (setLock)
SkillPlayerInfo.Clear();
}
@ -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<int>(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<float>(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 = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
string skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{skillData.Color}'>{player.GetSkillName(skillData.Skill)}</font> <br>";
string remainingLine = cooldown != 0 ? $"<font class='fontSize-m' color='#FFFFFF'>{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}</font> <br>" : "";
var hudContent = infoLine + skillLine + remainingLine;
player.PrintToCenterHtml(hudContent);
if (cooldown == 0)
playerInfo.PrintHTML = null;
else
playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
}
public static void UseSkill(CCSPlayerController player)
@ -121,7 +121,7 @@ namespace jRandomSkills
public List<QAngle>? 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;

View file

@ -12,7 +12,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(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;
}
}
}

View file

@ -11,7 +11,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -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<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -13,7 +13,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"), false);
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(skillName, "ChanceTo") - Config.GetValue<float>(skillName, "ChanceFrom")) + Config.GetValue<float>(skillName, "ChanceFrom");
float newScale = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(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;

View file

@ -8,13 +8,11 @@ namespace jRandomSkills
public class Assassin : ISkill
{
private const Skills skillName = Skills.Assassin;
private static readonly float damageMultiplier = Config.GetValue<float>(skillName, "damageMultiplier");
private static readonly float toleranceDeg = Config.GetValue<float>(skillName, "toleranceDeg");
private static readonly string[] nades = ["inferno", "flashbang", "smokegrenade", "decoy", "hegrenade"];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(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<float>(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;

View file

@ -13,7 +13,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"), false);
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(skillName, "ChanceTo") - Config.GetValue<float>(skillName, "chanceFrom")) + Config.GetValue<float>(skillName, "chanceFrom"), 1);
float gravityModifier = (float)Math.Round(Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "chanceFrom")) + SkillsInfo.GetValue<float>(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;

View file

@ -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<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -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<float>(skillName, "speedMultipier");
private static readonly float maxSpeed = Config.GetValue<float>(skillName, "maxSpeed");
private static readonly int damageDeal = Config.GetValue<int>(skillName, "damageDeal");
private static readonly HashSet<CDecoyProjectile> decoys = [];
private static readonly ConcurrentDictionary<CDecoyProjectile, byte> decoys = [];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<int>(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<float>(skillName, "speedMultipier"), SkillsInfo.GetValue<float>(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;

View file

@ -12,7 +12,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"), false);
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(skillName, "ChanceTo") - Config.GetValue<float>(skillName, "ChanceFrom")) + Config.GetValue<float>(skillName, "ChanceFrom");
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(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;

View file

@ -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<float>(skillName, "torseReflectionChance") * 100;
private static readonly float legReflectionChance = Config.GetValue<float>(skillName, "legReflectionChance") * 100;
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(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<float>(skillName, "legReflectionChance") * 100)
return;
}
else
if (chance > torseReflectionChance)
if (chance > SkillsInfo.GetValue<float>(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;
}
}
}

View file

@ -9,13 +9,10 @@ namespace jRandomSkills
public class BunnyHop : ISkill
{
private const Skills skillName = Skills.BunnyHop;
private static readonly float maxSpeed = Config.GetValue<float>(skillName, "maxSpeed");
private static readonly float bunnyHopVelocity = Config.GetValue<float>(skillName, "jumpVelocity");
private static readonly float jumpBoost = Config.GetValue<float>(skillName, "jumpBoost");
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(skillName, "jumpVelocity");
var maxSpeed = SkillsInfo.GetValue<float>(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<float>(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;

View file

@ -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<ulong, List<uint>> invisibleEntities = [];
private static readonly ConcurrentDictionary<ulong, List<uint>> invisibleEntities = [];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -12,7 +12,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"), false);
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(skillName, "chanceTo") - Config.GetValue<float>(skillName, "chanceFrom")) + Config.GetValue<float>(skillName, "chanceFrom");
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "chanceTo") - SkillsInfo.GetValue<float>(skillName, "chanceFrom")) + SkillsInfo.GetValue<float>(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;

View file

@ -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<CCSPlayerController, CBaseModelEntity> chickens = [];
private static readonly ConcurrentDictionary<CCSPlayerController, CBaseModelEntity> chickens = [];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<CDynamicProp>("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;
string infoLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
string skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{skillData.Color}'>{player.GetSkillName(skillData.Skill)}</font> <br>";
string remainingLine = $"<font class='fontSize-m' color='#FF0000'>{player.GetTranslation("disabled_weapon")}</font> <br>";
var hudContent = infoLine + skillLine + remainingLine;
player.PrintToCenterHtml(hudContent);
if (weapon == null || !disabledWeapons.Contains(weapon.DesignerName))
{
playerInfo.PrintHTML = null;
return;
}
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)
playerInfo.PrintHTML = $"<font color='#FF0000'>{player.GetTranslation("disabled_weapon")}</font>";
}
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)
{
}
}

View file

@ -9,11 +9,10 @@ namespace jRandomSkills
public class ChillOut : ISkill
{
private const Skills skillName = Skills.ChillOut;
private static readonly float bombArmedTime = Config.GetValue<float>(skillName, "bombArmedTime");
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(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;
}

View file

@ -11,7 +11,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -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 Darkness : ISkill
{
private const Skills skillName = Skills.Darkness;
private static readonly float brightness = Config.GetValue<float>(skillName, "brightness");
private static readonly Dictionary<CCSPlayerController, List<CPostProcessingVolume>> defaultPostProcessings = [];
private static readonly List<CPostProcessingVolume> newPostProcessing = [];
private static readonly ConcurrentDictionary<CCSPlayerController, List<CPostProcessingVolume>> defaultPostProcessings = [];
private static readonly ConcurrentBag<CPostProcessingVolume> newPostProcessing = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
lock (setLock)
{
foreach (var player in defaultPostProcessings.Keys)
DisableSkill(player);
@ -30,6 +33,7 @@ namespace jRandomSkills
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
@ -98,10 +102,13 @@ namespace jRandomSkills
}
public static void DisableSkill(CCSPlayerController 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<CPostProcessingVolume>("post_processing_volume");
if (postProcessing == null) return;
var brightness = SkillsInfo.GetValue<float>(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;
}

View file

@ -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<float>(skillName, "jumpVelocity");
private static readonly float pushVelocity = Config.GetValue<float>(skillName, "pushVelocity");
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(skillName, "pushVelocity");
newVelocity.Z = playerPawn.AbsVelocity.Z + SkillsInfo.GetValue<float>(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;

View file

@ -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<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -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<CCSPlayerController> deafPlayers = [];
private static readonly ConcurrentDictionary<CCSPlayerController, byte> deafPlayers = [];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -12,7 +12,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"), false);
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(skillName, "chanceTo") - Config.GetValue<float>(skillName, "chanceFrom")) + Config.GetValue<float>(skillName, "chanceFrom");
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "chanceTo") - SkillsInfo.GetValue<float>(skillName, "chanceFrom")) + SkillsInfo.GetValue<float>(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;

View file

@ -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<CCSPlayerController> distancerPlayers = [];
private static readonly ConcurrentDictionary<CCSPlayerController, byte> distancerPlayers = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
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 = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
string skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{skillData.Color}'>{player.GetSkillName(skillData.Skill)}</font> <br>";
string remainingLine = $"<font class='fontSize-m' color='#FFFFFF'>{closetEnemy}: <font color='{distanceColor}'>{closetDistance}</font></font> <br>";
var hudContent = infoLine + skillLine + remainingLine;
player.PrintToCenterHtml(hudContent);
playerInfo.PrintHTML = $"{closetEnemy}: <font color='{distanceColor}'>{closetDistance}</font>";
}
}
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)
{
}
}

View file

@ -9,11 +9,10 @@ namespace jRandomSkills
public class Dracula : ISkill
{
private const Skills skillName = Skills.Dracula;
private static readonly float healthRegainScale = Config.GetValue<float>(skillName, "healthRegainScale");
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(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;
}

View file

@ -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<string>(skillName, "color"), false);
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<string> 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<bool>(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)
{
}
}

View file

@ -13,7 +13,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"), false);
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(skillName, "maxScale") - Config.GetValue<float>(skillName, "minScale")) + Config.GetValue<float>(skillName, "minScale");
float newSize = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "maxScale") - SkillsInfo.GetValue<float>(skillName, "minScale")) + SkillsInfo.GetValue<float>(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;

View file

@ -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<float>(skillName, "cooldown");
private static readonly float amplitude = Config.GetValue<float>(skillName, "amplitude");
private static readonly float frequency = Config.GetValue<float>(skillName, "frequency");
private static readonly float duration = Config.GetValue<float>(skillName, "duration");
private static readonly float radius = Config.GetValue<float>(skillName, "radius");
private static readonly Dictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
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<float>(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 = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
string skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{skillData.Color}'>{player.GetSkillName(skillData.Skill)}</font> <br>";
string remainingLine = cooldown != 0 ? $"<font class='fontSize-m' color='#FFFFFF'>{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}</font> <br>" : "";
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", $"<font color='#FF0000'>{cooldown}</font>")}";
}
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<float>(skillName, "amplitude");
shake.Frequency = SkillsInfo.GetValue<float>(skillName, "frequency");
shake.Duration = SkillsInfo.GetValue<float>(skillName, "duration");
shake.Radius = SkillsInfo.GetValue<float>(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;

View file

@ -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<float>(skillName, "cooldown");
private static readonly Dictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
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<float>(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<float>(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<float>(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 = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
string skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{skillData.Color}'>{player.GetSkillName(skillData.Skill)}</font> <br>";
string remainingLine = cooldown != 0 ? $"<font class='fontSize-m' color='#FFFFFF'>{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}</font> <br>" : "";
var hudContent = infoLine + skillLine + remainingLine;
player.PrintToCenterHtml(hudContent);
if (cooldown == 0)
playerInfo.PrintHTML = null;
else
playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
}
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;
}
}
}

View file

@ -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<float>(skillName, "damage");
private static readonly float damageRadius = Config.GetValue<float>(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<string>(skillName, "color"), false);
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(skillName, "ChanceTo") - Config.GetValue<float>(skillName, "ChanceFrom")) + Config.GetValue<float>(skillName, "ChanceFrom");
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(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<CHEGrenadeProjectile>("hegrenade_projectile");
if (heProjectile == null || !heProjectile.IsValid) return;
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<CBaseCSGrenadeProjectile>();
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;
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.Damage = SkillsInfo.GetValue<float>(skillName, "damage");
heProjectile.DmgRadius = SkillsInfo.GetValue<float>(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<CEntityInstance>(0);
CTakeDamageInfo param2 = h.GetParam<CTakeDamageInfo>(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;

View file

@ -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<float>(skillName, "distance");
private static readonly Dictionary<ulong, (uint, CDynamicProp)> cameras = [];
private static readonly ConcurrentDictionary<ulong, (uint, CDynamicProp)> cameras = [];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(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<float>(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;
}

View file

@ -12,7 +12,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -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<ulong, int> jumpedPlayers = [];
public static readonly ConcurrentDictionary<ulong, int> jumpedPlayers = [];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"), false);
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(skillName, "ChanceTo") - Config.GetValue<float>(skillName, "ChanceFrom")) + Config.GetValue<float>(skillName, "ChanceFrom");
float newSpeed = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(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;

View file

@ -6,30 +6,31 @@ 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<float>(skillName, "cooldown");
private static readonly int barricadeHealth = Config.GetValue<int>(skillName, "barricadeHealth");
private static readonly string propModel = Config.GetValue<string>(skillName, "propModel");
private static readonly Dictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly Dictionary<ulong, int> barricades = [];
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly ConcurrentDictionary<ulong, int> barricades = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"), false);
Instance.RegisterListener<OnServerPrecacheResources>((ResourceManifest manifest) => manifest.AddResource(propModel));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"), false);
Instance.RegisterListener<OnServerPrecacheResources>((ResourceManifest manifest) => manifest.AddResource(SkillsInfo.GetValue<string>(skillName, "propModel")));
}
public static void NewRound()
{
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<float>(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 = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
string skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{skillData.Color}'>{player.GetSkillName(skillData.Skill)}</font> <br>";
string remainingLine = cooldown != 0 ? $"<font class='fontSize-m' color='#FFFFFF'>{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}</font> <br>" : "";
var hudContent = infoLine + skillLine + remainingLine;
player.PrintToCenterHtml(hudContent);
if (cooldown == 0)
playerInfo.PrintHTML = null;
else
playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
}
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<int>(skillName, "barricadeHealth"));
Server.NextFrame(() =>
{
box.SetModel(propModel);
box.SetModel(SkillsInfo.GetValue<string>(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;

View file

@ -12,20 +12,21 @@ namespace jRandomSkills
public class FragileBomb : ISkill
{
private const Skills skillName = Skills.FragileBomb;
private static int bombHealth = Config.GetValue<int>(skillName, "maxBombHealth");
private static readonly int maxBombHealth = Config.GetValue<int>(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<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
bombHealth = maxBombHealth;
bombHealth = SkillsInfo.GetValue<int>(skillName, "maxBombHealth");
maxBombHealth = SkillsInfo.GetValue<int>(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;
}

View file

@ -9,12 +9,11 @@ namespace jRandomSkills
public class FriendlyFire : ISkill
{
private const Skills skillName = Skills.FriendlyFire;
private static readonly float healthMultiplier = Config.GetValue<float>(skillName, "healthMultiplier");
private static readonly string[] nades = ["inferno", "flashbang", "smokegrenade", "decoy", "hegrenade"];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(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;
}

View file

@ -10,13 +10,11 @@ namespace jRandomSkills
public class FrozenDecoy : ISkill
{
private const Skills skillName = Skills.FrozenDecoy;
private static readonly float decoyRadius = Config.GetValue<float>(skillName, "triggerRadius");
private static readonly int slownessMultiplier = Config.GetValue<int>(skillName, "slownessMultiplier");
private static readonly List<Vector> decoys = [];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(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<int>(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;

View file

@ -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<int>(skillName, "refreshPrice");
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<bool>(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<int>(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<int>(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;
}

View file

@ -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<ulong, List<uint>> invisibleEntities = [];
private static readonly ConcurrentDictionary<ulong, List<uint>> 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<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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;
string infoLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
string skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{skillData.Color}'>{player.GetSkillName(skillData.Skill)}</font> <br>";
string remainingLine = $"<font class='fontSize-m' color='#FF0000'>{player.GetTranslation("disabled_weapon")}</font> <br>";
var hudContent = infoLine + skillLine + remainingLine;
player.PrintToCenterHtml(hudContent);
if (weapon == null || !weapon.IsValid || !disabledWeapons.Contains(weapon.DesignerName))
{
playerInfo.PrintHTML = null;
return;
}
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)
playerInfo.PrintHTML = $"<font color='#FF0000'>{player.GetTranslation("disabled_weapon")}</font>";
}
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)
{
}
}

View file

@ -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<int> smokes = [];
private readonly static ConcurrentDictionary<int, byte> smokes = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
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)
{
}
}

View file

@ -4,21 +4,24 @@ 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<CCSPlayerController> glitchedPlayers = [];
private static readonly ConcurrentDictionary<CCSPlayerController, byte> glitchedPlayers = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
lock (setLock)
glitchedPlayers.Clear();
foreach (var player in Utilities.GetPlayers())
{
@ -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)
{
}
}

View file

@ -11,7 +11,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -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<float>(skillName, "cooldown");
private static readonly float duration = Config.GetValue<float>(skillName, "duration");
private static readonly Dictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
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<float>(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 = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
string skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{skillData.Color}'>{player.GetSkillName(skillData.Skill)}</font> <br>";
string remainingLine = cooldown != 0 ? $"<font class='fontSize-m' color='#FFFFFF'>{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}</font> <br>" : "";
var hudContent = infoLine + skillLine + remainingLine;
player.PrintToCenterHtml(hudContent);
if (cooldown == 0)
playerInfo.PrintHTML = null;
else
playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
}
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<float>(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;

View file

@ -12,7 +12,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -10,13 +10,11 @@ namespace jRandomSkills
public class HealingSmoke : ISkill
{
private const Skills skillName = Skills.HealingSmoke;
private static readonly int smokeHeal = Config.GetValue<int>(skillName, "smokeHeal");
private static readonly float smokeRadius = Config.GetValue<float>(skillName, "smokeRadius");
private static readonly List<Vector> smokes = [];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(skillName, "smokeRadius"))
AddHealth(player.PlayerPawn.Value, SkillsInfo.GetValue<int>(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;

View file

@ -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<string, int> 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<string, int> maxReserveAmmo = dictionary;
private static readonly int healthToAdd = Config.GetValue<int>(skillName, "healthToAdd");
private static readonly ConcurrentDictionary<string, int> ConcurrentDictionary = new(
[
new KeyValuePair<string, int>("weapon_glock", 120), new KeyValuePair<string, int>("weapon_usp_silencer", 24), new KeyValuePair<string, int>("weapon_hkp2000", 52), new KeyValuePair<string, int>("weapon_p250", 26),
new KeyValuePair<string, int>("weapon_cz75", 12), new KeyValuePair<string, int>("weapon_deagle", 35), new KeyValuePair<string, int>("weapon_fiveseven", 100), new KeyValuePair<string, int>("weapon_elite", 120),
new KeyValuePair<string, int>("weapon_tec9", 90), new KeyValuePair<string, int>("weapon_revolver", 8), new KeyValuePair<string, int>("weapon_mac10", 100), new KeyValuePair<string, int>("weapon_mp9", 120),
new KeyValuePair<string, int>("weapon_mp7", 120), new KeyValuePair<string, int>("weapon_mp5", 120), new KeyValuePair<string, int>("weapon_mp5sd", 120), new KeyValuePair<string, int>("weapon_ump45", 100),
new KeyValuePair<string, int>("weapon_p90", 100), new KeyValuePair<string, int>("weapon_bizon", 120), new KeyValuePair<string, int>("weapon_ak47", 90), new KeyValuePair<string, int>("weapon_m4a1", 90),
new KeyValuePair<string, int>("weapon_m4a1_silencer", 80), new KeyValuePair<string, int>("weapon_galilar", 90), new KeyValuePair<string, int>("weapon_famas", 90), new KeyValuePair<string, int>("weapon_aug", 90),
new KeyValuePair<string, int>("weapon_sg556", 90), new KeyValuePair<string, int>("weapon_ssg08", 90), new KeyValuePair<string, int>("weapon_awp", 30), new KeyValuePair<string, int>("weapon_scar20", 90),
new KeyValuePair<string, int>("weapon_g3sg1", 90), new KeyValuePair<string, int>("weapon_nova", 32), new KeyValuePair<string, int>("weapon_xm1014", 32), new KeyValuePair<string, int>("weapon_sawedoff", 32),
new KeyValuePair<string, int>("weapon_mag7", 32), new KeyValuePair<string, int>("weapon_m249", 200), new KeyValuePair<string, int>("weapon_negev", 300)
]);
private static readonly ConcurrentDictionary<string, int> maxReserveAmmo = ConcurrentDictionary;
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<int>(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;
}

View file

@ -10,12 +10,10 @@ namespace jRandomSkills
public class HolyHandGrenade : ISkill
{
private const Skills skillName = Skills.HolyHandGrenade;
private static readonly float damageMultiplier = Config.GetValue<float>(skillName, "damageMultiplier");
private static readonly float damageRadiusMultiplier = Config.GetValue<float>(skillName, "damageRadiusMultiplier");
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(skillName, "damageMultiplier");
hegrenade.DmgRadius *= SkillsInfo.GetValue<float>(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;

View file

@ -15,7 +15,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -11,7 +11,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -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<int>(skillName, "maxStepBeam");
private static readonly Dictionary<CCSPlayerController, List<CBeam>> stepBeams = [];
private static readonly ConcurrentDictionary<CCSPlayerController, List<CBeam>> stepBeams = [];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<int>(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;
}

View file

@ -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<CCSPlayerController> jammedPlayers = [];
private static readonly ConcurrentDictionary<CCSPlayerController, byte> jammedPlayers = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"), false);
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"), false);
}
public static void NewRound()
{
foreach (var player in jammedPlayers)
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)
{
}
}

View file

@ -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<float>(skillName, "minTime");
private static readonly float maxTime = Config.GetValue<float>(skillName, "maxTime");
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(skillName, "minTime");
var maxTime = SkillsInfo.GetValue<float>(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<float>(skillName, "minTime");
var maxTime = SkillsInfo.GetValue<float>(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 = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
string skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{skillData.Color}'>{player.GetSkillName(skillData.Skill)}</font> <br>";
string remainingLine = $"<font class='fontSize-m' color='#FFFFFF'>{player.GetTranslation("jester_mode")}: <font color='{(jesterMode ? "#00ff00" : "#ff0000")}'>{player.GetTranslation(jesterMode ? "jester_on" : "jester_off")}</font></font> <br>";
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")}: <font color='{(jesterMode ? "#00ff00" : "#ff0000")}'>{player.GetTranslation(jesterMode ? "jester_on" : "jester_off")}</font>";
}
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;

View file

@ -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<CCSPlayerPawn, int> bannedPlayers = [];
public static readonly ConcurrentDictionary<CCSPlayerPawn, int> bannedPlayers = [];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -8,11 +8,10 @@ namespace jRandomSkills
public class JumpingJack : ISkill
{
private const Skills skillName = Skills.JumpingJack;
private static readonly int addHealth = Config.GetValue<int>(skillName, "healthToAdd");
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<int>(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;
}

View file

@ -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<float>(skillName, "flashDuration");
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(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;
}

View file

@ -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<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -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<float>(skillName, "maxDistance");
private static bool hooked = false;
private const int actionCode = 503;
private static readonly MemoryFunctionVoid<IntPtr, short> Shoot_Secondary = new(GameData.GetSignature("Shoot_Secondary"));
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<CBasePlayerWeapon>(0);
var action = hook.GetParam<short>(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<CCSPlayerPawn>();
if (pawn == null || !pawn.IsValid || pawn.Controller.Value == null || !pawn.Controller.Value.IsValid) return HookResult.Continue;
var player = pawn.Controller.Value.As<CCSPlayerController>();
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<float>(skillName, "maxDistance");
Ray ray = new(Vector3.Zero);
CTraceFilter filter = new(pawn.Index, pawn.Index)
@ -57,7 +115,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));
@ -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;
}

View file

@ -16,11 +16,10 @@ namespace jRandomSkills
public class LongZeus : ISkill
{
private const Skills skillName = Skills.LongZeus;
private static readonly float maxDistance = Config.GetValue<float>(skillName, "maxDistance");
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(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;
}

View file

@ -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<uint>(skillName, "customFOV");
private static readonly Dictionary<CCSPlayerController, uint> playersFOV = [];
private static readonly ConcurrentDictionary<CCSPlayerController, uint> playersFOV = [];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<uint>(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;
}

View file

@ -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<int>(skillName, "healthToAdd");
private static readonly int healthShotLimit = Config.GetValue<int>(skillName, "healthShotLimit");
private static readonly float timerCooldown = Config.GetValue<float>(skillName, "cooldown");
private static readonly Dictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
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<int>(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<float>(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 = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
string skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{skillData.Color}'>{player.GetSkillName(skillData.Skill)}</font> <br>";
string remainingLine = cooldown != 0
? $"<font class='fontSize-m' color='#FFFFFF'>{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}</font> <br>"
: $"<font class='fontSize-m' color='#{(skillInfo == null || skillInfo.Count == 0 ? "FF0000" : "00FF00")}'>{(skillInfo == null ? 0 : skillInfo.Count)}/{healthShotLimit}</font> <br>";
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", $"<font color='#FF0000'>{cooldown}</font>")}"
: $"<font color='#{(skillInfo == null || skillInfo.Count == 0 ? "FF0000" : "00FF00")}'>{(skillInfo == null ? 0 : skillInfo.Count)}/{SkillsInfo.GetValue<int>(skillName, "healthShotLimit")}</font>";
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<int>(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;

View file

@ -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<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -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<float>(skillName, "explosionRadius");
private static readonly int explosionDamage = Config.GetValue<int>(skillName, "explosionDamage");
private static readonly QAngle angle = new(10, -5, 9);
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void PlayerDeath(EventPlayerDeath @event)
@ -32,39 +30,50 @@ namespace jRandomSkills
private static void SpawnExplosion(CCSPlayerController player)
{
var heProjectile = Utilities.CreateEntityByName<CHEGrenadeProjectile>("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<CBaseCSGrenadeProjectile>();
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.Damage = SkillsInfo.GetValue<int>(skillName, "explosionDamage");
heProjectile.DmgRadius = SkillsInfo.GetValue<float>(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;

View file

@ -5,25 +5,25 @@ 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<float>(skillName, "idlePercentInvisibility");
private static readonly float duckPercentInvisibility = Config.GetValue<float>(skillName, "duckPercentInvisibility");
private static readonly float knifePercentInvisibility = Config.GetValue<float>(skillName, "knifePercentInvisibility");
private static readonly Dictionary<nint, float> invisibilityChanged = [];
private static readonly Dictionary<ulong, List<uint>> invisibleEntities = [];
private static readonly ConcurrentDictionary<nint, float> invisibilityChanged = [];
private static readonly ConcurrentDictionary<ulong, List<uint>> invisibleEntities = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
lock (setLock)
invisibilityChanged.Clear();
}
@ -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<float>(skillName, "duckPercentInvisibility");
if (activeWeapon != null && activeWeapon.DesignerName == "weapon_knife")
percentInvisibility += knifePercentInvisibility;
percentInvisibility += SkillsInfo.GetValue<float>(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<float>(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;

View file

@ -11,7 +11,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -12,7 +12,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -4,23 +4,24 @@ 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<float>(skillName, "cooldown");
private static readonly float duration = Config.GetValue<float>(skillName, "duration");
private static readonly Dictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
lock (setLock)
SkillPlayerInfo.Clear();
}
@ -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<float>(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<float>(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 = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
string skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{skillData.Color}'>{player.GetSkillName(skillData.Skill)}</font> <br>";
string remainingLine = cooldown != 0
? (
flying != 0
? $"<font class='fontSize-m' color='#FFFFFF'>{player.GetTranslation("active_hud_info", $"<font color='#00FF00'>{Math.Round(flying / 100, 2)}</font>")}</font> <br>"
: $"<font class='fontSize-m' color='#FFFFFF'>{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}</font> <br>"
) : "";
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", $"<font color='#00FF00'>{Math.Round(flying / 100, 2)}</font>")}"
: $"{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
}
public static void UseSkill(CCSPlayerController player)
{
var playerPawn = player.PlayerPawn.Value;
var duration = SkillsInfo.GetValue<float>(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;

View file

@ -9,10 +9,10 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"), false);
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -12,7 +12,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -12,7 +12,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -10,16 +10,13 @@ namespace jRandomSkills
public class PawelJumper : ISkill
{
private const Skills skillName = Skills.PawelJumper;
private static readonly int extraJumpsMin = Config.GetValue<int>(skillName, "extraJumpsMin");
private static readonly int extraJumpsMax = Config.GetValue<int>(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<string>(skillName, "color"), false);
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<int>(skillName, "extraJumpsMin"), SkillsInfo.GetValue<int>(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;

View file

@ -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<string>(skillName, "color"), false);
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"), false);
}
public static void PlayerDeath(EventPlayerDeath @event)
@ -24,10 +25,13 @@ namespace jRandomSkills
if (playerInfo?.Skill == skillName)
{
if (Instance.Random.NextDouble() <= playerInfo.SkillChance)
{
lock (setLock)
{
player.Respawn();
Instance.AddTimer(.2f, () => player.Respawn());
SkillUtils.PrintToChat(player, player.GetTranslation("phoenix_respawn"), false); ;
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<float>(skillName, "ChanceTo") - Config.GetValue<float>(skillName, "ChanceFrom")) + Config.GetValue<float>(skillName, "ChanceFrom");
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(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;

View file

@ -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<float>(skillName, "maximumFuel");
private static readonly float fuelConsumption = Config.GetValue<float>(skillName, "fuelConsumption");
private static readonly float refuelling = Config.GetValue<float>(skillName, "refuelling");
private static readonly Dictionary<ulong, Pilot_PlayerInfo> PlayerPilotInfo = [];
private static readonly ConcurrentDictionary<ulong, Pilot_PlayerInfo> PlayerPilotInfo = [];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(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<float>(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<float>(skillName, "fuelConsumption") : -SkillsInfo.GetValue<float>(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<float>(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 = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
string skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{skillData.Color}'>{player.GetSkillName(skillData.Skill)}</font> <br>";
string remainingLine = $"<font class='fontSize-m' color='#ffffff'>{player.GetTranslation("pilot_hud_info")}:</font> <font color='{fuelColor}'>{(pilotInfo.Fuel/maximumFuel)*100:F0}%</font> <br>";
var hudContent = infoLine + skillLine + remainingLine;
player.PrintToCenterHtml(hudContent);
playerInfo.PrintHTML = $"{player.GetTranslation("pilot_hud_info")}: <font color='{fuelColor}'>{(pilotInfo.Fuel/maximumFuel)*100:F0}%</font>";
}
private static string GetFuelColor(float fuelPercentage)
{
var maximumFuel = SkillsInfo.GetValue<float>(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;

View file

@ -10,11 +10,10 @@ namespace jRandomSkills
public class Planter : ISkill
{
private const Skills skillName = Skills.Planter;
private static readonly int extraC4BlowTime = Config.GetValue<int>(skillName, "extraC4BlowTime");
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void BombPlanted(EventBombPlanted @event)
@ -27,7 +26,7 @@ namespace jRandomSkills
var plantedBomb = Utilities.FindAllEntitiesByDesignerName<CPlantedC4>("planted_c4").FirstOrDefault();
if (plantedBomb != null)
Server.NextFrame(() => plantedBomb.C4Blow = (float)Server.EngineTime + extraC4BlowTime);
Server.NextFrame(() => plantedBomb.C4Blow = (float)Server.EngineTime + SkillsInfo.GetValue<int>(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<bool>(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;
}

View file

@ -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<float>(skillName, "Cooldown");
private static readonly int healthToDamage = Config.GetValue<int>(skillName, "Damage");
private static readonly HashSet<CCSPlayerController> poisonedPlayers = [];
private static readonly ConcurrentDictionary<CCSPlayerController, byte> poisonedPlayers = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"), false);
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"), false);
}
public static void NewRound()
{
lock (setLock)
poisonedPlayers.Clear();
}
public static void OnTick()
{
if (Server.TickCount % (int)(64 * cooldown) == 0)
if (Server.TickCount % (int)(64 * SkillsInfo.GetValue<float>(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<int>(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;

View file

@ -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<ulong> bannedPlayers = [];
private static readonly ConcurrentDictionary<ulong, byte> 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,22 +21,25 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
lock (setLock)
{
bannedPlayers.Clear();
foreach (var player in Utilities.GetPlayers())
SkillUtils.CloseMenu(player);
}
}
public static void WeaponEquip(EventItemEquip @event)
{
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)
{
}
}

View file

@ -12,7 +12,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -4,28 +4,31 @@ 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<CCSPlayerPawn, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly ConcurrentDictionary<CCSPlayerPawn, PlayerSkillInfo> SkillPlayerInfo = [];
private static Vector? bombLocation = null;
private static readonly float maxDefusingRange = Config.GetValue<float>(skillName, "maxDefusingRange");
private static readonly float defusingTime = Config.GetValue<float>(skillName, "defusingTime");
private static readonly float tickRate = 64f;
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
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<CCSPlayerController>();
if (player == null || !player.IsValid) return;
if (pawn.AbsOrigin == null || SkillUtils.GetDistance(pawn.AbsOrigin, bombLocation) > SkillsInfo.GetValue<float>(skillName, "maxDefusingRange"))
{
info.Defusing = false;
info.DefusingTime = defusingTime;
info.DefusingTime = SkillsInfo.GetValue<float>(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<CCSPlayerController>(), 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<float>(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 = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
string skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{skillData.Color}'>{player.GetSkillName(skillData.Skill)}</font> <br>";
string remainingLine = cooldown != 0 ? $"<font class='fontSize-m' color='#FFFFFF'>{player.GetTranslation("psychicdefusing_hud_info", $"<font color='#00d5ff'>{cooldown}</font>")}</font> <br>" : "";
var hudContent = infoLine + skillLine + remainingLine;
player.PrintToCenterHtml(hudContent);
if (cooldown == 0)
playerInfo.PrintHTML = null;
else
playerInfo.PrintHTML = $"{player.GetTranslation("psychicdefusing_hud_info", $"<font color='#00d5ff'>{cooldown}</font>")}";
}
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;

View file

@ -9,12 +9,10 @@ namespace jRandomSkills
public class Push : ISkill
{
private const Skills skillName = Skills.Push;
private static readonly float jumpVelocity = Config.GetValue<float>(skillName, "jumpVelocity");
private static readonly float pushVelocity = Config.GetValue<float>(skillName, "pushVelocity");
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"), false);
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(skillName, "ChanceTo") - Config.GetValue<float>(skillName, "ChanceFrom")) + Config.GetValue<float>(skillName, "ChanceFrom");
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(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<float>(skillName, "pushVelocity");
newVelocity.Z = player.PlayerPawn.Value.AbsVelocity.Z + SkillsInfo.GetValue<float>(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;

View file

@ -10,11 +10,10 @@ namespace jRandomSkills
public class Pyro : ISkill
{
private const Skills skillName = Skills.Pyro;
private static readonly float regenerationMultiplier = Config.GetValue<float>(skillName, "regenerationMultiplier");
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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<float>(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;
}

View file

@ -12,7 +12,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -12,7 +12,7 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(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)
{
}
}

View file

@ -9,17 +9,15 @@ namespace jRandomSkills
public class Rambo : ISkill
{
private const Skills skillName = Skills.Rambo;
private static readonly int minExtraHealth = Config.GetValue<int>(skillName, "minExtraHealth");
private static readonly int maxExtraHealth = Config.GetValue<int>(skillName, "maxExtraHealth");
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void EnableSkill(CCSPlayerController player)
{
int healthBonus = Instance.Random.Next(minExtraHealth, maxExtraHealth);
int healthBonus = Instance.Random.Next(SkillsInfo.GetValue<int>(skillName, "minExtraHealth"), SkillsInfo.GetValue<int>(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;

View file

@ -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<float>(skillName, "cooldown");
private static readonly Dictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> 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,11 +25,12 @@ namespace jRandomSkills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, Config.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
lock (setLock)
SkillPlayerInfo.Clear();
}
@ -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<float>(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 = $"<font class='fontSize-l' class='fontWeight-Bold' color='#FFFFFF'>{player.GetTranslation("your_skill")}:</font> <br>";
string skillLine = $"<font class='fontSize-l' class='fontWeight-Bold' color='{skillData.Color}'>{player.GetSkillName(skillData.Skill)}</font> <br>";
string remainingLine = cooldown != 0 ? $"<font class='fontSize-m' color='#FFFFFF'>{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}</font> <br>" : "";
var hudContent = infoLine + skillLine + remainingLine;
player.PrintToCenterHtml(hudContent);
if (cooldown == 0)
playerInfo.PrintHTML = null;
else
playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
}
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;
}

Some files were not shown because too many files have changed in this diff Show more