diff --git a/jRandomSkills - SRC Files/jRandomSkills.csproj b/jRandomSkills - SRC Files/jRandomSkills.csproj
index c7dca49..3bcdaa1 100644
--- a/jRandomSkills - SRC Files/jRandomSkills.csproj
+++ b/jRandomSkills - SRC Files/jRandomSkills.csproj
@@ -15,9 +15,9 @@
-
+
-
+
diff --git a/jRandomSkills - SRC Files/src/command/Command.cs b/jRandomSkills - SRC Files/src/command/Command.cs
index 32bac6f..b88aec7 100644
--- a/jRandomSkills - SRC Files/src/command/Command.cs
+++ b/jRandomSkills - SRC Files/src/command/Command.cs
@@ -42,6 +42,7 @@ namespace src.command
{ SplitCommands(config.NormalCommands.HealCommand.Alias), ("Heal", Command_Heal) },
{ SplitCommands(config.NormalCommands.HealthCommand.Alias), ("Set heath", Command_Health) },
{ SplitCommands(config.NormalCommands.PlantedBomb.Alias), ("Spawn planted bomb", Command_PlantedBomb) },
+ { SplitCommands(config.NormalCommands.BotPlace.Alias), ("Place bot on your position", Command_BotPlace) },
{ SplitCommands(config.NormalCommands.HudCommand.Alias), ("Enable/Disable HUD", Command_HUD) },
{ SplitCommands(config.NormalCommands.SetStaticSkillCommand.Alias), ("Set static skill", Command_SetStaticSkill) },
{ SplitCommands(config.NormalCommands.ChangeLanguageCommand.Alias), ("Change language", Command_ChangeLanguage) },
@@ -337,7 +338,7 @@ namespace src.command
if (int.TryParse(command.GetArg(1), out int health))
SkillUtils.AddHealth(pawn, health - pawn.Health, health);
- player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("healed")}");
+ player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("set_health")}");
}
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
@@ -358,7 +359,38 @@ namespace src.command
if (!int.TryParse(command.GetArg(1), out int time))
time = 40;
- bomb.C4Blow = (float)Server.EngineTime + time;
+ bomb.C4Blow = Server.CurrentTime + time;
+ player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("planted_bomb_spawned", [time])}");
+ }
+
+ [CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
+ private static void Command_BotPlace(CCSPlayerController? player, CommandInfo command)
+ {
+ Debug.WriteToDebug($"Player {player?.PlayerName} used the css_bot_place {command.ArgString} command.");
+ if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
+ if (!string.IsNullOrEmpty(config.NormalCommands.BotPlace.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.BotPlace.Permissions)) return;
+
+ var pawn = player.PlayerPawn.Value;
+ if (!player.PawnIsAlive || pawn.AbsOrigin == null || pawn.AbsRotation == null) return;
+
+ if (!int.TryParse(command.GetArg(1), out int botSlot))
+ botSlot = -1;
+
+ var bot = Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.IsBot && p.PawnIsAlive && (botSlot == -1 || p.Slot == botSlot)).FirstOrDefault();
+ if (bot == null || bot.PlayerPawn.Value == null || !bot.PlayerPawn.Value.IsValid)
+ {
+ player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("bot_placed_not_found")}");
+ return;
+ }
+
+ bot.PlayerPawn.Value.Teleport(new Vector(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z), new QAngle(pawn.AbsRotation.X, pawn.AbsRotation.Y, pawn.AbsRotation.Z), Vector.Zero);
+
+ bot.PlayerPawn.Value.TakesDamage = true;
+ if ((bool.TryParse(command.GetArg(2), out bool godmode) && godmode == true)
+ || (int.TryParse(command.GetArg(2), out int godmodeInt) && godmodeInt == 1))
+ bot.PlayerPawn.Value.TakesDamage = false;
+
+ player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("bot_placed")}");
}
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
diff --git a/jRandomSkills - SRC Files/src/jRandomSkills.cs b/jRandomSkills - SRC Files/src/jRandomSkills.cs
index 3274761..26b74d7 100644
--- a/jRandomSkills - SRC Files/src/jRandomSkills.cs
+++ b/jRandomSkills - SRC Files/src/jRandomSkills.cs
@@ -118,8 +118,8 @@ namespace src
public Skills SpecialSkill { get; set; }
public float? SkillChance { get; set; }
public bool IsDrawing { get; set; }
- public DateTime SkillHudExpired { get; set; }
- public DateTime SkillDescriptionHudExpired { get; set; }
+ public DateTime SkillHudExpired { get; set; } = Config.LoadedConfig.SkillHudDuration == -1 ? DateTime.MaxValue : DateTime.Now.AddSeconds(Config.LoadedConfig.SkillHudDuration);
+ public DateTime SkillDescriptionHudExpired { get; set; } = Config.LoadedConfig.SkillDescriptionDuration == -1 ? DateTime.MaxValue : DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration);
public string? PrintHTML { get; set; }
public bool DisplayHUD { get; set; }
public bool SkillUsed = false;
diff --git a/jRandomSkills - SRC Files/src/player/ISkill.cs b/jRandomSkills - SRC Files/src/player/ISkill.cs
index b6ff606..bcb9206 100644
--- a/jRandomSkills - SRC Files/src/player/ISkill.cs
+++ b/jRandomSkills - SRC Files/src/player/ISkill.cs
@@ -32,6 +32,7 @@ public interface ISkill
public static void GrenadeThrown(EventGrenadeThrown _) { }
public static void BombBeginplant(EventBombBeginplant _) { }
+ public static void BombAbortplant(EventBombAbortplant _) { }
public static void BombPlanted(EventBombPlanted _) { }
public static void BombBegindefuse(EventBombBegindefuse _) { }
@@ -121,6 +122,7 @@ public enum Skills
Magneto,
Magnifier,
Medic,
+ Miner,
MoneySwap,
Muhammed,
Ninja,
diff --git a/jRandomSkills - SRC Files/src/player/PlayerEvents.cs b/jRandomSkills - SRC Files/src/player/PlayerEvents.cs
index 2718ecc..0085c12 100644
--- a/jRandomSkills - SRC Files/src/player/PlayerEvents.cs
+++ b/jRandomSkills - SRC Files/src/player/PlayerEvents.cs
@@ -8,6 +8,9 @@ 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 src.player.skills;
using src.utils;
using System.Collections.Concurrent;
@@ -58,6 +61,7 @@ namespace src.player
Instance.RegisterEventHandler(GrenadeThrown);
Instance.RegisterEventHandler(BombBeginplant);
+ Instance.RegisterEventHandler(BombAbortplant);
Instance.RegisterEventHandler(BombPlanted);
Instance.RegisterEventHandler(BombBegindefuse);
@@ -82,9 +86,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "PlayerMakeSound", [um]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "PlayerMakeSound", [um]);
return HookResult.Continue;
}
}
@@ -93,9 +101,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "WeaponFire", [@event]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "WeaponFire", [@event]);
return HookResult.Continue;
}
}
@@ -104,9 +116,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "WeaponEquip", [@event]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "WeaponEquip", [@event]);
return HookResult.Continue;
}
}
@@ -115,9 +131,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "WeaponPickup", [@event]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "WeaponPickup", [@event]);
return HookResult.Continue;
}
}
@@ -126,9 +146,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "WeaponReload", [@event]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "WeaponReload", [@event]);
return HookResult.Continue;
}
}
@@ -137,9 +161,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "GrenadeThrown", [@event]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "GrenadeThrown", [@event]);
return HookResult.Continue;
}
}
@@ -148,9 +176,28 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "BombBeginplant", [@event]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "BombBeginplant", [@event]);
+ return HookResult.Continue;
+ }
+ }
+
+ private static HookResult BombAbortplant(EventBombAbortplant @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, "BombAbortplant", [@event]);
return HookResult.Continue;
}
}
@@ -159,9 +206,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "BombPlanted", [@event]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "BombPlanted", [@event]);
return HookResult.Continue;
}
}
@@ -170,9 +221,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "BombBegindefuse", [@event]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "BombBegindefuse", [@event]);
return HookResult.Continue;
}
}
@@ -181,9 +236,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "DecoyStarted", [@event]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "DecoyStarted", [@event]);
return HookResult.Continue;
}
}
@@ -192,9 +251,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "DecoyDetonate", [@event]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "DecoyDetonate", [@event]);
return HookResult.Continue;
}
}
@@ -203,9 +266,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "SmokegrenadeDetonate", [@event]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "SmokegrenadeDetonate", [@event]);
return HookResult.Continue;
}
}
@@ -214,9 +281,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "SmokegrenadeExpired", [@event]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "SmokegrenadeExpired", [@event]);
return HookResult.Continue;
}
}
@@ -225,9 +296,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "PlayerHurt", [@event]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "PlayerHurt", [@event]);
return HookResult.Continue;
}
}
@@ -236,9 +311,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "PlayerJump", [@event]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "PlayerJump", [@event]);
return HookResult.Continue;
}
}
@@ -247,9 +326,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "PlayerBlind", [@event]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "PlayerBlind", [@event]);
return HookResult.Continue;
}
}
@@ -258,9 +341,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "OnTakeDamage", [h]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "OnTakeDamage", [h]);
return HookResult.Continue;
}
}
@@ -272,9 +359,13 @@ namespace src.player
CBaseTrigger trigger = hook.GetParam(0);
CBaseEntity entity = hook.GetParam(1);
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "OnTriggerEnter", [trigger, entity]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "OnTriggerEnter", [trigger, entity]);
return HookResult.Continue;
}
}
@@ -286,9 +377,13 @@ namespace src.player
CBaseTrigger trigger = hook.GetParam(0);
CBaseEntity entity = hook.GetParam(1);
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "OnTriggerExit", [trigger, entity]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "OnTriggerExit", [trigger, entity]);
return HookResult.Continue;
}
}
@@ -297,12 +392,18 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- if (SkillsInfo.GetValue(playerSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
- return;
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill)
+ .Distinct()
+ .OrderBy(skill => skill.ToString() == "AreaReaper")
+ .ThenBy(skill => skill.ToString() == "ChillOut");
+
+ foreach (var skill in activeSkills)
+ if (SkillsInfo.GetValue(skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
+ continue;
else
- Instance.SkillAction(playerSkill.Skill.ToString(), "OnTick");
+ Instance.SkillAction(skill.ToString(), "OnTick");
}
}
@@ -528,9 +629,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "PlayerDeath", [@event]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "PlayerDeath", [@event]);
var victim = @event.Userid;
var attacker = @event.Attacker;
@@ -562,28 +667,48 @@ namespace src.player
private static void CheckUseSkill(CCSPlayerController player, PlayerButtons pressed, PlayerButtons released)
{
+ if (player == null || !player.IsValid || !player.PawnIsAlive) return;
+
lock (setLock)
{
string? button = Config.LoadedConfig.AlternativeSkillButton;
if (string.IsNullOrEmpty(button) || button.Length < 2) return;
+
string buttonName = $"{char.ToUpper(button[0])}{button[1..].ToLower()}";
+ if (!Enum.TryParse(buttonName, out var skillButton)) return;
- if (Enum.TryParse(buttonName, out var skillButton))
- {
- if (pressed != skillButton) return;
- }
- else return;
+ if ((pressed & skillButton) == 0) return;
- if (player == null) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo == null || playerInfo.IsDrawing) return;
if (SkillsInfo.GetValue(playerInfo.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
return;
- var playerPawn = player.PlayerPawn.Value;
- if (playerPawn?.CBodyComponent == null) return;
- if (!player.IsValid || !player.PawnIsAlive) return;
+ if (skillButton == PlayerButtons.Use)
+ {
+ var pawn = player.PlayerPawn.Value;
+ if (pawn == null || !pawn.IsValid) return;
+ if (pawn.AbsOrigin == null || pawn.AbsRotation == null) return;
+
+ if (pawn.IsDefusing) return;
+
+ 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 contents = 0;
+ CGameTrace trace = TraceRay.TraceShape(eyePos, endPos, mask, contents, player);
+
+ if (trace.DidHit())
+ {
+ var entity = Activator.CreateInstance(typeof(CBaseEntity), trace.HitEntity) as CBaseEntity;
+ if (entity == null || !entity.IsValid) return;
+
+ string designer = entity.DesignerName;
+ if (designer.Contains("door") || designer.Contains("button") || designer.Contains("weapon") || designer.Contains("blocker")) return;
+ }
+ }
Debug.WriteToDebug($"Player {player.PlayerName} used the skill: {playerInfo.Skill} by PlayerButtons: {pressed}");
Instance.SkillAction(playerInfo.Skill.ToString(), "UseSkill", [player]);
@@ -594,9 +719,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "OnEntitySpawned", [entity]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "OnEntitySpawned", [entity]);
}
}
@@ -722,8 +851,12 @@ namespace src.player
});
Debug.WriteToDebug($"Player {skillPlayer.PlayerName} has got the skill \"{player.GetSkillName(randomSkill.Skill)}\".");
- skillPlayer.SkillHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillHudDuration);
- skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration);
+
+ float hudExpired = Config.LoadedConfig.SkillHudDuration;
+ skillPlayer.SkillHudExpired = hudExpired == -1 ? DateTime.MaxValue : DateTime.Now.AddSeconds(hudExpired);
+
+ float descriptionHudExpired = Config.LoadedConfig.SkillHudDuration;
+ skillPlayer.SkillDescriptionHudExpired = descriptionHudExpired == -1 ? DateTime.MaxValue : DateTime.Now.AddSeconds(descriptionHudExpired);
if (Config.LoadedConfig.TeamMateSkillChatInfo)
{
@@ -859,9 +992,13 @@ namespace src.player
{
lock (setLock)
{
- foreach (var playerSkill in Instance.SkillPlayer)
- if (!playerSkill.IsDrawing)
- Instance.SkillAction(playerSkill.Skill.ToString(), "CheckTransmit", [infoList]);
+ var activeSkills = Instance.SkillPlayer
+ .Where(p => !p.IsDrawing)
+ .Select(p => p.Skill.ToString())
+ .Distinct();
+
+ foreach (string skillName in activeSkills)
+ Instance.SkillAction(skillName, "CheckTransmit", [infoList]);
}
}
diff --git a/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs b/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs
index 0412210..4bfd430 100644
--- a/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs
+++ b/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs
@@ -121,6 +121,7 @@ namespace src.player
if (string.IsNullOrEmpty(skillLine)) return;
if (player == null || !player.IsValid) return;
if (SkillUtils.HasMenu(player)) return;
+
Event.UpdateSkillHUD(player, infoLine, skillLine, remainingLine, isDescription);
}
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/AimLock.cs b/jRandomSkills - SRC Files/src/player/skills/AimLock.cs
index 932c7d5..d38d39f 100644
--- a/jRandomSkills - SRC Files/src/player/skills/AimLock.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/AimLock.cs
@@ -31,7 +31,12 @@ namespace src.player.skills
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo?.Skill == skillName)
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
+ {
UpdateHUD(player, skillInfo);
+
+ if (skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue(skillName, "duration")) > DateTime.Now)
+ LookAtEnemey(player);
+ }
}
}
@@ -100,7 +105,7 @@ namespace src.player.skills
foreach (var enemy in Utilities.GetPlayers().Where(p => p.IsValid && p.PawnIsAlive && p.Team != player.Team))
{
var enemyPawn = enemy.PlayerPawn.Value;
- if (enemyPawn == null || !enemyPawn.IsValid || enemyPawn.AbsOrigin == null) return;
+ if (enemyPawn == null || !enemyPawn.IsValid || enemyPawn.AbsOrigin == null) continue;
double dist = SkillUtils.GetDistance(enemyPawn.AbsOrigin, pawn.AbsOrigin);
if (dist < minDist)
@@ -112,11 +117,13 @@ namespace src.player.skills
if (closetEnemy != null)
{
- Vector enemyPos = closetEnemy.PlayerPawn.Value!.AbsOrigin!;
- Vector myPos = pawn.AbsOrigin;
+ var enemyPawn = closetEnemy.PlayerPawn.Value;
+ 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 = enemyPos - myPos;
+ Vector direction = enemyEyePos - myEyePos;
QAngle angle = VectorToAngle(direction);
pawn.Look(angle);
@@ -138,9 +145,11 @@ 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 = 5f) : 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, float offsetZ = 0) : 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/AreaReaper.cs b/jRandomSkills - SRC Files/src/player/skills/AreaReaper.cs
index 588ed2d..12a50af 100644
--- a/jRandomSkills - SRC Files/src/player/skills/AreaReaper.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/AreaReaper.cs
@@ -1,8 +1,8 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
-using static src.jRandomSkills;
using src.utils;
+using static src.jRandomSkills;
namespace src.player.skills
{
@@ -21,7 +21,6 @@ namespace src.player.skills
{
foreach (var player in Utilities.GetPlayers())
SkillUtils.CloseMenu(player);
- Instance.AddTimer(0.1f, EnableBombsite);
}
public static void TypeSkill(CCSPlayerController player, string[] commands)
@@ -44,7 +43,9 @@ namespace src.player.skills
var bombTargets = Utilities.FindAllEntitiesByDesignerName("func_bomb_target").ToArray();
if (bombTargets.Length == 2)
{
- bombTargets[site].AcceptInput("Disable");
+ bombTargets[site].BombPlantedHere = true;
+ Utilities.SetStateChanged(bombTargets[site], "CBombTarget", "m_bBombPlantedHere");
+
playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("areareaper_site_disabled", (site == 0 ? 'A' : 'B'))}");
}
@@ -63,16 +64,43 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
SkillUtils.CloseMenu(player);
- if (Instance.SkillPlayer.FirstOrDefault(p => p.Skill == skillName) != null) return;
- EnableBombsite();
-
+ Server.NextWorldUpdate(() =>
+ {
+ if (Instance.SkillPlayer.FirstOrDefault(p => p.Skill == skillName) != null) return;
+ EnableBombsite();
+ });
}
private static void EnableBombsite()
{
var bombTargets = Utilities.FindAllEntitiesByDesignerName("func_bomb_target");
foreach (var bombTarget in bombTargets)
- bombTarget.AcceptInput("Enable");
+ {
+ bombTarget.BombPlantedHere = false;
+ Utilities.SetStateChanged(bombTarget, "CBombTarget", "m_bBombPlantedHere");
+ }
+ }
+
+ public static void OnTick()
+ {
+ var bombTargets = Utilities.FindAllEntitiesByDesignerName("func_bomb_target");
+ foreach (var player in Utilities.GetPlayers().Where(p => p.Team == CsTeam.Terrorist))
+ {
+ if (!Instance.IsPlayerValid(player)) continue;
+
+ var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
+ if (playerInfo?.Skill == null) continue;
+
+ var pawn = player.PlayerPawn.Value;
+ if (pawn == null || !pawn.IsValid) continue;
+
+ if (pawn.WeaponServices == null) continue;
+ var activeWeapon = pawn.WeaponServices.ActiveWeapon.Value;
+ if (activeWeapon == null || !activeWeapon.IsValid || activeWeapon.DesignerName != "weapon_c4") continue;
+
+ if (!pawn.InBombZone && pawn.InBombZoneTrigger)
+ player.PrintToCenterAlert(player.GetTranslation("areareaper_bombsite_disabled"));
+ }
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#edf5b5", CsTeam onlyTeam = CsTeam.CounterTerrorist, 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/ChillOut.cs b/jRandomSkills - SRC Files/src/player/skills/ChillOut.cs
index c9deaac..6850385 100644
--- a/jRandomSkills - SRC Files/src/player/skills/ChillOut.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/ChillOut.cs
@@ -2,6 +2,7 @@ using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
+using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills
@@ -9,16 +10,38 @@ namespace src.player.skills
public class ChillOut : ISkill
{
private const Skills skillName = Skills.ChillOut;
+ private static readonly ConcurrentDictionary plantingPlayers = [];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"));
}
+ public static void NewRound()
+ {
+ plantingPlayers.Clear();
+ }
+
+ public static void DisableSkill(CCSPlayerController player)
+ {
+ if (player == null || !player.IsValid) return;
+ plantingPlayers.TryRemove(player.SteamID, out _);
+ SkillUtils.ResetPrintHTML(player);
+ }
+
+ public static void BombAbortplant(EventBombAbortplant @event)
+ {
+ var user = @event.Userid;
+ if (user == null || !user.IsValid || !user.PawnIsAlive) return;
+ plantingPlayers.TryRemove(user.SteamID, out _);
+ SkillUtils.ResetPrintHTML(user);
+ }
+
public static void BombBeginplant(EventBombBeginplant @event)
{
var player = @event.Userid;
if (!Instance.IsPlayerValid(player)) return;
+ plantingPlayers.TryAdd(player!.SteamID, Server.CurrentTime);
var anyChillOut = Instance.SkillPlayer.FirstOrDefault(p => p.Skill == skillName);
if (anyChillOut != null)
@@ -33,6 +56,42 @@ namespace src.player.skills
}
}
+ public static void BombPlanted(EventBombPlanted @event)
+ {
+ var player = @event.Userid;
+ if (!Instance.IsPlayerValid(player)) return;
+ plantingPlayers.TryRemove(player!.SteamID, out _);
+ SkillUtils.ResetPrintHTML(player);
+ }
+
+ public static void OnTick()
+ {
+ float currentTime = Server.CurrentTime;
+ float extraTime = SkillsInfo.GetValue(skillName, "bombArmedTime");
+
+ foreach (var player in Utilities.GetPlayers().Where(p => p.Team == CsTeam.Terrorist))
+ {
+ if (!Instance.IsPlayerValid(player)) continue;
+
+ var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
+ if (playerInfo == null) continue;
+
+ var pawn = player.PlayerPawn.Value;
+ if (pawn == null || !pawn.IsValid) continue;
+
+ if (pawn.WeaponServices == null) continue;
+ var activeWeapon = pawn.WeaponServices.ActiveWeapon.Value;
+ if (activeWeapon == null || !activeWeapon.IsValid || activeWeapon.DesignerName != "weapon_c4") continue;
+
+ if (plantingPlayers.TryGetValue(player.SteamID, out float plantTime))
+ {
+ float remaining = plantTime + extraTime - currentTime;
+ playerInfo.PrintHTML = $"{player.GetTranslation("planter_planting", $"{Math.Max(0, remaining):0.0}s")}";
+ player.PrintToCenter("");
+ }
+ }
+ }
+
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#343deb", CsTeam onlyTeam = CsTeam.CounterTerrorist, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float bombArmedTime = 10f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public float BombArmedTime { get; set; } = bombArmedTime;
diff --git a/jRandomSkills - SRC Files/src/player/skills/HomingNades.cs b/jRandomSkills - SRC Files/src/player/skills/HomingNades.cs
index e427aff..9fa7317 100644
--- a/jRandomSkills - SRC Files/src/player/skills/HomingNades.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/HomingNades.cs
@@ -11,7 +11,7 @@ namespace src.player.skills
public class HomingNades : ISkill
{
private const Skills skillName = Skills.HomingNades;
- private readonly static ConcurrentDictionary nades = [];
+ private readonly static ConcurrentDictionary nades = [];
public static void LoadSkill()
{
@@ -30,7 +30,7 @@ namespace src.player.skills
foreach (var index in nades.Keys.ToList())
{
if (!nades.TryGetValue(index, out var data)) continue;
- (Vector oldPos, double createdTime) = data;
+ Vector oldPos = data;
var nade = Utilities.GetEntityFromIndex((int)index);
if (nade == null || !nade.IsValid || nade.AbsOrigin == null)
@@ -43,14 +43,13 @@ namespace src.player.skills
double distanceMoved = SkillUtils.GetDistance(currentPos, oldPos);
Vector calculatedVelocity = CalculateVelocity(nade, nade.TeamNum);
- Server.PrintToChatAll($"Dist: {distanceMoved}, vel: {calculatedVelocity}");
+ bool isZero = calculatedVelocity.IsZero();
- if (distanceMoved < 4 || calculatedVelocity.IsZero())
+ if (distanceMoved < 4 || isZero)
{
- Server.PrintToChatAll($"Short, {Server.TickedTime} -> {createdTime + 3}, {createdTime + 3 - Server.TickedTime}s");
-
- nade.DetonateTime = (float)createdTime + 3;
+ nade.DetonateTime = isZero ? 0 : nade.CreateTime + 3;
Utilities.SetStateChanged(nade, "CBaseGrenade", "m_flDetonateTime");
+
nades.TryRemove(index, out _);
continue;
}
@@ -63,7 +62,7 @@ namespace src.player.skills
if (speed > maxVelocity)
newVelocity *= (maxVelocity / speed);
- nades[index] = (currentPos, createdTime);
+ nades[index] = currentPos;
nade.Teleport(null, null, newVelocity);
}
}
@@ -84,9 +83,6 @@ namespace src.player.skills
double dist = SkillUtils.GetDistance(nadePos, pawn.AbsOrigin);
if (dist < SkillsInfo.GetValue(skillName, "detonationRange"))
{
- nade.DetonateTime = 0;
- Utilities.SetStateChanged(nade, "CBaseGrenade", "m_flDetonateTime");
-
nades.TryRemove(nade.Index, out _);
return Vector.Zero;
}
@@ -134,10 +130,15 @@ namespace src.player.skills
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo?.Skill != skillName) return;
- grenade.DetonateTime = (float)Server.TickedTime + 6;
-
Vector pos = new(grenade.AbsOrigin?.X, grenade.AbsOrigin?.Y, grenade.AbsOrigin?.Z);
- nades.TryAdd(grenade.Index, (pos, Server.TickedTime));
+ nades.TryAdd(grenade.Index, pos);
+
+ Server.NextWorldUpdate(() =>
+ {
+ if (grenade == null || !grenade.IsValid) return;
+ grenade.DetonateTime += 100f;
+ Utilities.SetStateChanged(grenade, "CBaseGrenade", "m_flDetonateTime");
+ });
}
public static void EnableSkill(CCSPlayerController player)
diff --git a/jRandomSkills - SRC Files/src/player/skills/Miner.cs b/jRandomSkills - SRC Files/src/player/skills/Miner.cs
new file mode 100644
index 0000000..e39871e
--- /dev/null
+++ b/jRandomSkills - SRC Files/src/player/skills/Miner.cs
@@ -0,0 +1,113 @@
+using CounterStrikeSharp.API;
+using CounterStrikeSharp.API.Core;
+using CounterStrikeSharp.API.Modules.Entities.Constants;
+using CounterStrikeSharp.API.Modules.Utils;
+using src.utils;
+using System.Collections.Concurrent;
+using static src.jRandomSkills;
+
+namespace src.player.skills
+{
+ public class Miner : ISkill
+ {
+ private const Skills skillName = Skills.Miner;
+ private readonly static ConcurrentDictionary nades = [];
+
+ public static void LoadSkill()
+ {
+ SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"));
+ }
+
+ public static void NewRound()
+ {
+ nades.Clear();
+ }
+
+ public static void OnTick()
+ {
+ if (Server.TickCount % 10 != 0) return;
+ float detonationRange = SkillsInfo.GetValue(skillName, "detonationRange");
+ float currentTime = Server.CurrentTime;
+
+ foreach (var index in nades.Keys.ToList())
+ {
+ var nade = Utilities.GetEntityFromIndex((int)index);
+ if (nade == null || !nade.IsValid || nade.AbsOrigin == null)
+ {
+ nades.TryRemove(index, out _);
+ continue;
+ }
+
+ if (nade.CreateTime + 3 > currentTime) return;
+ Vector currentPos = new(nade.AbsOrigin.X, nade.AbsOrigin.Y, nade.AbsOrigin.Z);
+
+ foreach (var enemy in Utilities.GetPlayers().Where(p => p.IsValid && p.PawnIsAlive && p.TeamNum != nade.TeamNum))
+ {
+ var enemyPawn = enemy.PlayerPawn.Value;
+ if (enemyPawn == null || !enemyPawn.IsValid || enemyPawn.AbsOrigin == null) continue;
+
+ Vector enemyPos = new(enemyPawn.AbsOrigin.X, enemyPawn.AbsOrigin.Y, enemyPawn.AbsOrigin.Z);
+ double distance = SkillUtils.GetDistance(currentPos, enemyPos);
+
+ if (distance <= detonationRange)
+ {
+ Detonate(nade);
+ nades.TryRemove(index, out _);
+ break;
+ }
+ }
+ }
+ }
+
+ private static void Detonate(CBaseCSGrenadeProjectile grenade)
+ {
+ if (grenade == null || !grenade.IsValid || grenade.AbsOrigin == null) return;
+
+ Vector position = grenade.AbsOrigin;
+ position.Z += 60;
+ grenade.Teleport(position);
+
+ grenade.EmitSound("IncGrenade.Bounce_M");
+
+ grenade.DetonateTime = Server.CurrentTime + .5f;
+ Utilities.SetStateChanged(grenade, "CBaseGrenade", "m_flDetonateTime");
+ }
+
+ public static void OnEntitySpawned(CEntityInstance @event)
+ {
+ var name = @event.DesignerName;
+ if (name != "hegrenade_projectile") return;
+
+ var grenade = @event.As();
+ if (grenade == null || !grenade.IsValid) return;
+
+ if (grenade.OwnerEntity.Value == null || !grenade.OwnerEntity.Value.IsValid) return;
+ var pawn = grenade.OwnerEntity.Value.As();
+
+ if (pawn.Controller.Value == null || !pawn.Controller.Value.IsValid) return;
+ var player = pawn.Controller.Value.As();
+
+ var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
+ if (playerInfo?.Skill != skillName) return;
+
+ nades.TryAdd(grenade.Index, 0);
+
+ Server.NextWorldUpdate(() =>
+ {
+ if (grenade == null || !grenade.IsValid) return;
+ grenade.DetonateTime = float.MaxValue;
+ Utilities.SetStateChanged(grenade, "CBaseGrenade", "m_flDetonateTime");
+ });
+ }
+
+ public static void EnableSkill(CCSPlayerController player)
+ {
+ SkillUtils.TryGiveWeapon(player, CsItem.HEGrenade);
+ }
+
+ public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#adf542", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float detonationRange = 130) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
+ {
+ public float DetonationRange { get; set; } = detonationRange;
+ }
+ }
+}
\ No newline at end of file
diff --git a/jRandomSkills - SRC Files/src/player/skills/Muhammed.cs b/jRandomSkills - SRC Files/src/player/skills/Muhammed.cs
index a407a1d..a73459b 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Muhammed.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Muhammed.cs
@@ -1,7 +1,9 @@
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 static src.jRandomSkills;
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
@@ -11,20 +13,37 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Muhammed;
private static readonly QAngle angle = new(10, -5, 9);
+ private static readonly ConcurrentDictionary nades = [];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"));
}
+ public static void NewRound()
+ {
+ nades.Clear();
+ }
+
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (!IsDeadPlayerValid(player)) return;
- var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
- if (playerInfo?.Skill == skillName)
- SpawnExplosion(player!);
+ CsTeam lastTeam = player!.Team;
+
+ Server.NextWorldUpdate(() =>
+ {
+
+ if (player == null || !player.IsValid || player.Team != lastTeam) return;
+
+ var pawn = player.PlayerPawn.Value;
+ if (pawn == null || !pawn.IsValid || pawn.Health == pawn.MaxHealth) return;
+
+ var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
+ if (playerInfo?.Skill == skillName)
+ SpawnExplosion(player!);
+ });
}
private static void SpawnExplosion(CCSPlayerController player)
@@ -32,7 +51,7 @@ namespace src.player.skills
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
- Vector pos = pawn.AbsOrigin;
+ Vector pos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z);
pos.Z += 10;
SkillUtils.CreateHEGrenadeProjectile(pos, angle, new Vector(0, 0, -10), player.TeamNum);
@@ -44,6 +63,8 @@ namespace src.player.skills
var fileNames = new[] { "radiobotfallback01", "radiobotfallback02", "radiobotfallback04" };
var randomFile = fileNames[new Random().Next(fileNames.Length)];
player.ExecuteClientCommand($"play vo/agents/balkan/{randomFile}.vsnd");
+
+ nades.AddOrUpdate(Server.TickCount, player.TeamNum, (_, _) => player.TeamNum);
}
public static void OnEntitySpawned(CEntityInstance entity)
@@ -53,6 +74,8 @@ namespace src.player.skills
var heProjectile = entity.As();
if (heProjectile == null || !heProjectile.IsValid || heProjectile.AbsRotation == null) return;
+ int lastTick = Server.TickCount;
+
Server.NextFrame(() =>
{
if (heProjectile == null || !heProjectile.IsValid) return;
@@ -63,9 +86,37 @@ namespace src.player.skills
heProjectile.Damage = SkillsInfo.GetValue(skillName, "explosionDamage");
heProjectile.DmgRadius = SkillsInfo.GetValue(skillName, "explosionRadius");
heProjectile.DetonateTime = 0;
+
+ if (nades.TryRemove(lastTick, out byte teamNum))
+ heProjectile.Globalname = $"muhammed_team_{teamNum}_{heProjectile.Index}";
});
}
+ 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;
+
+ var nade = param2.Attacker.Value;
+ if (nade == null || !nade.IsValid) return;
+
+ if (nade.DesignerName != "hegrenade_projectile") return;
+ if (string.IsNullOrEmpty(nade.Globalname) || !nade.Globalname.StartsWith("muhammed_team_")) return;
+
+ if (!int.TryParse(nade.Globalname.Split('_')[2], out int nadeTeam)) return;
+
+ CCSPlayerPawn victimPawn = new(param.Handle);
+
+ if (victimPawn.DesignerName != "player") return;
+ if (victimPawn == null || victimPawn.Controller?.Value == null) return;
+ if (victimPawn.TeamNum != nadeTeam) return;
+
+ float reduction = SkillsInfo.GetValue(skillName, "dmgReductionForTeamates");
+ param2.Damage *= 1f - Math.Clamp(reduction, 0f, 1f);
+ }
+
private static bool NearlyEquals(float a, float b, float epsilon = 0.001f) => Math.Abs(a - b) < epsilon;
private static bool IsDeadPlayerValid(CCSPlayerController? player)
@@ -73,12 +124,11 @@ namespace src.player.skills
return player != null && player.IsValid && player.PlayerPawn?.Value != null;
}
- public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#F5CB42", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float explosionRadius = 500.0f, int explosionDamage = 999, float dmgReductionForTeamates = .5f, bool explosionAfterWorldDeath = true) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
+ public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#F5CB42", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float explosionRadius = 500.0f, int explosionDamage = 999, float dmgReductionForTeamates = .5f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public float ExplosionRadius { get; set; } = explosionRadius;
public int ExplosionDamage { get; set; } = explosionDamage;
public float DmgReductionForTeamates { get; set; } = dmgReductionForTeamates;
- public bool ExplosionAfterWorldDeath { get; set; } = explosionAfterWorldDeath;
}
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Planter.cs b/jRandomSkills - SRC Files/src/player/skills/Planter.cs
index 06c9d16..1697e03 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Planter.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Planter.cs
@@ -3,6 +3,7 @@ using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
+using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills
@@ -10,42 +11,91 @@ namespace src.player.skills
public class Planter : ISkill
{
private const Skills skillName = Skills.Planter;
+ private static readonly ConcurrentDictionary plantingPlayers = [];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue(skillName, "color"));
}
+ public static void BombBeginplant(EventBombBeginplant @event)
+ {
+ var user = @event.Userid;
+ if (user == null || !user.IsValid || !user.PawnIsAlive) return;
+ plantingPlayers.TryAdd(user.SteamID, Server.CurrentTime);
+ }
+
+ public static void BombAbortplant(EventBombAbortplant @event)
+ {
+ var user = @event.Userid;
+ if (user == null || !user.IsValid || !user.PawnIsAlive) return;
+ plantingPlayers.TryRemove(user.SteamID, out _);
+ SkillUtils.ResetPrintHTML(user);
+ }
+
public static void BombPlanted(EventBombPlanted @event)
{
var player = @event.Userid;
if (!Instance.IsPlayerValid(player)) return;
+ plantingPlayers.TryRemove(player!.SteamID, out _);
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
if (playerInfo?.Skill != skillName) return;
+ playerInfo.PrintHTML = null;
var plantedBomb = Utilities.FindAllEntitiesByDesignerName("planted_c4").FirstOrDefault();
if (plantedBomb != null)
- Server.NextFrame(() => plantedBomb.C4Blow = (float)Server.EngineTime + SkillsInfo.GetValue(skillName, "extraC4BlowTime"));
+ Server.NextFrame(() => plantedBomb.C4Blow = Server.CurrentTime + SkillsInfo.GetValue(skillName, "extraC4BlowTime"));
- player!.PrintToCenterAlert(player.GetTranslation("bombplanted", SkillsInfo.GetValue(skillName, "extraC4BlowTime")));
+ foreach (var p in Utilities.GetPlayers().Where(p => p.IsValid && p.PawnIsAlive))
+ p.PrintToCenterAlert(p.GetTranslation("bombplanted", SkillsInfo.GetValue(skillName, "extraC4BlowTime")));
+ }
+
+ public static void NewRound()
+ {
+ foreach (var player in Utilities.GetPlayers())
+ DisableSkill(player);
+ plantingPlayers.Clear();
}
public static void DisableSkill(CCSPlayerController player)
{
- if (!Instance.IsPlayerValid(player)) return;
- Schema.SetSchemaValue(player!.PlayerPawn.Value!.Handle, "CCSPlayerPawn", "m_bInBombZone", false);
+ if (player == null || !player.IsValid) return;
+ plantingPlayers.TryRemove(player.SteamID, out _);
+ SkillUtils.ResetPrintHTML(player);
+
+ var pawn = player.PlayerPawn.Value;
+ if (pawn == null || !pawn.IsValid) return;
+
+ Schema.SetSchemaValue(pawn!.Handle, "CCSPlayerPawn", "m_bInBombZone", false);
}
public static void OnTick()
{
- foreach (var player in Utilities.GetPlayers())
+ float currentTime = Server.CurrentTime;
+ foreach (var player in Utilities.GetPlayers().Where(p => p.Team == CsTeam.Terrorist))
{
if (!Instance.IsPlayerValid(player)) continue;
- var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
- if (playerInfo?.Skill == skillName)
- Schema.SetSchemaValue(player!.PlayerPawn.Value!.Handle, "CCSPlayerPawn", "m_bInBombZone", true);
+ var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
+ if (playerInfo?.Skill != skillName) continue;
+
+ var pawn = player.PlayerPawn.Value;
+ if (pawn == null || !pawn.IsValid) continue;
+
+ if (pawn.WeaponServices == null) continue;
+ var activeWeapon = pawn.WeaponServices.ActiveWeapon.Value;
+ if (activeWeapon == null || !activeWeapon.IsValid || activeWeapon.DesignerName != "weapon_c4") continue;
+
+ pawn.InBombZone = true;
+ Schema.SetSchemaValue(pawn.Handle, "CCSPlayerPawn", "m_bInBombZone", true);
+
+ if (plantingPlayers.TryGetValue(player.SteamID, out float plantTime))
+ {
+ float remaining = plantTime + 3f - currentTime;
+ playerInfo.PrintHTML = $"{player.GetTranslation("planter_planting", $"{Math.Max(0, remaining):0.0}s")}";
+ player.PrintToCenter("");
+ }
}
}
diff --git a/jRandomSkills - SRC Files/src/player/skills/Shade.cs b/jRandomSkills - SRC Files/src/player/skills/Shade.cs
index e2c3651..bd85b22 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Shade.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Shade.cs
@@ -61,6 +61,8 @@ namespace src.player.skills
foreach (var item in noSpace)
if (item.Value >= Server.TickCount)
UpdateHUD(item.Key);
+ else
+ SkillUtils.ResetPrintHTML(item.Key);
}
private static void UpdateHUD(CCSPlayerController player)
@@ -75,11 +77,40 @@ namespace src.player.skills
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.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);
+
ulong mask = pawn.Collision.CollisionAttribute.InteractsWith;
ulong contents = pawn.Collision.CollisionGroup;
CGameTrace trace = TraceRay.TraceShape(startPos, endPos, mask, contents, player);
- return !trace.HitWorld(out _);
+ if (trace.DidHit()) return false;
+ return IsPositionSafe(player, endPos);
+ }
+
+ 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;
}
private static void TeleportAttackerBehindVictim(CCSPlayerController attacker, CCSPlayerController victim)
@@ -89,22 +120,29 @@ namespace src.player.skills
if (victimPawn == null || attackerPawn == null || victimPawn.AbsOrigin == null || victimPawn.AbsRotation == null) return;
- QAngle victimAngles = victimPawn.AbsRotation;
- Vector victimEyePos = new(victimPawn.AbsOrigin.X, victimPawn.AbsOrigin.Y, victimPawn.AbsOrigin.Z + victimPawn.ViewOffset.Z);
- int[] angles = [0, 90, -90];
+ Vector victimPos = new(victimPawn.AbsOrigin.X, victimPawn.AbsOrigin.Y, victimPawn.AbsOrigin.Z);
+ QAngle victimAngles = new(victimPawn.AbsRotation.X, victimPawn.AbsRotation.Y, victimPawn.AbsRotation.Z);
+ float distance = SkillsInfo.GetValue(skillName, "teleportDistance");
+ int[] angles = [0, 90, -90];
bool teleported = false;
+
foreach (int extraAngle in angles)
{
- QAngle newAngle = new(victimAngles.X, victimAngles.Y + extraAngle, victimAngles.Z);
- Vector behindPosition = victimEyePos - SkillUtils.GetForwardVector(newAngle) * SkillsInfo.GetValue(skillName, "teleportDistance");
- if (!CheckTeleport(victim, victimEyePos, behindPosition)) continue;
- attackerPawn.Teleport(behindPosition, newAngle, new(0, 0, 0));
- teleported = true;
- break;
+ QAngle targetAngle = new(0, victimAngles.Y + extraAngle, 0);
+ Vector direction = SkillUtils.GetForwardVector(targetAngle);
+ Vector targetPos = victimPos - (direction * distance);
+
+ if (CheckTeleport(victim, victimPos, targetPos))
+ {
+ attackerPawn.Teleport(targetPos, targetAngle, Vector.Zero);
+ teleported = true;
+ break;
+ }
}
+
if (!teleported)
- noSpace.AddOrUpdate(attacker, Server.TickCount + (64 * 2), (k, v) => Server.TickCount + (64 * 2));
+ noSpace.AddOrUpdate(attacker, 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 32850e0..f553380 100644
--- a/jRandomSkills - SRC Files/src/player/skills/ShortBomb.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/ShortBomb.cs
@@ -25,9 +25,10 @@ namespace src.player.skills
var plantedBomb = Utilities.FindAllEntitiesByDesignerName("planted_c4").FirstOrDefault();
if (plantedBomb != null)
- Server.NextFrame(() => plantedBomb.C4Blow = (float)Server.EngineTime + SkillsInfo.GetValue(skillName, "detonationTime"));
+ Server.NextFrame(() => plantedBomb.C4Blow = Server.CurrentTime + SkillsInfo.GetValue(skillName, "detonationTime"));
- player!.PrintToCenterAlert(player.GetTranslation("bombplanted", SkillsInfo.GetValue(skillName, "detonationTime")));
+ foreach (var p in Utilities.GetPlayers().Where(p => p.IsValid && p.PawnIsAlive))
+ p.PrintToCenterAlert(p.GetTranslation("bombplanted", SkillsInfo.GetValue(skillName, "detonationTime")));
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#f5b74c", CsTeam onlyTeam = CsTeam.Terrorist, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int detonationTime = 20) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
diff --git a/jRandomSkills - SRC Files/src/player/skills/Smoker.cs b/jRandomSkills - SRC Files/src/player/skills/Smoker.cs
index 5bc203e..2a2a959 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Smoker.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Smoker.cs
@@ -62,7 +62,6 @@ namespace src.player.skills
return;
}
- Server.PrintToChatAll("Create Smoke");
SkillUtils.CreateSmokeGrenadeProjectile(pos, QAngle.Zero, Vector.Zero, player.TeamNum);
}, TimerFlags.REPEAT | TimerFlags.STOP_ON_MAPCHANGE);
diff --git a/jRandomSkills - SRC Files/src/player/skills/SniperElite.cs b/jRandomSkills - SRC Files/src/player/skills/SniperElite.cs
index b46feaa..68483ec 100644
--- a/jRandomSkills - SRC Files/src/player/skills/SniperElite.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/SniperElite.cs
@@ -165,8 +165,7 @@ namespace src.player.skills
weaponToGive = weapon_awp + "_script";
}
- Server.NextFrame(() =>
- {
+ Instance.AddTimer(.15f, () => {
if (player != null && player.IsValid && player.PlayerPawn.Value != null && player.PlayerPawn.Value.IsValid)
{
var createdWeapon = player.PlayerPawn.Value?.ItemServices?.As().GiveNamedItem(weaponToGive.Replace("_script", ""));
@@ -190,7 +189,7 @@ namespace src.player.skills
DeleteDroppedAWP(player);
isProcessing.TryRemove(steamID, out _);
- });
+ }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
}
catch {
isProcessing.TryRemove(steamID, out _);
diff --git a/jRandomSkills - SRC Files/src/player/skills/Watchmaker.cs b/jRandomSkills - SRC Files/src/player/skills/Watchmaker.cs
index 897a362..79e0c29 100644
--- a/jRandomSkills - SRC Files/src/player/skills/Watchmaker.cs
+++ b/jRandomSkills - SRC Files/src/player/skills/Watchmaker.cs
@@ -30,8 +30,7 @@ namespace src.player.skills
{
if (bombPlanted) return;
var name = entity.DesignerName;
- if (!name.EndsWith("_projectile"))
- return;
+ if (!name.EndsWith("_projectile")) return;
var grenade = entity.As();
if (grenade.OwnerEntity.Value == null || !grenade.OwnerEntity.Value.IsValid) return;
diff --git a/jRandomSkills - SRC Files/src/utils/Config.cs b/jRandomSkills - SRC Files/src/utils/Config.cs
index a8f559a..fecc86f 100644
--- a/jRandomSkills - SRC Files/src/utils/Config.cs
+++ b/jRandomSkills - SRC Files/src/utils/Config.cs
@@ -170,8 +170,9 @@ namespace src.utils
SkillsListCommand = new NormalCommand("supermoc, skille, listamocy, supermoce, skills, listaHabilidades, habilidades, 技能列表, 超能力列表", "@jRandomSkills/admin"),
UseSkillCommand = new NormalCommand("t, useSkill, usarHabilidade, 技能使用, 使用技能", "@jRandomSkills/admin"),
HealCommand = new NormalCommand("heal, ulecz, curar, tratar, 治疗, 治愈", "@jRandomSkills/admin"),
- HealthCommand = new NormalCommand("sethealth, health", "@jRandomSkills/admin"),
- PlantedBomb = new NormalCommand("plantedbomb, bomb", "@jRandomSkills/admin"),
+ HealthCommand = new NormalCommand("sethealth, set_health, health", "@jRandomSkills/admin"),
+ PlantedBomb = new NormalCommand("plantedbomb, planted_bomb, bomb", "@jRandomSkills/admin"),
+ BotPlace = new NormalCommand("botplace, bot_place", "@jRandomSkills/admin"),
ConsoleCommand = new NormalCommand("console, sv, 控制台, 服务器", "@jRandomSkills/owner"),
HudCommand = new NormalCommand("hud, hood", ""),
SetStaticSkillCommand = new NormalCommand("ustawstatycznyskill, ustaw_statyczny_skill, setstaticskill, set_static_skill", "@jRandomSkills/admin"),
@@ -250,6 +251,7 @@ namespace src.utils
public required NormalCommand HealCommand { get; set; }
public required NormalCommand HealthCommand { get; set; }
public required NormalCommand PlantedBomb { get; set; }
+ public required NormalCommand BotPlace { get; set; }
public required NormalCommand ConsoleCommand { get; set; }
public required NormalCommand HudCommand { get; set; }
public required NormalCommand SetStaticSkillCommand { get; set; }
diff --git a/jRandomSkills - Server Files/plugins/jRandomSkills/MaxMind.Db.dll b/jRandomSkills - Server Files/plugins/jRandomSkills/MaxMind.Db.dll
index 346afb5..01695fd 100644
Binary files a/jRandomSkills - Server Files/plugins/jRandomSkills/MaxMind.Db.dll and b/jRandomSkills - Server Files/plugins/jRandomSkills/MaxMind.Db.dll differ
diff --git a/jRandomSkills - Server Files/plugins/jRandomSkills/WASDMenuAPI.dll b/jRandomSkills - Server Files/plugins/jRandomSkills/WASDMenuAPI.dll
index 3ee78b0..0a2ba24 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/jRandomSkills.dll b/jRandomSkills - Server Files/plugins/jRandomSkills/jRandomSkills.dll
index 8cc9a7a..f647514 100644
Binary files a/jRandomSkills - Server Files/plugins/jRandomSkills/jRandomSkills.dll and b/jRandomSkills - Server Files/plugins/jRandomSkills/jRandomSkills.dll differ