diff --git a/jRandomSkills - SRC Files/jRandomSkills.csproj b/jRandomSkills - SRC Files/jRandomSkills.csproj
index 3bcdaa1..0953faa 100644
--- a/jRandomSkills - SRC Files/jRandomSkills.csproj
+++ b/jRandomSkills - SRC Files/jRandomSkills.csproj
@@ -15,14 +15,19 @@
-
-
+
-
+
+
+ libs/RayTraceApi.dll
+
+
+
+
diff --git a/jRandomSkills - SRC Files/libs/RayTraceApi.dll b/jRandomSkills - SRC Files/libs/RayTraceApi.dll
new file mode 100644
index 0000000..584aea0
Binary files /dev/null and b/jRandomSkills - SRC Files/libs/RayTraceApi.dll differ
diff --git a/jRandomSkills - SRC Files/src/command/Command.cs b/jRandomSkills - SRC Files/src/command/Command.cs
index b88aec7..6c6da80 100644
--- a/jRandomSkills - SRC Files/src/command/Command.cs
+++ b/jRandomSkills - SRC Files/src/command/Command.cs
@@ -17,6 +17,7 @@ namespace src.command
private static bool gamePaused = false;
private static Config.SettingsModel config = Config.LoadedConfig;
private static readonly ConcurrentDictionary oldCommands = [];
+ private static readonly ConcurrentDictionary nextSkill = [];
private static readonly object setLock = new();
public static void Load()
@@ -47,6 +48,7 @@ namespace src.command
{ 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.NormalCommands.NextCommand.Alias), ("Next skill", Command_Next) },
{ SplitCommands(config.VotingCommands.ChangeMapCommand.Alias), ("Change map", Command_ChangeMap) },
{ SplitCommands(config.VotingCommands.StartGameCommand.Alias), ("Start game", Command_StartGame) },
@@ -142,7 +144,7 @@ namespace src.command
{
Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [targetPlayer]);
skillPlayer.Skill = skill.Skill;
- skillPlayer.SpecialSkill = src.player.Skills.None;
+ skillPlayer.SpecialSkill = Skills.None;
Instance.SkillAction(skill.Skill.ToString(), "EnableSkill", [targetPlayer]);
skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration);
@@ -337,7 +339,7 @@ namespace src.command
var pawn = player.PlayerPawn.Value;
if (int.TryParse(command.GetArg(1), out int health))
SkillUtils.AddHealth(pawn, health - pawn.Health, health);
-
+
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("set_health")}");
}
@@ -578,5 +580,48 @@ namespace src.command
}
}
}
+
+ [CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
+ private static void Command_Next(CCSPlayerController? player, CommandInfo command)
+ {
+ if (player == null || !player.IsValid) return;
+
+ Debug.WriteToDebug($"Player {player.PlayerName} used the css_next {command.ArgString} command.");
+ if (!string.IsNullOrEmpty(config.NormalCommands.NextCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.NextCommand.Permissions)) return;
+
+ var skillsList = SkillData.Skills.OrderBy(s => s.Skill.ToString()).ToList();
+ if (skillsList.Count == 0) return;
+
+ nextSkill.TryGetValue(player.Index, out int currentIndex);
+
+ int nextIndex = (currentIndex + 1) % skillsList.Count;
+
+ string arg = command.GetArg(1);
+ if (!string.IsNullOrEmpty(arg))
+ {
+ if (arg == "-1")
+ nextIndex--;
+ else
+ nextIndex = int.Parse(arg);
+ }
+
+ var skill = skillsList[nextIndex];
+ player.PrintToChat(nextIndex.ToString());
+
+ var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
+ if (skillPlayer == null) return;
+
+ Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [player]);
+ skillPlayer.Skill = skill.Skill;
+ skillPlayer.SpecialSkill = Skills.None;
+
+ nextSkill[player.Index] = nextIndex;
+
+ Instance.SkillAction(skill.Skill.ToString(), "EnableSkill", [player]);
+ skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration);
+
+ if (skill.Display)
+ SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(skill.Skill)}", border: "b");
+ }
}
}
\ No newline at end of file
diff --git a/jRandomSkills - SRC Files/src/gamedata/jRandomSkills.gamedata.json b/jRandomSkills - SRC Files/src/gamedata/jRandomSkills.gamedata.json
index 713f6f8..7c8be60 100644
--- a/jRandomSkills - SRC Files/src/gamedata/jRandomSkills.gamedata.json
+++ b/jRandomSkills - SRC Files/src/gamedata/jRandomSkills.gamedata.json
@@ -16,15 +16,22 @@
"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"
+ "windows": "48 89 5C 24 ? 57 48 83 EC 20 48 8B 01 48 8B F9 0F BF DA",
+ "linux": "55 48 8D 15 ? ? ? ? 48 89 E5 41 54 41 89 F4 53 48 8B 07 48 89 FB 48 8B 80 ? ? ? ? 48 39 D0 0F 85"
}
},
"SnapViewAngles": {
"signatures": {
"library": "server",
"windows": "48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 55 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B DA 48 8B F1 48 8D 55",
- "linux": "55 48 89 E5 41 57 41 56 41 55 41 54 53 48 89 FB 48 89 F7 48 81 EC ? ? ? ? E8 ? ? ? ? 48 8B 93"
+ "linux": "55 48 89 E5 41 57 49 89 FF 48 89 F7 41 56 41 55 41 54 53 48 81 EC"
+ }
+ },
+ "CCSPlayerController_HandleCommandDrop": {
+ "signatures": {
+ "library": "server",
+ "windows": "48 89 5C 24 ? 57 48 83 EC ? 48 8B FA E8 ? ? ? ? 48 8B D8",
+ "linux": "55 48 89 E5 41 54 49 89 F4 53 E8 ? ? ? ? 48 85 C0 74 ? 48 89 C3"
}
}
}
\ No newline at end of file
diff --git a/jRandomSkills - SRC Files/src/jRandomSkills.cs b/jRandomSkills - SRC Files/src/jRandomSkills.cs
index 0fd62d4..6c3679e 100644
--- a/jRandomSkills - SRC Files/src/jRandomSkills.cs
+++ b/jRandomSkills - SRC Files/src/jRandomSkills.cs
@@ -28,7 +28,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.2.1.b7";
+ public override string ModuleVersion => "1.2.1.b8";
public override void Load(bool hotReload)
{
@@ -213,8 +213,9 @@ namespace src
{ "WASDMenuAPI", "./WASDMenuAPI.dll" },
{ "MaxMind", "./MaxMind.Db.dll" },
{ "GeoLite2", "./packages/GeoLite2-Country.mmdb" },
- { "CS2TraceRay", "./../../shared/CS2TraceRay/CS2TraceRay.dll" },
- { "CS2TraceRay gamedata", "./../../gamedata/CS2TraceRay.gamedata.json" },
+ { "RayTraceApi", "./../../shared/RayTraceApi/RayTraceApi.dll" },
+ { "RayTraceImpl", "./../../plugins/RayTraceImpl/RayTraceImpl.dll" },
+ { "RayTrace MetaMod", "./../../../metamod/RayTrace.vdf" },
{ "jRandomSkills gamedata", "./../../gamedata/jRandomSkills.gamedata.json" }
};
@@ -263,7 +264,7 @@ namespace src
private static async Task GetLatestVersion()
{
- using HttpClient client = new HttpClient();
+ using HttpClient client = new();
client.DefaultRequestHeaders.UserAgent.Add(new System.Net.Http.Headers.ProductInfoHeaderValue("jRandomSkills", "1.0"));
const string URL = "https://api.github.com/repos/Juzlus/jRandomSkills/releases/latest";
diff --git a/jRandomSkills - SRC Files/src/player/ISkill.cs b/jRandomSkills - SRC Files/src/player/ISkill.cs
index 0dd186c..5e09f91 100644
--- a/jRandomSkills - SRC Files/src/player/ISkill.cs
+++ b/jRandomSkills - SRC Files/src/player/ISkill.cs
@@ -29,7 +29,9 @@ public interface ISkill
public static void WeaponEquip(EventItemEquip _) { }
public static void WeaponPickup(EventItemPickup _) { }
public static void WeaponReload(EventWeaponReload _) { }
+ public static bool WeaponDrop(DynamicHook _, CCSPlayerController __) { return false; }
public static void GrenadeThrown(EventGrenadeThrown _) { }
+ public static void BulletImpact(EventBulletImpact _) { }
public static void BombBeginplant(EventBombBeginplant _) { }
public static void BombAbortplant(EventBombAbortplant _) { }
@@ -146,7 +148,6 @@ public enum Skills
RadarHack,
Rambo,
RandomWeapon,
- RCMelon,
ReZombie,
ReactiveArmor,
Regeneration,
diff --git a/jRandomSkills - SRC Files/src/player/PlayerEvents.cs b/jRandomSkills - SRC Files/src/player/PlayerEvents.cs
index 6c727e9..9367d3a 100644
--- a/jRandomSkills - SRC Files/src/player/PlayerEvents.cs
+++ b/jRandomSkills - SRC Files/src/player/PlayerEvents.cs
@@ -2,15 +2,14 @@ using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes;
using CounterStrikeSharp.API.Modules.Admin;
+using CounterStrikeSharp.API.Modules.Commands;
using CounterStrikeSharp.API.Modules.Cvars;
using CounterStrikeSharp.API.Modules.Events;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.UserMessages;
using CounterStrikeSharp.API.Modules.Utils;
-using CS2TraceRay.Class;
-using CS2TraceRay.Enum;
-using CS2TraceRay.Struct;
+using RayTraceAPI;
using src.player.skills;
using src.utils;
using System.Collections.Concurrent;
@@ -40,6 +39,8 @@ namespace src.player
public static readonly ConcurrentDictionary staticSkills = [];
private static readonly object setLock = new();
+ private static readonly MemoryFunctionVoid DropWeaponFunc = new(GameData.GetSignature("CCSPlayerController_HandleCommandDrop"));
+
public static void Load()
{
Instance.RegisterEventHandler(PlayerConnectFull);
@@ -78,9 +79,13 @@ namespace src.player
Instance.HookUserMessage(208, PlayerMakeSound);
VirtualFunctions.CBaseEntity_TakeDamageOldFunc.Hook(OnTakeDamage, HookMode.Pre);
+ Instance.RegisterEventHandler(BulletImpact);
+
VirtualFunctions.CBaseTrigger_StartTouchFunc.Hook(OnTriggerEnter, HookMode.Post);
VirtualFunctions.CBaseTrigger_EndTouchFunc.Hook(OnTriggerExit, HookMode.Pre);
VirtualFunctions.CCSPlayer_ItemServices_CanAcquireFunc.Hook(OnWeaponCanAcquire, HookMode.Pre);
+
+ DropWeaponFunc.Hook(WeaponDrop, HookMode.Pre);
}
private static HookResult PlayerMakeSound(UserMessage um)
@@ -426,7 +431,34 @@ namespace src.player
return block ? HookResult.Stop : HookResult.Continue;
}
}
-
+
+ private static HookResult WeaponDrop(DynamicHook hook)
+ {
+ lock (setLock)
+ {
+ CCSPlayerController player = hook.GetParam(0);
+ if (player == null || !player.IsValid)
+ return HookResult.Continue;
+
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ bool block = false;
+ foreach (string skillName in activeSkills)
+ {
+ bool? result = (bool?)Instance.SkillAction(skillName, "WeaponDrop", [hook, player]);
+ if (result == true)
+ {
+ block = true;
+ break;
+ }
+ }
+ return block ? HookResult.Stop : HookResult.Continue;
+ }
+ }
+
private static void OnTick()
{
lock (setLock)
@@ -488,6 +520,8 @@ namespace src.player
var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (skillPlayer == null) return HookResult.Continue;
+ Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [player]);
+
var items = Instance.SkillPlayer.ToList();
Instance.SkillPlayer = [.. items.Where(p => p.SteamID != skillPlayer.SteamID)];
@@ -735,13 +769,13 @@ namespace src.player
Vector eyePos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z);
Vector endPos = eyePos + SkillUtils.GetForwardVector(pawn.EyeAngles) * 80;
- ulong mask = pawn.Collision.CollisionAttribute.InteractsWith | (ulong)(Contents.Solid | Contents.Hitbox | Contents.Pickup | Contents.TouchAll | Contents.CarriedObject | Contents.CarriedWeapon | Contents.Debris);
+ ulong mask = (ulong)(InteractionLayers.MASK_WORLD_ONLY | InteractionLayers.Player | InteractionLayers.NPC);
ulong contents = 0;
- CGameTrace trace = TraceRay.TraceShape(eyePos, endPos, mask, contents, player);
+ var result = RayTrace.TraceShape(player, eyePos, endPos, mask, contents);
- if (trace.DidHit())
+ if (result.HasValue && result.Value.DidHit)
{
- var entity = Activator.CreateInstance(typeof(CBaseEntity), trace.HitEntity) as CBaseEntity;
+ var entity = Activator.CreateInstance(typeof(CBaseEntity), result.Value.HitEntity) as CBaseEntity;
if (entity == null || !entity.IsValid) return;
string designer = entity.DesignerName;
@@ -768,12 +802,32 @@ namespace src.player
}
}
+ private static HookResult BulletImpact(EventBulletImpact @event, GameEventInfo info)
+ {
+ lock (setLock)
+ {
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "BulletImpact", [@event]);
+ return HookResult.Continue;
+ }
+ }
+
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();
+ var validPlayers = Utilities.GetPlayers()
+ .Where(p => p != null && p.IsValid && !p.IsBot && !p.IsHLTV)
+ .Where(p => {
+ try { return p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist; }
+ catch { return false; }
+ }).ToList();
if (Config.LoadedConfig.GameMode == (int)Config.GameModes.TeamSkills)
{
@@ -797,7 +851,7 @@ namespace src.player
foreach (var player in validPlayers)
{
if (player == null) continue;
- var teammates = validPlayers.Where(p => p.Team == player.Team && p != player);
+ var teammates = validPlayers.Where(p => p != null && p.IsValid && p.Team == player.Team && p != player).ToList();
string teammateSkills = "";
var skillPlayer = Instance?.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
@@ -875,6 +929,8 @@ namespace src.player
Instance?.AddTimer(.2f, () =>
{
+ if(player == null || !player.IsValid) return;
+
if (randomSkill.Display)
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(randomSkill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(randomSkill.Skill)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
@@ -901,6 +957,8 @@ namespace src.player
{
Instance?.AddTimer(.6f, () =>
{
+ if (player == null || !player.IsValid) return;
+
foreach (var teammate in teammates)
{
var teammateInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == teammate.SteamID);
diff --git a/jRandomSkills - SRC Files/src/player/skills/AimLock.cs b/jRandomSkills - SRC Files/src/player/skills/AimLock.cs
index d38d39f..aae909c 100644
--- a/jRandomSkills - SRC Files/src/player/skills/AimLock.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/AimLock.cs
@@ -121,9 +121,15 @@ namespace src.player.skills
if (enemyPawn == null || enemyPawn.AbsOrigin == null) return;
Vector myEyePos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z);
- Vector enemyEyePos = new(enemyPawn.AbsOrigin.X, enemyPawn.AbsOrigin.Y, enemyPawn.AbsOrigin.Z + enemyPawn.ViewOffset.Z + SkillsInfo.GetValue(skillName, "offsetZ"));
- Vector direction = enemyEyePos - myEyePos;
+ Vector diff = SkillUtils.GetForwardVector(enemyPawn.AbsRotation!) * 5;
+ Vector enemyHead = new(
+ enemyPawn.AbsOrigin.X + diff.X,
+ enemyPawn.AbsOrigin.Y + diff.Y,
+ enemyPawn.AbsOrigin.Z + enemyPawn.ViewOffset.Z + 2
+ );
+
+ Vector direction = enemyHead - myEyePos;
QAngle angle = VectorToAngle(direction);
pawn.Look(angle);
@@ -145,11 +151,10 @@ namespace src.player.skills
public DateTime Cooldown { get; set; }
}
- public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#fa7b48", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 20f, float duration = .3f, float offsetZ = 0) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
+ public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#fa7b48", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 20f, float duration = .3f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public float Cooldown { get; set; } = cooldown;
public float Duration { get; set; } = duration;
- public float Offset { get; set; } = offsetZ;
}
}
}
\ No newline at end of file
diff --git a/jRandomSkills - SRC Files/src/player/skills/Anomaly.cs b/jRandomSkills - SRC Files/src/player/skills/Anomaly.cs
index 84175ce..5cdf5ed 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Anomaly.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Anomaly.cs
@@ -40,7 +40,7 @@ namespace src.player.skills
{
if (skillInfo.LastRotations == null || skillInfo.LastPositions == null) continue;
skillInfo.LastPositions.Enqueue(new Vector(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z));
- skillInfo.LastRotations.Enqueue(new QAngle(pawn.EyeAngles.X, pawn.EyeAngles.Y, pawn.EyeAngles.Z));
+ skillInfo.LastRotations.Enqueue(new QAngle(pawn.V_angle.X, pawn.V_angle.Y, 0));
if (skillInfo.LastRotations.Count > SkillsInfo.GetValue(skillName, "secondsInBack"))
{
skillInfo.LastPositions.TryDequeue(out _);
@@ -106,7 +106,10 @@ namespace src.player.skills
Vector? lastPosition = skillInfo.LastPositions.FirstOrDefault();
QAngle? lastRotation = skillInfo.LastRotations.FirstOrDefault();
if (lastPosition != null && lastRotation != null)
- playerPawn.Teleport(lastPosition, lastRotation, null);
+ {
+ playerPawn.Teleport(lastPosition, null, null);
+ playerPawn.Look(lastRotation);
+ }
}
}
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Baseball.cs b/jRandomSkills - SRC Files/src/player/skills/Baseball.cs
index 595f1aa..8bd9b20 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Baseball.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Baseball.cs
@@ -11,7 +11,7 @@ namespace src.player.skills
public class Baseball : ISkill
{
private const Skills skillName = Skills.Baseball;
- private static readonly ConcurrentDictionary decoys = [];
+ private static readonly ConcurrentDictionary decoys = [];
public static void LoadSkill()
{
@@ -50,7 +50,7 @@ namespace src.player.skills
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo?.Skill != skillName) return;
- decoys.TryAdd(decoy, 0);
+ decoys.TryAdd(decoy.Index, 0);
decoy.Collision.CollisionAttribute.InteractsWith = pawn.Collision.CollisionAttribute.InteractsWith;
decoy.Collision.CollisionGroup = pawn.Collision.CollisionGroup;
@@ -60,25 +60,33 @@ namespace src.player.skills
{
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 decoy = decoys.FirstOrDefault(d => d.Key.Index == @event.Entityid).Key;
- if (decoy != null && decoy.IsValid)
- decoy.AcceptInput("Kill");
+ if (decoys.ContainsKey((uint)@event.Entityid))
+ {
+ var decoy = Utilities.GetEntityFromIndex(@event.Entityid);
+ if (decoy != null && decoy.IsValid)
+ decoy.AcceptInput("Kill");
+ }
}
public static void OnTick()
{
- foreach (var decoy in decoys.Keys)
+ foreach (var decoyIndex in decoys.Keys)
{
- if (!decoy.IsValid)
+ var decoy = Utilities.GetEntityFromIndex((int)decoyIndex);
+
+ if (decoy == null || !decoy.IsValid)
{
- decoys.TryRemove(decoy, out _);
+ decoys.TryRemove(decoyIndex, out _);
continue;
}
+
decoy.Bounces = 0;
if (Server.TickCount % 8 != 0) continue;
+
var vel = decoy.AbsVelocity;
float speed = vel.Length();
float targetSpeed = Math.Min(speed * SkillsInfo.GetValue(skillName, "speedMultipier"), SkillsInfo.GetValue(skillName, "maxSpeed"));
diff --git a/jRandomSkills - SRC Files/src/player/skills/Behind.cs b/jRandomSkills - SRC Files/src/player/skills/Behind.cs
index 63e64d3..0852d2c 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Behind.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Behind.cs
@@ -45,16 +45,8 @@ namespace src.player.skills
if (pawn == null || !pawn.IsValid || pawn.LifeState != (int)LifeState_t.LIFE_ALIVE) return;
- var currentPosition = pawn.AbsOrigin;
- var currentAngles = pawn.EyeAngles;
-
- QAngle newAngles = new(
- currentAngles.X,
- currentAngles.Y + 180,
- currentAngles.Z
- );
-
- pawn.Teleport(currentPosition, newAngles, new Vector(0, 0, 0));
+ QAngle look = new(pawn.V_angle.X, pawn.V_angle.Y + 180, 0);
+ pawn.Look(look);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#00FF00", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float chanceFrom = .2f, float chanceTo = .4f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
diff --git a/jRandomSkills - SRC Files/src/player/skills/BunnyHop.cs b/jRandomSkills - SRC Files/src/player/skills/BunnyHop.cs
index 410ee7c..5c4cbd7 100644
--- a/jRandomSkills - SRC Files/src/player/skills/BunnyHop.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/BunnyHop.cs
@@ -31,7 +31,7 @@ namespace src.player.skills
{
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return;
- if (JumpBan.bannedPlayers.ContainsKey(playerPawn)) return;
+ if (JumpBan.bannedPlayers.ContainsKey(player.Index)) return;
var flags = (PlayerFlags)playerPawn.Flags;
var buttons = player.Buttons;
diff --git a/jRandomSkills - SRC Files/src/player/skills/C4Camouflage.cs b/jRandomSkills - SRC Files/src/player/skills/C4Camouflage.cs
index 077dfe3..f97d44a 100644
--- a/jRandomSkills - SRC Files/src/player/skills/C4Camouflage.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/C4Camouflage.cs
@@ -11,7 +11,7 @@ namespace src.player.skills
public class C4Camouflage : ISkill
{
private const Skills skillName = Skills.C4Camouflage;
- private static readonly ConcurrentDictionary invisiblePlayers = [];
+ private static readonly ConcurrentDictionary invisiblePlayers = [];
private const string bloodParticle = "particles/blood_impact/blood_impact_high.vpcf";
public static void LoadSkill()
@@ -44,16 +44,16 @@ namespace src.player.skills
if (playerInfo?.Skill != skillName) return;
if (weapon == "c4")
- invisiblePlayers.TryAdd(player, 0);
+ invisiblePlayers.TryAdd(player.Index, 0);
else
- invisiblePlayers.TryRemove(player, out _);
+ invisiblePlayers.TryRemove(player.Index, out _);
}
public static void OnTick()
{
foreach (var player in Utilities.GetPlayers())
if (!player.PawnIsAlive)
- invisiblePlayers.TryRemove(player, out _);
+ invisiblePlayers.TryRemove(player.Index, out _);
}
public static void CheckTransmit([CastFrom(typeof(nint))] CCheckTransmitInfoList infoList)
@@ -72,10 +72,15 @@ namespace src.player.skills
if (targetInfo?.Skill == skillName) isObservingC4Camouflage = true;
}
- foreach (var _player in invisiblePlayers.Keys)
- if (player.SteamID != _player.SteamID && !isObservingC4Camouflage)
+ foreach (var playerIndex in invisiblePlayers.Keys)
+ {
+ var playerController = Utilities.GetPlayerFromIndex((int)playerIndex);
+ if (playerController == null || !playerController.IsValid || playerController.SteamID == player.SteamID)
+ continue;
+
+ if (!isObservingC4Camouflage)
{
- var playerPawn = _player.PlayerPawn.Value;
+ var playerPawn = playerController.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) continue;
var entity = Utilities.GetEntityFromIndex((int)playerPawn.Index);
@@ -89,6 +94,7 @@ namespace src.player.skills
if (bombEntity == null || !bombEntity.IsValid) continue;
info.TransmitEntities.Remove(bombEntity.Index);
}
+ }
}
}
@@ -105,19 +111,19 @@ namespace src.player.skills
var activeWeapon = playerPawn.WeaponServices.ActiveWeapon.Value;
if (activeWeapon.DesignerName != "weapon_c4") return;
- invisiblePlayers.TryAdd(player, 0);
+ invisiblePlayers.TryAdd(player.Index, 0);
}
public static void DisableSkill(CCSPlayerController player)
{
- invisiblePlayers.TryRemove(player, out _);
+ invisiblePlayers.TryRemove(player.Index, out _);
}
public static void PlayerHurt(EventPlayerHurt @event)
{
var player = @event.Userid;
if (player == null || !player.IsValid) return;
- if (!invisiblePlayers.ContainsKey(player)) return;
+ if (!invisiblePlayers.ContainsKey(player.Index)) return;
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return;
diff --git a/jRandomSkills - SRC Files/src/player/skills/CarefulBullets.cs b/jRandomSkills - SRC Files/src/player/skills/CarefulBullets.cs
index c67492f..c32a737 100644
--- a/jRandomSkills - SRC Files/src/player/skills/CarefulBullets.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/CarefulBullets.cs
@@ -1,10 +1,10 @@
-using CounterStrikeSharp.API.Core;
+using CounterStrikeSharp.API;
+using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils;
-using static src.jRandomSkills;
-using System.Collections.Concurrent;
using src.utils;
-using CounterStrikeSharp.API;
+using System.Collections.Concurrent;
+using static src.jRandomSkills;
namespace src.player.skills
{
@@ -13,6 +13,7 @@ namespace src.player.skills
private const Skills skillName = Skills.CarefulBullets;
private static readonly ConcurrentDictionary targetPlayers = [];
private static readonly ConcurrentDictionary lastShot = [];
+ private static readonly ConcurrentDictionary hitPlayer = [];
private static readonly object setLock = new();
public static void LoadSkill()
@@ -26,6 +27,7 @@ namespace src.player.skills
{
targetPlayers.Clear();
lastShot.Clear();
+ hitPlayer.Clear();
}
foreach (var player in Utilities.GetPlayers())
{
@@ -100,48 +102,70 @@ namespace src.player.skills
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("selectplayerskill_incorrect_enemy_index")}");
}
+ public static void BulletImpact(EventBulletImpact @event)
+ {
+ var player = @event.Userid;
+ if (player == null || !player.IsValid) return;
+
+ var playerPawn = player.PlayerPawn.Value;
+ if (playerPawn == null || !playerPawn.IsValid) return;
+
+ if (!targetPlayers.ContainsKey(player.SteamID) || !player.PawnIsAlive)
+ return;
+
+ ulong steamID = player.SteamID;
+
+ Server.NextFrame(() =>
+ {
+ if (player == null || !player.IsValid) return;
+ if (playerPawn == null || !playerPawn.IsValid) return;
+
+ bool ishitPlayer = hitPlayer.TryGetValue(steamID, out int tick) && tick + 10 >= Server.TickCount;
+
+ if (!lastShot.ContainsKey(steamID))
+ {
+ lastShot.TryAdd(steamID, ishitPlayer);
+
+ Instance.AddTickTimer(1, () =>
+ {
+ if (lastShot.TryRemove(steamID, out bool didHit) && !didHit)
+ SkillUtils.TakeHealth(playerPawn, SkillsInfo.GetValue(skillName, "damageAfterMiss"));
+ lastShot.TryRemove(steamID, out _);
+ });
+ }
+ else if (ishitPlayer)
+ lastShot.TryUpdate(steamID, true, false);
+ });
+ }
+
public static void OnTakeDamage(DynamicHook h)
{
CEntityInstance param = h.GetParam(0);
CTakeDamageInfo param2 = h.GetParam(1);
- if (param?.Entity == null || param2?.Attacker?.Value == null)
+ if (param == null || param.Entity == null || param2 == null || param2.Attacker == null || param2.Attacker.Value == null)
return;
CCSPlayerPawn attackerPawn = new(param2.Attacker.Value.Handle);
+ CCSPlayerPawn victimPawn = new(param.Handle);
- if (attackerPawn.DesignerName != "player")
+ if (attackerPawn.DesignerName != "player" || victimPawn.DesignerName != "player")
return;
- if (attackerPawn == null || attackerPawn.Controller?.Value == null)
+ if (attackerPawn == null || attackerPawn.Controller?.Value == null || victimPawn == null || victimPawn.Controller?.Value == null)
return;
CCSPlayerController attacker = attackerPawn.Controller.Value.As();
+ if (!targetPlayers.ContainsKey(attacker.SteamID)) return;
- if (!targetPlayers.ContainsKey(attacker.SteamID) || !attacker.PawnIsAlive)
- return;
-
- bool hitPlayer = param.DesignerName == "player";
-
- if (!lastShot.ContainsKey(attacker.SteamID))
- {
- lastShot.TryAdd(attacker.SteamID, hitPlayer);
-
- Instance.AddTickTimer(1, () =>
- {
- if (lastShot.TryRemove(attacker.SteamID, out bool didHit) && !didHit)
- SkillUtils.TakeHealth(attackerPawn, SkillsInfo.GetValue(skillName, "damageAfterMiss"));
- lastShot.TryRemove(attacker.SteamID, out _);
- });
- }
- else if (hitPlayer)
- lastShot.TryUpdate(attacker.SteamID, true, false);
+ hitPlayer.AddOrUpdate(attacker.SteamID, Server.TickCount, (_, _) => Server.TickCount);
}
public static void DisableSkill(CCSPlayerController player)
{
targetPlayers.TryRemove(player.SteamID, out _);
lastShot.TryRemove(player.SteamID, out _);
+ hitPlayer.TryRemove(player.SteamID, out _);
SkillUtils.CloseMenu(player);
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Chicken.cs b/jRandomSkills - SRC Files/src/player/skills/Chicken.cs
index 831fa01..f886784 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Chicken.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Chicken.cs
@@ -21,9 +21,9 @@ namespace src.player.skills
"weapon_xm1014", "weapon_mag7", "weapon_sawedoff", "weapon_m249",
"weapon_negev"
];
- private static readonly ConcurrentDictionary chickens = [];
- private static readonly string defaultCTModel = "characters/models/ctm_sas/ctm_sas.vmdl";
- private static readonly string defaultTModel = "characters/models/tm_phoenix/tm_phoenix.vmdl";
+ private static readonly ConcurrentDictionary chickens = [];
+ private static readonly string defaultCTModel = "agents/models/ctm_sas/ctm_sas.vmdl";
+ private static readonly string defaultTModel = "agents/models/tm_phoenix/tm_phoenix.vmdl";
private static readonly ConcurrentDictionary originalModels = [];
public static void LoadSkill()
@@ -35,9 +35,14 @@ namespace src.player.skills
{
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");
+ {
+ var chicken = Utilities.GetEntityFromIndex((int)valuePair.Value);
+ if (chicken != null && chicken.IsValid)
+ chicken.AcceptInput("Kill");
+ }
+
chickens.Clear();
originalModels.Clear();
}
@@ -96,11 +101,12 @@ namespace src.player.skills
SetWeaponAttack(player, false);
}
- if (chickens.TryGetValue(player, out var chicken))
+ if (chickens.TryRemove(player.Index, out var chickenIndex))
{
+ var chicken = Utilities.GetEntityFromIndex((int)chickenIndex);
+
if (chicken != null && chicken.IsValid)
chicken.AcceptInput("Kill");
- chickens.TryRemove(player, out _);
}
if (originalModels.TryGetValue(player.SteamID, out var model))
@@ -110,6 +116,9 @@ namespace src.player.skills
Server.NextFrame(() =>
{
+ if (player == null || !player.IsValid) return;
+ if (pawn == null || !pawn.IsValid) return;
+
if (string.IsNullOrEmpty(model))
model = player.Team == CsTeam.Terrorist ? defaultTModel : defaultCTModel;
@@ -157,19 +166,27 @@ namespace src.player.skills
chickenModel.CBodyComponent.SceneNode.GetSkeletonInstance().Scale = 1;
Utilities.SetStateChanged(chickenModel, "CBaseEntity", "m_CBodyComponent");
- Server.NextFrame(() => chickenModel.AcceptInput("SetScale", chickenModel, chickenModel, "1"));
+
+ Server.NextFrame(() => {
+ if (chickenModel == null || !chickenModel.IsValid) return;
+ chickenModel.AcceptInput("SetScale", chickenModel, chickenModel, "1");
+ });
chickenModel.AcceptInput("SetParent", playerPawn, playerPawn, "!activator");
- chickens.TryAdd(player, chickenModel);
+ chickens.TryAdd(player.Index, chickenModel.Index);
}
public static void OnTick()
{
foreach (var valuePair in chickens)
{
- var player = valuePair.Key;
- var chicken = valuePair.Value;
+ var playerIndex = valuePair.Key;
+ var chickenIndex = valuePair.Value;
+
+ var player = Utilities.GetPlayerFromIndex((int)playerIndex);
if (player == null || !player.IsValid) continue;
+
+ var chicken = Utilities.GetEntityFromIndex((int)chickenIndex);
if (chicken == null || !chicken.IsValid) continue;
var pawn = player.PlayerPawn.Value;
diff --git a/jRandomSkills - SRC Files/src/player/skills/Cypher.cs b/jRandomSkills - SRC Files/src/player/skills/Cypher.cs
index 59c7e6d..59ddf19 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Cypher.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Cypher.cs
@@ -3,8 +3,7 @@ using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Timers;
using CounterStrikeSharp.API.Modules.Utils;
-using CS2TraceRay.Class;
-using CS2TraceRay.Struct;
+using RayTraceAPI;
using src.utils;
using System.Collections.Concurrent;
using System.Drawing;
@@ -17,7 +16,7 @@ namespace src.player.skills
public class Cypher : ISkill
{
private const Skills skillName = Skills.Cypher;
- private static readonly ConcurrentDictionary playersInfo = [];
+ private static readonly ConcurrentDictionary playersInfo = [];
private static readonly object setLock = new();
private const string cameraPropModel = "models/props/de_train/hr_train_s2/train_electronics/train_electronics_security_camera_01.vmdl";
@@ -42,16 +41,16 @@ namespace src.player.skills
{
var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return;
- if (playersInfo.TryGetValue(player, out var playerSkill))
+ if (playersInfo.TryGetValue(player.Index, out var playerSkill))
ChangeCamera(playerSkill);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.CameraServices == null) return;
- playersInfo.TryAdd(player, new PlayerSkill
+ playersInfo.TryAdd(player.Index, new PlayerSkill
{
- Player = player,
+ Player = player.Index,
CameraProp = null,
CameraView = null,
CameraActive = false,
@@ -64,29 +63,36 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
- if (playersInfo.TryGetValue(player, out var playerSkill))
+ if (playersInfo.TryGetValue(player.Index, out var playerSkill))
{
ChangeCamera(playerSkill, true);
KillCamera(playerSkill);
}
- playersInfo.TryRemove(player, out _);
+ playersInfo.TryRemove(player.Index, out _);
}
private static void KillCamera(PlayerSkill playerSkill)
{
- if (playerSkill.CameraView != null && playerSkill.CameraView.IsValid)
+ if (playerSkill.CameraView != null && playerSkill.CameraView != 0)
{
- playerSkill.CameraView.AcceptInput("Kill");
+ var cameraView = Utilities.GetEntityFromIndex((int)playerSkill.CameraView);
+ if (cameraView != null && cameraView.IsValid)
+ cameraView.AcceptInput("Kill");
playerSkill.CameraView = null;
- playerSkill.CameraActive = false;
}
- if (playerSkill.CameraProp != null && playerSkill.CameraProp.IsValid)
+ if (playerSkill.CameraProp != null && playerSkill.CameraProp != 0)
{
- playerSkill.CameraProp.EmitSound("SolidMetal.BulletImpact");
- playerSkill.CameraProp.AcceptInput("Kill");
+ var cameraProp = Utilities.GetEntityFromIndex((int)playerSkill.CameraProp);
+ if (cameraProp != null && cameraProp.IsValid)
+ {
+ cameraProp.EmitSound("SolidMetal.BulletImpact");
+ cameraProp.AcceptInput("Kill");
+ }
playerSkill.CameraProp = null;
}
+
+ playerSkill.CameraActive = false;
playerSkill.NextCamera = Server.TickCount + SkillsInfo.GetValue(skillName, "Cooldown") * 64;
}
@@ -94,65 +100,88 @@ namespace src.player.skills
{
foreach (var playerSkill in playersInfo.Values)
{
- if (playerSkill.CameraActive && playerSkill.CameraView != null && playerSkill.CameraView.IsValid)
+ if (playerSkill.CameraActive && playerSkill.CameraView != null && playerSkill.CameraView != 0)
{
- var pawn = playerSkill.Player.PlayerPawn.Value;
- if (pawn == null || !pawn.IsValid) continue;
+ var enemy = Utilities.GetPlayerFromIndex((int)playerSkill.Player);
+ if (enemy == null || !enemy.IsValid || enemy.PlayerPawn == null) continue;
- if (pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
+ var enemyPawn = enemy.PlayerPawn.Value;
+ if (enemyPawn == null || !enemyPawn.IsValid) continue;
+
+ if (enemyPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
{
- DisableSkill(playerSkill.Player);
+ DisableSkill(enemy);
continue;
}
- playerSkill.CameraView.Teleport(null, pawn.V_angle);
+
+ var cameraView = Utilities.GetEntityFromIndex((int)playerSkill.CameraView);
+ if (cameraView == null || !cameraView.IsValid) continue;
+
+ cameraView.Teleport(null, enemyPawn.V_angle);
}
UpdateHUD(playerSkill);
}
}
- private static void ChangeCamera(PlayerSkill player, bool forceToDefault = false)
+ private static void ChangeCamera(PlayerSkill playerInfo, bool forceToDefault = false)
{
- player.CameraActive = forceToDefault ? false : !player.CameraActive;
- if (player.CameraProp == null && !forceToDefault)
+ var player = Utilities.GetPlayerFromIndex((int)playerInfo.Player);
+ if (player == null || !player.IsValid) return;
+
+ playerInfo.CameraActive = forceToDefault ? false : !playerInfo.CameraActive;
+ if (playerInfo.CameraProp == null && !forceToDefault)
{
- if (player.NextCamera > Server.TickCount) return;
- player.CameraProp = CreateCameraProp(player.Player);
- if (player.CameraProp == null)
+ if (playerInfo.NextCamera > Server.TickCount) return;
+
+ var newProp = CreateCameraProp(player);
+ playerInfo.CameraProp = newProp?.Index ?? null;
+
+ if (playerInfo.CameraProp == null)
{
- player.NoSpace = Server.TickCount + (64 * 2);
+ playerInfo.NoSpace = Server.TickCount + (64 * 2);
return;
}
- player.CameraView = CreateCameraView(player.Player);
- if (player.CameraView == null) return;
+ else
+ playerInfo.CameraView = CreateCameraView(newProp)?.Index ?? null;
+
+ if (playerInfo.CameraView == null) return;
}
- var pawn = player.Player.PlayerPawn.Value;
- if (player.PlayerCameraRaw == 0)
+ var pawn = player.PlayerPawn.Value;
+ if (playerInfo.PlayerCameraRaw == 0)
return;
- BlockWeapon(player.Player, player.CameraActive);
+ BlockWeapon(player, playerInfo.CameraActive);
Server.NextWorldUpdate(() =>
{
if (pawn != null && pawn.LifeState == (byte)LifeState_t.LIFE_ALIVE)
{
- if (player.CameraActive && player.CameraProp != null)
+ if (playerInfo.CameraActive && playerInfo.CameraProp != null)
{
- if ( pawn.AbsRotation != null)
- player.LastAngle = new QAngle(pawn.AbsRotation.X, pawn.AbsRotation.Y, pawn.AbsRotation.Z);
- pawn.Teleport(null, player.CameraProp.AbsRotation);
+ if (pawn.AbsRotation != null)
+ playerInfo.LastAngle = new QAngle(pawn.V_angle.X, pawn.V_angle.Y, 0);
+
+ var cameraProp = Utilities.GetEntityFromIndex((int)playerInfo.CameraProp);
+ if (cameraProp == null || !cameraProp.IsValid) return;
+
+ pawn.Teleport(null, cameraProp.AbsRotation);
}
else if (!forceToDefault)
- pawn.Teleport(null, player.LastAngle);
+ {
+ pawn.Look(playerInfo.LastAngle);
+ }
}
- if (player.CameraActive && player.CameraView != null)
+ if (playerInfo.CameraActive && playerInfo.CameraView != null)
{
- pawn!.CameraServices!.ViewEntity.Raw = player.CameraView.EntityHandle.Raw;
- SkillUtils.ApplyScreenColor(player.Player, 0, 0, 255, 20, 100, 1020);
+ var cameraView = Utilities.GetEntityFromIndex((int)playerInfo.CameraView);
+ if (cameraView == null || !cameraView.IsValid) return;
- ulong? playerSteamID = player.Player?.SteamID;
- if (playerSteamID == null) return;
+ pawn!.CameraServices!.ViewEntity.Raw = cameraView.EntityHandle.Raw;
+ SkillUtils.ApplyScreenColor(player, 0, 0, 255, 20, 100, 1020);
+
+ ulong playerSteamID = player.SteamID;
Timer? cameraTimer = null;
cameraTimer = jRandomSkills.Instance.AddTimer(2f, () =>
@@ -164,7 +193,7 @@ namespace src.player.skills
return;
}
- if (!playersInfo.TryGetValue(target, out var playerSkill) || playerSkill.CameraActive == false)
+ if (!playersInfo.TryGetValue(target.Index, out var playerSkill) || playerSkill.CameraActive == false)
{
cameraTimer?.Kill();
return;
@@ -174,7 +203,7 @@ namespace src.player.skills
}, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT);
}
else
- pawn!.CameraServices!.ViewEntity.Raw = player.PlayerCameraRaw;
+ pawn!.CameraServices!.ViewEntity.Raw = playerInfo.PlayerCameraRaw;
Utilities.SetStateChanged(pawn, "CBasePlayerPawn", "m_pCameraServices");
});
@@ -182,6 +211,18 @@ namespace src.player.skills
private static CDynamicProp? CreateCameraProp(CCSPlayerController player)
{
+ var playerPawn = player.PlayerPawn.Value;
+ if (playerPawn == null || !playerPawn.IsValid) return null;
+
+ Vector? cameraVector = GetNewCameraPosition(player);
+ if (cameraVector == null) return null;
+
+ Vector diffVector = SkillUtils.GetForwardVector(playerPawn.V_angle) * 10;
+ Vector finalPos = new(cameraVector.X + diffVector.X, cameraVector.Y + diffVector.Y, cameraVector.Z);
+
+ if (!CheckCameraPosition(finalPos, player))
+ return null;
+
var camera = Utilities.CreateEntityByName("prop_dynamic_override");
if (camera == null || !camera.IsValid) return null;
@@ -189,47 +230,32 @@ namespace src.player.skills
camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
camera.Entity!.Name = camera.Globalname = $"CypherCamera_{Server.TickCount}_{player.SteamID}";
- var playerPawn = player.PlayerPawn.Value;
- if (playerPawn == null || !playerPawn.IsValid) return null;
-
- Vector? cameraVector = GetNewCameraPosition(player);
- Vector diffVector = SkillUtils.GetForwardVector(playerPawn.V_angle) * 10;
- if (cameraVector == null) return null;
- cameraVector = new Vector(cameraVector.X + diffVector.X, cameraVector.Y + diffVector.Y, cameraVector.Z);
-
- if (!CheckCameraPosition(cameraVector, player))
- return null;
-
- Server.NextFrame(() =>
- {
- camera.SetModel(cameraPropModel);
- camera.Teleport(cameraVector, new QAngle(0, playerPawn.V_angle.Y + 180, 0));
- camera.DispatchSpawn();
- });
+ if (camera == null || !camera.IsValid) return null;
+ camera.SetModel(cameraPropModel);
+ camera.Teleport(cameraVector, new QAngle(0, playerPawn.V_angle.Y + 180, 0));
+ camera.DispatchSpawn();
return camera;
}
- private static CDynamicProp? CreateCameraView(CCSPlayerController player)
+ private static CDynamicProp? CreateCameraView(CDynamicProp? cameraProp)
{
+ if (cameraProp == null || !cameraProp.IsValid || cameraProp.AbsRotation == null || cameraProp.AbsOrigin == null)
+ return null;
+
+ Vector diffVector = SkillUtils.GetForwardVector(cameraProp.AbsRotation) * 25;
+ Vector finalPos = cameraProp.AbsOrigin + diffVector;
+
var camera = Utilities.CreateEntityByName("prop_dynamic");
if (camera == null || !camera.IsValid) return null;
- var playerPawn = player.PlayerPawn.Value;
- if (playerPawn == null || !playerPawn.IsValid) return null;
-
- Vector? cameraVector = GetNewCameraPosition(player);
- Vector diffVector = SkillUtils.GetForwardVector(playerPawn.V_angle) * 25;
- if (cameraVector == null) return null;
-
- cameraVector = new Vector(cameraVector.X - diffVector.X, cameraVector.Y - diffVector.Y, cameraVector.Z);
- if (cameraVector == null) return null;
-
Server.NextFrame(() =>
{
+ if (camera == null || !camera.IsValid) return;
camera.SetModel(cameraViewModel);
camera.Render = Color.FromArgb(0, 255, 255, 255);
- camera.Teleport(cameraVector, playerPawn.EyeAngles);
+
+ camera.Teleport(finalPos, cameraProp.AbsRotation);
camera.DispatchSpawn();
});
@@ -254,7 +280,7 @@ namespace src.player.skills
var player = Utilities.GetPlayerFromSteamId(steamID);
if (player == null) return;
- if (playersInfo.TryGetValue(player, out var playerSkill))
+ if (playersInfo.TryGetValue(player.Index, out var playerSkill))
{
ChangeCamera(playerSkill, true);
KillCamera(playerSkill);
@@ -286,18 +312,13 @@ namespace src.player.skills
Vector eyePos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + playerPawn.ViewOffset.Z);
Vector endPos = eyePos + SkillUtils.GetForwardVector(playerPawn.V_angle) * 4096f;
- ulong solid = 0x1;
- ulong window = 0x1000;
- ulong passBullets = 0x2000;
+ ulong mask = (ulong)(InteractionLayers.Solid | InteractionLayers.Window | InteractionLayers.PassBullets);
+ var result = RayTrace.TraceShape(player, eyePos, endPos, mask);
- ulong mask = solid | window | passBullets;
- ulong contents = playerPawn.Collision.CollisionGroup;
- CGameTrace trace = TraceRay.TraceShape(eyePos, endPos, mask, contents, player);
-
- if (trace.HitWorld(out _))
+ if (result.HasValue && result.Value.HitWorld(out _))
{
- Vector3 hitPost = trace.EndPos;
- Vector3 normal = trace.Normal;
+ Vector3 hitPost = result.Value.EndPos;
+ Vector3 normal = result.Value.Normal;
float offset = 8;
Vector finalPos = new(
@@ -320,15 +341,10 @@ namespace src.player.skills
Vector endPos = cameraVector + SkillUtils.GetForwardVector(new QAngle(0, playerPawn.V_angle.Y + 180, 0)) * -5;
cameraVector += SkillUtils.GetForwardVector(new QAngle(0, playerPawn.V_angle.Y + 180, 0)) * 5;
- ulong solid = 0x1;
- ulong window = 0x1000;
- ulong passBullets = 0x2000;
+ ulong mask = (ulong)(InteractionLayers.Solid | InteractionLayers.Window | InteractionLayers.PassBullets);
+ var result = RayTrace.TraceShape(player, cameraVector, endPos, mask);
- ulong mask = solid | window | passBullets;
- ulong contents = playerPawn.Collision.CollisionGroup;
- CGameTrace trace = TraceRay.TraceShape(cameraVector, endPos, mask, contents, player);
-
- if (trace.HitWorld(out _))
+ if (result.HasValue && result.Value.HitWorld(out _))
return true;
return false;
@@ -336,28 +352,30 @@ namespace src.player.skills
private static void UpdateHUD(PlayerSkill playerSkill)
{
- if (playerSkill == null || playerSkill.Player == null) return;
+ if (playerSkill == null) return;
- float cooldown = 0;
- float time = (playerSkill.NextCamera - Server.TickCount) / 64;
- cooldown = (int)Math.Ceiling(Math.Max(time, 0));
+ var player = Utilities.GetPlayerFromIndex((int)playerSkill.Player);
+ if (player == null || !player.IsValid) return;
- var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == playerSkill?.Player?.SteamID);
+ var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player.SteamID);
if (playerInfo == null) return;
+ float ticksLeft = playerSkill.NextCamera - Server.TickCount;
+ int secondsLeft = (int)Math.Ceiling(Math.Max(ticksLeft / 64.0f, 0));
+
if (playerSkill.NoSpace >= Server.TickCount)
- playerInfo.PrintHTML = $"{playerSkill.Player.GetTranslation("cypher_nospace")}";
- else if (cooldown == 0)
+ playerInfo.PrintHTML = $"{player.GetTranslation("cypher_nospace")}";
+ else if (secondsLeft > 0 && playerSkill.CameraProp == null)
+ playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"{secondsLeft}")}";
+ else
playerInfo.PrintHTML = null;
- else if (playerSkill?.CameraProp == null)
- playerInfo.PrintHTML = $"{playerSkill?.Player.GetTranslation("hud_info", $"{cooldown}")}";
}
public class PlayerSkill
{
- public required CCSPlayerController Player { get; set; }
- public CDynamicProp? CameraProp { get; set; }
- public CDynamicProp? CameraView { get; set; }
+ public required uint Player { get; set; }
+ public uint? CameraProp { get; set; }
+ public uint? CameraView { get; set; }
public uint PlayerCameraRaw { get; set; }
public bool CameraActive { get; set; }
public float NextCamera { get; set; }
diff --git a/jRandomSkills - SRC Files/src/player/skills/Deaf.cs b/jRandomSkills - SRC Files/src/player/skills/Deaf.cs
index 1444fba..2345ee2 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Deaf.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Deaf.cs
@@ -11,7 +11,7 @@ namespace src.player.skills
public class Deaf : ISkill
{
private const Skills skillName = Skills.Deaf;
- private static readonly ConcurrentDictionary deafPlayers = [];
+ private static readonly ConcurrentDictionary deafPlayers = [];
public static void LoadSkill()
{
@@ -20,8 +20,13 @@ namespace src.player.skills
public static void NewRound()
{
- foreach (var player in deafPlayers.Keys)
+ foreach (var playerIndex in deafPlayers.Keys)
+ {
+ var player = Utilities.GetPlayerFromIndex((int)playerIndex);
+ if (player == null || !player.IsValid) continue;
DisableSkill(player);
+ }
+
deafPlayers.Clear();
foreach (var player in Utilities.GetPlayers())
SkillUtils.CloseMenu(player);
@@ -29,8 +34,12 @@ namespace src.player.skills
public static void PlayerMakeSound(UserMessage um)
{
- foreach (var player in deafPlayers.Keys)
+ foreach (var playerIndex in deafPlayers.Keys)
+ {
+ var player = Utilities.GetPlayerFromIndex((int)playerIndex);
+ if (player == null || !player.IsValid) continue;
um.Recipients.Remove(player);
+ }
}
public static void OnTick()
@@ -44,7 +53,7 @@ namespace src.player.skills
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();
- ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString())));
+ ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))];
SkillUtils.UpdateMenu(player, menuItems);
}
}
@@ -70,7 +79,7 @@ namespace src.player.skills
return;
}
- deafPlayers.TryAdd(enemy, 0);
+ deafPlayers.TryAdd(enemy.Index, 0);
playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("deaf_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("deaf_enemy_info"));
@@ -95,7 +104,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
SkillUtils.CloseMenu(player);
- deafPlayers.TryRemove(player, out _);
+ deafPlayers.TryRemove(player.Index, out _);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#dae01f", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
diff --git a/jRandomSkills - SRC Files/src/player/skills/Distancer.cs b/jRandomSkills - SRC Files/src/player/skills/Distancer.cs
index 77a4f8e..6a7c804 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Distancer.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Distancer.cs
@@ -9,7 +9,7 @@ namespace src.player.skills
public class Distancer : ISkill
{
private const Skills skillName = Skills.Distancer;
- private static readonly ConcurrentDictionary distancerPlayers = [];
+ private static readonly ConcurrentDictionary distancerPlayers = [];
private static readonly object setLock = new();
public static void LoadSkill()
@@ -26,8 +26,11 @@ namespace src.player.skills
public static void OnTick()
{
if (SkillUtils.IsFreezeTime()) return;
- foreach (var player in distancerPlayers.Keys)
+ foreach (var playerIndex in distancerPlayers.Keys)
{
+ var player = Utilities.GetPlayerFromIndex((int)playerIndex);
+ if (player == null || !player.IsValid) continue;
+
var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
if (playerInfo == null) continue;
@@ -56,12 +59,12 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player)
{
- distancerPlayers.TryAdd(player, 0);
+ distancerPlayers.TryAdd(player.Index, 0);
}
public static void DisableSkill(CCSPlayerController player)
{
- distancerPlayers.TryRemove(player, out _);
+ distancerPlayers.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player);
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Duplicator.cs b/jRandomSkills - SRC Files/src/player/skills/Duplicator.cs
index 463eca2..ee41b22 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Duplicator.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Duplicator.cs
@@ -1,9 +1,10 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
+using CounterStrikeSharp.API.Modules.Entities;
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
{
@@ -120,12 +121,18 @@ namespace src.player.skills
bool ctSkill = Event.counterterroristSkills.Any(s => s.Name == enemySkill.ToString());
bool ttSkill = Event.terroristSkills.Any(s => s.Name == enemySkill.ToString());
+ ulong steamID = player.SteamID;
+ string enemyName = enemy.PlayerName;
+
if ((player.Team == CsTeam.Terrorist && ctSkill) || (player.Team == CsTeam.CounterTerrorist && ttSkill))
{
Instance.AddTimer(.1f, () =>
{
+ var player = Utilities.GetPlayerFromSteamId(steamID);
+ if (player == null || !player.IsValid) return;
+
Instance.SkillAction(skillName.ToString(), "EnableSkill", [player]);
- player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("thief_incorrect_skill", enemy.PlayerName));
+ player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("thief_incorrect_skill", enemyName));
});
return;
}
@@ -139,6 +146,9 @@ namespace src.player.skills
if (SkillsInfo.GetValue(enemySkill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
Instance?.AddTimer(Math.Max((float)(Event.GetFreezeTimeEnd() - DateTime.Now).TotalSeconds, 0), () => {
+ var player = Utilities.GetPlayerFromSteamId(steamID);
+ if (player == null || !player.IsValid) return;
+
if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID && p.Skill == enemySkill) == null) return;
Instance?.SkillAction(enemySkill.ToString(), "EnableSkill", [player]);
});
diff --git a/jRandomSkills - SRC Files/src/player/skills/ExplosiveShot.cs b/jRandomSkills - SRC Files/src/player/skills/ExplosiveShot.cs
index 39eee08..4d551dd 100644
--- a/jRandomSkills - SRC Files/src/player/skills/ExplosiveShot.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/ExplosiveShot.cs
@@ -1,6 +1,5 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
-using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using static src.jRandomSkills;
@@ -24,8 +23,10 @@ namespace src.player.skills
{
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo == null) return;
+
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue(skillName, "ChanceTo") - SkillsInfo.GetValue(skillName, "ChanceFrom")) + SkillsInfo.GetValue(skillName, "ChanceFrom");
playerInfo.SkillChance = newChance;
+
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
}
@@ -59,29 +60,20 @@ namespace src.player.skills
private static bool NearlyEquals(float a, float b, float epsilon = 0.001f) => Math.Abs(a -b) < epsilon;
- public static void OnTakeDamage(DynamicHook h)
+ public static void BulletImpact(EventBulletImpact @event)
{
if (lastTick == Server.TickCount) return;
- CEntityInstance param = h.GetParam(0);
- CTakeDamageInfo param2 = h.GetParam(1);
+ var player = @event.Userid;
+ if (player == null || !player.IsValid) return;
- if (param == null || param.Entity == null || param2 == null || param2.Attacker == null || param2.Attacker.Value == null)
- return;
+ var pos = new Vector(@event.X, @event.Y, @event.Z);
- CCSPlayerPawn attackerPawn = new(param2.Attacker.Value.Handle);
- if (attackerPawn.DesignerName != "player")
- return;
-
- if (attackerPawn == null || attackerPawn.Controller?.Value == null)
- return;
-
- CCSPlayerController attacker = attackerPawn.Controller.Value.As();
- var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID);
+ var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo == null || playerInfo.Skill != skillName) return;
if (Instance.Random.NextDouble() <= playerInfo.SkillChance)
- SpawnExplosion(param2.DamagePosition);
+ SpawnExplosion(pos);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#9c0000", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float damage = 25f, float damageRadius = 210f, float chanceFrom = .15f, float chanceTo = .3f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
diff --git a/jRandomSkills - SRC Files/src/player/skills/FalconEye.cs b/jRandomSkills - SRC Files/src/player/skills/FalconEye.cs
index 81839a1..f97698e 100644
--- a/jRandomSkills - SRC Files/src/player/skills/FalconEye.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/FalconEye.cs
@@ -11,7 +11,7 @@ namespace src.player.skills
public class FalconEye : ISkill
{
private const Skills skillName = Skills.FalconEye;
- private static readonly ConcurrentDictionary cameras = [];
+ private static readonly ConcurrentDictionary cameras = [];
public static void LoadSkill()
{
@@ -20,9 +20,14 @@ namespace src.player.skills
public static void NewRound()
{
- foreach (var camera in cameras)
- if (camera.Value.Item2 != null && camera.Value.Item2.IsValid)
- camera.Value.Item2.AcceptInput("Kill");
+ foreach (var cameraIndex in cameras.Values)
+ {
+ var camera = Utilities.GetEntityFromIndex((int)cameraIndex.Item2);
+ if (camera == null || !camera.IsValid) continue;
+
+ camera.AcceptInput("Kill");
+ }
+
cameras.Clear();
}
@@ -56,18 +61,23 @@ namespace src.player.skills
public static void OnTick()
{
foreach (var player in Utilities.GetPlayers())
- if (cameras.TryGetValue(player.SteamID, out var cameraInfo) && cameraInfo.Item2.IsValid)
+ if (cameras.TryGetValue(player.SteamID, out var cameraInfo) && cameraInfo.Item2 != 0)
{
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue;
+
if (pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
{
ChangeCamera(player, true);
continue;
}
+
Vector pos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + SkillsInfo.GetValue(skillName, "distance"));
QAngle angle = new(90, 0, -pawn.V_angle.Y);
- cameraInfo.Item2.Teleport(pos, angle);
+
+ var camera = Utilities.GetEntityFromIndex((int)cameraInfo.Item2);
+ if (camera == null || !camera.IsValid) continue;
+ camera.Teleport(pos, angle);
}
}
@@ -77,10 +87,15 @@ namespace src.player.skills
uint newCameraRaw;
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.CameraServices == null) return;
- if (cameras.TryGetValue(player.SteamID, out var cameraInfo) && cameraInfo.Item2.IsValid)
+
+ if (cameras.TryGetValue(player.SteamID, out var cameraInfo) && cameraInfo.Item2 != 0)
{
orginalCameraRaw = cameraInfo.Item1;
- newCameraRaw = cameraInfo.Item2.EntityHandle.Raw;
+
+ var camera = Utilities.GetEntityFromIndex((int)cameraInfo.Item2);
+ if (camera == null || !camera.IsValid) return;
+
+ newCameraRaw = camera.EntityHandle.Raw;
}
else
{
@@ -108,13 +123,14 @@ namespace src.player.skills
Server.NextFrame(() =>
{
+ if (camera == null || !camera.IsValid) return;
camera.SetModel("models/actors/ghost_speaker.vmdl");
camera.Render = Color.FromArgb(0, 255, 255, 255);
camera.Teleport(pos, new QAngle(90, 0, 0));
camera.DispatchSpawn();
});
- cameras.AddOrUpdate(player.SteamID, (pawn.CameraServices!.ViewEntity.Raw, camera), (k, v) => (pawn.CameraServices!.ViewEntity.Raw, camera));
+ cameras.AddOrUpdate(player.SteamID, (pawn.CameraServices!.ViewEntity.Raw, camera.Index), (k, v) => (pawn.CameraServices!.ViewEntity.Raw, camera.Index));
return camera.EntityHandle.Raw;
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Fortnite.cs b/jRandomSkills - SRC Files/src/player/skills/Fortnite.cs
index 4163af1..1113b86 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Fortnite.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Fortnite.cs
@@ -112,6 +112,7 @@ namespace src.player.skills
barricades.TryAdd(box.Index, SkillsInfo.GetValue(skillName, "barricadeHealth"));
Server.NextFrame(() =>
{
+ if (box == null || !box.IsValid) return;
box.SetModel(SkillsInfo.GetValue(skillName, "propModel"));
box.Teleport(pos, angle, null);
});
diff --git a/jRandomSkills - SRC Files/src/player/skills/FragileBomb.cs b/jRandomSkills - SRC Files/src/player/skills/FragileBomb.cs
index 79ba292..93ce550 100644
--- a/jRandomSkills - SRC Files/src/player/skills/FragileBomb.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/FragileBomb.cs
@@ -1,10 +1,9 @@
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 src.utils;
using static src.jRandomSkills;
+using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
namespace src.player.skills
{
@@ -14,8 +13,8 @@ namespace src.player.skills
private static int bombHealth = 1000;
private static int maxBombHealth = 1000;
- private static CPlantedC4? plantedC4;
- private static CTriggerMultiple? triggerC4;
+ private static int lastTick = 0;
+ private static Vector? plantedC4;
public static void LoadSkill()
{
@@ -27,80 +26,42 @@ namespace src.player.skills
bombHealth = SkillsInfo.GetValue(skillName, "maxBombHealth");
maxBombHealth = SkillsInfo.GetValue(skillName, "maxBombHealth");
plantedC4 = null;
- triggerC4 = null;
}
public static void BombPlanted(EventBombPlanted _)
{
var plantedBomb = Utilities.FindAllEntitiesByDesignerName("planted_c4").FirstOrDefault();
- if (plantedBomb == null) return;
- plantedC4 = plantedBomb;
- CreateTrigger();
- }
-
- private static void CreateTrigger()
- {
- var trigger = Utilities.CreateEntityByName("trigger_multiple");
- if (trigger == null || plantedC4 == null || trigger.AbsOrigin == null || plantedC4.AbsOrigin == null) return;
-
- trigger.Collision.SolidType = SolidType_t.SOLID_CAPSULE;
- trigger.Collision.SolidFlags = 0;
- trigger.Spawnflags = 1;
- trigger.Globalname = $"planted_bomb_prop_{trigger.Index}";
- trigger.Collision.SolidFlags = 1;
-
- trigger.AbsOrigin.X = plantedC4.AbsOrigin.X;
- trigger.AbsOrigin.Y = plantedC4.AbsOrigin.Y;
- trigger.AbsOrigin.Z = plantedC4.AbsOrigin.Z;
-
- trigger.Collision.CapsuleRadius = 10;
- trigger.Collision.BoundingRadius = 10;
-
- trigger.Collision.CollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_TRIGGER;
- trigger.Collision.EnablePhysics = 1;
- trigger.Collision.TriggerBloat = 0;
-
- trigger.Collision.SurroundType = SurroundingBoundsType_t.USE_OBB_COLLISION_BOUNDS;
- trigger.Collision.CollisionAttribute.CollisionFunctionMask = 39;
- trigger.Collision.CollisionAttribute.CollisionGroup = 2;
-
- trigger.DispatchSpawn();
- triggerC4 = trigger;
+ if (plantedBomb == null || !plantedBomb.IsValid || plantedBomb.AbsOrigin == null) return;
+ plantedC4 = new(plantedBomb.AbsOrigin.X, plantedBomb.AbsOrigin.Y, plantedBomb.AbsOrigin.Z);
}
private static void RemoveBomb()
{
- if (plantedC4 != null && plantedC4.IsValid)
- plantedC4.AcceptInput("Kill");
- if (triggerC4 != null && triggerC4.IsValid)
- triggerC4.AcceptInput("Kill");
+ plantedC4 = null;
+ var plantedBomb = Utilities.FindAllEntitiesByDesignerName("planted_c4").FirstOrDefault();
+ if (plantedBomb != null && plantedBomb.IsValid)
+ plantedBomb.AcceptInput("Kill");
SkillUtils.TerminateRound(CsTeam.CounterTerrorist);
}
- public static void OnTakeDamage(DynamicHook h)
+ public static void BulletImpact(EventBulletImpact @event)
{
- CEntityInstance param = h.GetParam(0);
- CTakeDamageInfo param2 = h.GetParam(1);
+ if (lastTick == Server.TickCount) return;
- if (param == null || param.Entity == null || param2 == null || param2.Attacker == null || param2.Attacker.Value == null)
- return;
+ var player = @event.Userid;
+ if (player == null || !player.IsValid || plantedC4 == null) return;
- CCSPlayerPawn attackerPawn = new(param2.Attacker.Value.Handle);
+ var pos = new Vector(@event.X, @event.Y, @event.Z);
- if (attackerPawn.DesignerName != "player" || param.DesignerName != "trigger_multiple")
- return;
-
- CTriggerMultiple trigger = new(param.Handle);
-
- if (attackerPawn == null || attackerPawn.Controller?.Value == null || trigger == null || !trigger.Globalname.StartsWith("planted_bomb_prop_"))
- return;
-
- CCSPlayerController attacker = attackerPawn.Controller.Value.As();
-
- var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID);
+ var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo == null || playerInfo.Skill != skillName) return;
- bombHealth -= (int)param2.TotalledDamage;
+ if (SkillUtils.Distance(plantedC4, pos) >= 8)
+ return;
+
+ lastTick = Server.TickCount;
+ bombHealth -= Instance.Random.Next(25, 42);
+
if (bombHealth <= 0)
{
RemoveBomb();
diff --git a/jRandomSkills - SRC Files/src/player/skills/FriendlyFire.cs b/jRandomSkills - SRC Files/src/player/skills/FriendlyFire.cs
index 8fb4811..3210119 100644
--- a/jRandomSkills - SRC Files/src/player/skills/FriendlyFire.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/FriendlyFire.cs
@@ -1,5 +1,6 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
+using CounterStrikeSharp.API.Modules.Cvars;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using static src.jRandomSkills;
@@ -34,6 +35,10 @@ namespace src.player.skills
var pawn = victim.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return;
+
+ if (damage == 0)
+ damage = Instance.Random.Next(4, 6);
+
SkillUtils.AddHealth(pawn, damage + (int)(damage * SkillsInfo.GetValue(skillName, "healthMultiplier")), pawn.MaxHealth);
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Gambler.cs b/jRandomSkills - SRC Files/src/player/skills/Gambler.cs
index 43e7c30..abf5806 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Gambler.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Gambler.cs
@@ -28,6 +28,8 @@ namespace src.player.skills
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo?.Skill != skillName) return;
+ ulong steamID = player.SteamID;
+
if (playerInfo.SkillUsed)
{
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("areareaper_used_info")}");
@@ -56,7 +58,10 @@ namespace src.player.skills
if (SkillsInfo.GetValue(skill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
Instance?.AddTimer(Math.Max((float)(Event.GetFreezeTimeEnd() - DateTime.Now).TotalSeconds, 0), () => {
- if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID && p.Skill == skill.Skill) == null) return;
+ var player = Utilities.GetPlayerFromSteamId(steamID);
+ if (player == null || !player.IsValid) return;
+
+ if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == steamID && p.Skill == skill.Skill) == null) return;
Instance?.SkillAction(skill.Skill.ToString(), "EnableSkill", [player]);
});
else
diff --git a/jRandomSkills - SRC Files/src/player/skills/Ghost.cs b/jRandomSkills - SRC Files/src/player/skills/Ghost.cs
index 5d07c97..35d45e1 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Ghost.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Ghost.cs
@@ -24,7 +24,7 @@ namespace src.player.skills
"weapon_g3sg1", "weapon_nova", "weapon_xm1014", "weapon_mag7",
"weapon_sawedoff", "weapon_m249", "weapon_negev"
];
- private static readonly ConcurrentDictionary invisiblePlayers = [];
+ private static readonly ConcurrentDictionary invisiblePlayers = [];
private const string bloodParticle = "particles/blood_impact/blood_impact_high.vpcf";
public static void LoadSkill()
@@ -76,22 +76,31 @@ namespace src.player.skills
if (targetInfo?.Skill == skillName) isObservingGhost = true;
}
- foreach (var _player in invisiblePlayers.Keys)
- if (player.SteamID != _player.SteamID && !isObservingGhost)
+ foreach (var playerIndex in invisiblePlayers.Keys)
+ {
+ var playerController = Utilities.GetPlayerFromIndex((int)playerIndex);
+ if (playerController == null || !playerController.IsValid || playerController.SteamID == player.SteamID)
+ continue;
+
+ if (!isObservingGhost)
{
- var playerPawn = _player.PlayerPawn.Value;
+ var playerPawn = playerController.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) continue;
var entity = Utilities.GetEntityFromIndex((int)playerPawn.Index);
if (entity == null || !entity.IsValid) continue;
+
info.TransmitEntities.Remove(entity.Index);
- var bombIndex = GetBombIndex(_player);
+ var bombIndex = GetBombIndex(playerController);
if (bombIndex == null) continue;
+
var bombEntity = Utilities.GetEntityFromIndex((int)bombIndex);
if (bombEntity == null || !bombEntity.IsValid) continue;
+
info.TransmitEntities.Remove(bombEntity.Index);
}
+ }
}
}
@@ -99,14 +108,14 @@ namespace src.player.skills
{
Event.EnableTransmit();
SetWeaponAttack(player, true);
- invisiblePlayers.TryAdd(player, 0);
+ invisiblePlayers.TryAdd(player.Index, 0);
}
public static void DisableSkill(CCSPlayerController player)
{
SkillUtils.ResetPrintHTML(player);
SetWeaponAttack(player, false);
- invisiblePlayers.TryRemove(player, out _);
+ invisiblePlayers.TryRemove(player.Index, out _);
}
public static void OnTick()
@@ -116,8 +125,9 @@ namespace src.player.skills
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo?.Skill == skillName)
UpdateHUD(player);
+
if (!player.PawnIsAlive)
- invisiblePlayers.TryRemove(player, out _);
+ invisiblePlayers.TryRemove(player.Index, out _);
}
}
@@ -125,7 +135,7 @@ namespace src.player.skills
{
var player = @event.Userid;
if (player == null || !player.IsValid) return;
- if (!invisiblePlayers.ContainsKey(player)) return;
+ if (!invisiblePlayers.ContainsKey(player.Index)) return;
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return;
diff --git a/jRandomSkills - SRC Files/src/player/skills/GodMode.cs b/jRandomSkills - SRC Files/src/player/skills/GodMode.cs
index c8ab2e1..b68769f 100644
--- a/jRandomSkills - SRC Files/src/player/skills/GodMode.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/GodMode.cs
@@ -1,9 +1,10 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
+using CounterStrikeSharp.API.Modules.Entities;
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
{
@@ -49,6 +50,10 @@ namespace src.player.skills
{
SkillPlayerInfo.TryRemove(player.SteamID, out _);
SkillUtils.ResetPrintHTML(player);
+
+ var playerPawn = player.PlayerPawn.Value;
+ if (playerPawn != null && playerPawn.IsValid)
+ playerPawn.TakesDamage = true;
}
private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo)
@@ -77,7 +82,9 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return;
- if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
+ ulong steamID = player.SteamID;
+
+ if (SkillPlayerInfo.TryGetValue(steamID, out var skillInfo))
{
if (!player.IsValid || !player.PawnIsAlive || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return;
if (skillInfo.CanUse)
@@ -89,8 +96,11 @@ namespace src.player.skills
player.PlayerPawn.Value.TakesDamage = false;
Instance.AddTimer(SkillsInfo.GetValue(skillName, "duration"), () => {
- if (player.IsValid && player.PawnIsAlive)
+
+ var player = Utilities.GetPlayerFromSteamId(steamID);
+ if (player != null && player.IsValid && player.PawnIsAlive)
{
+ if (player.PlayerPawn == null || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return;
player.PlayerPawn.Value.TakesDamage = true;
player.PrintToChat($" {ChatColors.Red} {player.GetTranslation("godmode_off")}");
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/HealingSmoke.cs b/jRandomSkills - SRC Files/src/player/skills/HealingSmoke.cs
index ca2c993..7fb7cf7 100644
--- a/jRandomSkills - SRC Files/src/player/skills/HealingSmoke.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/HealingSmoke.cs
@@ -65,6 +65,7 @@ namespace src.player.skills
Server.NextFrame(() =>
{
+ if (entity == null || !entity.IsValid) return;
var smoke = entity.As();
smoke.SmokeColor.X = 0;
smoke.SmokeColor.Y = 255;
diff --git a/jRandomSkills - SRC Files/src/player/skills/HolyHandGrenade.cs b/jRandomSkills - SRC Files/src/player/skills/HolyHandGrenade.cs
index 296f499..11bdf49 100644
--- a/jRandomSkills - SRC Files/src/player/skills/HolyHandGrenade.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/HolyHandGrenade.cs
@@ -24,6 +24,7 @@ namespace src.player.skills
Server.NextFrame(() =>
{
+ if (@event == null || !@event.IsValid) return;
var hegrenade = @event.As();
if (hegrenade == null || !hegrenade.IsValid) return;
diff --git a/jRandomSkills - SRC Files/src/player/skills/Iana.cs b/jRandomSkills - SRC Files/src/player/skills/Iana.cs
index d20090d..18ec2d9 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Iana.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Iana.cs
@@ -3,8 +3,6 @@ using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Timers;
using CounterStrikeSharp.API.Modules.Utils;
-using CS2TraceRay.Class;
-using CS2TraceRay.Struct;
using src.utils;
using System.Collections.Concurrent;
using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
@@ -15,7 +13,7 @@ namespace src.player.skills
public class Iana : ISkill
{
private const Skills skillName = Skills.Iana;
- private static readonly ConcurrentDictionary playersInfo = [];
+ private static readonly ConcurrentDictionary playersInfo = [];
private static readonly object setLock = new();
public static void LoadSkill()
@@ -35,7 +33,7 @@ namespace src.player.skills
{
var player = @event.Userid;
if (player == null) return;
- if (playersInfo.TryGetValue(player, out var playerSkill))
+ if (playersInfo.TryGetValue(player.Index, out var playerSkill))
if (playerSkill.CloneProp != null)
BlockWeapon(player, true);
}
@@ -44,7 +42,7 @@ namespace src.player.skills
{
var player = @event.Userid;
if (player == null) return;
- if (playersInfo.TryGetValue(player, out var playerSkill))
+ if (playersInfo.TryGetValue(player.Index, out var playerSkill))
if (playerSkill.CloneProp != null)
BlockWeapon(player, true);
}
@@ -54,9 +52,12 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return;
- if (playersInfo.TryGetValue(player, out var playerSkill))
+ if (playersInfo.TryGetValue(player.Index, out var playerSkill))
if (playerSkill.CloneProp == null && playerSkill.NextUse <= Server.TickCount)
+ {
+ UpdateWeapons(player, playerSkill);
CreateClone(playerSkill);
+ }
else if (playerSkill.CloneProp != null)
KillClone(playerSkill);
}
@@ -64,9 +65,9 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player)
{
if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.CameraServices == null) return;
- playersInfo.TryAdd(player, new PlayerSkill
+ playersInfo.TryAdd(player.Index, new PlayerSkill
{
- Player = player,
+ PlayerIndex = player.Index,
CloneProp = null,
NextUse = 0,
UseTime = 0,
@@ -75,32 +76,54 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
- if (playersInfo.TryGetValue(player, out var playerSkill))
+ if (playersInfo.TryGetValue(player.Index, out var playerSkill))
KillClone(playerSkill);
- playersInfo.TryRemove(player, out _);
+ playersInfo.TryRemove(player.Index, out _);
+ }
+
+ private static void UpdateWeapons(CCSPlayerController player, PlayerSkill playerSkill)
+ {
+ if (player == null || !player.IsValid) return;
+
+ var playerPawn = player.PlayerPawn.Value;
+ if (playerPawn == null || !playerPawn.IsValid || playerPawn.WeaponServices == null) return;
+
+ playerSkill.Weapons.Clear();
+
+ foreach (var weapon in playerPawn.WeaponServices.MyWeapons)
+ if (weapon != null && weapon.IsValid && weapon.Value != null && weapon.Value.IsValid)
+ playerSkill.Weapons.Add(weapon.Value.AttributeManager.Item.ItemID);
}
private static void KillClone(PlayerSkill playerSkill)
{
- playerSkill.Player.EmitSound("SolidMetal.BulletImpact");
- if (playerSkill.CloneProp != null && playerSkill.CloneProp.IsValid && playerSkill.CloneProp.AbsOrigin != null && playerSkill.CloneProp.AbsRotation != null)
+ var player = Utilities.GetPlayerFromIndex((int)playerSkill.PlayerIndex);
+ if (player == null || !player.IsValid) return;
+
+ player.EmitSound("SolidMetal.BulletImpact");
+
+ CDynamicProp? cloneProp = null;
+ if (playerSkill.CloneProp != null)
+ cloneProp = Utilities.GetEntityFromIndex((int)playerSkill.CloneProp);
+
+ if (cloneProp != null && cloneProp.IsValid && cloneProp.AbsOrigin != null && cloneProp.AbsRotation != null)
{
- var playerPawn = playerSkill.Player.PlayerPawn.Value;
+ var playerPawn = player.PlayerPawn.Value;
if (playerPawn != null && playerPawn.IsValid)
{
- Vector pos = new(playerSkill.CloneProp.AbsOrigin.X, playerSkill.CloneProp.AbsOrigin.Y, playerSkill.CloneProp.AbsOrigin.Z);
- QAngle angle = new(playerSkill.CloneProp.AbsRotation.X, playerSkill.CloneProp.AbsRotation.Y, playerSkill.CloneProp.AbsRotation.Z);
+ Vector pos = new(cloneProp.AbsOrigin.X, cloneProp.AbsOrigin.Y, cloneProp.AbsOrigin.Z);
Server.NextFrame(() =>
{
- playerPawn.Teleport(pos, angle);
+ if (playerPawn == null || !playerPawn.IsValid) return;
+ playerPawn.Teleport(pos);
});
}
- playerSkill.CloneProp.AcceptInput("Kill");
+ cloneProp.AcceptInput("Kill");
playerSkill.CloneProp = null;
}
- SkillUtils.ApplyScreenColor(playerSkill.Player, 0, 0, 0, 0, 10, 0, 2);
- BlockWeapon(playerSkill.Player, false);
+ SkillUtils.ApplyScreenColor(player, 0, 0, 0, 0, 10, 0, 2);
+ BlockWeapon(player, false);
playerSkill.NextUse = Server.TickCount + SkillsInfo.GetValue(skillName, "Cooldown") * 64;
playerSkill.UseTime = 0;
}
@@ -113,20 +136,32 @@ namespace src.player.skills
private static CDynamicProp? CreateClone(PlayerSkill playerSkill)
{
- var player = playerSkill.Player;
- if (player == null) return null;
+ var player = Utilities.GetPlayerFromIndex((int)playerSkill.PlayerIndex);
+ if (player == null || !player.IsValid) return null;
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null || playerPawn.AbsRotation == null) return null;
- Vector pos = playerPawn.AbsOrigin + SkillUtils.GetForwardVector(playerPawn.AbsRotation) * 50;
- Vector pos2 = playerPawn.AbsOrigin + SkillUtils.GetForwardVector(playerPawn.AbsRotation) * (50 + 25);
- if (!CheckPosition(player, pos2) || !((PlayerFlags)playerPawn.Flags).HasFlag(PlayerFlags.FL_ONGROUND))
+ if (!((PlayerFlags)playerPawn.Flags).HasFlag(PlayerFlags.FL_ONGROUND))
{
playerSkill.InfoTime = Server.TickCount;
return null;
}
+ QAngle angle = new(0, playerPawn.EyeAngles.Y, 0);
+ Vector pos = playerPawn.AbsOrigin + SkillUtils.GetForwardVector(angle) * 50;
+ pos.Z += 2;
+
+ if (!CheckPosition(player, pos))
+ {
+ pos.Z += 10;
+ if (!CheckPosition(player, pos))
+ {
+ playerSkill.InfoTime = Server.TickCount;
+ return null;
+ }
+ }
+
var clone = Utilities.CreateEntityByName("prop_dynamic");
if (clone == null || !clone.IsValid) return null;
@@ -137,16 +172,21 @@ namespace src.player.skills
Server.NextFrame(() =>
{
+ if (player == null || !player.IsValid) return;
+ if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null || playerPawn.AbsRotation == null) return;
+
+ if (clone == null || !clone.IsValid) return;
+
clone.SetModel(playerPawn!.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.ModelName);
clone.Teleport(playerPawn.AbsOrigin, new QAngle(0, playerPawn.V_angle.Y, 0));
playerPawn.Teleport(pos);
SkillUtils.ApplyScreenColor(player, r: 255, g: 255, b: 0, a: 20, duration: 100, holdTime: 1020);
- BlockWeapon(playerSkill.Player, true);
+ BlockWeapon(player, true);
playerSkill.UseTime = Server.TickCount;
playerSkill.NextUse = Server.TickCount + 64000;
- playerSkill.CloneProp = clone;
+ playerSkill.CloneProp = clone.Index;
jRandomSkills.Instance.AddTimer(SkillsInfo.GetValue(skillName, "Duration"), () =>
{
@@ -167,7 +207,7 @@ namespace src.player.skills
return;
}
- if (!playersInfo.TryGetValue(target, out var playerSkill) || playerSkill.CloneProp == null)
+ if (!playersInfo.TryGetValue(target.Index, out var playerSkill) || playerSkill.CloneProp == null)
{
cloneTimer?.Kill();
return;
@@ -183,16 +223,14 @@ namespace src.player.skills
private unsafe static bool CheckPosition(CCSPlayerController player, Vector endPos)
{
var playerPawn = player.PlayerPawn.Value;
- if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return false;
- Vector eyePos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 25);
- endPos.Z += 25;
+ Vector start = new(playerPawn!.AbsOrigin!.X, playerPawn!.AbsOrigin!.Y, endPos.Z);
+ var result = RayTrace.TraceHullShape(start, endPos, player);
- ulong mask = playerPawn.Collision.CollisionAttribute.InteractsWith;
- ulong contents = playerPawn.Collision.CollisionGroup;
- CGameTrace trace = TraceRay.TraceShape(eyePos, endPos, mask, contents, player);
-
- return !trace.DidHit();
+ if (!result.HasValue)
+ return false;
+
+ return !result.Value.DidHit;
}
private static float CalculateDamage(CCSPlayerController player, string weaponName, float damage, bool isHeadshot)
@@ -240,12 +278,16 @@ namespace src.player.skills
float dealDamage = param2.Damage;
- if (playersInfo.TryGetValue(player, out var playerSkill))
+ if (playersInfo.TryGetValue(player.Index, out var playerSkill))
{
- if (playerSkill.CloneProp != null && playerSkill.CloneProp.IsValid && playerSkill.CloneProp.AbsOrigin != null)
+ CDynamicProp? cloneProp = null;
+ if (playerSkill.CloneProp != null)
+ cloneProp = Utilities.GetEntityFromIndex((int)playerSkill.CloneProp);
+
+ if (cloneProp != null && cloneProp.IsValid && cloneProp.AbsOrigin != null)
{
Vector pos = param2.DamagePosition;
- Vector posCl = playerSkill.CloneProp.AbsOrigin;
+ Vector posCl = cloneProp.AbsOrigin;
bool isHead = false;
float viewOffset = 63.27f;
@@ -273,7 +315,7 @@ namespace src.player.skills
var victim = @event.Userid!;
if (!jRandomSkills.Instance.IsPlayerValid(victim)) return;
- if (playersInfo.TryGetValue(victim, out var playerSkill) && playerSkill.CloneProp != null)
+ if (playersInfo.TryGetValue(victim.Index, out var playerSkill) && playerSkill.CloneProp != null)
{
KillClone(playerSkill);
SkillUtils.RestoreHealth(victim);
@@ -299,7 +341,10 @@ namespace src.player.skills
private static void UpdateHUD(PlayerSkill playerSkill)
{
- if (playerSkill == null || playerSkill.Player == null) return;
+ if (playerSkill == null) return;
+
+ var player = Utilities.GetPlayerFromIndex((int)playerSkill.PlayerIndex);
+ if (player == null || !player.IsValid) return;
float cooldown = 0;
float time1 = (playerSkill.NextUse - Server.TickCount) / 64;
@@ -309,26 +354,57 @@ namespace src.player.skills
float time2 = SkillsInfo.GetValue(skillName, "Duration") - (Server.TickCount - playerSkill.UseTime) / 64;
duration = (int)Math.Ceiling(Math.Max(time2, 0));
- var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == playerSkill?.Player?.SteamID);
+ var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player.SteamID);
if (playerInfo == null) return;
if (playerSkill.InfoTime + (64 * 2) > Server.TickCount)
- playerInfo.PrintHTML = $"{playerSkill?.Player.GetTranslation("shade_nospace")}";
+ playerInfo.PrintHTML = $"{player.GetTranslation("shade_nospace")}";
else if (cooldown == 0 && duration == 0)
playerInfo.PrintHTML = null;
else if (duration > 0)
- playerInfo.PrintHTML = $"{playerSkill?.Player.GetTranslation("hud_info", $"{duration}")}";
+ playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"{duration}")}";
else if (cooldown > 0)
- playerInfo.PrintHTML = $"{playerSkill?.Player.GetTranslation("hud_info", $"{cooldown}")}";
+ playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"{cooldown}")}";
+ }
+
+ public static bool OnWeaponCanAcquire(DynamicHook hook, CCSPlayerController player, CEconItemView econItem, CCSWeaponBaseVData vdata)
+ {
+ string weaponName = vdata.Name;
+ if (string.IsNullOrEmpty(weaponName)) return false;
+
+ var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
+ if (playerInfo?.Skill != skillName) return false;
+
+ if (playersInfo.TryGetValue(player.Index, out var playerSkill))
+ if (playerSkill.CloneProp == null || playerSkill.Weapons.Contains(econItem.ItemID))
+ return false;
+
+ hook.SetReturn(AcquireResult.InvalidItem);
+ return true;
+ }
+
+ public static bool WeaponDrop(DynamicHook hook, CCSPlayerController player)
+ {
+ if (player == null || !player.IsValid) return false;
+
+ if (playersInfo.TryGetValue(player.Index, out var playerSkill))
+ if (playerSkill.CloneProp != null)
+ {
+ hook.SetReturn(1);
+ return true;
+ }
+
+ return false;
}
public class PlayerSkill
{
- public required CCSPlayerController Player { get; set; }
- public CDynamicProp? CloneProp { get; set; }
+ public required uint PlayerIndex { get; set; }
+ public uint? CloneProp { get; set; }
public float NextUse { get; set; }
public float UseTime { get; set; }
public int InfoTime { get; set; }
+ public List Weapons { get; set; } = [];
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#d0d930", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 30, float duration = 10) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
diff --git a/jRandomSkills - SRC Files/src/player/skills/Illiterate.cs b/jRandomSkills - SRC Files/src/player/skills/Illiterate.cs
index 54a7ca1..8449df7 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Illiterate.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Illiterate.cs
@@ -9,7 +9,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Illiterate;
private static bool isActive = false;
- private static int offset = jRandomSkills.Instance.Random.Next(2, 26);
+ private static int offset = jRandomSkills.Instance.Random.Next(1, 26);
public static void LoadSkill()
{
@@ -54,8 +54,12 @@ namespace src.player.skills
public static string? GetRandomText(string? input)
{
if (string.IsNullOrEmpty(input)) return null;
- if (Server.TickCount % 64 == 0)
- offset = jRandomSkills.Instance.Random.Next(2, 26);
+
+ if (Server.TickCount % 64 == 0 || offset == 0)
+ {
+ offset = jRandomSkills.Instance.Random.Next(1, 26);
+ if (offset == 13) offset = 14;
+ }
return new string([.. input.Select(c =>
{
@@ -63,15 +67,14 @@ namespace src.player.skills
if (!char.IsLetter(c)) return c;
char baseChar = char.IsUpper(c) ? 'A' : 'a';
- return (char)(baseChar + (c - baseChar + offset) % 26);
+ int shifted = (c - baseChar + offset) % 26;
+
+ return (char)(baseChar + shifted);
})]);
}
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/Impostor.cs b/jRandomSkills - SRC Files/src/player/skills/Impostor.cs
index e57c4d2..614bb31 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Impostor.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Impostor.cs
@@ -11,8 +11,8 @@ namespace src.player.skills
public class Impostor : ISkill
{
private const Skills skillName = Skills.Impostor;
- private static readonly string defaultCTModel = "characters/models/ctm_sas/ctm_sas.vmdl";
- private static readonly string defaultTModel = "characters/models/tm_phoenix/tm_phoenix.vmdl";
+ private static readonly string defaultCTModel = "agents//models/ctm_sas/ctm_sas.vmdl";
+ private static readonly string defaultTModel = "agents/models/tm_phoenix/tm_phoenix.vmdl";
private static readonly ConcurrentDictionary originalModels = [];
public static void LoadSkill()
@@ -63,6 +63,7 @@ namespace src.player.skills
Server.NextFrame(() =>
{
+ if (pawn == null || !pawn.IsValid) return;
pawn.SetModel(model);
var originalRender = pawn.Render;
diff --git a/jRandomSkills - SRC Files/src/player/skills/Jackal.cs b/jRandomSkills - SRC Files/src/player/skills/Jackal.cs
index 35bac69..0c519a2 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Jackal.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Jackal.cs
@@ -5,6 +5,7 @@ using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
+using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
namespace src.player.skills
{
@@ -12,8 +13,8 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Jackal;
private static readonly ConcurrentDictionary playersInAction = [];
- private static readonly ConcurrentDictionary playersStep = [];
- private static readonly string particleName = "particles/ui/hud/ui_map_def_utility_trail.vpcf";
+ private static readonly ConcurrentDictionary playersStep = [];
+ private static readonly ConcurrentDictionary activeTimers = [];
public static void LoadSkill()
{
@@ -23,9 +24,15 @@ namespace src.player.skills
public static void NewRound()
{
- foreach (var step in playersStep.Values)
- if (step != null && step.IsValid)
- step.AcceptInput("Kill");
+ foreach (var particleIndex in playersStep.Values)
+ {
+ if (particleIndex == null) continue;
+ var particle = Utilities.GetEntityFromIndex((int)particleIndex);
+
+ if (particle != null && particle.IsValid)
+ particle.AcceptInput("Kill");
+ }
+
playersStep.Clear();
playersInAction.Clear();
}
@@ -51,11 +58,15 @@ namespace src.player.skills
foreach (var param in playersStep)
{
- var enemy = param.Key;
- var step = param.Value;
- if (step == null || !step.IsValid) continue;
+ var enemyIndex = param.Key;
+ var particleIndex = param.Value;
- var entity = Utilities.GetEntityFromIndex((int)step.Index);
+ if (particleIndex == null) continue;
+
+ var enemy = Utilities.GetPlayerFromIndex((int)enemyIndex);
+ if (enemy == null || !enemy.IsValid) continue;
+
+ var entity = Utilities.GetEntityFromIndex((int)particleIndex);
if (entity == null || !entity.IsValid) continue;
if (!hasSkill || enemy.Team == player.Team)
@@ -69,13 +80,17 @@ namespace src.player.skills
if (player == null) return;
var playerPawn = player.PlayerPawn.Value;
+ ulong steamID = player.SteamID;
+ if (activeTimers.TryRemove(steamID, out var oldTimer))
+ oldTimer?.Kill();
+
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null || playerPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
- if (!playersStep.ContainsKey(player)) return;
+ if (!playersStep.ContainsKey(player.Index)) return;
CParticleSystem particle = Utilities.CreateEntityByName("info_particle_system")!;
if (particle == null) return;
- particle.EffectName = particleName;
+ particle.EffectName = SkillsInfo.GetValue(skillName, "particleName");
particle.StartActive = true;
particle.Teleport(playerPawn.AbsOrigin);
@@ -84,12 +99,18 @@ namespace src.player.skills
particle.AcceptInput("SetParent", playerPawn, particle, "!activator");
particle.AcceptInput("Start");
- playersStep.AddOrUpdate(player, particle, (k, v) => particle);
+ uint particleId = particle.Index;
- Instance.AddTimer(2.5f, () => {
+ playersStep.AddOrUpdate(player.Index, particle.Index, (k, v) => particle.Index);
+
+ activeTimers[player.SteamID] = Instance.AddTimer(2.5f, () => {
+ var particle = Utilities.GetEntityFromIndex((int)particleId);
if (particle != null && particle.IsValid)
particle.AcceptInput("Kill");
- CreatePlayerTrail(player);
+
+ var player = Utilities.GetPlayerFromSteamId(steamID);
+ if (player != null && player.IsValid && playersStep.ContainsKey(player.Index))
+ CreatePlayerTrail(player);
});
}
@@ -99,23 +120,30 @@ namespace src.player.skills
playersInAction.TryAdd(player.SteamID, 0);
foreach (var _player in Utilities.GetPlayers().Where(p => p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.PawnIsAlive && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist))
{
- if (!playersStep.ContainsKey(_player))
- playersStep.TryAdd(_player, null);
+ if (!playersStep.ContainsKey(_player.Index))
+ playersStep.TryAdd(_player.Index, null);
CreatePlayerTrail(_player);
}
}
public static void DisableSkill(CCSPlayerController player)
{
- playersStep.TryRemove(player, out _);
playersInAction.TryRemove(player.SteamID, out _);
+
+ if (playersStep.TryRemove(player.Index, out var particleIndex) && particleIndex != null)
+ {
+ var particle = Utilities.GetEntityFromIndex((int)particleIndex);
+ if (particle != null && particle.IsValid)
+ particle.AcceptInput("Kill");
+ }
+
if (playersInAction.IsEmpty)
NewRound();
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#f542ef", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", string particleName = "particles/ui/hud/ui_map_def_utility_trail.vpcf") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
- string ParticleName { get; set; } = particleName;
+ public string ParticleName { get; set; } = particleName;
}
}
}
\ No newline at end of file
diff --git a/jRandomSkills - SRC Files/src/player/skills/Jammer.cs b/jRandomSkills - SRC Files/src/player/skills/Jammer.cs
index c65faac..d9ac126 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Jammer.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Jammer.cs
@@ -10,7 +10,7 @@ namespace src.player.skills
public class Jammer : ISkill
{
private const Skills skillName = Skills.Jammer;
- private static readonly ConcurrentDictionary jammedPlayers = [];
+ private static readonly ConcurrentDictionary jammedPlayers = [];
private static readonly object setLock = new();
public static void LoadSkill()
@@ -22,8 +22,12 @@ namespace src.player.skills
{
lock (setLock)
{
- foreach (var player in jammedPlayers.Keys)
+ foreach (var playerIndex in jammedPlayers.Keys)
+ {
+ var player = Utilities.GetPlayerFromIndex((int)playerIndex);
+ if (player == null || !player.IsValid) continue;
SetCrosshair(player, true);
+ }
jammedPlayers.Clear();
}
foreach (var player in Utilities.GetPlayers())
@@ -67,7 +71,7 @@ namespace src.player.skills
return;
}
- jammedPlayers.TryAdd(enemy, 0);
+ jammedPlayers.TryAdd(enemy.Index, 0);
SetCrosshair(enemy, false);
playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("jammer_player_info", enemy.PlayerName));
@@ -103,7 +107,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
SetCrosshair(player, true);
- jammedPlayers.TryRemove(player, out _);
+ jammedPlayers.TryRemove(player.Index, out _);
SkillUtils.CloseMenu(player);
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Jester.cs b/jRandomSkills - SRC Files/src/player/skills/Jester.cs
index 0855998..3474cb6 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Jester.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Jester.cs
@@ -1,5 +1,6 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
+using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
@@ -12,7 +13,7 @@ namespace src.player.skills
public class Jester : ISkill
{
private const Skills skillName = Skills.Jester;
- private static readonly ConcurrentBag jesters = [];
+ private static readonly ConcurrentDictionary jesters = [];
public static void LoadSkill()
{
@@ -23,7 +24,7 @@ namespace src.player.skills
{
Server.NextWorldUpdate(() =>
{
- foreach (var jester in jesters.ToList())
+ foreach (var jester in jesters.Values)
{
if (jester.Timer != null)
{
@@ -71,7 +72,8 @@ namespace src.player.skills
var player = @event.Userid;
if (player == null || !player.IsValid) return;
- var jester = GetJesterInfo(player.SteamID);
+ ulong steamId = player.SteamID;
+ var jester = GetJesterInfo(steamId);
if (jester == null) return;
if (jester.Timer != null)
@@ -81,8 +83,7 @@ namespace src.player.skills
}
jester.Timer = Instance.AddTimer(1, () => {
- if (player != null && player.IsValid)
- ChangeMode(player.SteamID, false);
+ ChangeMode(steamId, false);
});
}
@@ -91,7 +92,8 @@ namespace src.player.skills
var player = @event.Userid;
if (player == null || !player.IsValid) return;
- var jester = GetJesterInfo(player.SteamID);
+ ulong steamId = player.SteamID;
+ var jester = GetJesterInfo(steamId);
if (jester == null) return;
if (jester.Timer != null)
@@ -102,7 +104,7 @@ namespace src.player.skills
jester.Timer = Instance.AddTimer(1, () => {
if (player != null && player.IsValid)
- ChangeMode(player.SteamID, false);
+ ChangeMode(steamId, false);
});
}
@@ -133,20 +135,18 @@ namespace src.player.skills
var maxTime = SkillsInfo.GetValue(skillName, "maxTime");
float wait = (float)Instance.Random.NextDouble() * (maxTime - minTime) + minTime;
- jesters.Add(new JesterInfo {
- SteamId = player.SteamID,
+ ulong steamId = player.SteamID;
+
+ jesters.TryAdd(steamId, new JesterInfo {
+ SteamId = steamId,
Active = false,
- Timer = Instance.AddTimer(wait, () => ChangeMode(player.SteamID))
+ Timer = Instance.AddTimer(wait, () => ChangeMode(steamId))
});
}
private static void ChangeMode(ulong steamId, bool? forceActive = null)
{
- var player = Utilities.GetPlayerFromSteamId(steamId);
- if (player == null || !player.IsValid || !player.PawnIsAlive) return;
-
- var jester = GetJesterInfo(player.SteamID);
- if (jester == null) return;
+ if (!jesters.TryGetValue(steamId, out var jester)) return;
if (jester.Timer != null)
{
@@ -154,6 +154,13 @@ namespace src.player.skills
jester.Timer = null;
}
+ var player = Utilities.GetPlayerFromSteamId(steamId);
+ if (player == null || !player.IsValid || !player.PawnIsAlive)
+ {
+ jesters.TryRemove(steamId, out _);
+ return;
+ }
+
bool previousState = jester.Active;
jester.Active = forceActive ?? !jester.Active;
@@ -167,7 +174,7 @@ namespace src.player.skills
var maxTime = SkillsInfo.GetValue(skillName, "maxTime");
float wait = (float)Instance.Random.NextDouble() * (maxTime - minTime) + minTime;
- jester.Timer = Instance.AddTimer(wait, () => ChangeMode(player.SteamID));
+ jester.Timer = Instance.AddTimer(wait, () => ChangeMode(steamId));
}
private static void SetPlayerColor(CCSPlayerController? player, bool forceDisable = false)
@@ -208,7 +215,12 @@ namespace src.player.skills
playerInfo.PrintHTML = $"{player.GetTranslation("jester_mode")}: {player.GetTranslation(jester.Active ? "jester_on" : "jester_off")}";
}
- public static JesterInfo? GetJesterInfo(ulong steamID) => jesters.FirstOrDefault(j => j.SteamId == steamID);
+ public static JesterInfo? GetJesterInfo(ulong steamID)
+ {
+ if (jesters.TryGetValue(steamID, value: out var info))
+ return info;
+ return null;
+ }
public class JesterInfo()
{
diff --git a/jRandomSkills - SRC Files/src/player/skills/JumpBan.cs b/jRandomSkills - SRC Files/src/player/skills/JumpBan.cs
index ebab4a2..8a63461 100644
--- a/jRandomSkills - SRC Files/src/player/skills/JumpBan.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/JumpBan.cs
@@ -10,7 +10,7 @@ namespace src.player.skills
public class JumpBan : ISkill
{
private const Skills skillName = Skills.JumpBan;
- public static readonly ConcurrentDictionary bannedPlayers = [];
+ public static readonly ConcurrentDictionary bannedPlayers = [];
public static void LoadSkill()
{
@@ -28,19 +28,25 @@ namespace src.player.skills
{
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.AddOrUpdate(player.PlayerPawn.Value, Server.TickCount + 10, (k, v) => Server.TickCount + 10);
+ if (!bannedPlayers.TryGetValue(player.Index, out _)) return;
+ bannedPlayers.AddOrUpdate(player.Index, Server.TickCount + 10, (k, v) => Server.TickCount + 10);
}
public static void OnTick()
{
foreach (var item in bannedPlayers)
{
- var pawn = item.Key;
+ var playerIndex = item.Key;
var time = item.Value;
+
+ var player = Utilities.GetPlayerFromIndex((int)playerIndex);
+ if (player == null || !player.IsValid || player.PlayerPawn == null) continue;
+
+ var pawn = player.PlayerPawn.Value;
+ if (pawn == null || !pawn.IsValid) continue;
+
if (time > Server.TickCount)
- if (pawn != null && pawn.IsValid)
- pawn.AbsVelocity.Z = -100;
+ pawn.AbsVelocity.Z = -100;
}
if (Server.TickCount % 32 != 0) return;
@@ -52,7 +58,7 @@ namespace src.player.skills
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();
- ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString())));
+ ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))];
SkillUtils.UpdateMenu(player, menuItems);
}
}
@@ -78,7 +84,7 @@ namespace src.player.skills
return;
}
- bannedPlayers.AddOrUpdate(enemy.PlayerPawn.Value, 0, (k, v) => 0);
+ bannedPlayers.AddOrUpdate(enemy.Index, 0, (k, v) => 0);
playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("jumpban_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("jumpban_enemy_info"));
@@ -103,7 +109,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return;
- bannedPlayers.TryRemove(player.PlayerPawn.Value, out _);
+ bannedPlayers.TryRemove(player.Index, out _);
SkillUtils.CloseMenu(player);
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/LongKnife.cs b/jRandomSkills - SRC Files/src/player/skills/LongKnife.cs
index 575e4cf..001d1c2 100644
--- a/jRandomSkills - SRC Files/src/player/skills/LongKnife.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/LongKnife.cs
@@ -2,14 +2,9 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils;
-using CS2TraceRay.Class;
-using CS2TraceRay.Enum;
-using CS2TraceRay.Struct;
using src.utils;
using System.Collections.Concurrent;
-using System.Drawing;
using static src.jRandomSkills;
-using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
namespace src.player.skills
{
@@ -22,8 +17,6 @@ namespace src.player.skills
private static readonly ConcurrentDictionary playersInAction = [];
private static readonly MemoryFunctionVoid Shoot_Secondary = new(GameData.GetSignature("Shoot_Secondary"));
- private static int i = 0;
-
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"));
@@ -95,40 +88,22 @@ namespace src.player.skills
private unsafe static void KnifeHit(CCSPlayerController player, bool heavyHit)
{
var pawn = player!.PlayerPawn.Value;
- if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
+ 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) * SkillsInfo.GetValue(skillName, "maxDistance");
+ var result = RayTrace.EyeTrace(player);
+ if (result == null || !result.HasValue)
+ return;
- ulong hitboxes = 0x2;
- ulong mask = pawn.Collision.CollisionAttribute.InteractsWith | hitboxes;
- ulong contents = pawn.Collision.CollisionGroup;
- CGameTrace trace = TraceRay.TraceShape(eyePos, endPos, mask, contents, player);
+ if (!result.Value.HitPlayer(out CCSPlayerController? target) || target == null)
+ return;
- if (Config.LoadedConfig.CS2TraceRayDebug)
- {
- 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())
- {
- var val = Activator.CreateInstance(typeof(CBaseEntity), trace.HitEntity) as CBaseEntity;
- player.PrintToChat($"Hit: {trace.DidHit()}, Entity: {(val == null ? "null" : val.DesignerName)}, Solid: {trace.AllSolid}, Contents: {(Contents)trace.Contents}, Hitbox: {trace.HitboxData[0].HitGroup}");
- }
- else
- player.PrintToChat($"Hit: {trace.DidHit()}, Object: {trace.HitEntity}, Solid: {trace.AllSolid}, Contents: {(Contents)trace.Contents}, Hitbox: {trace.HitboxData[0].HitGroup}");
- }
-
- CEntityInstance entityInstance = new(trace.HitEntity);
- if (string.IsNullOrEmpty(entityInstance.DesignerName))
+ if (target.Handle == player.Handle || result.Value.Distance() <= 70)
+ return;
+
+ if (target.PlayerPawn.Value == null || !target.PlayerPawn.Value.IsValid)
return;
- CBaseEntity entity = entityInstance.As();
- if (!trace.HitPlayer(out CCSPlayerController? target) || target == null)
- return;
-
- if (target.Handle == player.Handle || target.PlayerPawn.Value == null || !target.PlayerPawn.Value.IsValid || trace.Distance() <= 70) return;
if (!SkillsInfo.GetValue(skillName, "friendlyFire") && player.Team == target.Team) return;
target.PlayerPawn.Value.EmitSound("Player.DamageBody.Onlooker");
diff --git a/jRandomSkills - SRC Files/src/player/skills/LongZeus.cs b/jRandomSkills - SRC Files/src/player/skills/LongZeus.cs
index ab13800..c6edcb6 100644
--- a/jRandomSkills - SRC Files/src/player/skills/LongZeus.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/LongZeus.cs
@@ -1,13 +1,8 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
-using CS2TraceRay.Class;
-using CS2TraceRay.Enum;
-using CS2TraceRay.Struct;
using src.utils;
-using System.Drawing;
using static src.jRandomSkills;
-using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
namespace src.player.skills
{
@@ -34,30 +29,11 @@ namespace src.player.skills
var activeWeapon = pawn.WeaponServices.ActiveWeapon.Value;
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) * SkillsInfo.GetValue(skillName, "maxDistance");
+ var result = RayTrace.EyeTrace(player);
+ if (result == null || !result.HasValue)
+ return;
- ulong hitboxes = 0x2;
- ulong mask = pawn.Collision.CollisionAttribute.InteractsWith | hitboxes;
- ulong contents = pawn.Collision.CollisionGroup;
- CGameTrace trace = TraceRay.TraceShape(eyePos, endPos, mask, contents, player);
-
- if (Config.LoadedConfig.CS2TraceRayDebug)
- {
- 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())
- {
- var val = Activator.CreateInstance(typeof(CBaseEntity), trace.HitEntity) as CBaseEntity;
- player.PrintToChat($"Hit: {trace.DidHit()}, Entity: {(val == null ? "null" : val.DesignerName)}, Solid: {trace.AllSolid}, Contents: {(Contents)trace.Contents}, Hitbox: {trace.HitboxData[0].HitGroup}");
- }
- else
- player.PrintToChat($"Hit: {trace.DidHit()}, Object: {trace.HitEntity}, Solid: {trace.AllSolid}, Contents: {(Contents)trace.Contents}, Hitbox: {trace.HitboxData[0].HitGroup}");
- }
-
- if (!trace.HitPlayer(out CCSPlayerController? target) || target == null)
+ if (!result.Value.HitPlayer(out CCSPlayerController? target) || target == null)
return;
if (target.Handle == player.Handle) return;
diff --git a/jRandomSkills - SRC Files/src/player/skills/Magnifier.cs b/jRandomSkills - SRC Files/src/player/skills/Magnifier.cs
index c313ae8..41074a7 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Magnifier.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Magnifier.cs
@@ -10,7 +10,7 @@ namespace src.player.skills
public class Magnifier : ISkill
{
private const Skills skillName = Skills.Magnifier;
- private static readonly ConcurrentDictionary playersFOV = [];
+ private static readonly ConcurrentDictionary playersFOV = [];
public static void LoadSkill()
{
@@ -19,8 +19,13 @@ namespace src.player.skills
public static void NewRound()
{
- foreach (var player in playersFOV.Keys)
+ foreach (var playerIndex in playersFOV.Keys)
+ {
+ var player = Utilities.GetPlayerFromIndex((int)playerIndex);
+ if (player == null || player.IsValid) continue;
DisableSkill(player);
+ }
+
playersFOV.Clear();
foreach (var player in Utilities.GetPlayers())
SkillUtils.CloseMenu(player);
@@ -70,8 +75,8 @@ namespace src.player.skills
return;
}
- if (!playersFOV.ContainsKey(enemy))
- playersFOV.TryAdd(enemy, enemy.DesiredFOV);
+ if (!playersFOV.ContainsKey(enemy.Index))
+ playersFOV.TryAdd(enemy.Index, enemy.DesiredFOV);
enemy.DesiredFOV = SkillsInfo.GetValue(skillName, "customFOV");
Utilities.SetStateChanged(enemy, "CBasePlayerController", "m_iDesiredFOV");
@@ -98,12 +103,12 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
- if (playersFOV.TryGetValue(player, out uint fov))
+ if (playersFOV.TryGetValue(player.Index, out uint fov))
{
player.DesiredFOV = fov;
Utilities.SetStateChanged(player, "CBasePlayerController", "m_iDesiredFOV");
}
- playersFOV.TryRemove(player, out _);
+ playersFOV.TryRemove(player.Index, out _);
SkillUtils.CloseMenu(player);
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Ninja.cs b/jRandomSkills - SRC Files/src/player/skills/Ninja.cs
index 984024f..16f6c52 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Ninja.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Ninja.cs
@@ -13,7 +13,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Ninja;
private static readonly ConcurrentDictionary invisibilityChanged = [];
- private static readonly ConcurrentDictionary invisiblePlayers = [];
+ private static readonly ConcurrentDictionary invisiblePlayers = [];
private const string bloodParticle = "particles/blood_impact/blood_impact_high.vpcf";
private static readonly object setLock = new();
@@ -68,22 +68,28 @@ namespace src.player.skills
if (targetInfo?.Skill == skillName) isObservingNinja = true;
}
- foreach (var _player in invisiblePlayers.Keys)
- if (player.SteamID != _player.SteamID && !isObservingNinja)
+ foreach (var playerIndex in invisiblePlayers.Keys)
+ {
+ var playerController = Utilities.GetPlayerFromIndex((int)playerIndex);
+ if (playerController == null || !playerController.IsValid || playerController.SteamID == player.SteamID)
+ continue;
+
+ if (!isObservingNinja)
{
- var playerPawn = _player.PlayerPawn.Value;
+ var playerPawn = playerController.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) continue;
var entity = Utilities.GetEntityFromIndex((int)playerPawn.Index);
if (entity == null || !entity.IsValid) continue;
info.TransmitEntities.Remove(entity.Index);
- var bombIndex = GetBombIndex(_player);
+ var bombIndex = GetBombIndex(playerController);
if (bombIndex == null) continue;
var bombEntity = Utilities.GetEntityFromIndex((int)bombIndex);
if (bombEntity == null || !bombEntity.IsValid) continue;
info.TransmitEntities.Remove(bombEntity.Index);
}
+ }
}
}
@@ -95,7 +101,7 @@ namespace src.player.skills
if (playerInfo?.Skill == skillName)
UpdateNinja(player);
if (!player.PawnIsAlive)
- invisiblePlayers.TryRemove(player, out _);
+ invisiblePlayers.TryRemove(player.Index, out _);
}
}
@@ -107,7 +113,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
SetPlayerVisibility(player, 0);
- invisiblePlayers.TryRemove(player, out _);
+ invisiblePlayers.TryRemove(player.Index, out _);
}
private static void UpdateNinja(CCSPlayerController? player)
@@ -136,14 +142,14 @@ namespace src.player.skills
if (percentInvisibility == oldInvisibility)
return;
- invisibilityChanged.TryAdd(player.Handle, percentInvisibility);
+ invisibilityChanged.AddOrUpdate(player.Handle, percentInvisibility, (_, _) => percentInvisibility);
if (percentInvisibility > .9)
- invisiblePlayers.TryAdd(player, 0);
+ invisiblePlayers.TryAdd(player.Index, 0);
else
{
SetPlayerVisibility(player, percentInvisibility);
- invisiblePlayers.TryRemove(player, out _);
+ invisiblePlayers.TryRemove(player.Index, out _);
}
}
@@ -162,7 +168,7 @@ namespace src.player.skills
{
var player = @event.Userid;
if (player == null || !player.IsValid) return;
- if (!invisiblePlayers.ContainsKey(player)) return;
+ if (!invisiblePlayers.ContainsKey(player.Index)) return;
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return;
diff --git a/jRandomSkills - SRC Files/src/player/skills/NoRecoil.cs b/jRandomSkills - SRC Files/src/player/skills/NoRecoil.cs
index 399833e..1978bdc 100644
--- a/jRandomSkills - SRC Files/src/player/skills/NoRecoil.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/NoRecoil.cs
@@ -41,8 +41,14 @@ namespace src.player.skills
{
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.CameraServices == null) continue;
- pawn.AimPunchTickBase = 0;
- pawn.AimPunchTickFraction = 0f;
+
+ if (pawn.AimPunchServices != null)
+ {
+ pawn.AimPunchServices.PredictableBaseTick = 0;
+ pawn.AimPunchServices.PredictableBaseTickInterpAmount = 0;
+ pawn.AimPunchServices.UnpredictableBaseTick = 0;
+ }
+
pawn.CameraServices.CsViewPunchAngleTick = 0;
pawn.CameraServices.CsViewPunchAngleTickRatio = 0f;
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Noclip.cs b/jRandomSkills - SRC Files/src/player/skills/Noclip.cs
index 7c05562..1ca494c 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Noclip.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Noclip.cs
@@ -1,9 +1,8 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
+using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils;
-using CS2TraceRay.Class;
-using CS2TraceRay.Struct;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
@@ -93,7 +92,9 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return;
- if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
+ ulong steamId = player.SteamID;
+
+ if (SkillPlayerInfo.TryGetValue(steamId, out var skillInfo))
{
if (skillInfo.IsFlying)
{
@@ -109,11 +110,18 @@ namespace src.player.skills
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();
skillInfo.Timer = Instance.AddTimer(duration, () =>
{
+ var player = Utilities.GetPlayerFromSteamId(steamId);
+ if (player == null || !player.IsValid) return;
+
+ var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == steamId);
+ if (playerInfo == null) return;
+
StopFlying(player, skillInfo);
});
}
@@ -174,54 +182,39 @@ namespace src.player.skills
ulong mask = playerPawn.Collision.CollisionAttribute.InteractsWith;
ulong contents = playerPawn.Collision.CollisionGroup;
+
bool hasGround = false;
+ Vector stuckVector = new(currentPos.X, currentPos.Y, currentPos.Z);
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;
+ var groundResult = RayTrace.TraceShape(player, start, end, mask, contents);
+ if (!groundResult.HasValue || !groundResult.Value.DidHit) continue;
- hasGround = true;
Vector newPos =
- groundTrace.EndPos.Z > targetPos.Z
- ? new(groundTrace.EndPos.X, groundTrace.EndPos.Y, groundTrace.EndPos.Z)
+ groundResult.Value.EndPos.Z > targetPos.Z
+ ? new(groundResult.Value.EndPos.X, groundResult.Value.EndPos.Y, groundResult.Value.EndPos.Z)
: targetPos;
- if (IsPositionSafe(newPos, player))
+ hasGround = true;
+ stuckVector = newPos;
+
+ var result = RayTrace.TraceHullShape(
+ targetPos,
+ targetPos,
+ player
+ );
+
+ if (result.HasValue && !result.Value.DidHit)
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;
+ return hasGround ? stuckVector : null;
}
public class PlayerSkillInfo
diff --git a/jRandomSkills - SRC Files/src/player/skills/Phoenix.cs b/jRandomSkills - SRC Files/src/player/skills/Phoenix.cs
index 159bfe9..c0d4e77 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Phoenix.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Phoenix.cs
@@ -1,5 +1,6 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
+using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using static src.jRandomSkills;
@@ -29,7 +30,15 @@ namespace src.player.skills
lock (setLock)
{
player.Respawn();
- Instance.AddTimer(.2f, () => player.Respawn());
+ ulong steamId = player.SteamID;
+
+ Instance.AddTimer(.2f, () => {
+ var player = Utilities.GetPlayerFromSteamId(steamId);
+ if (player == null || !player.IsValid) return;
+
+ player.Respawn();
+ });
+
SkillUtils.PrintToChat(player, player.GetTranslation("phoenix_respawn"));
}
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Planter.cs b/jRandomSkills - SRC Files/src/player/skills/Planter.cs
index d4cca24..4eb5496 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Planter.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Planter.cs
@@ -45,7 +45,10 @@ namespace src.player.skills
var plantedBomb = Utilities.FindAllEntitiesByDesignerName("planted_c4").FirstOrDefault();
if (plantedBomb != null)
- Server.NextFrame(() => plantedBomb.C4Blow = Server.CurrentTime + SkillsInfo.GetValue(skillName, "extraC4BlowTime"));
+ Server.NextFrame(() => {
+ if (plantedBomb != null && plantedBomb.IsValid)
+ plantedBomb.C4Blow = Server.CurrentTime + SkillsInfo.GetValue(skillName, "extraC4BlowTime");
+ });
foreach (var p in Utilities.GetPlayers().Where(p => p.IsValid))
p.PrintToCenterAlert(p.GetTranslation("bombplanted", SkillsInfo.GetValue(skillName, "extraC4BlowTime")));
diff --git a/jRandomSkills - SRC Files/src/player/skills/Poison.cs b/jRandomSkills - SRC Files/src/player/skills/Poison.cs
index 6319998..03c81b5 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Poison.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Poison.cs
@@ -10,7 +10,7 @@ namespace src.player.skills
public class Poison : ISkill
{
private const Skills skillName = Skills.Poison;
- private static readonly ConcurrentDictionary poisonedPlayers = [];
+ private static readonly ConcurrentDictionary poisonedPlayers = [];
private static readonly object setLock = new();
public static void LoadSkill()
@@ -28,10 +28,14 @@ namespace src.player.skills
{
if (Server.TickCount % (int)(64 * SkillsInfo.GetValue(skillName, "Cooldown")) == 0)
{
- foreach (var player in poisonedPlayers.Keys)
+ foreach (var playerIndex in poisonedPlayers.Keys)
{
+ var player = Utilities.GetPlayerFromIndex((int)playerIndex);
+ if (player == null || !player.IsValid || player.PlayerPawn == null) continue;
+
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) continue;
+
if (pawn.Health <= SkillsInfo.GetValue(skillName, "MinHealth")) continue;
SkillUtils.TakeHealth(pawn, SkillsInfo.GetValue(skillName, "Damage"));
}
@@ -72,7 +76,7 @@ namespace src.player.skills
return;
}
- poisonedPlayers.TryAdd(enemy, 0);
+ poisonedPlayers.TryAdd(enemy.Index, 0);
playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("poison_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("poison_enemy_info"));
@@ -96,7 +100,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
- poisonedPlayers.TryRemove(player, out _);
+ poisonedPlayers.TryRemove(player.Index, out _);
SkillUtils.CloseMenu(player);
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/PsychicDefusing.cs b/jRandomSkills - SRC Files/src/player/skills/PsychicDefusing.cs
index 9c1451a..41ed828 100644
--- a/jRandomSkills - SRC Files/src/player/skills/PsychicDefusing.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/PsychicDefusing.cs
@@ -4,14 +4,13 @@ using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
-using CounterStrikeSharp.API.Modules.Entities.Constants;
namespace src.player.skills
{
public class PsychicDefusing : ISkill
{
private const Skills skillName = Skills.PsychicDefusing;
- private static readonly ConcurrentDictionary SkillPlayerInfo = [];
+ private static readonly ConcurrentDictionary SkillPlayerInfo = [];
private static Vector? bombLocation = null;
private static readonly float tickRate = 64f;
private static readonly object setLock = new();
@@ -35,12 +34,9 @@ namespace src.player.skills
var player = @event.Userid;
if (player == null || !player.IsValid) return;
- var pawn = player.PlayerPawn.Value;
- if (pawn == null || !pawn.IsValid) return;
-
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo?.Skill == skillName)
- SkillPlayerInfo.TryRemove(pawn, out _);
+ SkillPlayerInfo.TryRemove(player.Index, out _);
}
public static void BombPlanted(EventBombPlanted _)
@@ -55,15 +51,15 @@ namespace src.player.skills
if (bombLocation == null) return;
foreach (var skillInfo in SkillPlayerInfo)
{
- var pawn = skillInfo.Key;
+ var playerIndex = skillInfo.Key;
var info = skillInfo.Value;
- var playerController = pawn.Controller.Value;
- if (playerController == null || !pawn.Controller.IsValid) return;
-
- var player = playerController.As();
- if (player == null || !player.IsValid) return;
+ var player = Utilities.GetPlayerFromIndex((int)playerIndex);
+ if (player == null || !player.IsValid || player.PlayerPawn == null) continue;
+ var pawn = player.PlayerPawn.Value;
+ if (pawn == null || !pawn.IsValid) continue;
+
if (pawn.AbsOrigin == null || SkillUtils.GetDistance(pawn.AbsOrigin, bombLocation) > SkillsInfo.GetValue(skillName, "maxDefusingRange"))
{
info.Defusing = false;
@@ -97,7 +93,8 @@ namespace src.player.skills
{
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return;
- SkillPlayerInfo.TryAdd(pawn, new PlayerSkillInfo
+
+ SkillPlayerInfo.TryAdd(player.Index, new PlayerSkillInfo
{
SteamID = player.SteamID,
Defusing = false,
@@ -108,9 +105,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
SkillUtils.ResetPrintHTML(player);
- var pawn = player.PlayerPawn.Value;
- if (pawn == null || !pawn.IsValid) return;
- SkillPlayerInfo.TryRemove(pawn, out _);
+ SkillPlayerInfo.TryRemove(player.Index, out _);
}
private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo)
diff --git a/jRandomSkills - SRC Files/src/player/skills/Push.cs b/jRandomSkills - SRC Files/src/player/skills/Push.cs
index 33f7386..fd61bca 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Push.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Push.cs
@@ -44,16 +44,16 @@ namespace src.player.skills
private static void PushEnemy(CCSPlayerController player, QAngle attackerAngle)
{
- if (player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid || player.PlayerPawn.Value.LifeState != (int)LifeState_t.LIFE_ALIVE)
+ var playerPawn = player.PlayerPawn.Value;
+ if (playerPawn == null || !playerPawn.IsValid || playerPawn.LifeState != (int)LifeState_t.LIFE_ALIVE)
return;
- var currentPosition = player.PlayerPawn.Value.AbsOrigin;
- var currentAngles = player.PlayerPawn.Value.EyeAngles;
+ var currentPosition = playerPawn.AbsOrigin;
Vector newVelocity = SkillUtils.GetForwardVector(attackerAngle) * SkillsInfo.GetValue(skillName, "pushVelocity");
- newVelocity.Z = player.PlayerPawn.Value.AbsVelocity.Z + SkillsInfo.GetValue(skillName, "jumpVelocity");
+ newVelocity.Z = playerPawn.AbsVelocity.Z + SkillsInfo.GetValue(skillName, "jumpVelocity");
- player.PlayerPawn.Value.Teleport(currentPosition, currentAngles, newVelocity);
+ playerPawn.Teleport(currentPosition, null, newVelocity);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1e9ab0", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float chanceFrom = .3f, float chanceTo = .4f, float jumpVelocity = 300f, float pushVelocity = 400f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
diff --git a/jRandomSkills - SRC Files/src/player/skills/QuickShot.cs b/jRandomSkills - SRC Files/src/player/skills/QuickShot.cs
index 2db900b..4f7358f 100644
--- a/jRandomSkills - SRC Files/src/player/skills/QuickShot.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/QuickShot.cs
@@ -30,9 +30,14 @@ namespace src.player.skills
var weapon = weaponServices.ActiveWeapon.Value;
if (weapon == null || !weapon.IsValid || pawn.CameraServices == null) continue;
-
- pawn.AimPunchTickBase = 0;
- pawn.AimPunchTickFraction = 0f;
+
+ if (pawn.AimPunchServices != null)
+ {
+ pawn.AimPunchServices.PredictableBaseTick = 0;
+ pawn.AimPunchServices.PredictableBaseTickInterpAmount = 0;
+ pawn.AimPunchServices.UnpredictableBaseTick = 0;
+ }
+
pawn.CameraServices.CsViewPunchAngleTick = 0;
pawn.CameraServices.CsViewPunchAngleTickRatio = 0f;
diff --git a/jRandomSkills - SRC Files/src/player/skills/RCMelon.cs b/jRandomSkills - SRC Files/src/player/skills/RCMelon.cs
deleted file mode 100644
index e11a942..0000000
--- a/jRandomSkills - SRC Files/src/player/skills/RCMelon.cs
+++ /dev/null
@@ -1,274 +0,0 @@
-using CounterStrikeSharp.API;
-using CounterStrikeSharp.API.Core;
-using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
-using CounterStrikeSharp.API.Modules.Utils;
-using CS2TraceRay.Class;
-using CS2TraceRay.Struct;
-using src.utils;
-using System.Collections.Concurrent;
-using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
-using static src.jRandomSkills;
-
-namespace src.player.skills
-{
- public class RCMelon : ISkill
- {
- private const Skills skillName = Skills.RCMelon;
- private static readonly ConcurrentDictionary playersInfo = [];
- private const string melonProp = "models/cs_italy/italy_food_melon/italy_food_melon.vmdl";
- private static readonly object setLock = new();
-
- public static void LoadSkill()
- {
- // SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"));
- Instance.AddToManifest(melonProp);
- }
-
- public static void NewRound()
- {
- foreach (var playerSkill in playersInfo.Values)
- KillClone(playerSkill);
- lock (setLock)
- playersInfo.Clear();
- }
-
- public static void WeaponPickup(EventItemPickup @event)
- {
- var player = @event.Userid;
- if (player == null) return;
- if (playersInfo.TryGetValue(player, out var playerSkill))
- if (playerSkill.CloneProp != null)
- BlockWeapon(player, true);
- }
-
- public static void WeaponEquip(EventItemEquip @event)
- {
- var player = @event.Userid;
- if (player == null) return;
- if (playersInfo.TryGetValue(player, out var playerSkill))
- if (playerSkill.CloneProp != null)
- BlockWeapon(player, true);
- }
-
- public static void UseSkill(CCSPlayerController player)
- {
- var playerPawn = player.PlayerPawn.Value;
- if (playerPawn?.CBodyComponent == null) return;
-
- if (playersInfo.TryGetValue(player, out var playerSkill))
- if (playerSkill.CloneProp == null && playerSkill.NextUse <= Server.TickCount)
- CreateMelon(playerSkill);
- else if (playerSkill.CloneProp != null)
- KillClone(playerSkill);
- }
-
- public static void EnableSkill(CCSPlayerController player)
- {
- if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.CameraServices == null) return;
- playersInfo.TryAdd(player, new PlayerSkill
- {
- Player = player,
- CloneProp = null,
- NextUse = 0,
- UseTime = 0,
- PlayerModel = player.PlayerPawn.Value!.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.ModelName,
- });
- }
-
- public static void DisableSkill(CCSPlayerController player)
- {
- if (playersInfo.TryGetValue(player, out var playerSkill))
- KillClone(playerSkill);
- playersInfo.TryRemove(player, out _);
- }
-
- private static void KillClone(PlayerSkill playerSkill)
- {
- playerSkill.Player.EmitSound("SolidMetal.BulletImpact");
- if (playerSkill.CloneProp != null && playerSkill.CloneProp.IsValid && playerSkill.CloneProp.AbsOrigin != null && playerSkill.CloneProp.AbsRotation != null)
- {
- var playerPawn = playerSkill.Player.PlayerPawn.Value;
- if (playerPawn != null && playerPawn.IsValid)
- {
- Vector pos = new(playerSkill.CloneProp.AbsOrigin.X, playerSkill.CloneProp.AbsOrigin.Y, playerSkill.CloneProp.AbsOrigin.Z);
- QAngle angle = new(playerSkill.CloneProp.AbsRotation.X, playerSkill.CloneProp.AbsRotation.Y, playerSkill.CloneProp.AbsRotation.Z);
- Server.NextFrame(() =>
- {
- playerPawn.Teleport(pos, angle);
- });
- }
- playerSkill.CloneProp.AcceptInput("Kill");
- playerSkill.CloneProp = null;
- }
-
- BlockWeapon(playerSkill.Player, false);
- playerSkill.NextUse = Server.TickCount + SkillsInfo.GetValue(skillName, "Cooldown") * 64;
- playerSkill.UseTime = 0;
- }
-
- public static void OnTick()
- {
- foreach (var playerSkill in playersInfo.Values)
- UpdateHUD(playerSkill);
- }
-
- private static CDynamicProp? CreateMelon(PlayerSkill playerSkill)
- {
- var player = playerSkill.Player;
- if (player == null) return null;
-
- var playerPawn = player.PlayerPawn.Value;
- if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null || playerPawn.AbsRotation == null) return null;
-
- Vector pos = playerPawn.AbsOrigin + SkillUtils.GetForwardVector(playerPawn.AbsRotation) * 50;
- Vector pos2 = playerPawn.AbsOrigin + SkillUtils.GetForwardVector(playerPawn.AbsRotation) * (50 + 25);
- if (!CheckPosition(player, pos2) || !((PlayerFlags)playerPawn.Flags).HasFlag(PlayerFlags.FL_ONGROUND))
- {
- playerSkill.InfoTime = Server.TickCount;
- return null;
- }
-
- var clone = Utilities.CreateEntityByName("prop_dynamic");
- if (clone == null || !clone.IsValid) return null;
-
- clone.Collision.SolidType = SolidType_t.SOLID_VPHYSICS;
- clone.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(clone.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
- clone.Entity!.Name = clone.Globalname = $"IanaClone_{Server.TickCount}_{player.SteamID}";
- clone.DispatchSpawn();
-
- Server.NextFrame(() =>
- {
- clone.SetModel(playerSkill.PlayerModel);
- clone.Teleport(playerPawn.AbsOrigin, new QAngle(0, playerPawn.V_angle.Y, 0));
-
- playerPawn.Teleport(pos);
- BlockWeapon(playerSkill.Player, true);
- playerSkill.UseTime = Server.TickCount;
- playerSkill.NextUse = Server.TickCount + 64000;
- playerSkill.CloneProp = clone;
-
- Instance.AddTimer(SkillsInfo.GetValue(skillName, "Duration"), () =>
- {
- if (playerSkill.CloneProp != null)
- KillClone(playerSkill);
- });
-
- playerPawn.SetModel(melonProp);
- });
-
- return clone;
- }
-
- private unsafe static bool CheckPosition(CCSPlayerController player, Vector endPos)
- {
- var playerPawn = player.PlayerPawn.Value;
- if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return false;
-
- Vector eyePos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 25);
- endPos.Z += 25;
-
- ulong mask = playerPawn.Collision.CollisionAttribute.InteractsWith;
- ulong contents = playerPawn.Collision.CollisionGroup;
- CGameTrace trace = TraceRay.TraceShape(eyePos, endPos, mask, contents, player);
-
- return !trace.DidHit();
- }
-
- public static void OnTakeDamage(DynamicHook h)
- {
- CEntityInstance param = h.GetParam(0);
- CTakeDamageInfo param2 = h.GetParam(1);
-
- if (param == null || param.Entity == null || param2 == null)
- return;
-
- if (string.IsNullOrEmpty(param.Entity.Name)) return;
- if (!param.Entity.Name.StartsWith("IanaClone_")) return;
-
- var nameParams = param.Entity.Name.Split('_')[2];
- _ = ulong.TryParse(nameParams, out ulong steamID);
- if (steamID == 0) return;
-
- var player = Utilities.GetPlayerFromSteamId(steamID);
- if (player == null) return;
-
- if (playersInfo.TryGetValue(player, out var playerSkill))
- {
- KillClone(playerSkill);
- var playerPawn = player.PlayerPawn.Value;
- if (playerPawn != null)
- SkillUtils.TakeHealth(playerPawn, (int)param2.Damage);
- }
- }
-
- public static void PlayerHurt(EventPlayerHurt @event)
- {
- var victim = @event.Userid!;
- if (!Instance.IsPlayerValid(victim)) return;
-
- if (playersInfo.TryGetValue(victim, out var playerSkill) && playerSkill.CloneProp != null)
- {
- KillClone(playerSkill);
- SkillUtils.RestoreHealth(victim);
- }
- }
-
- private static void BlockWeapon(CCSPlayerController player, bool block)
- {
- if (player == null || !player.IsValid) return;
- var pawn = player.PlayerPawn.Value;
- if (pawn == null || !pawn.IsValid || pawn.WeaponServices == null) return;
-
- foreach (var weapon in pawn.WeaponServices.MyWeapons)
- if (weapon != null && weapon.IsValid && weapon.Value != null && weapon.Value.IsValid)
- {
- weapon.Value.NextPrimaryAttackTick = block ? int.MaxValue : Server.TickCount;
- weapon.Value.NextSecondaryAttackTick = block ? int.MaxValue : Server.TickCount;
-
- Utilities.SetStateChanged(weapon.Value, "CBasePlayerWeapon", "m_nNextPrimaryAttackTick");
- Utilities.SetStateChanged(weapon.Value, "CBasePlayerWeapon", "m_nNextSecondaryAttackTick");
- }
- }
-
- private static void UpdateHUD(PlayerSkill playerSkill)
- {
- if (playerSkill == null || playerSkill.Player == null) return;
-
- float cooldown = 0;
- float time1 = (playerSkill.NextUse - Server.TickCount) / 64;
- cooldown = (int)Math.Ceiling(Math.Max(time1, 0));
-
- float duration = 0;
- float time2 = SkillsInfo.GetValue(skillName, "Duration") - (Server.TickCount - playerSkill.UseTime) / 64;
- duration = (int)Math.Ceiling(Math.Max(time2, 0));
-
- var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == playerSkill?.Player?.SteamID);
- if (playerInfo == null) return;
-
- if (playerSkill.InfoTime + (64 * 2) > Server.TickCount)
- playerInfo.PrintHTML = $"{playerSkill?.Player.GetTranslation("shade_nospace")}";
- else if (cooldown == 0 && duration == 0)
- playerInfo.PrintHTML = null;
- else if (duration > 0)
- playerInfo.PrintHTML = $"{playerSkill?.Player.GetTranslation("hud_info", $"{duration}")}";
- else if (cooldown > 0)
- playerInfo.PrintHTML = $"{playerSkill?.Player.GetTranslation("hud_info", $"{cooldown}")}";
- }
-
- public class PlayerSkill
- {
- public required CCSPlayerController Player { get; set; }
- public CDynamicProp? CloneProp { get; set; }
- public float NextUse { get; set; }
- public float UseTime { get; set; }
- public int InfoTime { get; set; }
- public string PlayerModel { get; set; }
- }
-
- public class SkillConfig(Skills skill = skillName, bool active = false, string color = "#d0d930", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 30, float duration = 10) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
- {
- public float Cooldown { get; set; } = cooldown;
- public float Duration { get; set; } = duration;
- }
- }
-}
\ No newline at end of file
diff --git a/jRandomSkills - SRC Files/src/player/skills/RandomWeapon.cs b/jRandomSkills - SRC Files/src/player/skills/RandomWeapon.cs
index 5259dae..4f0ddd7 100644
--- a/jRandomSkills - SRC Files/src/player/skills/RandomWeapon.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/RandomWeapon.cs
@@ -1,10 +1,10 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
+using src.utils;
+using System.Collections.Concurrent;
using System.Collections.Immutable;
using static src.jRandomSkills;
-using System.Collections.Concurrent;
-using src.utils;
namespace src.player.skills
{
@@ -113,7 +113,7 @@ namespace src.player.skills
ConcurrentBag weaponList = [.. pistols.Concat(rifles).Where(w => !playerWeapons.Contains(w))];
- if (weaponList.Count == 0)
+ if (weaponList.IsEmpty)
return;
string weapon = weaponList.ToArray()[Instance.Random.Next(weaponList.Count)];
@@ -131,8 +131,12 @@ namespace src.player.skills
}
}
+ ulong steamId = player.SteamID;
Instance.AddTimer(.1f, () =>
{
+ var player = Utilities.GetPlayerFromSteamId(steamId);
+ if (player == null || !player.IsValid) return;
+
player.GiveNamedItem(weapon);
});
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/ReZombie.cs b/jRandomSkills - SRC Files/src/player/skills/ReZombie.cs
index 409740c..5f46fcf 100644
--- a/jRandomSkills - SRC Files/src/player/skills/ReZombie.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/ReZombie.cs
@@ -1,17 +1,18 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
+using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils;
+using src.utils;
+using System.Collections.Concurrent;
using System.Drawing;
using static src.jRandomSkills;
-using System.Collections.Concurrent;
-using src.utils;
namespace src.player.skills
{
public class ReZombie : ISkill
{
private const Skills skillName = Skills.ReZombie;
- private static readonly ConcurrentDictionary zombies = [];
+ private static readonly ConcurrentDictionary zombies = [];
private static readonly object setLock = new();
public static void LoadSkill()
@@ -21,14 +22,27 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player)
{
- zombies.TryRemove(player, out _);
+ zombies.TryRemove(player.Index, out _);
}
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return;
- zombies.TryRemove(player, out _);
+ zombies.TryRemove(player.Index, out _);
SetPlayerColor(player.PlayerPawn.Value, true);
+ ResetHealth(player);
+ }
+
+ public static void ResetHealth(CCSPlayerController player)
+ {
+ var pawn = player.PlayerPawn?.Value;
+ if (pawn == null) return;
+
+ pawn.MaxHealth = 100;
+ Utilities.SetStateChanged(pawn, "CBaseEntity", "m_iMaxHealth");
+
+ pawn.Health = Math.Min(pawn.Health, 100);
+ Utilities.SetStateChanged(pawn, "CBaseEntity", "m_iHealth");
}
public static void WeaponEquip(EventItemEquip @event)
@@ -36,46 +50,88 @@ namespace src.player.skills
var player = @event.Userid;
var weapon = @event.Item;
if (player == null || !player.IsValid) return;
- if (!zombies.ContainsKey(player) || weapon == "c4") return;
+ if (!zombies.ContainsKey(player.Index) || weapon == "c4") return;
player.ExecuteClientCommand("slot3");
}
public static void NewRound()
{
- foreach (var player in zombies.Keys)
+ foreach (var playerIndex in zombies.Keys)
+ {
+ var player = Utilities.GetPlayerFromIndex((int)playerIndex);
+ if (player == null || !player.IsValid) continue;
+
DisableSkill(player);
+ }
zombies.Clear();
}
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
- if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid || zombies.ContainsKey(player)) return;
+ if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid || zombies.ContainsKey(player.Index)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo?.Skill != skillName) return;
var pawn = player.PlayerPawn.Value;
if (pawn.AbsOrigin == null) return;
- Vector deadPosition = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z);
- QAngle deadRotation = new(pawn.EyeAngles.X, pawn.EyeAngles.Y, pawn.EyeAngles.Z);
+ Vector deadPosition = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z);
+ QAngle angle = new(pawn.V_angle.X, pawn.V_angle.Y, 0);
+
+ ulong steamID = player.SteamID;
player.Respawn();
+
Instance.AddTimer(.2f, () => {
lock (setLock)
{
+ var player = Utilities.GetPlayerFromSteamId(steamID);
+ if (player == null || !player.IsValid || !player.PlayerPawn.IsValid) return;
+
+ var pawn = player.PlayerPawn.Value;
+ if (pawn == null || !pawn.IsValid) return;
+
var zombieHealth = SkillsInfo.GetValue(skillName, "zombieHealth");
+
player.Respawn();
- zombies.TryAdd(player, 0);
+ zombies.TryAdd(player.Index, 0);
+
SetPlayerColor(pawn, false);
SkillUtils.AddHealth(pawn, zombieHealth - 100, zombieHealth);
- pawn.Teleport(deadPosition, deadRotation);
+
+ pawn.Teleport(deadPosition);
+ pawn.Look(angle);
player.ExecuteClientCommand("slot3");
- Instance.AddTimer(1, () => player.ExecuteClientCommand("slot3"));
+
+ Instance.AddTimer(1, () => {
+ var player = Utilities.GetPlayerFromSteamId(steamID);
+ if (player == null || !player.IsValid || !player.PlayerPawn.IsValid) return;
+
+ player.ExecuteClientCommand("slot3");
+ });
}
});
}
+ public static bool OnWeaponCanAcquire(DynamicHook hook, CCSPlayerController player, CEconItemView econItem, CCSWeaponBaseVData vdata)
+ {
+ string weaponName = vdata.Name;
+ if (string.IsNullOrEmpty(weaponName)) return false;
+
+ if (!zombies.ContainsKey(player.Index))
+ return false;
+
+ if (weaponName.Contains("knife") || weaponName.Contains("bayonet"))
+ return false;
+
+ var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
+ if (playerInfo?.Skill != skillName) return false;
+
+ hook.SetReturn(AcquireResult.InvalidItem);
+ return true;
+ }
+
private static void SetPlayerColor(CCSPlayerPawn pawn, bool normal)
{
var color = normal ? Color.FromArgb(255, 255, 255, 255) : Color.FromArgb(255, 255, 0, 0);
@@ -83,7 +139,7 @@ namespace src.player.skills
Utilities.SetStateChanged(pawn, "CBaseModelEntity", "m_clrRender");
}
- public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff5C0A", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int zombieHealth = 250) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
+ public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff5C0A", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int zombieHealth = 500) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public int ZombieHealth { get; set; } = zombieHealth;
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Replicator.cs b/jRandomSkills - SRC Files/src/player/skills/Replicator.cs
index f96ffa7..45d65e0 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Replicator.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Replicator.cs
@@ -5,6 +5,7 @@ using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
+using CounterStrikeSharp.API.Modules.Memory;
namespace src.player.skills
{
@@ -102,13 +103,13 @@ namespace src.player.skills
private static void CreateReplica(CCSPlayerController player)
{
var playerPawn = player.PlayerPawn.Value;
- var replica = Utilities.CreateEntityByName("prop_dynamic_override");
- if (replica == null || playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null || playerPawn.AbsRotation == null)
+ if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null || playerPawn.AbsRotation == null)
+ return;
+
+ var replica = Utilities.CreateEntityByName("prop_dynamic_override");
+ if (replica == null || !replica.IsValid)
return;
- float distance = 40;
- Vector pos = playerPawn.AbsOrigin + SkillUtils.GetForwardVector(playerPawn.AbsRotation) * distance;
-
replica.Flags = playerPawn.Flags;
replica.Flags |= (uint)Flags_t.FL_DUCKING;
replica.Collision.SolidType = SolidType_t.SOLID_VPHYSICS;
@@ -116,12 +117,13 @@ namespace src.player.skills
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.UseAnimGraph = true;
+ replica.AnimGraphUpdateEnabled = true;
+ bool isDucking = ((PlayerFlags)playerPawn.Flags).HasFlag(PlayerFlags.FL_DUCKING);
+
+ float distance = 40;
+ Vector pos = playerPawn.AbsOrigin + SkillUtils.GetForwardVector(playerPawn.AbsRotation) * distance;
- replica.AcceptInput("SetAnimation", value: animName);
replica.Teleport(pos, playerPawn.AbsRotation, null);
replica.DispatchSpawn();
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Rubber.cs b/jRandomSkills - SRC Files/src/player/skills/Rubber.cs
index 0964254..50c2605 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Rubber.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Rubber.cs
@@ -10,7 +10,7 @@ namespace src.player.skills
public class Rubber: ISkill
{
private const Skills skillName = Skills.Rubber;
- private static readonly ConcurrentDictionary playersToSlow = [];
+ private static readonly ConcurrentDictionary playersToSlow = [];
public static void LoadSkill()
{
@@ -35,25 +35,33 @@ namespace src.player.skills
var rubberTime = SkillsInfo.GetValue(skillName, "slownessTime");
if (attackerInfo?.Skill == skillName)
- playersToSlow.AddOrUpdate(victimPawn, Server.TickCount + (64 * rubberTime), (k, v) => Server.TickCount + (64 * rubberTime));
+ playersToSlow.AddOrUpdate(victim.Index, Server.TickCount + (64 * rubberTime), (k, v) => Server.TickCount + (64 * rubberTime));
}
public static void OnTick()
{
foreach(var item in playersToSlow)
{
- var pawn = item.Key;
+ var playerIndex = item.Key;
var time = item.Value;
+
+ var player = Utilities.GetPlayerFromIndex((int)playerIndex);
+ if (player == null || !player.IsValid) continue;
+
if (time >= Server.TickCount)
- ChangeVelocity(pawn);
+ ChangeVelocity(player);
else
playersToSlow.TryRemove(item.Key, out _);
}
}
- private static void ChangeVelocity(CCSPlayerPawn pawn)
+ private static void ChangeVelocity(CCSPlayerController player)
{
+ if (player.PlayerPawn == null) return;
+
+ var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return;
+
pawn.VelocityModifier = SkillsInfo.GetValue(skillName, "slownessModifier");
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Saper.cs b/jRandomSkills - SRC Files/src/player/skills/Saper.cs
index 1b8da9f..c4744a6 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Saper.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Saper.cs
@@ -25,7 +25,10 @@ namespace src.player.skills
{
var plantedBomb = Utilities.FindAllEntitiesByDesignerName("planted_c4").FirstOrDefault();
if (plantedBomb != null)
- Server.NextFrame(() => plantedBomb.DefuseCountDown = 0);
+ Server.NextFrame(() => {
+ if (plantedBomb != null && plantedBomb.IsValid)
+ plantedBomb.DefuseCountDown = 0;
+ });
}
}
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/SecondLife.cs b/jRandomSkills - SRC Files/src/player/skills/SecondLife.cs
index aa23ce6..a67a4a0 100644
--- a/jRandomSkills - SRC Files/src/player/skills/SecondLife.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/SecondLife.cs
@@ -43,7 +43,7 @@ namespace src.player.skills
var spawnpoint = SkillUtils.GetSpawnPointVector(victim);
if (spawnpoint == null) return;
- victimPawn.Teleport(spawnpoint, victimPawn.AbsRotation, null);
+ victimPawn.Teleport(spawnpoint, null, null);
}
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Shade.cs b/jRandomSkills - SRC Files/src/player/skills/Shade.cs
index bd85b22..3478a7e 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Shade.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Shade.cs
@@ -1,8 +1,6 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
-using CS2TraceRay.Class;
-using CS2TraceRay.Struct;
using static src.jRandomSkills;
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
using System.Collections.Concurrent;
@@ -13,7 +11,7 @@ namespace src.player.skills
public class Shade : ISkill
{
private const Skills skillName = Skills.Shade;
- private static readonly ConcurrentDictionary noSpace = [];
+ private static readonly ConcurrentDictionary noSpace = [];
public static void LoadSkill()
{
@@ -44,25 +42,32 @@ namespace src.player.skills
{
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo == null) return;
+
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue(skillName, "ChanceTo") - SkillsInfo.GetValue(skillName, "ChanceFrom")) + SkillsInfo.GetValue(skillName, "ChanceFrom");
playerInfo.SkillChance = newChance;
+
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
}
public static void DisableSkill(CCSPlayerController player)
{
- noSpace.TryRemove(player, out _);
+ noSpace.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player);
}
public static void OnTick()
{
- foreach (var item in noSpace)
- if (item.Value >= Server.TickCount)
- UpdateHUD(item.Key);
+ foreach (var (playerIndex, time) in noSpace)
+ {
+ var player = Utilities.GetPlayerFromIndex((int)playerIndex);
+ if (player == null || !player.IsValid) continue;
+
+ if (time >= Server.TickCount)
+ UpdateHUD(player);
else
- SkillUtils.ResetPrintHTML(item.Key);
+ SkillUtils.ResetPrintHTML(player);
+ }
}
private static void UpdateHUD(CCSPlayerController player)
@@ -72,45 +77,29 @@ namespace src.player.skills
playerInfo.PrintHTML = $"{player.GetTranslation("shade_nospace")}";
}
- private unsafe static bool CheckTeleport(CCSPlayerController player, Vector startPos, Vector endPos)
+ private unsafe static bool CheckTeleport(CCSPlayerController attacker, CCSPlayerController victim, Vector startPos, Vector endPos, QAngle angle)
{
- var pawn = player.PlayerPawn.Value;
- if (pawn == null || !pawn.IsValid) return false;
+ var attackerPawn = attacker.PlayerPawn.Value;
+ if (attackerPawn == null || !attackerPawn.IsValid) return false;
- Vector s = startPos + new Vector(0, 0, pawn.ViewOffset.Z / 2);
- Vector e = endPos + new Vector(0, 0, pawn.ViewOffset.Z / 2);
+ var victimPawn = attacker.PlayerPawn.Value;
+ if (victimPawn == null || !victimPawn.IsValid) return false;
- ulong mask = pawn.Collision.CollisionAttribute.InteractsWith;
- ulong contents = pawn.Collision.CollisionGroup;
- CGameTrace trace = TraceRay.TraceShape(startPos, endPos, mask, contents, player);
+ var result = RayTrace.TraceHullShape(
+ startPos,
+ endPos,
+ victim,
+ attackerPawn.Collision.Mins,
+ attackerPawn.Collision.Maxs,
+ null,
+ null,
+ angle
+ );
- if (trace.DidHit()) return false;
- return IsPositionSafe(player, endPos);
- }
+ if (!result.HasValue)
+ return false;
- private static bool IsPositionSafe(CCSPlayerController player, Vector pos)
- {
- 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;
+ return !result.Value.DidHit;
}
private static void TeleportAttackerBehindVictim(CCSPlayerController attacker, CCSPlayerController victim)
@@ -133,7 +122,7 @@ namespace src.player.skills
Vector direction = SkillUtils.GetForwardVector(targetAngle);
Vector targetPos = victimPos - (direction * distance);
- if (CheckTeleport(victim, victimPos, targetPos))
+ if (CheckTeleport(attacker, victim, victimPos, targetPos, targetAngle))
{
attackerPawn.Teleport(targetPos, targetAngle, Vector.Zero);
teleported = true;
@@ -142,7 +131,7 @@ namespace src.player.skills
}
if (!teleported)
- noSpace.AddOrUpdate(attacker, Server.TickCount + (64 * 2), (_, _) => Server.TickCount + (64 * 2));
+ noSpace.AddOrUpdate(attacker.Index, Server.TickCount + (64 * 2), (_, _) => Server.TickCount + (64 * 2));
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#4d4d4d", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float teleportDistance = 100f, float chanceFrom = .3f, float chanceTo = .45f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
diff --git a/jRandomSkills - SRC Files/src/player/skills/ShortBomb.cs b/jRandomSkills - SRC Files/src/player/skills/ShortBomb.cs
index a38f4e4..5cbf13d 100644
--- a/jRandomSkills - SRC Files/src/player/skills/ShortBomb.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/ShortBomb.cs
@@ -25,7 +25,10 @@ namespace src.player.skills
var plantedBomb = Utilities.FindAllEntitiesByDesignerName("planted_c4").FirstOrDefault();
if (plantedBomb != null)
- Server.NextFrame(() => plantedBomb.C4Blow = Server.CurrentTime + SkillsInfo.GetValue(skillName, "detonationTime"));
+ Server.NextFrame(() => {
+ if (plantedBomb != null && plantedBomb.IsValid)
+ plantedBomb.C4Blow = Server.CurrentTime + SkillsInfo.GetValue(skillName, "detonationTime");
+ });
foreach (var p in Utilities.GetPlayers().Where(p => p.IsValid))
p.PrintToCenterAlert(p.GetTranslation("bombplanted", SkillsInfo.GetValue(skillName, "detonationTime")));
diff --git a/jRandomSkills - SRC Files/src/player/skills/Smoker.cs b/jRandomSkills - SRC Files/src/player/skills/Smoker.cs
index 2a2a959..5bb1082 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Smoker.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Smoker.cs
@@ -1,5 +1,6 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
+using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Timers;
using CounterStrikeSharp.API.Modules.Utils;
@@ -50,12 +51,16 @@ namespace src.player.skills
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo?.Skill != skillName) return;
+ ulong steamID = player.SteamID;
+
Vector pos = new(@event.X, @event.Y, @event.Z);
float refillInterval = 15.5f;
Timer? smokeTimer = null;
smokeTimer = Instance.AddTimer(refillInterval, () =>
{
+ var player = Utilities.GetPlayerFromSteamId(steamID);
+
if (player == null || !player.IsValid)
{
smokeTimer?.Kill();
diff --git a/jRandomSkills - SRC Files/src/player/skills/SniperElite.cs b/jRandomSkills - SRC Files/src/player/skills/SniperElite.cs
index 68483ec..ed1b35c 100644
--- a/jRandomSkills - SRC Files/src/player/skills/SniperElite.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/SniperElite.cs
@@ -166,7 +166,10 @@ namespace src.player.skills
}
Instance.AddTimer(.15f, () => {
- if (player != null && player.IsValid && player.PlayerPawn.Value != null && player.PlayerPawn.Value.IsValid)
+ var player = Utilities.GetPlayerFromSteamId(steamID);
+ if (player == null || !player.IsValid) return;
+
+ if (player != null && player.IsValid && player.PlayerPawn != null && player.PlayerPawn.Value != null && player.PlayerPawn.Value.IsValid)
{
var createdWeapon = player.PlayerPawn.Value?.ItemServices?.As().GiveNamedItem(weaponToGive.Replace("_script", ""));
diff --git a/jRandomSkills - SRC Files/src/player/skills/Spectator.cs b/jRandomSkills - SRC Files/src/player/skills/Spectator.cs
index 281c040..dda8f7b 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Spectator.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Spectator.cs
@@ -11,7 +11,7 @@ namespace src.player.skills
public class Spectator : ISkill
{
private const Skills skillName = Skills.Spectator;
- private static readonly ConcurrentDictionary cameras = [];
+ private static readonly ConcurrentDictionary cameras = [];
public static void LoadSkill()
{
@@ -20,9 +20,13 @@ namespace src.player.skills
public static void NewRound()
{
- foreach (var camera in cameras)
- if (camera.Value.Item2 != null && camera.Value.Item2.IsValid)
- camera.Value.Item2.AcceptInput("Kill");
+ foreach (var info in cameras)
+ {
+ var cam = Utilities.GetEntityFromIndex((int)info.Value.Item2);
+ if (cam != null && cam.IsValid)
+ cam.AcceptInput("Kill");
+ }
+
cameras.Clear();
}
@@ -54,10 +58,24 @@ namespace src.player.skills
public static void OnTick()
{
foreach (var player in Utilities.GetPlayers())
- if (cameras.TryGetValue(player.SteamID, out var cameraInfo) && cameraInfo.Item2.IsValid)
+ if (cameras.TryGetValue(player.SteamID, out var cameraInfo) && cameraInfo.Item2 != 0)
{
- var pawn = cameraInfo.Item3;
- if (pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE
+
+ var enemy = Utilities.GetPlayerFromIndex((int)cameraInfo.Item3);
+ if (enemy == null || !enemy.IsValid || enemy.PlayerPawn == null)
+ {
+ ChangeCamera(player, true);
+ return;
+ }
+
+ var enemyPawn = player.PlayerPawn.Value;
+ if (enemyPawn == null || !enemyPawn.IsValid)
+ {
+ ChangeCamera(player, true);
+ return;
+ }
+
+ if (enemyPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE
|| (player.PlayerPawn.Value != null && player.PlayerPawn.Value.LifeState != (byte)LifeState_t.LIFE_ALIVE))
ChangeCamera(player, true);
}
@@ -70,10 +88,14 @@ namespace src.player.skills
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.CameraServices == null) return;
- if (cameras.TryGetValue(player.SteamID, out var cameraInfo) && cameraInfo.Item2 != null && cameraInfo.Item2.IsValid)
+ if (cameras.TryGetValue(player.SteamID, out var cameraInfo) && cameraInfo.Item2 != 0)
{
orginalCameraRaw = cameraInfo.Item1;
- cameraInfo.Item2.AcceptInput("Kill");
+
+ var cam = Utilities.GetEntityFromIndex((int)cameraInfo.Item2);
+ if (cam != null && cam.IsValid)
+ cam.AcceptInput("Kill");
+
if (!forceToDefault)
newCameraRaw = CreateCamera(player);
} else
@@ -109,22 +131,25 @@ namespace src.player.skills
var pawn = enemy.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.CameraServices == null || pawn.AbsOrigin == null) return 0;
- var pos = pawn.AbsOrigin - SkillUtils.GetForwardVector(pawn.EyeAngles) * SkillsInfo.GetValue(skillName, "distance");
+ QAngle angle = new(0, pawn.EyeAngles.Y, 0);
+
+ var pos = pawn.AbsOrigin - SkillUtils.GetForwardVector(angle) * SkillsInfo.GetValue(skillName, "distance");
pos.Z += pawn.ViewOffset.Z;
Server.NextFrame(() =>
{
+ if (camera == null || !camera.IsValid) return;
camera.SetModel("models/actors/ghost_speaker.vmdl");
camera.Render = Color.FromArgb(0, 255, 255, 255);
- camera.Teleport(pos, new QAngle(0, pawn.EyeAngles.Y, 0));
+ camera.Teleport(pos, angle);
camera.DispatchSpawn();
camera.AcceptInput("SetParent", pawn, pawn, "!activator");
});
if (cameras.TryGetValue(player.SteamID, out var cameraInfo))
- cameras.AddOrUpdate(player.SteamID, (cameraInfo.Item1, camera, pawn), (k, v) => (cameraInfo.Item1, camera, pawn));
+ cameras.AddOrUpdate(player.SteamID, (cameraInfo.Item1, camera.Index, player.Index), (k, v) => (cameraInfo.Item1, camera.Index, player.Index));
else
- cameras.AddOrUpdate(player.SteamID, (pawn.CameraServices.ViewEntity.Raw, camera, pawn), (k, v) => (pawn.CameraServices.ViewEntity.Raw, camera, pawn));
+ cameras.AddOrUpdate(player.SteamID, (pawn.CameraServices.ViewEntity.Raw, camera.Index, player.Index), (k, v) => (pawn.CameraServices.ViewEntity.Raw, camera.Index, player.Index));
return camera.EntityHandle.Raw;
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/SwapPosition.cs b/jRandomSkills - SRC Files/src/player/skills/SwapPosition.cs
index cee4aea..d2fc530 100644
--- a/jRandomSkills - SRC Files/src/player/skills/SwapPosition.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/SwapPosition.cs
@@ -123,15 +123,18 @@ namespace src.player.skills
if (attackerPawn.AbsOrigin == null || attackerPawn.AbsRotation == null || victimPawn.AbsOrigin == null || victimPawn.AbsRotation == null) return;
Vector attackerPosition = new(attackerPawn.AbsOrigin.X, attackerPawn.AbsOrigin.Y, attackerPawn.AbsOrigin.Z);
- QAngle attackerAngles = new(attackerPawn.AbsRotation.X, attackerPawn.AbsRotation.Y, attackerPawn.AbsRotation.Z);
+ QAngle attackerAngles = new(attackerPawn.V_angle.X, attackerPawn.V_angle.Y, 0);
Vector attackerVelocity = new(attackerPawn.AbsVelocity.X, attackerPawn.AbsVelocity.Y, attackerPawn.AbsVelocity.Z);
Vector victimPosition = new(victimPawn.AbsOrigin.X, victimPawn.AbsOrigin.Y, victimPawn.AbsOrigin.Z);
- QAngle victimAngles = new(victimPawn.AbsRotation.X, victimPawn.AbsRotation.Y, victimPawn.AbsRotation.Z);
+ QAngle victimAngles = new(victimPawn.V_angle.X, victimPawn.V_angle.Y, 0);
Vector victimVelocity = new(victimPawn.AbsVelocity.X, victimPawn.AbsVelocity.Y, victimPawn.AbsVelocity.Z);
- victimPawn.Teleport(attackerPosition, attackerAngles, attackerVelocity);
- attackerPawn.Teleport(victimPosition, victimAngles, victimVelocity);
+ victimPawn.Teleport(attackerPosition, null, attackerVelocity);
+ attackerPawn.Teleport(victimPosition, null, victimVelocity);
+
+ victimPawn.Look(attackerAngles);
+ attackerPawn.Look(victimAngles);
}
public class ZamianaMiejsc_PlayerInfo
diff --git a/jRandomSkills - SRC Files/src/player/skills/Teleporter.cs b/jRandomSkills - SRC Files/src/player/skills/Teleporter.cs
index 85d628d..0673350 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Teleporter.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Teleporter.cs
@@ -49,15 +49,18 @@ namespace src.player.skills
if (attackerPawn.AbsOrigin == null || victimPawn.AbsOrigin == null || attackerPawn.AbsRotation == null || victimPawn.AbsRotation == null) return;
Vector attackerPosition = new(attackerPawn.AbsOrigin.X, attackerPawn.AbsOrigin.Y, attackerPawn.AbsOrigin.Z);
- QAngle attackerAngles = new(attackerPawn.AbsRotation.X, attackerPawn.AbsRotation.Y, attackerPawn.AbsRotation.Z);
+ QAngle attackerAngles = new(attackerPawn.V_angle.X, attackerPawn.V_angle.Y, 0);
Vector attackerVelocity = new(attackerPawn.AbsVelocity.X, attackerPawn.AbsVelocity.Y, attackerPawn.AbsVelocity.Z);
Vector victimPosition = new(victimPawn.AbsOrigin.X, victimPawn.AbsOrigin.Y, victimPawn.AbsOrigin.Z);
- QAngle victimAngles = new(victimPawn.AbsRotation.X, victimPawn.AbsRotation.Y, victimPawn.AbsRotation.Z);
+ QAngle victimAngles = new(victimPawn.V_angle.X, victimPawn.V_angle.Y, 0);
Vector victimVelocity = new(victimPawn.AbsVelocity.X, victimPawn.AbsVelocity.Y, victimPawn.AbsVelocity.Z);
- victimPawn.Teleport(attackerPosition, attackerAngles, attackerVelocity);
- attackerPawn.Teleport(victimPosition, victimAngles, victimVelocity);
+ victimPawn.Teleport(attackerPosition, null, attackerVelocity);
+ attackerPawn.Teleport(victimPosition, null, victimVelocity);
+
+ victimPawn.Look(attackerAngles);
+ attackerPawn.Look(victimAngles);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8A2BE2", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float chanceFrom = .5f, float chanceTo = .6f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
diff --git a/jRandomSkills - SRC Files/src/player/skills/Thief.cs b/jRandomSkills - SRC Files/src/player/skills/Thief.cs
index 99b585e..a917a52 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Thief.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Thief.cs
@@ -120,10 +120,19 @@ namespace src.player.skills
bool ctSkill = Event.counterterroristSkills.Any(s => s.Name == enemySkill.ToString());
bool ttSkill = Event.terroristSkills.Any(s => s.Name == enemySkill.ToString());
+ ulong enemySteamId = enemy.SteamID;
+ ulong playerSteamId = player.SteamID;
+
if ((player.Team == CsTeam.Terrorist && ctSkill) || (player.Team == CsTeam.CounterTerrorist && ttSkill))
{
Instance.AddTimer(.1f, () =>
{
+ var enemy = Utilities.GetPlayerFromSteamId(enemySteamId);
+ if (enemy == null || !enemy.IsValid) return;
+
+ var player = Utilities.GetPlayerFromSteamId(playerSteamId);
+ if (player == null || !player.IsValid) return;
+
Instance.SkillAction(skillName.ToString(), "EnableSkill", [player]);
player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("thief_incorrect_skill", enemy.PlayerName));
});
@@ -133,24 +142,42 @@ namespace src.player.skills
SkillUtils.CloseMenu(player);
Instance.AddTimer(.1f, () =>
{
+ var enemy = Utilities.GetPlayerFromSteamId(enemySteamId);
+ if (enemy == null || !enemy.IsValid) return;
+
+ var player = Utilities.GetPlayerFromSteamId(playerSteamId);
+ if (player == null || !player.IsValid) return;
+
playerInfo.Skill = enemySkill;
playerInfo.SpecialSkill = skillName;
+
SkillUtils.CloseMenu(player);
Instance.SkillAction(enemySkill.ToString(), "EnableSkill", [player]);
+
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("thief_player_info", enemy.PlayerName));
if (SkillsInfo.GetValue(enemySkill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
Instance?.AddTimer(Math.Max((float)(Event.GetFreezeTimeEnd() - DateTime.Now).TotalSeconds, 0), () => {
+ var player = Utilities.GetPlayerFromSteamId(playerSteamId);
+ if (player == null || !player.IsValid) return;
+
if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID && p.Skill == enemySkill) == null) return;
- Instance?.SkillAction(enemySkill.ToString(), "EnableSkill", new[] { player });
+ Instance?.SkillAction(enemySkill.ToString(), "EnableSkill", [player]);
});
else
- Instance?.SkillAction(enemySkill.ToString(), "EnableSkill", new[] { player });
+ Instance?.SkillAction(enemySkill.ToString(), "EnableSkill", [player]);
});
Instance.AddTimer(.1f, () =>
{
+ var enemyInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == enemySteamId);
+ if (enemyInfo == null) return;
+
+ var enemy = Utilities.GetPlayerFromSteamId(enemySteamId);
+ if (enemy == null || !enemy.IsValid) return;
+
Instance.SkillAction(enemySkill.ToString(), "DisableSkill", [enemy]);
+
enemyInfo.SpecialSkill = enemySkill;
enemyInfo.Skill = Skills.None;
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("thief_enemy_info"));
diff --git a/jRandomSkills - SRC Files/src/player/skills/ThirdEye.cs b/jRandomSkills - SRC Files/src/player/skills/ThirdEye.cs
index 2eac8c1..e9f1954 100644
--- a/jRandomSkills - SRC Files/src/player/skills/ThirdEye.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/ThirdEye.cs
@@ -10,7 +10,7 @@ namespace src.player.skills
public class ThirdEye : ISkill
{
private const Skills skillName = Skills.ThirdEye;
- private static readonly ConcurrentDictionary cameras = [];
+ private static readonly ConcurrentDictionary cameras = [];
private static readonly object setLock = new();
public static void LoadSkill()
@@ -20,9 +20,13 @@ namespace src.player.skills
public static void NewRound()
{
- foreach (var camera in cameras)
- if (camera.Value.Item2 != null && camera.Value.Item2.IsValid)
- camera.Value.Item2.AcceptInput("Kill");
+ foreach (var cameraIndex in cameras.Values)
+ {
+ var camera = Utilities.GetEntityFromIndex((int)cameraIndex.Item2);
+ if (camera != null && camera.IsValid)
+ camera.AcceptInput("Kill");
+ }
+
lock (setLock)
cameras.Clear();
}
@@ -42,7 +46,7 @@ namespace src.player.skills
public static void OnTick()
{
foreach (var player in Utilities.GetPlayers())
- if (cameras.TryGetValue(player.SteamID, out var cameraInfo) && cameraInfo.Item2.IsValid)
+ if (cameras.TryGetValue(player.SteamID, out var cameraInfo) && cameraInfo.Item2 != 0)
{
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue;
@@ -55,7 +59,7 @@ namespace src.player.skills
var pos = pawn.AbsOrigin - SkillUtils.GetForwardVector(pawn.EyeAngles) * SkillsInfo.GetValue(skillName, "distance");
pos.Z += pawn.ViewOffset.Z;
- var cam = cameraInfo.Item2;
+ var cam = Utilities.GetEntityFromIndex((int)cameraInfo.Item2);
if (cam == null || cam.AbsOrigin == null || cam.AbsRotation == null) continue;
cam.Teleport(pos, pawn.V_angle);
}
@@ -66,10 +70,14 @@ namespace src.player.skills
uint orginalCameraRaw;
uint newCameraRaw;
var pawn = player.PlayerPawn.Value;
- if (cameras.TryGetValue(player.SteamID, out var cameraInfo) && cameraInfo.Item2.IsValid)
+ if (cameras.TryGetValue(player.SteamID, out var cameraInfo) && cameraInfo.Item2 != 0)
{
orginalCameraRaw = cameraInfo.Item1;
- newCameraRaw = cameraInfo.Item2.EntityHandle.Raw;
+
+ var cam = Utilities.GetEntityFromIndex((int)cameraInfo.Item2);
+ if (cam == null || !cam.IsValid) return;
+
+ newCameraRaw = cam.EntityHandle.Raw;
}
else
{
@@ -100,13 +108,14 @@ namespace src.player.skills
Server.NextFrame(() =>
{
+ if (camera == null || !camera.IsValid) return;
camera.SetModel("models/actors/ghost_speaker.vmdl");
camera.Render = Color.FromArgb(0, 255, 255, 255);
camera.Teleport(pawn!.AbsOrigin, pawn.EyeAngles);
camera.DispatchSpawn();
});
- cameras.AddOrUpdate(player.SteamID, (pawn.CameraServices!.ViewEntity.Raw, camera), (v, k) => (pawn.CameraServices!.ViewEntity.Raw, camera));
+ cameras.AddOrUpdate(player.SteamID, (pawn.CameraServices!.ViewEntity.Raw, camera.Index), (v, k) => (pawn.CameraServices!.ViewEntity.Raw, camera.Index));
return camera.EntityHandle.Raw;
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/ThrowingKnife.cs b/jRandomSkills - SRC Files/src/player/skills/ThrowingKnife.cs
index 207e089..714de46 100644
--- a/jRandomSkills - SRC Files/src/player/skills/ThrowingKnife.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/ThrowingKnife.cs
@@ -129,7 +129,7 @@ namespace src.player.skills
if (trigger != null && trigger.IsValid)
Server.NextFrame(() =>
{
- if (trigger.IsValid)
+ if (trigger != null && trigger.IsValid)
trigger.AcceptInput("Kill");
});
}
@@ -140,7 +140,7 @@ namespace src.player.skills
if (glow != null && glow.IsValid)
Server.NextFrame(() =>
{
- if (glow.IsValid)
+ if (glow != null && glow.IsValid)
glow.AcceptInput("Kill");
});
}
@@ -151,7 +151,7 @@ namespace src.player.skills
if (relay != null && relay.IsValid)
Server.NextFrame(() =>
{
- if (relay.IsValid)
+ if (relay != null && relay.IsValid)
relay.AcceptInput("Kill");
});
}
@@ -178,7 +178,11 @@ namespace src.player.skills
if (weapon == null || !weapon.IsValid || (!weapon.DesignerName.Contains("knife") && !weapon.DesignerName.Contains("bayonet"))) return;
player.DropActiveWeapon();
- Server.NextFrame(() => ThrowKnife(player, weapon) );
+ Server.NextFrame(() => {
+ if (player == null || !player.IsValid) return;
+ if (weapon == null || !weapon.IsValid) return;
+ ThrowKnife(player, weapon);
+ });
});
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/ToxicSmoke.cs b/jRandomSkills - SRC Files/src/player/skills/ToxicSmoke.cs
index 2ddad5c..303a4c3 100644
--- a/jRandomSkills - SRC Files/src/player/skills/ToxicSmoke.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/ToxicSmoke.cs
@@ -65,6 +65,7 @@ namespace src.player.skills
Server.NextFrame(() =>
{
+ if (entity == null || !entity.IsValid) return;
var smoke = entity.As();
smoke.SmokeColor.X = 255;
smoke.SmokeColor.Y = 0;
diff --git a/jRandomSkills - SRC Files/src/player/skills/WeaponsSwap.cs b/jRandomSkills - SRC Files/src/player/skills/WeaponsSwap.cs
index e3a7b70..a7a5289 100644
--- a/jRandomSkills - SRC Files/src/player/skills/WeaponsSwap.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/WeaponsSwap.cs
@@ -133,6 +133,8 @@ namespace src.player.skills
Server.NextFrame(() =>
{
+ if (player == null || !player.IsValid) return;
+ if (enemy == null || !enemy.IsValid) return;
player.RemoveWeapons();
enemy.RemoveWeapons();
GiveWeapons(player, enemyWeapon, playerWeapon.Contains("weapon_c4"));
diff --git a/jRandomSkills - SRC Files/src/utils/Config.cs b/jRandomSkills - SRC Files/src/utils/Config.cs
index c3af6d1..043ce3c 100644
--- a/jRandomSkills - SRC Files/src/utils/Config.cs
+++ b/jRandomSkills - SRC Files/src/utils/Config.cs
@@ -88,7 +88,7 @@ namespace src.utils
public bool DisplayAlwaysDescription { get; set; }
public bool DisableSpectateHUD { get; set; }
public bool FlashingHtmlHudFix { get; set; }
- public bool CS2TraceRayDebug { get; set; }
+ public bool TraceRayBeam { get; set; }
public string DisableHUDOnDeathPermission { get; set; }
public bool DisableSkillsOnRoundEnd { get; set; }
public LanguageSystem LanguageSystem { get; set; }
@@ -112,7 +112,7 @@ namespace src.utils
SkillDescriptionDuration = 7;
DisplayAlwaysDescription = false;
FlashingHtmlHudFix = true;
- CS2TraceRayDebug = false;
+ TraceRayBeam = false;
DisableSpectateHUD = false;
DisableHUDOnDeathPermission = "@jRandomSkills/death";
DisableSkillsOnRoundEnd = false;
@@ -180,6 +180,7 @@ namespace src.utils
SetStaticSkillCommand = new NormalCommand("ustawstatycznyskill, ustaw_statyczny_skill, setstaticskill, set_static_skill", "@jRandomSkills/admin"),
ChangeLanguageCommand = new NormalCommand("lang, language, changelang, change_lang, jezyk, język", ""),
ReloadCommand = new NormalCommand("reload, refresh", "@jRandomSkills/admin"),
+ NextCommand = new NormalCommand("next_skill", "@jRandomSkills/admin"),
};
VotingCommands = new VotingCommands
@@ -259,6 +260,7 @@ namespace src.utils
public required NormalCommand SetStaticSkillCommand { get; set; }
public required NormalCommand ChangeLanguageCommand { get; set; }
public required NormalCommand ReloadCommand { get; set; }
+ public required NormalCommand NextCommand { get; set; }
}
public class VotingCommand(bool enableVoting, string alias, string permissions, float timeToVote, float percentagesToSuccess, float timeToNextVoting, float timeToNextSameVoting, int minimumPlayersToStartVoting) : NormalCommand(alias, permissions)
diff --git a/jRandomSkills - SRC Files/src/utils/CustomTraceResult.cs b/jRandomSkills - SRC Files/src/utils/CustomTraceResult.cs
new file mode 100644
index 0000000..8a41399
--- /dev/null
+++ b/jRandomSkills - SRC Files/src/utils/CustomTraceResult.cs
@@ -0,0 +1,36 @@
+using RayTraceAPI;
+using System.Numerics;
+using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
+
+namespace jRandomSkills.src.utils
+{
+ public struct CustomTraceResult (TraceResult result, Vector startPos, ulong mask, ulong contents, bool drawBeam)
+ {
+ public float StartPosX = startPos.X;
+ public float StartPosY = startPos.Y;
+ public float StartPosZ = startPos.Z;
+
+ public float EndPosX = result.EndPosX;
+ public float EndPosY = result.EndPosY;
+ public float EndPosZ = result.EndPosZ;
+
+ public nint HitEntity = result.HitEntity;
+ public float Fraction = result.Fraction;
+ public int AllSolid = result.AllSolid;
+
+ public float NormalX = result.NormalX;
+ public float NormalY = result.NormalY;
+ public float NormalZ = result.NormalZ;
+
+ public ulong InteractsWith = mask;
+ public ulong InteractsExclude = contents;
+ public bool DrawBeam = drawBeam;
+
+ public readonly Vector3 StartPos => new(StartPosX, StartPosY, StartPosZ);
+ public readonly Vector3 EndPos => new(EndPosX, EndPosY, EndPosZ);
+ public readonly Vector3 Normal => new(NormalX, NormalY, NormalZ);
+ public readonly float Distance => Vector3.Distance(StartPos, EndPos);
+ public readonly bool DidHit => Fraction < 1f;
+ public readonly bool IsAllSolid => AllSolid != 0;
+ }
+}
diff --git a/jRandomSkills - SRC Files/src/utils/RayTrace.cs b/jRandomSkills - SRC Files/src/utils/RayTrace.cs
new file mode 100644
index 0000000..c28af98
--- /dev/null
+++ b/jRandomSkills - SRC Files/src/utils/RayTrace.cs
@@ -0,0 +1,299 @@
+using CounterStrikeSharp.API;
+using CounterStrikeSharp.API.Core;
+using CounterStrikeSharp.API.Core.Capabilities;
+using CounterStrikeSharp.API.Modules.Utils;
+using jRandomSkills.src.utils;
+using RayTraceAPI;
+using System.Drawing;
+using System.Numerics;
+using TraceOptions = RayTraceAPI.TraceOptions;
+using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
+
+namespace src.utils
+{
+ public static class RayTrace
+ {
+ private static PluginCapability RayTraceInterface { get; } = new("raytrace:craytraceinterface");
+
+ public static CustomTraceResult? TraceShape(CCSPlayerController player, Vector startPos, Vector endPos, ulong? mask = null, ulong? contents = null)
+ {
+ var playerPawn = player.PlayerPawn.Value;
+ if (playerPawn == null)
+ return null;
+
+ var rayTrace = RayTraceInterface.Get();
+ if (rayTrace == null)
+ return null;
+
+ if (mask == null)
+ {
+ mask = playerPawn.Collision.CollisionAttribute.InteractsWith | (ulong)InteractionLayers.Hitboxes;
+ mask &= ~(ulong)InteractionLayers.PlayerClip;
+ }
+ contents ??= playerPawn.Collision.CollisionGroup;
+
+ bool drawBeam = Config.LoadedConfig.TraceRayBeam;
+
+ TraceOptions options = new()
+ {
+ InteractsWith = (ulong)mask,
+ InteractsExclude = (ulong)contents,
+ DrawBeam = drawBeam == true ? 1 : 0,
+ };
+
+ rayTrace.TraceEndShape(startPos, endPos, playerPawn, options, out TraceResult result);
+
+ return new CustomTraceResult(result, startPos, (ulong)mask, (ulong)contents, drawBeam);
+ }
+
+ public static CustomTraceResult? EyeTrace(CCSPlayerController player)
+ {
+ var playerPawn = player.PlayerPawn.Value;
+ if (playerPawn == null)
+ return null;
+
+ var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
+ if (playerInfo == null) return null;
+
+ float maxDistance = SkillsInfo.GetValue(playerInfo.Skill, "maxDistance");
+ if (maxDistance == 0) maxDistance = 4096f;
+
+ Vector startPos = new(playerPawn.AbsOrigin!.X, playerPawn.AbsOrigin!.Y, playerPawn.AbsOrigin!.Z + playerPawn.ViewOffset.Z);
+ Vector endPos = startPos + SkillUtils.GetForwardVector(playerPawn.EyeAngles) * maxDistance;
+
+ return TraceShape(player, startPos, endPos);
+ }
+
+ public static CustomTraceResult? TraceHullShape(Vector startPos, Vector endPos, CCSPlayerController player, Vector? mins = null, Vector? maxs = null, ulong? mask = null, ulong? contents = null, QAngle? angle = null)
+ {
+ var playerPawn = player.PlayerPawn.Value;
+ if (playerPawn == null)
+ return null;
+
+ var rayTrace = RayTraceInterface.Get();
+ if (rayTrace == null)
+ return null;
+
+ mask ??= playerPawn.Collision.CollisionAttribute.InteractsWith;
+ contents ??= playerPawn.Collision.CollisionGroup;
+
+ bool drawBeam = Config.LoadedConfig.TraceRayBeam;
+
+ TraceOptions options = new()
+ {
+ InteractsWith = (ulong)mask,
+ InteractsExclude = (ulong)contents,
+ DrawBeam = drawBeam == true ? 1 : 0,
+ };
+
+ mins ??= playerPawn.Collision.Mins;
+ maxs ??= playerPawn.Collision.Maxs;
+
+ rayTrace.TraceHullShape(startPos, endPos, mins, maxs, playerPawn, options, out TraceResult result);
+
+ if (drawBeam)
+ {
+ angle ??= new(0, playerPawn.EyeAngles.Y, 0);
+ DrawBoxEdges(startPos, endPos, angle, mins, maxs, Color.Green);
+ }
+
+ return new CustomTraceResult(result, startPos, (ulong)mask, (ulong)contents, drawBeam);
+ }
+
+ private static void DrawBoxEdges(Vector start, Vector end, QAngle angles, Vector mins, Vector maxs, Color color)
+ {
+ AngleVectors(angles, out Vector forward, out Vector right, out Vector up);
+
+ float halfLength = (maxs.X - mins.X) / 2.0f;
+
+ Vector visualStart = start - (forward * halfLength);
+ Vector visualEnd = end + (forward * halfLength);
+
+ Vector GetVertex(Vector center, float rx, float ux)
+ {
+ return center + (right * rx) + (up * ux);
+ }
+
+ Vector[] s = [
+ GetVertex(visualStart, mins.Y, mins.Z),
+ GetVertex(visualStart, maxs.Y, mins.Z),
+ GetVertex(visualStart, maxs.Y, maxs.Z),
+ GetVertex(visualStart, mins.Y, maxs.Z)
+ ];
+
+ Vector[] e = [
+ GetVertex(visualEnd, mins.Y, mins.Z),
+ GetVertex(visualEnd, maxs.Y, mins.Z),
+ GetVertex(visualEnd, maxs.Y, maxs.Z),
+ GetVertex(visualEnd, mins.Y, maxs.Z)
+ ];
+
+ for (int i = 0; i < 4; i++)
+ {
+ int next = (i + 1) % 4;
+ CreateBeamLine(s[i], s[next], color);
+ CreateBeamLine(e[i], e[next], color);
+ CreateBeamLine(s[i], e[i], color);
+ }
+ }
+
+ private static void AngleVectors(QAngle angles, out Vector forward, out Vector right, out Vector up)
+ {
+ float sp, sy, cp, cy, sr, cr;
+
+ float pitch = angles.X * (MathF.PI / 180.0f);
+ float yaw = angles.Y * (MathF.PI / 180.0f);
+ float roll = angles.Z * (MathF.PI / 180.0f);
+
+ sp = MathF.Sin(pitch); cp = MathF.Cos(pitch);
+ sy = MathF.Sin(yaw); cy = MathF.Cos(yaw);
+ sr = MathF.Sin(roll); cr = MathF.Cos(roll);
+
+ forward = new Vector(cp * cy, cp * sy, -sp);
+ right = new Vector(-1 * sr * sp * cy + cr * sy, -1 * sr * sp * sy - cr * cy, -1 * sr * cp);
+ up = new Vector(cr * sp * cy + sr * sy, cr * sp * sy - sr * cy, cr * cp);
+ }
+
+ private static void CreateBeamLine(Vector start, Vector end, Color color)
+ {
+ var beam = Utilities.CreateEntityByName("env_beam");
+ if (beam == null || !beam.IsValid) return;
+
+ beam.Render = color;
+ beam.Width = 1.3f;
+
+ beam.Teleport(start, new QAngle(0, 0, 0), new Vector(0, 0, 0));
+ beam.EndPos.X = end.X;
+ beam.EndPos.Y = end.Y;
+ beam.EndPos.Z = end.Z;
+
+ beam.DispatchSpawn();
+ }
+
+ public static float Distance(this CustomTraceResult result)
+ {
+ return Vector3.Distance(result.StartPos, result.EndPos);
+ }
+
+ public static Vector3 Direction(this CustomTraceResult result)
+ {
+ return Vector3.Normalize(result.EndPos - result.Normal);
+ }
+
+ public static bool HitEntityByDesignerName(this CustomTraceResult result, out T? entity, string designerName, DesignerNameMatchType matchType = DesignerNameMatchType.Equals) where T : CEntityInstance
+ {
+ T? val = (T?)Activator.CreateInstance(typeof(T), result.HitEntity);
+ if ((object?)val != null && matchType switch
+ {
+ DesignerNameMatchType.Equals => val.DesignerName == designerName,
+ DesignerNameMatchType.StartsWith => val.DesignerName.StartsWith(designerName, StringComparison.OrdinalIgnoreCase),
+ DesignerNameMatchType.EndsWith => val.DesignerName.EndsWith(designerName, StringComparison.OrdinalIgnoreCase),
+ _ => false,
+ })
+ {
+ entity = val;
+ return true;
+ }
+
+ entity = null;
+ return false;
+ }
+
+ public static bool HitEntity(this CustomTraceResult result, out CBaseEntity? entity)
+ {
+ CEntityInstance entityInstance = new(result.HitEntity);
+ if (string.IsNullOrEmpty(entityInstance.DesignerName))
+ {
+ entity = null;
+ return false;
+ }
+
+ entity = entityInstance.As();
+ return entity != null;
+ }
+
+ public static bool HitPlayer(this CustomTraceResult result, out CCSPlayerController? player)
+ {
+ if (result.HitEntityByDesignerName(out CCSPlayerPawn? entity, "player"))
+ {
+ player = entity?.OriginalController.Value;
+ return player != null;
+ }
+
+ player = null;
+ return false;
+ }
+
+ public static bool HitWeapon(this CustomTraceResult result, out CBasePlayerWeapon? weapon)
+ {
+ return result.HitEntityByDesignerName(out weapon, "weapon_", DesignerNameMatchType.StartsWith);
+ }
+
+ public static bool HitChicken(this CustomTraceResult result, out CChicken? chicken)
+ {
+ return result.HitEntityByDesignerName(out chicken, "chicken");
+ }
+
+ public static bool HitButton(this CustomTraceResult result, out CBaseButton? button)
+ {
+ return result.HitEntityByDesignerName(out button, "func_door");
+ }
+
+ public static bool HitBuyzone(this CustomTraceResult result, out CBuyZone? buyzone)
+ {
+ return result.HitEntityByDesignerName(out buyzone, "func_buyzone");
+ }
+
+ public static bool HitSky(this CustomTraceResult result, out CEnvSky? sky)
+ {
+ return result.HitEntityByDesignerName(out sky, "env_sky");
+ }
+
+ public static bool HitDoor(this CustomTraceResult result, out CBaseDoor? door)
+ {
+ return result.HitEntityByDesignerName(out door, "func_door");
+ }
+
+ public static bool HitDoor(this CustomTraceResult result, out CRotDoor? door)
+ {
+ return result.HitEntityByDesignerName(out door, "func_door_rotating");
+ }
+
+ public static bool HitLadder(this CustomTraceResult result, out CFuncLadder? ladder)
+ {
+ return result.HitEntityByDesignerName(out ladder, "func_ladder");
+ }
+
+ public static bool HitGrenade(this CustomTraceResult result, out CBaseCSGrenade? grenade)
+ {
+ return result.HitEntityByDesignerName(out grenade, "grenade");
+ }
+
+ public static bool HitPlantedC4(this CustomTraceResult result, out CPlantedC4? c4)
+ {
+ return result.HitEntityByDesignerName(out c4, "planted_c4");
+ }
+
+ public static bool HitPointWorldText(this CustomTraceResult result, out CPointWorldText? pointWorldText)
+ {
+ return result.HitEntityByDesignerName(out pointWorldText, "point_worldtext");
+ }
+
+ public static bool HitC4(this CustomTraceResult result, out CC4? c4)
+ {
+ return result.HitEntityByDesignerName(out c4, "weapon_c4");
+ }
+
+ public static bool HitWorld(this CustomTraceResult result, out CWorld? world)
+ {
+ return result.HitEntityByDesignerName(out world, "worldent");
+ }
+
+ public enum DesignerNameMatchType
+ {
+ Equals,
+ StartsWith,
+ EndsWith
+ }
+ }
+}
diff --git a/jRandomSkills - SRC Files/src/utils/SkillUtils.cs b/jRandomSkills - SRC Files/src/utils/SkillUtils.cs
index 45dd42e..282bfae 100644
--- a/jRandomSkills - SRC Files/src/utils/SkillUtils.cs
+++ b/jRandomSkills - SRC Files/src/utils/SkillUtils.cs
@@ -165,7 +165,11 @@ namespace src.utils
skeleton.Scale = scale;
playerPawn.AcceptInput("SetScale", null, null, scale.ToString(CultureInfo.InvariantCulture));
- Server.NextWorldUpdate(() => Utilities.SetStateChanged(player.PlayerPawn.Value!, "CBaseEntity", "m_CBodyComponent"));
+
+ Server.NextWorldUpdate(() => {
+ if (playerPawn == null || !playerPawn.IsValid) return;
+ Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_CBodyComponent");
+ });
}
public static Vector? GetSpawnPointVector(CCSPlayerController player, bool enemySpawn = false)
@@ -224,6 +228,7 @@ namespace src.utils
if (pawn.Health <= 0)
Server.NextFrame(() =>
{
+ if (pawn == null || !pawn.IsValid) return;
pawn?.CommitSuicide(false, true);
});
}
diff --git a/jRandomSkills - Server Files/gamedata.zip b/jRandomSkills - Server Files/gamedata.zip
new file mode 100644
index 0000000..6f19514
Binary files /dev/null and b/jRandomSkills - Server Files/gamedata.zip differ
diff --git a/jRandomSkills - Server Files/gamedata/jRandomSkills.gamedata.json b/jRandomSkills - Server Files/gamedata/jRandomSkills.gamedata.json
index 713f6f8..7c8be60 100644
--- a/jRandomSkills - Server Files/gamedata/jRandomSkills.gamedata.json
+++ b/jRandomSkills - Server Files/gamedata/jRandomSkills.gamedata.json
@@ -16,15 +16,22 @@
"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"
+ "windows": "48 89 5C 24 ? 57 48 83 EC 20 48 8B 01 48 8B F9 0F BF DA",
+ "linux": "55 48 8D 15 ? ? ? ? 48 89 E5 41 54 41 89 F4 53 48 8B 07 48 89 FB 48 8B 80 ? ? ? ? 48 39 D0 0F 85"
}
},
"SnapViewAngles": {
"signatures": {
"library": "server",
"windows": "48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 55 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B DA 48 8B F1 48 8D 55",
- "linux": "55 48 89 E5 41 57 41 56 41 55 41 54 53 48 89 FB 48 89 F7 48 81 EC ? ? ? ? E8 ? ? ? ? 48 8B 93"
+ "linux": "55 48 89 E5 41 57 49 89 FF 48 89 F7 41 56 41 55 41 54 53 48 81 EC"
+ }
+ },
+ "CCSPlayerController_HandleCommandDrop": {
+ "signatures": {
+ "library": "server",
+ "windows": "48 89 5C 24 ? 57 48 83 EC ? 48 8B FA E8 ? ? ? ? 48 8B D8",
+ "linux": "55 48 89 E5 41 54 49 89 F4 53 E8 ? ? ? ? 48 85 C0 74 ? 48 89 C3"
}
}
}
\ No newline at end of file
diff --git a/jRandomSkills - Server Files/plugins/jRandomSkills/WASDMenuAPI.dll b/jRandomSkills - Server Files/plugins/jRandomSkills/WASDMenuAPI.dll
index d9e5906..4ab424a 100644
Binary files a/jRandomSkills - Server Files/plugins/jRandomSkills/WASDMenuAPI.dll and b/jRandomSkills - Server Files/plugins/jRandomSkills/WASDMenuAPI.dll differ
diff --git a/jRandomSkills - Server Files/plugins/jRandomSkills/configs/config.json b/jRandomSkills - Server Files/plugins/jRandomSkills/configs/config.json
index 8499a7d..a7888c8 100644
--- a/jRandomSkills - Server Files/plugins/jRandomSkills/configs/config.json
+++ b/jRandomSkills - Server Files/plugins/jRandomSkills/configs/config.json
@@ -13,7 +13,7 @@
"DisplayAlwaysDescription": false,
"DisableSpectateHUD": false,
"FlashingHtmlHudFix": true,
- "CS2TraceRayDebug": false,
+ "TraceRayBeam": false,
"DisableHUDOnDeathPermission": "@jRandomSkills/death",
"DisableSkillsOnRoundEnd": false,
"LanguageSystem": {
@@ -130,6 +130,10 @@
"ReloadCommand": {
"Alias": "reload, refresh",
"Permissions": "@jRandomSkills/admin"
+ },
+ "NextCommand": {
+ "Alias": "next_skill",
+ "Permissions": "@jRandomSkills/admin"
}
},
"VotingCommands": {
diff --git a/jRandomSkills - Server Files/plugins/jRandomSkills/configs/skillsInfo.json b/jRandomSkills - Server Files/plugins/jRandomSkills/configs/skillsInfo.json
index d999a49..0430a4a 100644
--- a/jRandomSkills - Server Files/plugins/jRandomSkills/configs/skillsInfo.json
+++ b/jRandomSkills - Server Files/plugins/jRandomSkills/configs/skillsInfo.json
@@ -262,7 +262,7 @@
"RequiredPermission": ""
},
{
- "ZombieHealth": 250,
+ "ZombieHealth": 500,
"NeedsTeammates": false,
"DisableOnFreezeTime": false,
"OnlyTeam": 0,
@@ -323,17 +323,6 @@
"Name": "ReactiveArmor",
"RequiredPermission": ""
},
- {
- "Cooldown": 30.0,
- "Duration": 10.0,
- "NeedsTeammates": false,
- "DisableOnFreezeTime": true,
- "OnlyTeam": 0,
- "Color": "#d0d930",
- "Active": false,
- "Name": "RCMelon",
- "RequiredPermission": ""
- },
{
"Cooldown": 15.0,
"NeedsTeammates": false,
@@ -706,6 +695,7 @@
"RequiredPermission": ""
},
{
+ "ParticleName": "particles/ui/hud/ui_map_def_utility_trail.vpcf",
"NeedsTeammates": false,
"DisableOnFreezeTime": false,
"OnlyTeam": 0,
@@ -747,9 +737,6 @@
"RequiredPermission": ""
},
{
- "MaximumFuel": 150.0,
- "FuelConsumption": 0.64,
- "Refuelling": 0.1,
"NeedsTeammates": false,
"DisableOnFreezeTime": true,
"OnlyTeam": 0,
@@ -1307,7 +1294,6 @@
{
"Cooldown": 20.0,
"Duration": 0.3,
- "Offset": 0.0,
"NeedsTeammates": false,
"DisableOnFreezeTime": true,
"OnlyTeam": 0,
diff --git a/jRandomSkills - Server Files/plugins/jRandomSkills/jRandomSkills.dll b/jRandomSkills - Server Files/plugins/jRandomSkills/jRandomSkills.dll
index dd03173..beff695 100644
Binary files a/jRandomSkills - Server Files/plugins/jRandomSkills/jRandomSkills.dll and b/jRandomSkills - Server Files/plugins/jRandomSkills/jRandomSkills.dll differ