diff --git a/jRandomSkills - SRC Files/jRandomSkills.csproj b/jRandomSkills - SRC Files/jRandomSkills.csproj
index 4e71fe3..2fc4f87 100644
--- a/jRandomSkills - SRC Files/jRandomSkills.csproj
+++ b/jRandomSkills - SRC Files/jRandomSkills.csproj
@@ -1,70 +1,86 @@
-
- net8.0
- enable
- enable
- true
-
+
+ net8.0
+ enable
+ enable
+ true
+ true
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- True
- Resources.resx
-
-
-
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
-
-
-
-
- $(MSBuildProjectDirectory)\src\lang
- $(MSBuildProjectDirectory)\..\jRandomSkills - Server Files\plugins\jRandomSkills\languages
- $(MSBuildProjectDirectory)\bin\Debug\net8.0
- $(MSBuildProjectDirectory)\..\jRandomSkills - Server Files\plugins\jRandomSkills
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+
+ $(MSBuildProjectDirectory)\src\lang
+ $(MSBuildProjectDirectory)\..\jRandomSkills - Server Files\plugins\jRandomSkills\languages
+ $(MSBuildProjectDirectory)\bin\Debug\net8.0
+ $(MSBuildProjectDirectory)\..\jRandomSkills - Server Files\plugins\jRandomSkills
+ $(MSBuildProjectDirectory)\src\gamedata
+ $(MSBuildProjectDirectory)\..\jRandomSkills - Server Files\gamedata
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jRandomSkills - SRC Files/src/command/VoteSystem.cs b/jRandomSkills - SRC Files/src/command/VoteSystem.cs
index fc8b944..801b7c0 100644
--- a/jRandomSkills - SRC Files/src/command/VoteSystem.cs
+++ b/jRandomSkills - SRC Files/src/command/VoteSystem.cs
@@ -3,6 +3,7 @@ using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
+using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
namespace src.command
{
@@ -10,6 +11,20 @@ namespace src.command
{
private static readonly ConcurrentDictionary votes = [];
+ private static void StartVoteTimer(VoteData vote, string commandName)
+ {
+ vote.ActiveTimer?.Kill();
+
+ vote.ActiveTimer = jRandomSkills.Instance.AddTimer(vote.TimeToVote, () =>
+ {
+ if (!votes.ContainsKey(vote) || !vote.GetActive()) return;
+
+ vote.SetActive(false);
+ vote.TimeToNextSameVoting = vote.TimeToNextVoting;
+ Localization.PrintTranslationToChatAll($" {ChatColors.Red}{{0}}", ["vote_timeout"], [commandName]);
+ });
+ }
+
private static VoteData? CreateVote(VoteType voteType, string? args = null)
{
var vote = new VoteData(10,
@@ -27,21 +42,15 @@ namespace src.command
foreach (var player in Utilities.GetPlayers())
player.EmitSound("UIPanorama.tab_mainmenu_news");
- if (vote == null) return vote;
- jRandomSkills.Instance.AddTimer(vote.TimeToVote, () =>
- {
- if (!votes.ContainsKey(vote) || !vote.GetActive()) return;
- vote.SetActive(false);
- vote.TimeToNextSameVoting = vote.TimeToNextVoting;
- Localization.PrintTranslationToChatAll($" {ChatColors.Red}{{0}}", ["vote_timeout"], [commandName]);
- });
+ StartVoteTimer(vote!, commandName);
- float[] times = [vote.TimeToVote, vote.TimeToVote + vote.TimeToNextVoting, vote.TimeToVote + vote.TimeToNextSameVoting];
+ float[] times = [vote!.TimeToVote, vote.TimeToVote + vote.TimeToNextVoting, vote.TimeToVote + vote.TimeToNextSameVoting];
jRandomSkills.Instance.AddTimer(times.Max(), () =>
{
if (!votes.ContainsKey(vote)) return;
votes.TryRemove(vote, out _);
});
+
return vote;
}
@@ -78,16 +87,21 @@ namespace src.command
private static void CheckVote(VoteData vote)
{
int voted = vote.PlayersVoted.Count;
- int playerCount = Utilities.GetPlayers().Where(p => !p.IsBot).ToArray().Length;
+ int playerCount = Utilities.GetPlayers().Count(p => !p.IsBot);
int playersNeeded = (int)Math.Ceiling(playerCount * (vote.PercentagesToSuccess / 100f));
+ string commandName = $"!{VoteTypeCommands.GetCommand(vote.Type)?.Replace("css_", "")}{(!string.IsNullOrEmpty(vote?.Args) ? $" {vote?.Args}" : "")}";
if (voted >= playersNeeded)
{
+ vote!.ActiveTimer?.Kill();
vote.SuccessAction.Invoke();
vote.SetActive(false);
}
else
- Localization.PrintTranslationToChatAll($" {ChatColors.Yellow}{{0}} '!{VoteTypeCommands.GetCommand(vote.Type)?.Replace("css_", "")}{(!string.IsNullOrEmpty(vote?.Args) ? $" {vote?.Args}" : "")}': {ChatColors.Green}{voted}/{playersNeeded}", ["vote_vote"]);
+ {
+ StartVoteTimer(vote!, commandName);
+ Localization.PrintTranslationToChatAll($" {ChatColors.Yellow}{{0}} '': {ChatColors.Green}{voted}/{playersNeeded}", ["vote_vote"]);
+ }
}
}
@@ -103,7 +117,7 @@ namespace src.command
public VoteType Type { get; set; } = type;
public string? Args { get; set; } = args;
public ConcurrentDictionary PlayersVoted { get; set; } = [];
-
+ public Timer? ActiveTimer { get; set; }
private DateTime CreatedTime { get; set; } = DateTime.Now;
public void SetActive(bool active)
diff --git a/jRandomSkills - SRC Files/src/gamedata/jRandomSkills.gamedata.json b/jRandomSkills - SRC Files/src/gamedata/jRandomSkills.gamedata.json
new file mode 100644
index 0000000..b393a45
--- /dev/null
+++ b/jRandomSkills - SRC Files/src/gamedata/jRandomSkills.gamedata.json
@@ -0,0 +1,23 @@
+{
+ "SmokeGrenadeProjectile_CreateFunc": {
+ "signatures": {
+ "library": "server",
+ "windows": "48 8B C4 48 89 58 ? 48 89 68 ? 48 89 70 ? 57 41 56 41 57 48 81 EC ? ? ? ? 48 8B B4 24 ? ? ? ? 4D 8B F8",
+ "linux": "55 4C 89 C1 48 89 E5 41 57 49 89 FF 41 56 45 89 CE"
+ }
+ },
+ "HEGrenadeProjectile_CreateFunc": {
+ "signatures": {
+ "library": "server",
+ "windows": "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC ? 48 8B AC 24 ? ? ? ? 49 8B F8",
+ "linux": "55 4C 89 C1 48 89 E5 41 57 49 89 D7"
+ }
+ },
+ "Shoot_Secondary": {
+ "signatures": {
+ "library": "server",
+ "windows": "48 89 5C 24 ? 57 48 83 EC 20 44 0F BF C2",
+ "linux": "55 48 89 E5 41 54 53 48 89 FB 66 83 FE 65"
+ }
+ }
+}
\ No newline at end of file
diff --git a/jRandomSkills - SRC Files/src/jRandomSkills.cs b/jRandomSkills - SRC Files/src/jRandomSkills.cs
index c8aa550..06db794 100644
--- a/jRandomSkills - SRC Files/src/jRandomSkills.cs
+++ b/jRandomSkills - SRC Files/src/jRandomSkills.cs
@@ -27,7 +27,7 @@ namespace src
public override string ModuleName => "[CS2] [ jRandomSkills ]";
public override string ModuleAuthor => "D3X, Juzlus";
public override string ModuleDescription => "Plugin adds random skills every round for CS2 by D3X. Modified by Juzlus.";
- public override string ModuleVersion => "1.10.0";
+ public override string ModuleVersion => "1.2.1";
public override void Load(bool hotReload)
{
diff --git a/jRandomSkills - SRC Files/src/player/ISkill.cs b/jRandomSkills - SRC Files/src/player/ISkill.cs
index 5911433..8a85a49 100644
--- a/jRandomSkills - SRC Files/src/player/ISkill.cs
+++ b/jRandomSkills - SRC Files/src/player/ISkill.cs
@@ -100,6 +100,7 @@ public enum Skills
Hermit,
HolyHandGrenade,
Iana,
+ Illiterate,
Impostor,
InfiniteAmmo,
Jackal,
@@ -150,6 +151,7 @@ public enum Skills
Shade,
ShortBomb,
Silent,
+ Smoker,
SniperElite,
Soldier,
SoundMaker,
diff --git a/jRandomSkills - SRC Files/src/player/PlayerEvents.cs b/jRandomSkills - SRC Files/src/player/PlayerEvents.cs
index 1050774..2718ecc 100644
--- a/jRandomSkills - SRC Files/src/player/PlayerEvents.cs
+++ b/jRandomSkills - SRC Files/src/player/PlayerEvents.cs
@@ -8,15 +8,18 @@ using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.UserMessages;
using CounterStrikeSharp.API.Modules.Utils;
+using src.player.skills;
using src.utils;
using System.Collections.Concurrent;
using static CounterStrikeSharp.API.Core.Listeners;
using static src.jRandomSkills;
+using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
namespace src.player
{
public static partial class Event
{
+ private static Timer? setSkillTimer = null;
private static DateTime freezeTimeEnd = DateTime.MinValue;
private static bool isTransmitRegistered = false;
public static readonly jSkill_SkillInfo noneSkill = new(Skills.None, SkillsInfo.GetValue(Skills.None, "color"), false);
@@ -39,6 +42,7 @@ namespace src.player
Instance.RegisterEventHandler(PlayerConnectFull);
Instance.RegisterEventHandler(PlayerDisconnect);
// Instance.RegisterEventHandler(PlayerChat);
+ Instance.RegisterEventHandler(PlayerSpawned);
Instance.RegisterEventHandler(RoundStart);
Instance.RegisterEventHandler(RoundEnd);
@@ -384,6 +388,32 @@ namespace src.player
return HookResult.Continue;
}
+ private static HookResult PlayerSpawned(EventPlayerSpawned @event, GameEventInfo info)
+ {
+ lock (setLock)
+ {
+ var player = @event.Userid;
+ if (player == null || !player.IsValid) return HookResult.Continue;
+
+ var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
+ if (skillPlayer == null) return HookResult.Continue;
+
+ if (setSkillTimer != null)
+ {
+ skillPlayer.IsDrawing = true;
+ return HookResult.Continue;
+ }
+
+ skillPlayer.IsDrawing = false;
+ if (Instance?.GameRules != null &&
+ Instance?.GameRules.WarmupPeriod == false &&
+ skillPlayer.Skill == Skills.None &&
+ skillPlayer.SpecialSkill == Skills.None)
+ SetRandomSkill(player);
+ return HookResult.Continue;
+ }
+ }
+
private static HookResult RoundStart(EventRoundStart @event, GameEventInfo info)
{
lock (setLock)
@@ -401,7 +431,11 @@ namespace src.player
Instance.RemoveListener(CheckTransmit);
int freezetime = ConVar.Find("mp_freezetime")?.GetPrimitiveValue() ?? 0;
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);
+
+ setSkillTimer?.Kill();
+
+ float timeToDraw = (Instance?.GameRules?.TeamIntroPeriod == true ? 7 : 0) + Math.Max(freezetime - Config.LoadedConfig.SkillTimeBeforeStart, 0) + .3f;
+ setSkillTimer = Instance?.AddTimer(timeToDraw, SetSkill);
return HookResult.Continue;
}
}
@@ -447,6 +481,7 @@ namespace src.player
private static HookResult RoundEnd(EventRoundEnd @event, GameEventInfo info)
{
+ Illiterate.Disable();
lock (setLock)
{
foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid))
@@ -567,6 +602,7 @@ namespace src.player
private static void SetSkill()
{
+ setSkillTimer = null;
lock (setLock)
{
var validPlayers = Utilities.GetPlayers().Where(p => p.IsValid && !p.IsBot && !p.IsHLTV && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist).ToList();
@@ -670,14 +706,20 @@ namespace src.player
skillPlayer.Skill = randomSkill.Skill;
skillPlayer.SpecialSkill = Skills.None;
- if (SkillsInfo.GetValue(randomSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
- Instance?.AddTimer(Config.LoadedConfig.SkillTimeBeforeStart, () =>
- {
- if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID && p.Skill == randomSkill.Skill) == null) return;
+ if (randomSkill.Skill == Skills.Illiterate)
+ Illiterate.Enable();
+
+ Instance?.AddTimer(.2f, () =>
+ {
+ if (SkillsInfo.GetValue(randomSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
+ Instance?.AddTimer(Config.LoadedConfig.SkillTimeBeforeStart, () =>
+ {
+ if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID && p.Skill == randomSkill.Skill) == null) return;
+ Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]);
+ });
+ else
Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]);
- });
- else
- Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]);
+ });
Debug.WriteToDebug($"Player {skillPlayer.PlayerName} has got the skill \"{player.GetSkillName(randomSkill.Skill)}\".");
skillPlayer.SkillHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillHudDuration);
@@ -685,7 +727,7 @@ namespace src.player
if (Config.LoadedConfig.TeamMateSkillChatInfo)
{
- Instance?.AddTimer(.5f, () =>
+ Instance?.AddTimer(.6f, () =>
{
foreach (var teammate in teammates)
{
@@ -732,6 +774,7 @@ namespace src.player
var skillPlayer = Instance?.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (skillPlayer == null) return;
+ skillPlayer.IsDrawing = false;
if (player.PlayerPawn.Value == null || !player.PlayerPawn.IsValid)
{
skillPlayer.Skill = Skills.None;
@@ -792,13 +835,20 @@ namespace src.player
skillPlayer.Skill = randomSkill.Skill;
skillPlayer.SpecialSkill = Skills.None;
- if (SkillsInfo.GetValue(randomSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
- Instance?.AddTimer(Config.LoadedConfig.SkillTimeBeforeStart, () => {
- if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID && p.Skill == randomSkill.Skill) == null) return;
+ if (randomSkill.Skill == Skills.Illiterate)
+ Illiterate.Enable();
+
+ Instance?.AddTimer(.2f, () =>
+ {
+ if (SkillsInfo.GetValue(randomSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
+ Instance?.AddTimer(Config.LoadedConfig.SkillTimeBeforeStart, () =>
+ {
+ if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID && p.Skill == randomSkill.Skill) == null) return;
+ Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]);
+ });
+ else
Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]);
- });
- else
- Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]);
+ });
Debug.WriteToDebug($"Player {skillPlayer.PlayerName} has got the skill \"{player.GetSkillName(randomSkill.Skill)}\".");
skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration);
@@ -820,6 +870,14 @@ namespace src.player
lock (setLock)
{
if (player == null || !player.IsValid) return;
+
+ if (Illiterate.CheckIlliterateSkill(player))
+ {
+ headerLine = Illiterate.GetRandomText(headerLine);
+ centerLine = Illiterate.GetRandomText(centerLine);
+ extraLine = Illiterate.GetRandomText(extraLine);
+ }
+
var config = Config.LoadedConfig.HtmlHudCustomisation;
var emptySymbol = $"";
var emptySymbol2 = $" ";
diff --git a/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs b/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs
index 94099ae..0412210 100644
--- a/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs
+++ b/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs
@@ -62,7 +62,7 @@ namespace src.player
infoLine = player.GetTranslation("your_skill");
skillLine = player.GetTranslation("none");
}
- else if (skillPlayer.IsDrawing)
+ else if (skillPlayer.IsDrawing && player.PawnIsAlive)
{
var randomSkill = SkillData.Skills.ToArray()[Instance.Random.Next(SkillData.Skills.Count)];
infoLine = player.GetTranslation("drawing_skill");
diff --git a/jRandomSkills - SRC Files/src/player/skills/Baseball.cs b/jRandomSkills - SRC Files/src/player/skills/Baseball.cs
index 21e0a73..595f1aa 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Baseball.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Baseball.cs
@@ -51,6 +51,9 @@ namespace src.player.skills
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo?.Skill != skillName) return;
decoys.TryAdd(decoy, 0);
+
+ decoy.Collision.CollisionAttribute.InteractsWith = pawn.Collision.CollisionAttribute.InteractsWith;
+ decoy.Collision.CollisionGroup = pawn.Collision.CollisionGroup;
}
public static void DecoyStarted(EventDecoyStarted @event)
diff --git a/jRandomSkills - SRC Files/src/player/skills/C4Camouflage.cs b/jRandomSkills - SRC Files/src/player/skills/C4Camouflage.cs
index 2d2ead8..077dfe3 100644
--- a/jRandomSkills - SRC Files/src/player/skills/C4Camouflage.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/C4Camouflage.cs
@@ -1,7 +1,6 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes;
-using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
@@ -62,8 +61,19 @@ namespace src.player.skills
foreach (var (info, player) in infoList)
{
if (player == null || !player.IsValid) continue;
+
+ var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero;
+ bool isObservingC4Camouflage = false;
+
+ if (targetHandle != nint.Zero)
+ {
+ var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle);
+ var targetInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == target?.SteamID);
+ if (targetInfo?.Skill == skillName) isObservingC4Camouflage = true;
+ }
+
foreach (var _player in invisiblePlayers.Keys)
- if (player.SteamID != _player.SteamID)
+ if (player.SteamID != _player.SteamID && !isObservingC4Camouflage)
{
var playerPawn = _player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) continue;
diff --git a/jRandomSkills - SRC Files/src/player/skills/Cypher.cs b/jRandomSkills - SRC Files/src/player/skills/Cypher.cs
index fd8b4bb..59c7e6d 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Cypher.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Cypher.cs
@@ -151,12 +151,13 @@ namespace src.player.skills
pawn!.CameraServices!.ViewEntity.Raw = player.CameraView.EntityHandle.Raw;
SkillUtils.ApplyScreenColor(player.Player, 0, 0, 255, 20, 100, 1020);
- Timer? cameraTimer = null;
- ulong playerSteamID = player.Player.SteamID;
+ ulong? playerSteamID = player.Player?.SteamID;
+ if (playerSteamID == null) return;
+ Timer? cameraTimer = null;
cameraTimer = jRandomSkills.Instance.AddTimer(2f, () =>
{
- var target = Utilities.GetPlayerFromSteamId(playerSteamID);
+ var target = Utilities.GetPlayers().FirstOrDefault(p => p.IsValid && p.SteamID == playerSteamID);
if (target == null || !target.IsValid || !target.PawnIsAlive)
{
cameraTimer?.Kill();
diff --git a/jRandomSkills - SRC Files/src/player/skills/Darkness.cs b/jRandomSkills - SRC Files/src/player/skills/Darkness.cs
index 9113c0b..4d0af6d 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Darkness.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Darkness.cs
@@ -112,24 +112,26 @@ namespace src.player.skills
private static void SetUpPostProcessing(CCSPlayerController player, bool turnOff = false)
{
if (player == null || !player.IsValid) return;
- ulong playerSteamID = player.SteamID;
+
+ ulong? playerSteamID = player?.SteamID;
+ if (playerSteamID == null) return;
lock (setLock)
{
if (!turnOff)
{
- playersInDark.TryAdd(playerSteamID, 0);
+ playersInDark.TryAdd((ulong)playerSteamID, 0);
ApplyColor(player);
Timer? darkTimer = null;
darkTimer = Instance.AddTimer(5f, () => {
- if (!playersInDark.ContainsKey(playerSteamID))
+ if (!playersInDark.ContainsKey((ulong)playerSteamID))
{
darkTimer?.Kill();
return;
}
- var target = Utilities.GetPlayerFromSteamId(playerSteamID);
+ var target = Utilities.GetPlayers().FirstOrDefault(p => p.IsValid && p.SteamID == playerSteamID);
if (target == null || !target.IsValid)
{
darkTimer?.Kill();
@@ -137,18 +139,18 @@ namespace src.player.skills
}
if (target.PawnIsAlive)
- ApplyColor(player);
+ ApplyColor(target);
}, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT);
}
else
{
SkillUtils.ApplyScreenColor(player, r: 0, g: 0, b: 0, a: 0, duration: 200, holdTime: 0);
- playersInDark.TryRemove(player.SteamID, out _);
+ playersInDark.TryRemove((ulong)playerSteamID, out _);
}
}
}
- private static void ApplyColor(CCSPlayerController player)
+ private static void ApplyColor(CCSPlayerController? player)
{
SkillUtils.ApplyScreenColor(player,
r: SkillsInfo.GetValue(skillName, "R"),
diff --git a/jRandomSkills - SRC Files/src/player/skills/Ghost.cs b/jRandomSkills - SRC Files/src/player/skills/Ghost.cs
index 010be1b..5d07c97 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Ghost.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Ghost.cs
@@ -1,7 +1,6 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes;
-using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
@@ -65,9 +64,20 @@ namespace src.player.skills
{
foreach (var (info, player) in infoList)
{
- if (player == null) continue;
+ if (player == null || !player.IsValid) continue;
+
+ var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero;
+ bool isObservingGhost = false;
+
+ if (targetHandle != nint.Zero)
+ {
+ var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle);
+ var targetInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == target?.SteamID);
+ if (targetInfo?.Skill == skillName) isObservingGhost = true;
+ }
+
foreach (var _player in invisiblePlayers.Keys)
- if (player.SteamID != _player.SteamID)
+ if (player.SteamID != _player.SteamID && !isObservingGhost)
{
var playerPawn = _player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) continue;
diff --git a/jRandomSkills - SRC Files/src/player/skills/Iana.cs b/jRandomSkills - SRC Files/src/player/skills/Iana.cs
index d88d3f1..d20090d 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Iana.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Iana.cs
@@ -154,12 +154,13 @@ namespace src.player.skills
KillClone(playerSkill);
});
- Timer? cloneTimer = null;
- ulong playerSteamID = player.SteamID;
+ ulong? playerSteamID = player?.SteamID;
+ if (playerSteamID == null) return;
+ Timer? cloneTimer = null;
cloneTimer = jRandomSkills.Instance.AddTimer(2f, () =>
{
- var target = Utilities.GetPlayerFromSteamId(playerSteamID);
+ var target = Utilities.GetPlayers().FirstOrDefault(p => p.IsValid && p.SteamID == playerSteamID);
if (target == null || !target.IsValid || !target.PawnIsAlive)
{
cloneTimer?.Kill();
diff --git a/jRandomSkills - SRC Files/src/player/skills/Illiterate.cs b/jRandomSkills - SRC Files/src/player/skills/Illiterate.cs
new file mode 100644
index 0000000..6e672b2
--- /dev/null
+++ b/jRandomSkills - SRC Files/src/player/skills/Illiterate.cs
@@ -0,0 +1,77 @@
+using CounterStrikeSharp.API;
+using CounterStrikeSharp.API.Core;
+using CounterStrikeSharp.API.Modules.Utils;
+using src.utils;
+
+namespace src.player.skills
+{
+ public class Illiterate : ISkill
+ {
+ private const Skills skillName = Skills.Illiterate;
+ private static bool isActive = false;
+ private static int offset = jRandomSkills.Instance.Random.Next(0, 26);
+
+ public static void LoadSkill()
+ {
+ SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"));
+ }
+
+ public static void NewRound()
+ {
+ isActive = false;
+ }
+
+ public static void EnableSkill(CCSPlayerController player)
+ {
+ isActive = true;
+ }
+
+ public static void Enable()
+ {
+ isActive = true;
+ }
+
+ public static void Disable()
+ {
+ isActive = false;
+ }
+
+ public static bool CheckIlliterateSkill(CCSPlayerController? player)
+ {
+ if (!isActive || player == null || !player.IsValid) return false;
+ if (player.Team == CsTeam.Spectator) return false;
+
+ var playersWithSkill = jRandomSkills.Instance.SkillPlayer.Where(p => p.Skill == skillName).Select(p => p.SteamID);
+ if (!playersWithSkill.Any()) return false;
+
+ return Utilities.GetPlayers().Any(
+ p => p.IsValid &&
+ p.PawnIsAlive &&
+ p.Team != player.Team
+ && playersWithSkill.Contains(p.SteamID));
+ }
+
+ public static string? GetRandomText(string? input)
+ {
+ if (string.IsNullOrEmpty(input)) return null;
+ if (Server.TickCount % 64 == 0)
+ offset = jRandomSkills.Instance.Random.Next(1, 26);
+
+ return new string([.. input.Select(c =>
+ {
+ if (char.IsDigit(c)) return '?';
+ if (!char.IsLetter(c)) return c;
+
+ char baseChar = char.IsUpper(c) ? 'A' : 'a';
+ return (char)(baseChar + (c - baseChar + offset) % 26);
+ })]);
+ }
+
+ public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1466F5", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float maximumFuel = 150f, float fuelConsumption = .64f, float refuelling = .1f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
+ {
+ public float MaximumFuel { get; set; } = maximumFuel;
+ public float FuelConsumption { get; set; } = fuelConsumption;
+ public float Refuelling { get; set; } = refuelling;
+ }
+ }
+}
\ No newline at end of file
diff --git a/jRandomSkills - SRC Files/src/player/skills/LongKnife.cs b/jRandomSkills - SRC Files/src/player/skills/LongKnife.cs
index b82ae1a..6aa7556 100644
--- a/jRandomSkills - SRC Files/src/player/skills/LongKnife.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/LongKnife.cs
@@ -107,9 +107,9 @@ namespace src.player.skills
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));
- CreateLine(new Vector(trace.StartPos.X, trace.StartPos.Y, trace.StartPos.Z), new Vector(trace.Position.X, trace.Position.Y, trace.Position.Z), Color.FromArgb(255, 0, 0, 255));
+ SkillUtils.CreateLine(eyePos, endPos, Color.FromArgb(255, 255, 255, 0));
+ SkillUtils.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));
+ SkillUtils.CreateLine(new Vector(trace.StartPos.X, trace.StartPos.Y, trace.StartPos.Z), new Vector(trace.Position.X, trace.Position.Y, trace.Position.Z), Color.FromArgb(255, 0, 0, 255));
if (trace.DidHit())
{
@@ -133,24 +133,6 @@ namespace src.player.skills
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)
- {
- CBeam beam = Utilities.CreateEntityByName("beam")!;
- if (beam == null) return;
-
- beam.Render = color;
- beam.Width = 2.0f;
- beam.EndWidth = 2.0f;
- beam.Teleport(start);
-
- beam.EndPos.X = end.X;
- beam.EndPos.Y = end.Y;
- beam.EndPos.Z = end.Z;
-
- beam.DispatchSpawn();
- beam.AcceptInput("FollowEntity", beam, null!, "");
- }
-
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#c9f8ff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float maxDistance = 4096f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public float MaxDistance { get; set; } = maxDistance;
diff --git a/jRandomSkills - SRC Files/src/player/skills/LongZeus.cs b/jRandomSkills - SRC Files/src/player/skills/LongZeus.cs
index bfc74e4..878114c 100644
--- a/jRandomSkills - SRC Files/src/player/skills/LongZeus.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/LongZeus.cs
@@ -45,9 +45,9 @@ namespace src.player.skills
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));
- CreateLine(new Vector(trace.StartPos.X, trace.StartPos.Y, trace.StartPos.Z), new Vector(trace.Position.X, trace.Position.Y, trace.Position.Z), Color.FromArgb(255, 0, 0, 255));
+ SkillUtils.CreateLine(eyePos, endPos, Color.FromArgb(255, 255, 255, 0));
+ SkillUtils.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));
+ SkillUtils.CreateLine(new Vector(trace.StartPos.X, trace.StartPos.Y, trace.StartPos.Z), new Vector(trace.Position.X, trace.Position.Y, trace.Position.Z), Color.FromArgb(255, 0, 0, 255));
if (trace.DidHit())
{
@@ -70,24 +70,6 @@ namespace src.player.skills
SkillUtils.TryGiveWeapon(player, CsItem.Zeus);
}
- private static void CreateLine(Vector start, Vector end, Color color)
- {
- CBeam beam = Utilities.CreateEntityByName("beam")!;
- if (beam == null) return;
-
- beam.Render = color;
- beam.Width = 2.0f;
- beam.EndWidth = 2.0f;
- beam.Teleport(start);
-
- beam.EndPos.X = end.X;
- beam.EndPos.Y = end.Y;
- beam.EndPos.Z = end.Z;
-
- beam.DispatchSpawn();
- beam.AcceptInput("FollowEntity", beam, null!, "");
- }
-
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#6effc7", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float maxDistance = 4096f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public float MaxDistance { get; set; } = maxDistance;
diff --git a/jRandomSkills - SRC Files/src/player/skills/Ninja.cs b/jRandomSkills - SRC Files/src/player/skills/Ninja.cs
index 53e95a5..5377b1a 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Ninja.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Ninja.cs
@@ -1,7 +1,6 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes;
-using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
@@ -57,9 +56,20 @@ namespace src.player.skills
{
foreach (var (info, player) in infoList)
{
- if (player == null) continue;
+ if (player == null || !player.IsValid) continue;
+
+ var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero;
+ bool isObservingNinja = false;
+
+ if (targetHandle != nint.Zero)
+ {
+ var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle);
+ var targetInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == target?.SteamID);
+ if (targetInfo?.Skill == skillName) isObservingNinja = true;
+ }
+
foreach (var _player in invisiblePlayers.Keys)
- if (player.SteamID != _player.SteamID)
+ if (player.SteamID != _player.SteamID && !isObservingNinja)
{
var playerPawn = _player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) continue;
diff --git a/jRandomSkills - SRC Files/src/player/skills/Noclip.cs b/jRandomSkills - SRC Files/src/player/skills/Noclip.cs
index 2bd94f2..7c05562 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Noclip.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Noclip.cs
@@ -1,9 +1,13 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
+using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils;
-using static src.jRandomSkills;
-using System.Collections.Concurrent;
+using CS2TraceRay.Class;
+using CS2TraceRay.Struct;
using src.utils;
+using System.Collections.Concurrent;
+using static src.jRandomSkills;
+using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
namespace src.player.skills
{
@@ -87,52 +91,139 @@ namespace src.player.skills
public static void UseSkill(CCSPlayerController player)
{
var playerPawn = player.PlayerPawn.Value;
- var duration = SkillsInfo.GetValue(skillName, "duration");
if (playerPawn?.CBodyComponent == null) return;
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
{
- if (!player.IsValid || !player.PawnIsAlive) return;
+ if (skillInfo.IsFlying)
+ {
+ StopFlying(player, skillInfo);
+ return;
+ }
+
if (skillInfo.CanUse)
{
+ var duration = SkillsInfo.GetValue(skillName, "duration");
+
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);
+ SetNoclip(player, true);
+ skillInfo.Timer?.Kill();
- playerPawn.ActualMoveType = MoveType_t.MOVETYPE_NOCLIP;
- 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));
+ skillInfo.Timer = Instance.AddTimer(duration, () =>
+ {
+ StopFlying(player, skillInfo);
});
}
}
}
+ private static void SetNoclip(CCSPlayerController player, bool noclip = true)
+ {
+ if (player == null || !player.IsValid) return;
+
+ var playerPawn = player.PlayerPawn.Value;
+ if (playerPawn == null || !playerPawn.IsValid || !player.PawnIsAlive) return;
+
+ playerPawn.MoveType = noclip ? MoveType_t.MOVETYPE_NOCLIP : MoveType_t.MOVETYPE_WALK;
+ Schema.SetSchemaValue(playerPawn.Handle, "CBaseEntity", "m_nActualMoveType", (int)playerPawn.MoveType);
+ Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_MoveType");
+ }
+
+ private static void StopFlying(CCSPlayerController player, PlayerSkillInfo skillInfo)
+ {
+ skillInfo.Timer?.Kill();
+ skillInfo.Timer = null;
+
+ if (!skillInfo.IsFlying) return;
+ skillInfo.IsFlying = false;
+
+ if (player == null || !player.IsValid || !player.PawnIsAlive) return;
+ SetNoclip(player, false);
+
+ var playerPawn = player.PlayerPawn.Value;
+ if (playerPawn == null || !playerPawn.IsValid || skillInfo.IsFlying) return;
+
+ Vector? safePoint = GetCorrectPosition(player, skillInfo);
+ playerPawn.Teleport(safePoint ?? skillInfo.LastPosition, null, new Vector(0, 0, 0));
+ }
+
+ private static Vector? GetCorrectPosition(CCSPlayerController player, PlayerSkillInfo skillInfo)
+ {
+ var playerPawn = player.PlayerPawn.Value;
+ if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return null;
+
+ Vector currentPos = playerPawn.AbsOrigin;
+ float offset = 50;
+
+ Vector[] checkOffsets =
+ {
+ currentPos,
+ currentPos + new Vector(offset, 0, 10),
+ currentPos + new Vector(-offset, 0, 10),
+ currentPos + new Vector(0, offset, 10),
+ currentPos + new Vector(0, -offset, 10),
+
+ currentPos + new Vector(offset, 0, 60),
+ currentPos + new Vector(-offset, 0, 60),
+ currentPos + new Vector(0, offset, 60),
+ currentPos + new Vector(0, -offset, 60),
+ };
+
+ ulong mask = playerPawn.Collision.CollisionAttribute.InteractsWith;
+ ulong contents = playerPawn.Collision.CollisionGroup;
+ bool hasGround = false;
+
+ foreach (Vector targetPos in checkOffsets)
+ {
+ Vector start = new(targetPos.X, targetPos.Y, targetPos.Z + 70);
+ Vector end = new(targetPos.X, targetPos.Y, targetPos.Z - 1000);
+
+ CGameTrace groundTrace = TraceRay.TraceShape(start, end, mask, contents, player);
+ if (!groundTrace.DidHit()) continue;
+
+ hasGround = true;
+ Vector newPos =
+ groundTrace.EndPos.Z > targetPos.Z
+ ? new(groundTrace.EndPos.X, groundTrace.EndPos.Y, groundTrace.EndPos.Z)
+ : targetPos;
+
+ if (IsPositionSafe(newPos, player))
+ return newPos;
+ }
+
+ if (hasGround)
+ skillInfo.Cooldown = DateTime.Now.AddSeconds(-SkillsInfo.GetValue(skillName, "cooldown") + SkillsInfo.GetValue(skillName, "cooldownWhenStuck"));
+ return hasGround ? currentPos : null;
+ }
+
+ private static bool IsPositionSafe(Vector pos, CCSPlayerController player)
+ {
+ var playerPawn = player.PlayerPawn.Value;
+ if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return false;
+
+ float footHeight = 0;
+ float headHeight = 70;
+ float innerDist = 12;
+
+ ulong mask = playerPawn.Collision.CollisionAttribute.InteractsWith;
+ ulong contents = playerPawn.Collision.CollisionGroup;
+
+ Vector s1 = new(pos.X - innerDist, pos.Y - innerDist, pos.Z + footHeight);
+ Vector e1 = new(pos.X + innerDist, pos.Y + innerDist, pos.Z + headHeight);
+ CGameTrace t1 = TraceRay.TraceShape(s1, e1, mask, contents, player);
+ if (t1.DidHit() || t1.AllSolid) return false;
+
+ Vector s2 = new(pos.X + innerDist, pos.Y - innerDist, pos.Z + footHeight);
+ Vector e2 = new(pos.X - innerDist, pos.Y + innerDist, pos.Z + headHeight);
+ CGameTrace t2 = TraceRay.TraceShape(s2, e2, mask, contents, player);
+ if (t2.DidHit() || t2.AllSolid) return false;
+
+ return true;
+ }
+
public class PlayerSkillInfo
{
public ulong SteamID { get; set; }
@@ -140,11 +231,13 @@ namespace src.player.skills
public bool IsFlying { get; set; }
public DateTime Cooldown { get; set; }
public Vector? LastPosition { get; set; }
+ public Timer? Timer { get; set; }
}
- public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#44ebd4", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 30f, float duration = 2f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
+ public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#44ebd4", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 30f, float duration = 2f, float cooldownWhenStuck = 5f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public float Cooldown { get; set; } = cooldown;
+ public float CooldownWhenStuck { get; set; } = cooldownWhenStuck;
public float Duration { get; set; } = duration;
}
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/PawelJumper.cs b/jRandomSkills - SRC Files/src/player/skills/PawelJumper.cs
index 4ae2893..6509f7b 100644
--- a/jRandomSkills - SRC Files/src/player/skills/PawelJumper.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/PawelJumper.cs
@@ -9,7 +9,6 @@ namespace src.player.skills
public class PawelJumper : ISkill
{
private const Skills skillName = Skills.PawelJumper;
- private static readonly PlayerFlags[] LF = new PlayerFlags[64];
private static readonly int?[] J = new int?[64];
private static readonly PlayerButtons[] LB = new PlayerButtons[64];
@@ -71,7 +70,6 @@ namespace src.player.skills
playerPawn.AbsVelocity.Z = 300;
}
- LF[player.Slot] = flags;
LB[player.Slot] = buttons;
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Pilot.cs b/jRandomSkills - SRC Files/src/player/skills/Pilot.cs
index d1dcc9d..ab67d81 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Pilot.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Pilot.cs
@@ -38,6 +38,7 @@ namespace src.player.skills
{
SteamID = player.SteamID,
Fuel = SkillsInfo.GetValue(skillName, "maximumFuel"),
+ LastButtons = 0
});
}
@@ -49,16 +50,37 @@ namespace src.player.skills
private static void HandlePilot(CCSPlayerController player)
{
+ var playerPawn = player.PlayerPawn.Value;
+ if (playerPawn == null || !playerPawn.IsValid) return;
+
+ if (!PlayerPilotInfo.TryGetValue(player.SteamID, out var pilotInfo)) return;
+
+ var flags = (PlayerFlags)playerPawn.Flags;
var buttons = player.Buttons;
+
+ bool isJumpDown = (playerPawn.MovementServices?.Buttons?.ButtonStates[0] & (ulong)PlayerButtons.Jump) != 0 || (buttons & PlayerButtons.Jump) != 0;
+ bool wasJumpDown = (pilotInfo.LastButtons & PlayerButtons.Jump) != 0;
+
+ bool jumpPressed = (isJumpDown && !wasJumpDown)
+ || (playerPawn.MovementServices?.QueuedButtonChangeMask & (ulong)PlayerButtons.Jump) != 0;
+
+ bool isOnGround = (flags & PlayerFlags.FL_ONGROUND) != 0;
+ bool inUse = jumpPressed && !isOnGround;
+
var maximumFuel = SkillsInfo.GetValue(skillName, "maximumFuel");
- if (PlayerPilotInfo.TryGetValue(player.SteamID, out var pilotInfo))
- {
- pilotInfo.Fuel = Math.Min(Math.Max(0, pilotInfo.Fuel - (buttons.HasFlag(PlayerButtons.Use) ? SkillsInfo.GetValue(skillName, "fuelConsumption") : -SkillsInfo.GetValue(skillName, "refuelling"))), maximumFuel);
- if (buttons.HasFlag(PlayerButtons.Use))
- if (pilotInfo.Fuel > 0 && player.PlayerPawn.Value != null && player.PlayerPawn.Value.IsValid && !player.PlayerPawn.Value.IsDefusing)
- ApplyPilotEffect(player);
- UpdateHUD(player, pilotInfo);
- }
+ pilotInfo.Fuel = Math.Min(
+ Math.Max(
+ 0,
+ pilotInfo.Fuel - (inUse
+ ? SkillsInfo.GetValue(skillName, "fuelConsumption")
+ : -SkillsInfo.GetValue(skillName, "refuelling"))),
+ maximumFuel);
+ pilotInfo.LastButtons = buttons;
+
+ if (inUse && pilotInfo.Fuel > 0)
+ ApplyPilotEffect(player);
+
+ UpdateHUD(player, pilotInfo);
}
private static void UpdateHUD(CCSPlayerController player, Pilot_PlayerInfo pilotInfo)
@@ -121,6 +143,7 @@ namespace src.player.skills
{
public ulong SteamID { get; set; }
public float Fuel { get; set; }
+ public PlayerButtons LastButtons { get; set; }
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1466F5", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float maximumFuel = 150f, float fuelConsumption = .64f, float refuelling = .1f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
diff --git a/jRandomSkills - SRC Files/src/player/skills/Replicator.cs b/jRandomSkills - SRC Files/src/player/skills/Replicator.cs
index edf539d..82e6df9 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Replicator.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Replicator.cs
@@ -99,9 +99,6 @@ namespace src.player.skills
float distance = 40;
Vector pos = playerPawn.AbsOrigin + SkillUtils.GetForwardVector(playerPawn.AbsRotation) * distance;
-
- if (((PlayerFlags)playerPawn.Flags).HasFlag(PlayerFlags.FL_DUCKING))
- pos.Z -= 19;
replica.Flags = playerPawn.Flags;
replica.Flags |= (uint)Flags_t.FL_DUCKING;
@@ -109,6 +106,13 @@ namespace src.player.skills
replica.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(replica.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
replica.SetModel(playerPawn!.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.ModelName);
replica.Entity!.Name = replica.Globalname = $"Replica_{Server.TickCount}_{(player.Team == CsTeam.CounterTerrorist ? "CT" : "TT")}";
+
+ replica.UseAnimGraph = false;
+ string animName = "idle_for_turns_stand_pistol";
+ if (((PlayerFlags)playerPawn.Flags).HasFlag(PlayerFlags.FL_DUCKING))
+ animName = "idle_for_turns_crouch_pistol";
+
+ replica.AcceptInput("SetAnimation", value: animName);
replica.Teleport(pos, playerPawn.AbsRotation, null);
replica.DispatchSpawn();
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Smoker.cs b/jRandomSkills - SRC Files/src/player/skills/Smoker.cs
new file mode 100644
index 0000000..fd52500
--- /dev/null
+++ b/jRandomSkills - SRC Files/src/player/skills/Smoker.cs
@@ -0,0 +1,75 @@
+using CounterStrikeSharp.API;
+using CounterStrikeSharp.API.Core;
+using CounterStrikeSharp.API.Core.Attributes;
+using CounterStrikeSharp.API.Modules.Entities;
+using CounterStrikeSharp.API.Modules.Entities.Constants;
+using CounterStrikeSharp.API.Modules.Utils;
+using Microsoft.Extensions.Logging;
+using src.utils;
+using System.Collections.Concurrent;
+using static src.jRandomSkills;
+
+namespace src.player.skills
+{
+ public class Smoker : ISkill
+ {
+ private const Skills skillName = Skills.Smoker;
+ private readonly static ConcurrentDictionary smokes = [];
+ private static readonly object setLock = new();
+
+ public static void LoadSkill()
+ {
+ SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"));
+ }
+
+ public static void NewRound()
+ {
+ lock (setLock)
+ smokes.Clear();
+
+
+ }
+
+ public static void EnableSkill(CCSPlayerController player)
+ {
+ SkillUtils.TryGiveWeapon(player, CsItem.SmokeGrenade);
+ }
+
+ public static void SmokegrenadeDetonate(EventSmokegrenadeDetonate @event)
+ {
+ Server.PrintToChatAll("BOOM");
+ var player = @event.Userid;
+ if (player == null || !player.IsValid) return;
+
+ var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
+ if (playerInfo?.Skill != skillName) return;
+
+ var smoke = Utilities.GetEntityFromIndex(@event.Entityid);
+ if (smoke == null || !smoke.IsValid) return;
+
+ smokes.TryAdd(smoke.Index, Server.TickCount);
+
+ // smoke.SmokeEffectTickBegin = Server.TickCount - ((19 - 15) * 64);
+ smoke.NextThinkTick = 0;
+
+ // Utilities.SetStateChanged(smoke, "CSmokeGrenadeProjectile", "m_nSmokeEffectTickBegin");
+ Utilities.SetStateChanged(smoke, "CBaseEntity", "m_nNextThinkTick");
+ }
+
+ public static void SmokegrenadeExpired(EventSmokegrenadeExpired @event)
+ {
+ var player = @event.Userid;
+ if (player == null || !player.IsValid) return;
+
+ var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
+ if (playerInfo?.Skill != skillName) return;
+
+ Vector pos = new(@event.X, @event.Y, @event.Z);
+ SkillUtils.CreateSmokeGrenadeProjectile(pos, new QAngle(0, 0, 0), new Vector(0, 0, 0), player.TeamNum);
+ }
+
+ public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#b5ab8f", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/jRandomSkills - SRC Files/src/player/skills/SoundMaker.cs b/jRandomSkills - SRC Files/src/player/skills/SoundMaker.cs
index 5e373c1..f77632d 100644
--- a/jRandomSkills - SRC Files/src/player/skills/SoundMaker.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/SoundMaker.cs
@@ -1,18 +1,22 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
+using CounterStrikeSharp.API.Modules.UserMessages;
using CounterStrikeSharp.API.Modules.Utils;
-using static src.jRandomSkills;
-using System.Collections.Concurrent;
using src.utils;
+using System.Collections.Concurrent;
+using static src.jRandomSkills;
namespace src.player.skills
{
public class SoundMaker : ISkill
{
private const Skills skillName = Skills.SoundMaker;
- private static readonly ConcurrentDictionary SkillPlayerInfo = [];
+ private static readonly ConcurrentDictionary SkillPlayerInfo = [];
private static readonly object setLock = new();
+ private const string soundEventName = "Hostage.Pain";
+ private const uint soundEventHash = 1876781570;
+
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"));
@@ -26,12 +30,7 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player)
{
- SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo
- {
- SteamID = player.SteamID,
- CanUse = true,
- Cooldown = DateTime.MinValue,
- });
+ SkillPlayerInfo.TryAdd(player.SteamID, 0);
}
public static void DisableSkill(CCSPlayerController player)
@@ -49,78 +48,40 @@ namespace src.player.skills
SkillPlayerInfo.TryRemove(player.SteamID, out _);
}
+ public static void PlayerMakeSound(UserMessage um)
+ {
+ var soundevent = um.ReadUInt("soundevent_hash");
+ if (soundevent != soundEventHash) return;
+
+ var userIndex = um.ReadUInt("source_entity_index");
+ if (userIndex == 0) return;
+
+ var sourcePlayer = Utilities.GetPlayers().FirstOrDefault(p => p.Pawn?.Value != null && p.Pawn.Value.IsValid && p.Pawn.Value.Index == userIndex);
+ if (sourcePlayer == null || !sourcePlayer.IsValid) return;
+
+ var toRemove = um.Recipients.Where(r =>
+ {
+ if (r.Team == sourcePlayer.Team) return true;
+ if (SkillPlayerInfo.ContainsKey(r.SteamID)) return false;
+ return true;
+ }).ToList();
+
+ foreach (var player in toRemove)
+ um.Recipients.Remove(player);
+ }
+
public static void OnTick()
{
- foreach (var player in Utilities.GetPlayers())
- {
- var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
- if (playerInfo?.Skill == skillName)
- if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
- UpdateHUD(player, skillInfo);
- }
+ if (Server.TickCount % (60 * SkillsInfo.GetValue(skillName, "cooldown")) != 0) return;
+
+ foreach (var player in Utilities.GetPlayers()
+ .Where(p => p != null && p.IsValid && p.PawnIsAlive && p.PlayerPawn.Value != null && p.PlayerPawn.Value.IsValid))
+ player.PlayerPawn.Value!.EmitSound(soundEventName, volume: 1f);
}
- private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo)
+ public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#e3ed8c", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int cooldown = 2) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
- float cooldown = 0;
- if (skillInfo != null)
- {
- float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "Cooldown")) - DateTime.Now).TotalSeconds);
- cooldown = Math.Max(time, 0);
-
- if (cooldown == 0 && skillInfo?.CanUse == false)
- skillInfo.CanUse = true;
- }
-
- var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
- if (playerInfo == null) return;
-
- if (cooldown == 0)
- playerInfo.PrintHTML = null;
- else
- playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"{cooldown}")}";
- }
-
- public static void UseSkill(CCSPlayerController player)
- {
- var playerPawn = player.PlayerPawn.Value;
- if (playerPawn?.CBodyComponent == null) return;
-
- if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
- {
- if (!player.IsValid || !player.PawnIsAlive) return;
- if (skillInfo.CanUse)
- {
- skillInfo.CanUse = false;
- skillInfo.Cooldown = DateTime.Now;
- MakeSound(player);
- }
- }
- }
-
- private static void MakeSound(CCSPlayerController player)
- {
- foreach (var enemy in Utilities.GetPlayers().Where(p => p.Team != player.Team))
- if (enemy != null && enemy.IsValid && enemy.PawnIsAlive && enemy.PlayerPawn.Value != null && enemy.PlayerPawn.Value.IsValid)
- enemy.PlayerPawn.Value.EmitSound(
- enemy.Team == CsTeam.CounterTerrorist
- ? SkillsInfo.GetValue(skillName, "CTSoundEvent")
- : SkillsInfo.GetValue(skillName, "TSoundEvent")
- , volume: 1f);
- }
-
- public class PlayerSkillInfo
- {
- public ulong SteamID { get; set; }
- public bool CanUse { get; set; }
- public DateTime Cooldown { get; set; }
- }
-
- public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#e3ed8c", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float cooldown = 5f, string ctSoundEvent = "c4.disarmstart", string tSoundEvent = "C4.PlantSoundB") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
- {
- public float Cooldown { get; set; } = cooldown;
- public string CTSoundEvent { get; set; } = ctSoundEvent;
- public string TSoundEvent { get; set; } = tSoundEvent;
+ public int Cooldown { get; set; } = cooldown;
}
}
}
\ No newline at end of file
diff --git a/jRandomSkills - SRC Files/src/player/skills/ToxicSmoke.cs b/jRandomSkills - SRC Files/src/player/skills/ToxicSmoke.cs
index e072ed3..4f72e81 100644
--- a/jRandomSkills - SRC Files/src/player/skills/ToxicSmoke.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/ToxicSmoke.cs
@@ -95,10 +95,6 @@ namespace src.player.skills
var trigger = SkillUtils.CreateTrigger(triggerName, SkillsInfo.GetValue(skillName, "smokeRadius"), new Vector(@event.X, @event.Y, @event.Z));
if (trigger == null) return;
triggers.TryAdd(trigger, 0);
-
- new VirtualFunctionVoid(trigger.Handle, 153);
-
-
}
public static void SmokegrenadeExpired(EventSmokegrenadeExpired @event)
@@ -138,7 +134,7 @@ namespace src.player.skills
}
}
- public class SkillConfig(Skills skill = skillName, bool active = false, string color = "#507529", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int smokeDamage = 2, float smokeRadius = 180) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
+ public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#507529", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int smokeDamage = 2, float smokeRadius = 180) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public int SmokeDamage { get; set; } = smokeDamage;
public float SmokeRadius { get; set; } = smokeRadius;
diff --git a/jRandomSkills - SRC Files/src/player/skills/Wallhack.cs b/jRandomSkills - SRC Files/src/player/skills/Wallhack.cs
index 27beb40..999899d 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Wallhack.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Wallhack.cs
@@ -13,7 +13,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Wallhack;
private static readonly ConcurrentDictionary playersInAction = [];
- private static readonly ConcurrentBag<(CDynamicProp, CDynamicProp, CsTeam)> glows = [];
+ private static readonly ConcurrentBag<(CDynamicProp, CDynamicProp, CsTeam, uint)> glows = [];
public static void LoadSkill()
{
@@ -32,8 +32,11 @@ namespace src.player.skills
foreach (var glow in glows)
{
- if (glow.Item3 != player.Team && (playerInfo?.Skill == skillName || (observerInfo != null && observerInfo?.Skill == skillName)))
- continue;
+ var enemy = Utilities.GetPlayers().FirstOrDefault(e => e.IsValid && e.Index == glow.Item4);
+
+ if (enemy != null && enemy.PawnIsAlive)
+ if (glow.Item3 != player.Team && (playerInfo?.Skill == skillName || (observerInfo != null && observerInfo?.Skill == skillName)))
+ continue;
var glowEntity1 = Utilities.GetEntityFromIndex((int)glow.Item1.Index);
if (glowEntity1 == null || !glowEntity1.IsValid) continue;
@@ -110,7 +113,7 @@ namespace src.player.skills
modelRelay.AcceptInput("FollowEntity", enemyPawn, modelRelay, "!activator");
modelGlow.AcceptInput("FollowEntity", modelRelay, modelGlow, "!activator");
- glows.Add((modelRelay, modelGlow, enemy.Team));
+ glows.Add((modelRelay, modelGlow, enemy.Team, enemy.Index));
}
}
diff --git a/jRandomSkills - SRC Files/src/utils/Config.cs b/jRandomSkills - SRC Files/src/utils/Config.cs
index fef56f7..123f3ea 100644
--- a/jRandomSkills - SRC Files/src/utils/Config.cs
+++ b/jRandomSkills - SRC Files/src/utils/Config.cs
@@ -1,5 +1,7 @@
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
+using System.ComponentModel;
+using System.ComponentModel.DataAnnotations;
using static src.jRandomSkills;
namespace src.utils
@@ -69,6 +71,9 @@ namespace src.utils
public class SettingsModel
{
+ [DisplayName("Game Mode")]
+ [Description("TESTfafw..")]
+ [Range(0, 5)]
public int GameMode { get; set; }
public bool YourSkillChatInfo { get; set; }
public bool KillerSkillChatInfo { get; set; }
@@ -120,6 +125,8 @@ namespace src.utils
new LanguageInfo("PT-BR, PT, BR, AO, CV, GW, MZ, ST, TL", "pt-br"),
new LanguageInfo("FR, MC, HT", "fr"),
new LanguageInfo("DE, AT, CH, LI, LU, BE", "de"),
+ new LanguageInfo("TR", "tr"),
+ new LanguageInfo("CZ", "cs"),
new LanguageInfo("PL", "pl"),
new LanguageInfo("EN, GB, US", "en")
]
diff --git a/jRandomSkills - SRC Files/src/utils/Localization.cs b/jRandomSkills - SRC Files/src/utils/Localization.cs
index d6030bd..0c3cf3d 100644
--- a/jRandomSkills - SRC Files/src/utils/Localization.cs
+++ b/jRandomSkills - SRC Files/src/utils/Localization.cs
@@ -6,6 +6,7 @@ using Newtonsoft.Json;
using System.Net;
using System.Collections.Concurrent;
using src.player;
+using src.player.skills;
namespace src.utils
{
@@ -80,7 +81,7 @@ namespace src.utils
}
var value = Math.Round((double)(chance ?? 1), 2);
- var skillNameText = GetTranslation(skill.ToString().ToLower(), langCode, value);
+ var skillNameText = GetTranslation(skill.ToString().ToLower(), langCode, player, value);
if (skillNameText.Contains('%')) skillNameText = skillNameText.Replace(value.ToString(), Math.Round(value * 100, 0).ToString());
return skillNameText;
}
@@ -104,7 +105,7 @@ namespace src.utils
var skillName = $"{skill.ToString().ToLower()}_desc2";
var value = Math.Round((double)(chance ?? 1), 2);
- var desc2 = GetTranslation(skillName, langCode, value);
+ var desc2 = GetTranslation(skillName, langCode, player, value);
var skilLDescription = desc2 == skillName
? player.GetTranslation($"{skill.ToString().ToLower()}_desc")
@@ -127,7 +128,7 @@ namespace src.utils
for (int i = 0; i < key.Length; i++)
{
object[] currentArgs = args != null && i < args.Length ? args[i] : [];
- string translation = GetTranslation(key[i], langCode, currentArgs);
+ string translation = GetTranslation(key[i], langCode, null, currentArgs);
translations.Add(translation);
}
player.PrintToChat(string.Format(message, [.. translations]));
@@ -137,10 +138,10 @@ namespace src.utils
public static string GetTranslation(this CCSPlayerController player, string key, params object[] args)
{
string langCode = GetLangCode(player);
- return GetTranslation(key, langCode, args);
+ return GetTranslation(key, langCode, player, args);
}
- public static string GetTranslation(string key, string? langCode = null, params object[] args)
+ public static string GetTranslation(string key, string? langCode = null, CCSPlayerController? player = null, params object[] args)
{
langCode ??= defaultLangCode;
if (_translations.TryGetValue(langCode, out var langDict) && langDict.TryGetValue(key, out var translation))
@@ -152,9 +153,14 @@ namespace src.utils
output = output.Replace("CHATCOLORS.RED", ChatColors.Red.ToString());
if (Config.LoadedConfig.AlternativeSkillButton != null)
output = output.Replace("css_useSkill", $"css_useSkill/{Config.LoadedConfig.AlternativeSkillButton}");
+
+ if (Illiterate.CheckIlliterateSkill(player))
+ return Illiterate.GetRandomText(output);
return output;
}
+ if (langCode != defaultLangCode)
+ return GetTranslation(key, null, player, args);
return key;
}
@@ -188,7 +194,10 @@ namespace src.utils
if (string.IsNullOrEmpty(playerIP)) return null;
if (!File.Exists(geoliteFilePath)) return null;
using var reader = new Reader(geoliteFilePath);
- var ip = IPAddress.Parse(playerIP);
+
+ if (!IPAddress.TryParse(playerIP, out var ip))
+ return null;
+
var data = reader.Find>(ip);
if (data == null || data.IsEmpty) return null;
diff --git a/jRandomSkills - SRC Files/src/utils/SkillUtils.cs b/jRandomSkills - SRC Files/src/utils/SkillUtils.cs
index 196e07b..36d8781 100644
--- a/jRandomSkills - SRC Files/src/utils/SkillUtils.cs
+++ b/jRandomSkills - SRC Files/src/utils/SkillUtils.cs
@@ -9,6 +9,7 @@ using CounterStrikeSharp.API.Modules.Utils;
using src.player;
using src.player.skills;
using System.Collections.Concurrent;
+using System.Drawing;
using System.Globalization;
using System.Runtime.InteropServices;
using WASDMenuAPI.Classes;
@@ -19,15 +20,21 @@ namespace src.utils
public static class SkillUtils
{
private static readonly MemoryFunctionWithReturn HEGrenadeProjectile_CreateFunc = new(GameData.GetSignature("HEGrenadeProjectile_CreateFunc"));
+ private static readonly MemoryFunctionWithReturn SmokeGrenadeProjectile_CreateFunc = new(GameData.GetSignature("SmokeGrenadeProjectile_CreateFunc"));
private static readonly MemoryFunctionVoid TerminateRoundFunc = new(GameData.GetSignature("CCSGameRules_TerminateRound"));
public static void PrintToChat(CCSPlayerController player, string msg, string border = "tb", string? title = null)
{
+ if (!player.IsValid) return;
+
var config = Config.LoadedConfig.ChatMessage;
float maxWidth = config.MaxWidth;
char symbol = config.LineSymbol;
if (string.IsNullOrEmpty(title)) title = player.GetTranslation("jRandomSkills");
+ if (Illiterate.CheckIlliterateSkill(player))
+ msg = Illiterate.GetRandomText(msg);
+
if (border.Contains('t') && config.LineShow)
player.PrintToChat($" {MeansureString.GetTextDashed($"{(config.TagFormat.Contains("{TAG}") ? config.TagFormat.Replace("{TAG}", title) : $"\u0002◢◆◤ {title} ◥◆◣")}", maxWidth, symbol, config.LineColor)}");
if (!string.IsNullOrEmpty(msg) && config.InfoMessageShow)
@@ -86,9 +93,29 @@ namespace src.utils
return new Vector(x, y, z);
}
-
- public static void ApplyScreenColor(CCSPlayerController player, int r, int g, int b, int a, int duration, int holdTime, int flags = 1)
+ public static CBeam? CreateLine(Vector start, Vector end, Color color)
{
+ CBeam beam = Utilities.CreateEntityByName("beam")!;
+ if (beam == null) return null;
+
+ beam.Render = color;
+ beam.Width = 2.0f;
+ beam.EndWidth = 2.0f;
+ beam.Teleport(start);
+
+ beam.EndPos.X = end.X;
+ beam.EndPos.Y = end.Y;
+ beam.EndPos.Z = end.Z;
+
+ beam.DispatchSpawn();
+
+ return beam;
+ }
+
+ public static void ApplyScreenColor(CCSPlayerController? player, int r, int g, int b, int a, int duration, int holdTime, int flags = 1)
+ {
+ if (player == null || !player.IsValid) return;
+
using var msg = UserMessage.FromPartialName("Fade");
if (msg == null) return;
int packageColor = (a << 24) | (b << 16) | (g << 8) | r;
@@ -142,6 +169,11 @@ namespace src.utils
HEGrenadeProjectile_CreateFunc.Invoke(pos.Handle, angle.Handle, vel.Handle, vel.Handle, IntPtr.Zero, 44, teamNum);
}
+ public static void CreateSmokeGrenadeProjectile(Vector pos, QAngle angle, Vector vel, int teamNum)
+ {
+ SmokeGrenadeProjectile_CreateFunc.Invoke(pos.Handle, angle.Handle, vel.Handle, vel.Handle, IntPtr.Zero, 45, teamNum);
+ }
+
public static void TakeHealth(CCSPlayerPawn? pawn, int damage)
{
if (pawn == null || !pawn.IsValid || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
@@ -280,9 +312,11 @@ namespace src.utils
var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo == null) return;
+ bool isIlliterate = Illiterate.CheckIlliterateSkill(player);
+
Dictionary> list = [];
foreach (var item in items)
- list.TryAdd(item.Item1, (p, option) =>
+ list.TryAdd(isIlliterate ? Illiterate.GetRandomText(item.Item1) : item.Item1, (p, option) =>
{
jRandomSkills.Instance.SkillAction(playerInfo.Skill.ToString(), "TypeSkill", [p, new[] { item.Item2 }]);
manager.CloseMenu(p);
@@ -329,15 +363,17 @@ namespace src.utils
string itemText = $"
";
string itemHoverText = $"
";
+ bool isIlliterate = Illiterate.CheckIlliterateSkill(player);
+
IWasdMenu menu = manager.CreateMenu(hudContent, itemText, itemHoverText, controllsLine);
foreach (var enemy in enemies)
- menu.Add(enemy.Item1, (p, option) =>
+ menu.Add(isIlliterate ? Illiterate.GetRandomText(enemy.Item1) : enemy.Item1, (p, option) =>
{
jRandomSkills.Instance.SkillAction(playerInfo.Skill.ToString(), "TypeSkill", [p, new[] { enemy.Item2 }]);
manager.CloseMenu(p);
});
if (lastElement != null)
- menu.Add(lastElement.Value.Item1, (p, option) =>
+ menu.Add(isIlliterate ? Illiterate.GetRandomText(lastElement.Value.Item1) : lastElement.Value.Item1, (p, option) =>
{
jRandomSkills.Instance.SkillAction(playerInfo.Skill.ToString(), "TypeSkill", [p, new[] { lastElement.Value.Item2 }]);
if (lastElement.Value.Item3)