This commit is contained in:
Juzlus 2026-02-03 07:02:40 +01:00
parent ae13d6a15c
commit 53917a8b4b
62 changed files with 2643 additions and 935 deletions

View file

@ -64,6 +64,7 @@ public enum Skills
BladeMaster,
BunnyHop,
C4Camouflage,
CarefulBullets,
Catapult,
Chicken,
ChillOut,

View file

@ -3,6 +3,7 @@ using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes;
using CounterStrikeSharp.API.Modules.Admin;
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;
@ -11,7 +12,6 @@ using src.utils;
using System.Collections.Concurrent;
using static CounterStrikeSharp.API.Core.Listeners;
using static src.jRandomSkills;
using static System.Net.Mime.MediaTypeNames;
namespace src.player
{
@ -38,6 +38,7 @@ namespace src.player
{
Instance.RegisterEventHandler<EventPlayerConnectFull>(PlayerConnectFull);
Instance.RegisterEventHandler<EventPlayerDisconnect>(PlayerDisconnect);
// Instance.RegisterEventHandler<EventPlayerChat>(PlayerChat);
Instance.RegisterEventHandler<EventRoundStart>(RoundStart);
Instance.RegisterEventHandler<EventRoundEnd>(RoundEnd);
@ -350,6 +351,39 @@ namespace src.player
}
}
private static HookResult PlayerChat(EventPlayerChat @event, GameEventInfo info)
{
var userID = @event.Userid;
if (userID == 0 || string.IsNullOrEmpty(@event.Text)) return HookResult.Continue;
string text = @event.Text.Split(' ')[0].Trim();
string commandName = text.StartsWith('!') || text.StartsWith('/') ? text[1..] : text;
foreach (var cmd in Instance.CommandDefinitions)
Server.PrintToChatAll("1. " + cmd.Name);
foreach (var cmd in Instance.CommandListeners.Keys)
Server.PrintToChatAll("2. " + cmd?.Target?.ToString());
var player = Utilities.GetPlayerFromUserid(userID);
if (player == null || !player.IsValid) return HookResult.Continue;
var skillPlayer = Instance?.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (skillPlayer == null) return HookResult.Continue;
var temp = skillPlayer.SkillHudExpired;
skillPlayer.SkillHudExpired = DateTime.MinValue;
;
Instance.AddTimer(5f, () =>
{
if (skillPlayer.SkillHudExpired == DateTime.MinValue)
skillPlayer.SkillHudExpired = temp;
});
return HookResult.Continue;
}
private static HookResult RoundStart(EventRoundStart @event, GameEventInfo info)
{
lock (setLock)
@ -398,7 +432,10 @@ namespace src.player
lock (setLock)
{
isTransmitRegistered = false;
Instance.AddTimer(.1f, () => DisableAll());
Instance.AddTimer(.1f, () => {
DisableAll();
ConVar.Find("sv_legacy_jump")?.SetValue("1");
});
Instance.RemoveListener<CheckTransmit>(CheckTransmit);
playersSkills.Clear();
staticSkills.Clear();

View file

@ -23,19 +23,7 @@ namespace src.player.skills
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == victim?.SteamID);
if (playerInfo?.Skill == skillName && hitgroup == (int)HitGroup_t.HITGROUP_HEAD)
ApplyIronHeadEffect(victim!, @event.DmgHealth);
}
private static void ApplyIronHeadEffect(CCSPlayerController victim, float damage)
{
var playerPawn = victim.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return;
var newHealth = playerPawn.Health + damage;
if (newHealth > 100)
newHealth = 100;
playerPawn.Health = (int)newHealth;
SkillUtils.RestoreHealth(victim);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8B4513", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)

View file

@ -66,20 +66,7 @@ namespace src.player.skills
if (weaponServices.ActiveWeapon == null || !weaponServices.ActiveWeapon.IsValid || weaponServices.ActiveWeapon.Value == null || !weaponServices.ActiveWeapon.Value.IsValid || weaponServices.ActiveWeapon.Value.DesignerName != "weapon_knife")
return;
RestoreHealth(victim, damage);
}
private static void RestoreHealth(CCSPlayerController victim, float damage)
{
var playerPawn = victim.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var newHealth = playerPawn.Health + damage;
if (newHealth > 100)
newHealth = 100;
playerPawn.Health = (int)newHealth;
Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_iHealth");
SkillUtils.RestoreHealth(victim);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#cc7504", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float torseReflectionChance = .95f, float legReflectionChance = .80f, float velocityModifier = .85f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)

View file

@ -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,6 +10,7 @@ namespace src.player.skills
public class BunnyHop : ISkill
{
private const Skills skillName = Skills.BunnyHop;
private static readonly ConcurrentDictionary<ulong, int> playersLastJump = [];
public static void LoadSkill()
{
@ -34,7 +36,13 @@ namespace src.player.skills
var flags = (PlayerFlags)playerPawn.Flags;
var buttons = player.Buttons;
if (buttons.HasFlag(PlayerButtons.Jump) && flags.HasFlag(PlayerFlags.FL_ONGROUND) && !playerPawn.MoveType.HasFlag(MoveType_t.MOVETYPE_LADDER))
if ((playerPawn.MovementServices?.QueuedButtonChangeMask & (ulong)PlayerButtons.Jump) != 0)
playersLastJump.AddOrUpdate(player.SteamID, Server.TickCount, (_, _) => Server.TickCount);
bool jumpPressed = buttons.HasFlag(PlayerButtons.Jump)
|| (playersLastJump.TryGetValue(player.SteamID, out int tick) && tick + 20 >= Server.TickCount);
if (jumpPressed && flags.HasFlag(PlayerFlags.FL_ONGROUND) && !playerPawn.MoveType.HasFlag(MoveType_t.MOVETYPE_LADDER))
{
playerPawn.AbsVelocity.Z = SkillsInfo.GetValue<float>(skillName, "jumpVelocity");
var maxSpeed = SkillsInfo.GetValue<float>(skillName, "maxSpeed");

View file

@ -61,7 +61,7 @@ namespace src.player.skills
{
foreach (var (info, player) in infoList)
{
if (player == null) continue;
if (player == null || !player.IsValid) continue;
foreach (var _player in invisiblePlayers.Keys)
if (player.SteamID != _player.SteamID)
{
@ -72,8 +72,9 @@ namespace src.player.skills
if (entity == null || !entity.IsValid) continue;
info.TransmitEntities.Remove(entity.Index);
var bombIndex = HideBomb(_player);
var bombIndex = GetBombIndex();
if (bombIndex == null) continue;
var bombEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)bombIndex);
if (bombEntity == null || !bombEntity.IsValid) continue;
info.TransmitEntities.Remove(bombEntity.Index);
@ -124,7 +125,7 @@ namespace src.player.skills
particle.AcceptInput("Start");
}
private static uint? HideBomb(CCSPlayerController player)
private static uint? GetBombIndex()
{
var bombEntities = Utilities.FindAllEntitiesByDesignerName<CC4>("weapon_c4").ToList();
if (bombEntities.Count == 0) return null;
@ -132,15 +133,6 @@ namespace src.player.skills
var bomb = bombEntities.FirstOrDefault();
if (bomb == null) return null;
// if (bomb.OwnerEntity.Index != player.Index) return null;
bomb.EntitySpottedState.Spotted = false;
Utilities.SetStateChanged(bomb, "CCSPlayerPawn", "m_entitySpottedState", Schema.GetSchemaOffset("EntitySpottedState_t", "m_bSpotted"));
for (int i = 0; i < bomb.EntitySpottedState.SpottedByMask.Length; i++)
bomb.EntitySpottedState.SpottedByMask[i] = 0;
Utilities.SetStateChanged(bomb, "CCSPlayerPawn", "m_entitySpottedState", Schema.GetSchemaOffset("EntitySpottedState_t", "m_bSpottedByMask"));
return bomb.Index;
}

View file

@ -0,0 +1,153 @@
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;
namespace src.player.skills
{
public class CarefulBullets : ISkill
{
private const Skills skillName = Skills.CarefulBullets;
private static readonly ConcurrentDictionary<ulong, byte> targetPlayers = [];
private static readonly ConcurrentDictionary<ulong, bool> lastShot = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
lock (setLock)
{
targetPlayers.Clear();
lastShot.Clear();
}
foreach (var player in Utilities.GetPlayers())
{
DisableSkill(player);
SkillUtils.CloseMenu(player);
}
}
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null) return;
DisableSkill(player);
}
public static void OnTick()
{
if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers())
{
if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
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 = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))];
SkillUtils.UpdateMenu(player, menuItems);
}
}
public static void TypeSkill(CCSPlayerController player, string[] commands)
{
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed)
{
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("areareaper_used_info")}");
return;
}
string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Team != player.Team && p.Index.ToString() == enemyId);
if (enemy == null)
{
player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("selectplayerskill_incorrect_enemy_index"));
return;
}
targetPlayers.TryAdd(enemy.SteamID, 0);
playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("carefulbullets_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("carefulbullets_enemy_info"));
}
public static void EnableSkill(CCSPlayerController player)
{
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo == null) return;
playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0)
{
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))];
SkillUtils.CreateMenu(player, menuItems);
}
else
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("selectplayerskill_incorrect_enemy_index")}");
}
public static void OnTakeDamage(DynamicHook h)
{
CEntityInstance param = h.GetParam<CEntityInstance>(0);
CTakeDamageInfo param2 = h.GetParam<CTakeDamageInfo>(1);
if (param?.Entity == null || param2?.Attacker?.Value == null)
return;
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<CCSPlayerController>();
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<int>(skillName, "damageAfterMiss"));
lastShot.TryRemove(attacker.SteamID, out _);
});
}
else if (hitPlayer)
lastShot.TryUpdate(attacker.SteamID, true, false);
}
public static void DisableSkill(CCSPlayerController player)
{
targetPlayers.TryRemove(player.SteamID, out _);
lastShot.TryRemove(player.SteamID, out _);
SkillUtils.CloseMenu(player);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#db6c35", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int damageAfterMiss = 5) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public int DamageAfterMiss { get; set; } = damageAfterMiss;
}
}
}

View file

@ -1,8 +1,7 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Timers;
using CounterStrikeSharp.API.Modules.Utils;
using CS2TraceRay.Class;
using CS2TraceRay.Struct;
@ -10,6 +9,7 @@ using src.utils;
using System.Collections.Concurrent;
using System.Drawing;
using System.Numerics;
using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
namespace src.player.skills
@ -25,7 +25,7 @@ namespace src.player.skills
public static void LoadSkill()
{
// SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
jRandomSkills.Instance.AddToManifest(cameraPropModel);
jRandomSkills.Instance.AddToManifest(cameraViewModel);
}
@ -56,7 +56,9 @@ namespace src.player.skills
CameraView = null,
CameraActive = false,
NextCamera = 0,
NoSpace = 0,
PlayerCameraRaw = player.PlayerPawn.Value.CameraServices.ViewEntity.Raw,
LastAngle = QAngle.Zero
});
}
@ -85,6 +87,7 @@ namespace src.player.skills
playerSkill.CameraProp.AcceptInput("Kill");
playerSkill.CameraProp = null;
}
playerSkill.NextCamera = Server.TickCount + SkillsInfo.GetValue<float>(skillName, "Cooldown") * 64;
}
public static void OnTick()
@ -114,8 +117,13 @@ namespace src.player.skills
{
if (player.NextCamera > Server.TickCount) return;
player.CameraProp = CreateCameraProp(player.Player);
if (player.CameraProp == null)
{
player.NoSpace = Server.TickCount + (64 * 2);
return;
}
player.CameraView = CreateCameraView(player.Player);
player.NextCamera = Server.TickCount + SkillsInfo.GetValue<float>(skillName, "Cooldown") * 64;
if (player.CameraView == null) return;
}
var pawn = player.Player.PlayerPawn.Value;
@ -123,13 +131,52 @@ namespace src.player.skills
return;
BlockWeapon(player.Player, player.CameraActive);
pawn!.CameraServices!.ViewEntity.Raw = player.CameraActive && player.CameraView != null ? player.CameraView.EntityHandle.Raw : player.PlayerCameraRaw;
Utilities.SetStateChanged(pawn, "CBasePlayerPawn", "m_pCameraServices");
if (player.CameraActive && player.CameraView != null)
Server.NextWorldUpdate(() =>
{
SkillUtils.ApplyScreenColor(player.Player, 0, 0, 255, 20, 100, 1020);
}
if (pawn != null && pawn.LifeState == (byte)LifeState_t.LIFE_ALIVE)
{
if (player.CameraActive && player.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);
}
else if (!forceToDefault)
pawn.Teleport(null, player.LastAngle);
}
if (player.CameraActive && player.CameraView != null)
{
pawn!.CameraServices!.ViewEntity.Raw = player.CameraView.EntityHandle.Raw;
SkillUtils.ApplyScreenColor(player.Player, 0, 0, 255, 20, 100, 1020);
Timer? cameraTimer = null;
ulong playerSteamID = player.Player.SteamID;
cameraTimer = jRandomSkills.Instance.AddTimer(2f, () =>
{
var target = Utilities.GetPlayerFromSteamId(playerSteamID);
if (target == null || !target.IsValid || !target.PawnIsAlive)
{
cameraTimer?.Kill();
return;
}
if (!playersInfo.TryGetValue(target, out var playerSkill) || playerSkill.CameraActive == false)
{
cameraTimer?.Kill();
return;
}
SkillUtils.ApplyScreenColor(target, 0, 0, 255, 20, 100, 1020);
}, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT);
}
else
pawn!.CameraServices!.ViewEntity.Raw = player.PlayerCameraRaw;
Utilities.SetStateChanged(pawn, "CBasePlayerPawn", "m_pCameraServices");
});
}
private static CDynamicProp? CreateCameraProp(CCSPlayerController player)
@ -140,7 +187,6 @@ namespace src.player.skills
camera.Collision.SolidType = SolidType_t.SOLID_VPHYSICS;
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}";
camera.DispatchSpawn();
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return null;
@ -150,10 +196,14 @@ namespace src.player.skills
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();
});
return camera;
@ -163,7 +213,6 @@ namespace src.player.skills
{
var camera = Utilities.CreateEntityByName<CDynamicProp>("prop_dynamic");
if (camera == null || !camera.IsValid) return null;
camera.DispatchSpawn();
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return null;
@ -172,14 +221,15 @@ namespace src.player.skills
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(() =>
{
camera.SetModel(cameraViewModel);
camera.Render = Color.FromArgb(0, 255, 255, 255);
camera.Teleport(cameraVector, playerPawn.EyeAngles);
camera.DispatchSpawn();
});
return camera;
@ -227,7 +277,7 @@ namespace src.player.skills
}
}
private unsafe static Vector? GetNewCameraPosition(CCSPlayerController player)
private static Vector? GetNewCameraPosition(CCSPlayerController player)
{
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return null;
@ -235,30 +285,54 @@ 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;
Ray ray = new(Vector3.Zero);
CTraceFilter filter = new(playerPawn.Index, playerPawn.Index)
{
m_nObjectSetMask = 0xf,
m_nCollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_PROJECTILE,
m_nInteractsWith = 8589946881,
m_nInteractsExclude = 0,
m_nBits = 11,
m_bIterateEntities = true,
m_bHitTriggers = false,
m_nInteractsAs = 0x40000,
m_bOnlyHitIfHasPhysics = true
};
ulong solid = 0x1;
ulong window = 0x1000;
ulong passBullets = 0x2000;
filter.m_nHierarchyIds[0] = playerPawn.GetHierarchyId();
filter.m_nHierarchyIds[1] = 0;
CGameTrace trace = TraceRay.TraceHull(eyePos, endPos, filter, ray);
ulong mask = solid | window | passBullets;
ulong contents = playerPawn.Collision.CollisionGroup;
CGameTrace trace = TraceRay.TraceShape(eyePos, endPos, mask, contents, player);
if (trace.HitWorld(out _))
return new Vector(trace.EndPos.X, trace.EndPos.Y, trace.EndPos.Z);
{
Vector3 hitPost = trace.EndPos;
Vector3 normal = trace.Normal;
float offset = 8;
Vector finalPos = new(
hitPost.X + (normal.X * offset),
hitPost.Y + (normal.Y * offset),
hitPost.Z + (normal.Z * offset)
);
return finalPos;
}
return null;
}
private static bool CheckCameraPosition(Vector cameraVector, CCSPlayerController player)
{
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return false;
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 = solid | window | passBullets;
ulong contents = playerPawn.Collision.CollisionGroup;
CGameTrace trace = TraceRay.TraceShape(cameraVector, endPos, mask, contents, player);
if (trace.HitWorld(out _))
return true;
return false;
}
private static void UpdateHUD(PlayerSkill playerSkill)
{
if (playerSkill == null || playerSkill.Player == null) return;
@ -270,7 +344,9 @@ namespace src.player.skills
var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == playerSkill?.Player?.SteamID);
if (playerInfo == null) return;
if (cooldown == 0)
if (playerSkill.NoSpace >= Server.TickCount)
playerInfo.PrintHTML = $"<font color='#FF0000'>{playerSkill.Player.GetTranslation("cypher_nospace")}</font>";
else if (cooldown == 0)
playerInfo.PrintHTML = null;
else if (playerSkill?.CameraProp == null)
playerInfo.PrintHTML = $"{playerSkill?.Player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
@ -284,6 +360,8 @@ namespace src.player.skills
public uint PlayerCameraRaw { get; set; }
public bool CameraActive { get; set; }
public float NextCamera { get; set; }
public float NoSpace { get; set; }
public required QAngle LastAngle { get; set; }
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#34ebd5", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 30) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)

View file

@ -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
{
@ -111,34 +112,32 @@ namespace src.player.skills
private static void SetUpPostProcessing(CCSPlayerController player, bool turnOff = false)
{
if (player == null || !player.IsValid) return;
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.CameraServices == null) return;
ulong playerSteamID = player.SteamID;
lock (setLock)
{
if (!turnOff)
{
playersInDark.TryAdd(player.SteamID, 0);
SkillUtils.ApplyScreenColor(player,
r: SkillsInfo.GetValue<int>(skillName, "R"),
g: SkillsInfo.GetValue<int>(skillName, "G"),
b: SkillsInfo.GetValue<int>(skillName, "B"),
a: SkillsInfo.GetValue<int>(skillName, "A"),
duration: 100,
holdTime: 3000);
playersInDark.TryAdd(playerSteamID, 0);
ApplyColor(player);
Instance.AddTimer(2.5f, () => {
if (!playersInDark.ContainsKey(player.SteamID))
Timer? darkTimer = null;
darkTimer = Instance.AddTimer(5f, () => {
if (!playersInDark.ContainsKey(playerSteamID))
{
darkTimer?.Kill();
return;
}
if (player.IsValid && player.PawnIsAlive)
SkillUtils.ApplyScreenColor(player,
r: SkillsInfo.GetValue<int>(skillName, "R"),
g: SkillsInfo.GetValue<int>(skillName, "G"),
b: SkillsInfo.GetValue<int>(skillName, "B"),
a: SkillsInfo.GetValue<int>(skillName, "A"),
duration: 100,
holdTime: 3000);
var target = Utilities.GetPlayerFromSteamId(playerSteamID);
if (target == null || !target.IsValid)
{
darkTimer?.Kill();
return;
}
if (target.PawnIsAlive)
ApplyColor(player);
}, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT);
}
else
@ -149,6 +148,17 @@ namespace src.player.skills
}
}
private static void ApplyColor(CCSPlayerController player)
{
SkillUtils.ApplyScreenColor(player,
r: SkillsInfo.GetValue<int>(skillName, "R"),
g: SkillsInfo.GetValue<int>(skillName, "G"),
b: SkillsInfo.GetValue<int>(skillName, "B"),
a: SkillsInfo.GetValue<int>(skillName, "A"),
duration: 100,
holdTime: 3000);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#383838", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int r = 0, int g = 0, int b = 0, int a = 230) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public int R { get; set; } = r;

View file

@ -2,6 +2,7 @@
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,15 +10,22 @@ namespace src.player.skills
public class Dash : ISkill
{
private const Skills skillName = Skills.Dash;
private static readonly PlayerFlags[] LF = new PlayerFlags[64];
private static readonly int?[] J = new int?[64];
private static readonly PlayerButtons[] LB = new PlayerButtons[64];
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
{
lock (setLock)
{
SkillPlayerInfo.Clear();
}
}
public static void OnTick()
{
foreach (var player in Utilities.GetPlayers())
@ -25,11 +33,55 @@ namespace src.player.skills
if (!Instance.IsPlayerValid(player)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo?.Skill == skillName)
HandleDash(player);
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
{
UpdateHUD(player, skillInfo);
HandleDash(player, skillInfo);
}
}
}
private static void HandleDash(CCSPlayerController player)
public static void EnableSkill(CCSPlayerController player)
{
SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo
{
SteamID = player.SteamID,
CanUse = true,
Cooldown = DateTime.MinValue,
LastFlags = 0,
Jumps = 0,
LastButtons = 0
});
}
public static void DisableSkill(CCSPlayerController player)
{
SkillPlayerInfo.TryRemove(player.SteamID, out _);
SkillUtils.ResetPrintHTML(player);
}
private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo)
{
float cooldown = 0;
if (skillInfo != null)
{
float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue<float>(skillName, "cooldown")) - DateTime.Now).TotalSeconds);
cooldown = Math.Max(time, 0);
if (cooldown == 0 && skillInfo?.CanUse == false)
skillInfo.CanUse = true;
}
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
if (playerInfo == null) return;
if (cooldown == 0)
playerInfo.PrintHTML = null;
else
playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
}
private static void HandleDash(CCSPlayerController player, PlayerSkillInfo skillInfo)
{
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return;
@ -37,55 +89,81 @@ namespace src.player.skills
var flags = (PlayerFlags)playerPawn.Flags;
var buttons = player.Buttons;
bool jumpPressed = (buttons & PlayerButtons.Jump) != 0
|| (playerPawn.MovementServices?.QueuedButtonChangeMask & (ulong)PlayerButtons.Jump) != 0;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerPawn == null || playerInfo == null) return;
if ((LF[player.Slot] & PlayerFlags.FL_ONGROUND) != 0 && (flags & PlayerFlags.FL_ONGROUND) == 0 && (LB[player.Slot] & PlayerButtons.Jump) == 0 && (buttons & PlayerButtons.Jump) != 0)
bool wasOnGround = (skillInfo.LastFlags & PlayerFlags.FL_ONGROUND) != 0;
bool isOnGround = (flags & PlayerFlags.FL_ONGROUND) != 0;
if (wasOnGround && !isOnGround && jumpPressed)
skillInfo.Jumps = 0;
else if (isOnGround)
skillInfo.Jumps = 0;
else if (!isOnGround && jumpPressed && skillInfo.Jumps < 1)
{
}
else if ((flags & PlayerFlags.FL_ONGROUND) != 0)
{
J[player.Slot] = 0;
}
else if ((LB[player.Slot] & PlayerButtons.Jump) == 0 && (buttons & PlayerButtons.Jump) != 0 && J[player.Slot] < 1)
{
J[player.Slot]++;
bool lastJumpPressed = (skillInfo.LastButtons & PlayerButtons.Jump) != 0;
if (!lastJumpPressed && skillInfo.CanUse)
{
skillInfo.Jumps++;
skillInfo.CanUse = false;
skillInfo.Cooldown = DateTime.Now;
float moveX = 0;
float moveY = 0;
float moveX = 0;
float moveY = 0;
PlayerButtons playerButtons = player.Buttons;
if (playerButtons.HasFlag(PlayerButtons.Forward))
moveY += 1;
if (playerButtons.HasFlag(PlayerButtons.Back))
moveY -= 1;
if (playerButtons.HasFlag(PlayerButtons.Moveleft))
moveX += 1;
if (playerButtons.HasFlag(PlayerButtons.Moveright))
moveX -= 1;
PlayerButtons playerButtons = player.Buttons;
if (SkillsInfo.GetValue<bool>(skillName, "anyDirection"))
{
if (playerButtons.HasFlag(PlayerButtons.Forward))
moveY += 1;
if (playerButtons.HasFlag(PlayerButtons.Back))
moveY -= 1;
if (playerButtons.HasFlag(PlayerButtons.Moveleft))
moveX += 1;
if (playerButtons.HasFlag(PlayerButtons.Moveright))
moveX -= 1;
if (moveX == 0 && moveY == 0)
moveY = 1;
if (moveX == 0 && moveY == 0)
moveY = 1;
}
else
moveY = 1;
float moveAngle = MathF.Atan2(moveX, moveY) * (180f / MathF.PI);
QAngle dashAngles = new(0, playerPawn.EyeAngles.Y + moveAngle, 0);
float moveAngle = MathF.Atan2(moveX, moveY) * (180f / MathF.PI);
QAngle dashAngles = new(0, playerPawn.EyeAngles.Y + moveAngle, 0);
Vector newVelocity = SkillUtils.GetForwardVector(dashAngles) * SkillsInfo.GetValue<float>(skillName, "pushVelocity");
newVelocity.Z = playerPawn.AbsVelocity.Z + SkillsInfo.GetValue<float>(skillName, "jumpVelocity");
Vector newVelocity = SkillUtils.GetForwardVector(dashAngles) * SkillsInfo.GetValue<float>(skillName, "pushVelocity");
newVelocity.Z = playerPawn.AbsVelocity.Z + SkillsInfo.GetValue<float>(skillName, "jumpVelocity");
playerPawn.AbsVelocity.X = newVelocity.X;
playerPawn.AbsVelocity.Y = newVelocity.Y;
playerPawn.AbsVelocity.Z = newVelocity.Z;
playerPawn.AbsVelocity.X = newVelocity.X;
playerPawn.AbsVelocity.Y = newVelocity.Y;
playerPawn.AbsVelocity.Z = newVelocity.Z;
}
}
LF[player.Slot] = flags;
LB[player.Slot] = buttons;
skillInfo.LastFlags = flags;
skillInfo.LastButtons = buttons;
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#42bbfc", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float jumpVelocity = 150f, float pushVelocity = 600f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
public class PlayerSkillInfo
{
public ulong SteamID { get; set; }
public bool CanUse { get; set; }
public DateTime Cooldown { get; set; }
public PlayerFlags LastFlags { get; set; }
public int Jumps { get; set; }
public PlayerButtons LastButtons { get; set; }
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#42bbfc", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float jumpVelocity = 150f, float pushVelocity = 600f, bool anyDirection = true, float cooldown = 2f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public float JumpVelocity { get; set; } = jumpVelocity;
public float PushVelocity { get; set; } = pushVelocity;
public bool AnyDirection { get; set; } = anyDirection;
public float Cooldown { get; set; } = cooldown;
}
}
}

View file

@ -76,7 +76,7 @@ namespace src.player.skills
if (entity == null || !entity.IsValid) continue;
info.TransmitEntities.Remove(entity.Index);
var bombIndex = HideBomb(_player);
var bombIndex = GetBombIndex(_player);
if (bombIndex == null) continue;
var bombEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)bombIndex);
if (bombEntity == null || !bombEntity.IsValid) continue;
@ -170,7 +170,7 @@ namespace src.player.skills
playerInfo.PrintHTML = $"<font color='#FF0000'>{player.GetTranslation("disabled_weapon")}</font>";
}
private static uint? HideBomb(CCSPlayerController player)
private static uint? GetBombIndex(CCSPlayerController player)
{
var bombEntities = Utilities.FindAllEntitiesByDesignerName<CC4>("weapon_c4").ToList();
if (bombEntities.Count == 0) return null;
@ -179,14 +179,6 @@ namespace src.player.skills
if (bomb == null) return null;
if (bomb.OwnerEntity.Index != player.Index) return null;
bomb.EntitySpottedState.Spotted = false;
Utilities.SetStateChanged(bomb, "CCSPlayerPawn", "m_entitySpottedState", Schema.GetSchemaOffset("EntitySpottedState_t", "m_bSpotted"));
for (int i = 0; i < bomb.EntitySpottedState.SpottedByMask.Length; i++)
bomb.EntitySpottedState.SpottedByMask[i] = 0;
Utilities.SetStateChanged(bomb, "CCSPlayerPawn", "m_entitySpottedState", Schema.GetSchemaOffset("EntitySpottedState_t", "m_bSpottedByMask"));
return bomb.Index;
}

View file

@ -72,7 +72,7 @@ namespace src.player.skills
{
foreach (Vector smokePos in smokes.Keys)
foreach (var player in Utilities.GetPlayers())
if (Server.TickCount % 17 == 0)
if (Server.TickCount % 16 == 0)
if (player.PlayerPawn.Value != null && player.PlayerPawn.Value.IsValid && player.PlayerPawn.Value.AbsOrigin != null)
if (SkillUtils.GetDistance(smokePos, player.PlayerPawn.Value.AbsOrigin) <= SkillsInfo.GetValue<float>(skillName, "smokeRadius"))
AddHealth(player.PlayerPawn.Value, SkillsInfo.GetValue<int>(skillName, "smokeHeal"));

View file

@ -1,7 +1,5 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Timers;
using CounterStrikeSharp.API.Modules.Utils;
@ -9,7 +7,7 @@ using CS2TraceRay.Class;
using CS2TraceRay.Struct;
using src.utils;
using System.Collections.Concurrent;
using System.Numerics;
using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
namespace src.player.skills
@ -22,7 +20,7 @@ namespace src.player.skills
public static void LoadSkill()
{
// SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()
@ -143,8 +141,9 @@ namespace src.player.skills
clone.Teleport(playerPawn.AbsOrigin, new QAngle(0, playerPawn.V_angle.Y, 0));
playerPawn.Teleport(pos);
SkillUtils.ApplyScreenColor(player, 255, 255, 0, 20, 100, 1020);
SkillUtils.ApplyScreenColor(player, r: 255, g: 255, b: 0, a: 20, duration: 100, holdTime: 1020);
BlockWeapon(playerSkill.Player, true);
playerSkill.UseTime = Server.TickCount;
playerSkill.NextUse = Server.TickCount + 64000;
playerSkill.CloneProp = clone;
@ -155,18 +154,25 @@ namespace src.player.skills
KillClone(playerSkill);
});
jRandomSkills.Instance.AddTimer(2f, () => {
if (playerSkill.CloneProp == null)
return;
Timer? cloneTimer = null;
ulong playerSteamID = player.SteamID;
if (player.IsValid && player.PawnIsAlive)
SkillUtils.ApplyScreenColor(player,
r: 255,
g: 255,
b: 0,
a: 20,
duration: 100,
holdTime: 1020);
cloneTimer = jRandomSkills.Instance.AddTimer(2f, () =>
{
var target = Utilities.GetPlayerFromSteamId(playerSteamID);
if (target == null || !target.IsValid || !target.PawnIsAlive)
{
cloneTimer?.Kill();
return;
}
if (!playersInfo.TryGetValue(target, out var playerSkill) || playerSkill.CloneProp == null)
{
cloneTimer?.Kill();
return;
}
SkillUtils.ApplyScreenColor(target, r: 255, g: 255, b: 0, a: 20, duration: 100, holdTime: 1020);
}, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT);
});
@ -181,22 +187,9 @@ namespace src.player.skills
Vector eyePos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 25);
endPos.Z += 25;
Ray ray = new(Vector3.Zero);
CTraceFilter filter = new(playerPawn.Index, playerPawn.Index)
{
m_nObjectSetMask = 0xf,
m_nCollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_PLAYER_MOVEMENT,
m_nInteractsWith = playerPawn.GetInteractsWith(),
m_nInteractsExclude = 0,
m_nBits = 11,
m_bIterateEntities = true,
m_bHitTriggers = false,
m_nInteractsAs = 0x40000
};
filter.m_nHierarchyIds[0] = playerPawn.GetHierarchyId();
filter.m_nHierarchyIds[1] = 0;
CGameTrace trace = TraceRay.TraceHull(eyePos, endPos, filter, ray);
ulong mask = playerPawn.Collision.CollisionAttribute.InteractsWith;
ulong contents = playerPawn.Collision.CollisionGroup;
CGameTrace trace = TraceRay.TraceShape(eyePos, endPos, mask, contents, player);
return !trace.DidHit();
}
@ -282,9 +275,7 @@ namespace src.player.skills
if (playersInfo.TryGetValue(victim, out var playerSkill) && playerSkill.CloneProp != null)
{
KillClone(playerSkill);
var victimPawn = victim.PlayerPawn.Value;
if (victimPawn == null) return;
SkillUtils.AddHealth(victimPawn, @event.DmgHealth);
SkillUtils.RestoreHealth(victim);
}
}

View file

@ -34,23 +34,31 @@ namespace src.player.skills
{
foreach( var (info, player) in infoList)
{
if (player == null) continue;
if (player == null || !player.IsValid) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero;
bool isObservingJackal = false;
if (targetHandle != nint.Zero)
{
var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle);
var targetInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == target?.SteamID);
if (targetInfo?.Skill == skillName) isObservingJackal = true;
}
bool hasSkill = playerInfo?.Skill == skillName || isObservingJackal;
foreach (var param in playersStep)
{
var enemy = param.Key;
var step = param.Value;
if (step == null || step.IsValid) continue;
var observedPlayer = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == player?.Pawn?.Value?.ObserverServices?.ObserverTarget?.Value?.Handle);
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
var observerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == observedPlayer?.SteamID);
if (step == null || !step.IsValid) continue;
var entity = Utilities.GetEntityFromIndex<CBaseEntity>((int)step.Index);
if (entity == null || !entity.IsValid) continue;
if (playerInfo?.Skill != skillName && observerInfo?.Skill != skillName)
info.TransmitEntities.Remove(entity.Index);
else if (enemy.Team == player.Team)
if (!hasSkill || enemy.Team == player.Team)
info.TransmitEntities.Remove(entity.Index);
}
}

View file

@ -50,25 +50,13 @@ namespace src.player.skills
if (!Instance.IsPlayerValid(attacker))
{
if (victimInfo?.Skill == skillName)
RestoreHealth(victim!, @event.DmgHealth);
SkillUtils.RestoreHealth(victim);
return;
}
var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID);
if (attackerInfo?.Skill == skillName || victimInfo?.Skill == skillName)
RestoreHealth(victim!, @event.DmgHealth);
}
private static void RestoreHealth(CCSPlayerController victim, float damage)
{
var playerPawn = victim.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return;
var newHealth = playerPawn.Health + damage;
if (newHealth > 100)
newHealth = 100;
playerPawn.Health = (int)newHealth;
SkillUtils.RestoreHealth(victim);
}
public static void EnableSkill(CCSPlayerController _)

View file

@ -1,4 +1,5 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using static src.jRandomSkills;

View file

@ -1,6 +1,5 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils;
using CS2TraceRay.Class;
@ -9,7 +8,6 @@ using CS2TraceRay.Struct;
using src.utils;
using System.Collections.Concurrent;
using System.Drawing;
using System.Numerics;
using static src.jRandomSkills;
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
@ -24,6 +22,8 @@ namespace src.player.skills
private static readonly ConcurrentDictionary<ulong, byte> playersInAction = [];
private static readonly MemoryFunctionVoid<IntPtr, short> Shoot_Secondary = new(GameData.GetSignature("Shoot_Secondary"));
private static int i = 0;
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
@ -100,23 +100,11 @@ namespace src.player.skills
Vector eyePos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z);
Vector endPos = eyePos + SkillUtils.GetForwardVector(pawn.EyeAngles) * SkillsInfo.GetValue<float>(skillName, "maxDistance");
Ray ray = new(Vector3.Zero);
CTraceFilter filter = new(pawn.Index, pawn.Index)
{
m_nObjectSetMask = 0xf,
m_nCollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_PLAYER_MOVEMENT,
m_nInteractsWith = pawn.GetInteractsWith(),
m_nInteractsExclude = 0,
m_nBits = 11,
m_bIterateEntities = true,
m_bHitTriggers = false,
m_nInteractsAs = 0x40000
};
filter.m_nHierarchyIds[0] = pawn.GetHierarchyId();
filter.m_nHierarchyIds[1] = 0;
CGameTrace trace = TraceRay.TraceHull(eyePos, endPos, filter, ray);
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)
{
CreateLine(eyePos, endPos, Color.FromArgb(255, 255, 255, 0));
@ -126,12 +114,17 @@ namespace src.player.skills
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}");
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()}, Entity: {trace.HitEntity}, Solid: {trace.AllSolid}, Contents: {(Contents)trace.Contents}");
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))
return;
CBaseEntity entity = entityInstance.As<CBaseEntity>();
if (!trace.HitPlayer(out CCSPlayerController? target) || target == null)
return;

View file

@ -7,7 +7,6 @@ using CS2TraceRay.Enum;
using CS2TraceRay.Struct;
using src.utils;
using System.Drawing;
using System.Numerics;
using static src.jRandomSkills;
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
@ -39,22 +38,10 @@ namespace src.player.skills
Vector eyePos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z);
Vector endPos = eyePos + SkillUtils.GetForwardVector(pawn.EyeAngles) * SkillsInfo.GetValue<float>(skillName, "maxDistance");
Ray ray = new(Vector3.Zero);
CTraceFilter filter = new(pawn.Index, pawn.Index)
{
m_nObjectSetMask = 0xf,
m_nCollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_PLAYER_MOVEMENT,
m_nInteractsWith = pawn.GetInteractsWith(),
m_nInteractsExclude = 0,
m_nBits = 11,
m_bIterateEntities = true,
m_bHitTriggers = false,
m_nInteractsAs = 0x40000
};
filter.m_nHierarchyIds[0] = pawn.GetHierarchyId();
filter.m_nHierarchyIds[1] = 0;
CGameTrace trace = TraceRay.TraceHull(eyePos, endPos, filter, ray);
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)
{
@ -65,10 +52,10 @@ namespace src.player.skills
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}");
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()}, Entity: {trace.HitEntity}, Solid: {trace.AllSolid}, Contents: {(Contents)trace.Contents}");
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)

View file

@ -68,7 +68,7 @@ namespace src.player.skills
if (entity == null || !entity.IsValid) continue;
info.TransmitEntities.Remove(entity.Index);
var bombIndex = HideBomb(_player);
var bombIndex = GetBombIndex(_player);
if (bombIndex == null) continue;
var bombEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)bombIndex);
if (bombEntity == null || !bombEntity.IsValid) continue;
@ -170,7 +170,7 @@ namespace src.player.skills
particle.AcceptInput("Start");
}
private static uint? HideBomb(CCSPlayerController player)
private static uint? GetBombIndex(CCSPlayerController player)
{
var bombEntities = Utilities.FindAllEntitiesByDesignerName<CC4>("weapon_c4").ToList();
if (bombEntities.Count == 0) return null;
@ -179,14 +179,6 @@ namespace src.player.skills
if (bomb == null) return null;
if (bomb.OwnerEntity.Index != player.Index) return null;
bomb.EntitySpottedState.Spotted = false;
Utilities.SetStateChanged(bomb, "CCSPlayerPawn", "m_entitySpottedState", Schema.GetSchemaOffset("EntitySpottedState_t", "m_bSpotted"));
for (int i = 0; i < bomb.EntitySpottedState.SpottedByMask.Length; i++)
bomb.EntitySpottedState.SpottedByMask[i] = 0;
Utilities.SetStateChanged(bomb, "CCSPlayerPawn", "m_entitySpottedState", Schema.GetSchemaOffset("EntitySpottedState_t", "m_bSpottedByMask"));
return bomb.Index;
}

View file

@ -1,4 +1,5 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using static src.jRandomSkills;
@ -24,8 +25,8 @@ namespace src.player.skills
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
if (playerInfo?.Skill != skillName) return;
if (weapon == "hegrenade" || weapon == "inferno")
SkillUtils.AddHealth(player!.PlayerPawn.Value, damage);
if (weapon == "hegrenade" || weapon == "inferno" || weapon == "decoy" || weapon == "flashbang" || weapon == "smokegrenade" || weapon == "molotov")
SkillUtils.RestoreHealth(player);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a38c1a", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)

View file

@ -28,20 +28,7 @@ namespace src.player.skills
HitGroup_t[] disabledHitbox = [HitGroup_t.HITGROUP_LEFTARM, HitGroup_t.HITGROUP_RIGHTARM, HitGroup_t.HITGROUP_LEFTLEG, HitGroup_t.HITGROUP_RIGHTLEG];
if (hitgroup != HitGroup_t.HITGROUP_HEAD)
RestoreHealth(victim!, damage);
}
private static void RestoreHealth(CCSPlayerController victim, float damage)
{
var playerPawn = victim.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return;
var newHealth = playerPawn.Health + damage;
if (newHealth > 100)
newHealth = 100;
playerPawn.Health = (int)newHealth;
Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_iHealth");
SkillUtils.RestoreHealth(victim);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#3c47de", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)

View file

@ -52,18 +52,20 @@ namespace src.player.skills
var flags = (PlayerFlags)playerPawn.Flags;
var buttons = player.Buttons;
bool isJumpDown = (playerPawn.MovementServices?.Buttons?.ButtonStates[0] & (ulong)PlayerButtons.Jump) != 0 || (buttons & PlayerButtons.Jump) != 0;
bool wasJumpDown = (LB[player.Slot] & PlayerButtons.Jump) != 0;
bool jumpPressed = (isJumpDown && !wasJumpDown)
|| (playerPawn.MovementServices?.QueuedButtonChangeMask & (ulong)PlayerButtons.Jump) != 0;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerPawn == null || playerInfo == null) return;
if ((LF[player.Slot] & PlayerFlags.FL_ONGROUND) != 0 && (flags & PlayerFlags.FL_ONGROUND) == 0 && (LB[player.Slot] & PlayerButtons.Jump) == 0 && (buttons & PlayerButtons.Jump) != 0)
{
//J[player.Slot] ++;
}
else if ((flags & PlayerFlags.FL_ONGROUND) != 0)
{
bool isOnGround = (flags & PlayerFlags.FL_ONGROUND) != 0;
if (isOnGround)
J[player.Slot] = 0;
}
else if ((LB[player.Slot] & PlayerButtons.Jump) == 0 && (buttons & PlayerButtons.Jump) != 0 && J[player.Slot] < playerInfo.SkillChance)
else if (jumpPressed && J[player.Slot] < playerInfo.SkillChance + 1)
{
J[player.Slot]++;
playerPawn.AbsVelocity.Z = 300;

View file

@ -27,6 +27,8 @@ namespace src.player.skills
var plantedBomb = Utilities.FindAllEntitiesByDesignerName<CPlantedC4>("planted_c4").FirstOrDefault();
if (plantedBomb != null)
Server.NextFrame(() => plantedBomb.C4Blow = (float)Server.EngineTime + SkillsInfo.GetValue<int>(skillName, "extraC4BlowTime"));
player!.PrintToCenterAlert(player.GetTranslation("bombplanted", SkillsInfo.GetValue<int>(skillName, "extraC4BlowTime")));
}
public static void DisableSkill(CCSPlayerController player)

View file

@ -28,20 +28,7 @@ namespace src.player.skills
HitGroup_t[] disabledHitbox = [HitGroup_t.HITGROUP_LEFTARM, HitGroup_t.HITGROUP_RIGHTARM, HitGroup_t.HITGROUP_LEFTLEG, HitGroup_t.HITGROUP_RIGHTLEG];
if (disabledHitbox.Contains(hitgroup))
RestoreHealth(victim!, damage);
}
private static void RestoreHealth(CCSPlayerController victim, float damage)
{
var playerPawn = victim.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return;
var newHealth = playerPawn.Health + damage;
if (newHealth > 100)
newHealth = 100;
playerPawn.Health = (int)newHealth;
Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_iHealth");
SkillUtils.RestoreHealth(victim);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#9c9c9c", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)

View file

@ -26,7 +26,8 @@ namespace src.player.skills
var victimInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == victim?.SteamID);
if (victimInfo == null || victimInfo.Skill != skillName) return ;
RestoreHealth(victim!, damage * SkillsInfo.GetValue<float>(skillName, "regenerationMultiplier"));
var pawn = victim!.PlayerPawn.Value;
SkillUtils.AddHealth(pawn, (int)(damage * SkillsInfo.GetValue<float>(skillName, "regenerationMultiplier")));
}
public static void EnableSkill(CCSPlayerController player)
@ -34,19 +35,6 @@ namespace src.player.skills
SkillUtils.TryGiveWeapon(player, player.Team == CsTeam.CounterTerrorist ? CsItem.IncendiaryGrenade : CsItem.Molotov);
}
private static void RestoreHealth(CCSPlayerController victim, float damage)
{
var playerPawn = victim.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return;
var newHealth = playerPawn.Health + damage;
if (newHealth > 100)
newHealth = 100;
playerPawn.Health = (int)newHealth;
Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_iHealth");
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#3c47de", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float regenerationMultiplier = 1.5f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
{
public float RegenerationMultiplier { get; set; } = regenerationMultiplier;

View file

@ -1,14 +1,11 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
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 System.Numerics;
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
using static src.jRandomSkills;
@ -170,22 +167,9 @@ namespace src.player.skills
Vector eyePos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 25);
endPos.Z += 25;
Ray ray = new(Vector3.Zero);
CTraceFilter filter = new(playerPawn.Index, playerPawn.Index)
{
m_nObjectSetMask = 0xf,
m_nCollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_PLAYER_MOVEMENT,
m_nInteractsWith = playerPawn.GetInteractsWith(),
m_nInteractsExclude = 0,
m_nBits = 11,
m_bIterateEntities = true,
m_bHitTriggers = false,
m_nInteractsAs = 0x40000
};
filter.m_nHierarchyIds[0] = playerPawn.GetHierarchyId();
filter.m_nHierarchyIds[1] = 0;
CGameTrace trace = TraceRay.TraceHull(eyePos, endPos, filter, ray);
ulong mask = playerPawn.Collision.CollisionAttribute.InteractsWith;
ulong contents = playerPawn.Collision.CollisionGroup;
CGameTrace trace = TraceRay.TraceShape(eyePos, endPos, mask, contents, player);
return !trace.DidHit();
}
@ -225,9 +209,7 @@ namespace src.player.skills
if (playersInfo.TryGetValue(victim, out var playerSkill) && playerSkill.CloneProp != null)
{
KillClone(playerSkill);
var victimPawn = victim.PlayerPawn.Value;
if (victimPawn == null) return;
SkillUtils.AddHealth(victimPawn, @event.DmgHealth);
SkillUtils.RestoreHealth(victim);
}
}

View file

@ -47,7 +47,7 @@ namespace src.player.skills
if (!victim.IsValid || !victim.PawnIsAlive || !skillInfo.CanUse) return;
skillInfo.CanUse = false;
skillInfo.Cooldown = DateTime.Now;
RestoreHealth(victim, damage);
SkillUtils.RestoreHealth(victim);
}
}
@ -88,19 +88,6 @@ namespace src.player.skills
playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
}
private static void RestoreHealth(CCSPlayerController victim, float damage)
{
var playerPawn = victim.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return;
var newHealth = playerPawn.Health + damage;
if (newHealth > 100)
newHealth = 100;
playerPawn.Health = (int)newHealth;
Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_iHealth");
}
public class PlayerSkillInfo
{
public ulong SteamID { get; set; }

View file

@ -20,6 +20,12 @@ namespace src.player.skills
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo == null) return;
int moneyBonus = Instance.Random.Next(SkillsInfo.GetValue<int>(skillName, "minMoney"), SkillsInfo.GetValue<int>(skillName, "maxMoney"));
var moneyServices = player.InGameMoneyServices;
if (moneyServices == null) return;
moneyBonus = Math.Min(moneyBonus, 16000 - moneyServices.Account);
playerInfo.SkillChance = moneyBonus;
AddMoney(player, moneyBonus);
}
@ -28,16 +34,22 @@ namespace src.player.skills
{
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo == null) return;
AddMoney(player, -(int)(playerInfo.SkillChance ?? 0));
var moneyServices = player.InGameMoneyServices;
if (moneyServices == null) return;
player.PrintToChat(moneyServices.CashSpentThisRound.ToString());
int money = Math.Abs((int)playerInfo.SkillChance! - moneyServices.CashSpentThisRound);
AddMoney(player, -money, 3000);
}
private static void AddMoney(CCSPlayerController player, int money)
private static void AddMoney(CCSPlayerController player, int money, int minimum = 0)
{
if (player == null || !player.IsValid) return;
var moneyServices = player.InGameMoneyServices;
if (moneyServices == null) return;
moneyServices.Account = Math.Min(Math.Max(moneyServices.Account + money, 0), 16000);
moneyServices.Account = Math.Clamp(moneyServices.Account + money, minimum, 16000);
Utilities.SetStateChanged(player, "CCSPlayerController", "m_pInGameMoneyServices");
}

View file

@ -1,10 +1,8 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
using CS2TraceRay.Class;
using CS2TraceRay.Struct;
using System.Numerics;
using static src.jRandomSkills;
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
using System.Collections.Concurrent;
@ -69,29 +67,18 @@ namespace src.player.skills
{
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
if (playerInfo == null) return;
playerInfo.PrintHTML = $"{player.GetTranslation("shade_nospace")}";
playerInfo.PrintHTML = $"<font color='#FF0000'>{player.GetTranslation("shade_nospace")}</font>";
}
private unsafe static bool CheckTeleport(CCSPlayerController player, Vector startPos, Vector endPos)
{
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return false;
Ray ray = new(new Vector3(-16, -16, -0), new Vector3(16, 16, 72));
CTraceFilter filter = new(pawn.Index, pawn.Index)
{
m_nObjectSetMask = 0xf,
m_nCollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_PLAYER_MOVEMENT,
m_nInteractsWith = pawn.GetInteractsWith(),
m_nInteractsExclude = 0,
m_nBits = 11,
m_bIterateEntities = true,
m_bHitTriggers = false,
m_nInteractsAs = 0x40000
};
filter.m_nHierarchyIds[0] = pawn.GetHierarchyId();
filter.m_nHierarchyIds[1] = 0;
CGameTrace trace = TraceRay.TraceHull(startPos, endPos, filter, ray);
ulong mask = pawn.Collision.CollisionAttribute.InteractsWith;
ulong contents = pawn.Collision.CollisionGroup;
CGameTrace trace = TraceRay.TraceShape(startPos, endPos, mask, contents, player);
return !trace.HitWorld(out _);
}

View file

@ -26,6 +26,8 @@ namespace src.player.skills
var plantedBomb = Utilities.FindAllEntitiesByDesignerName<CPlantedC4>("planted_c4").FirstOrDefault();
if (plantedBomb != null)
Server.NextFrame(() => plantedBomb.C4Blow = (float)Server.EngineTime + SkillsInfo.GetValue<int>(skillName, "detonationTime"));
player!.PrintToCenterAlert(player.GetTranslation("bombplanted", SkillsInfo.GetValue<int>(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)

View file

@ -1,19 +1,23 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
using System.Collections.Concurrent;
using System.Drawing;
using static src.jRandomSkills;
namespace src.player.skills
{
public class SniperElite : ISkill
{
private const Skills skillName = Skills.SniperElite;
private static readonly ConcurrentDictionary<ulong, List<CEntityInstance>> playerAWPs = [];
private static readonly ConcurrentDictionary<ulong, string> sniperElites = [];
private static readonly ConcurrentDictionary<ulong, List<uint>> playerAWPIndexes = [];
private static readonly ConcurrentDictionary<ulong, string> savedWeapons = [];
private static readonly ConcurrentDictionary<ulong, byte> isProcessing = [];
private static readonly object setLock = new();
private const string weapon_awp = "weapon_awp";
private static readonly string[] rifles = [ "weapon_mp9", "weapon_mac10", "weapon_bizon", "weapon_mp7", "weapon_ump45", "weapon_p90",
"weapon_mp5sd", "weapon_famas", "weapon_galilar", "weapon_m4a1", "weapon_m4a1_silencer", "weapon_ak47",
"weapon_aug", "weapon_sg553", "weapon_ssg08", "weapon_awp", "weapon_scar20", "weapon_g3sg1",
@ -29,8 +33,9 @@ namespace src.player.skills
lock (setLock)
{
sniperElites.Clear();
playerAWPs.Clear();
savedWeapons.Clear();
playerAWPIndexes.Clear();
isProcessing.Clear();
}
}
@ -38,6 +43,7 @@ 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)
DisableSkill(player);
@ -47,118 +53,169 @@ 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)
{
if (rifles.Contains(@event.Item) && @event.Item != weapon_awp)
savedWeapons.AddOrUpdate(player.SteamID, string.Empty, (_, _) => string.Empty);
DeleteDroppedAWP(player);
}
}
public static void EnableSkill(CCSPlayerController player)
{
sniperElites.TryAdd(player.SteamID, "weapon_awp");
savedWeapons.TryAdd(player.SteamID, string.Empty);
}
public static void DisableSkill(CCSPlayerController player)
{
sniperElites.TryRemove(player.SteamID, out _);
playerAWPs.TryRemove(player.SteamID, out _);
player.ExecuteClientCommand("slot3");
if (playerAWPIndexes.TryGetValue(player.SteamID, out var AWPs))
foreach (var index in AWPs.ToList())
{
var ent = Utilities.GetEntityFromIndex<CBaseEntity>((int)index);
if (ent != null && ent.IsValid)
ent.AcceptInput("Kill");
}
if (savedWeapons.TryGetValue(player.SteamID, out string? savedWeapon) && !string.IsNullOrWhiteSpace(savedWeapon))
Server.NextFrame(() =>
player.PlayerPawn.Value?.ItemServices?.As<CCSPlayer_ItemServices>().GiveNamedItem<CEntityInstance>(savedWeapon));
Server.NextFrame(() => player.ExecuteClientCommand("lastinv"));
savedWeapons.TryRemove(player.SteamID, out _);
playerAWPIndexes.TryRemove(player.SteamID, out _);
isProcessing.TryRemove(player.SteamID, out _);
}
public static void UseSkill(CCSPlayerController player)
{
var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return;
if (sniperElites.ContainsKey(player.SteamID))
if (player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid || isProcessing.ContainsKey(player.SteamID)) return;
if (savedWeapons.ContainsKey(player.SteamID))
RemoveAndGiveWeapon(player);
}
private static void RemoveAndGiveWeapon(CCSPlayerController player)
{
string holdedWeapon = "weapon_awp";
if (sniperElites.TryGetValue(player.SteamID, out string? weapon))
if (!string.IsNullOrEmpty(weapon))
holdedWeapon = weapon;
ulong steamID = player.SteamID;
try
{
if (!isProcessing.TryAdd(steamID, 0)) return;
CBasePlayerWeapon? activeRifle = GetActiveRifle(player);
string weaponToGive = weapon_awp;
if (activeRifle != null && activeRifle.IsValid)
RemoveWeapon(player, activeRifle.DesignerName);
{
string currentWeaponName = SkillUtils.GetDesignerName(activeRifle);
bool isScriptAWP = false;
sniperElites.TryAdd(player.SteamID, (activeRifle != null && activeRifle.IsValid) ? SkillUtils.GetDesignerName(activeRifle) : "weapon_awp");
Server.NextFrame(() => {
string weapon = holdedWeapon ?? "weapon_awp";
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return;
var createdWeapon = player.PlayerPawn.Value?.ItemServices?.As<CCSPlayer_ItemServices>().GiveNamedItem<CEntityInstance>(weapon);
lock (setLock)
isScriptAWP = playerAWPIndexes.TryGetValue(steamID, out var indexes) && indexes.Contains(activeRifle.Index);
if (createdWeapon != null && createdWeapon.IsValid && createdWeapon.DesignerName == "weapon_awp")
if (isScriptAWP)
{
lock (setLock)
if (savedWeapons.TryGetValue(steamID, out var savedWeapon) && !string.IsNullOrEmpty(savedWeapon))
{
if (playerAWPs.TryGetValue(player.SteamID, out var list))
list.Add(createdWeapon);
else
playerAWPs.TryAdd(player.SteamID, [createdWeapon]);
weaponToGive = savedWeapon;
savedWeapons.AddOrUpdate(steamID, string.Empty, (_, _) => string.Empty);
}
else
{
isProcessing.TryRemove(steamID, out _);
return;
}
}
else
{
savedWeapons.AddOrUpdate(steamID, currentWeaponName, (_, _) => currentWeaponName);
weaponToGive = weapon_awp + "_script";
}
activeRifle.AcceptInput("Kill");
}
else
{
if (savedWeapons.TryGetValue(steamID, out string? savedWeapon) && !string.IsNullOrEmpty(savedWeapon))
{
weaponToGive = savedWeapon;
savedWeapons.AddOrUpdate(steamID, string.Empty, (_, _) => string.Empty);
}
else
weaponToGive = weapon_awp + "_script";
}
Server.NextFrame(() =>
{
if (player != null && player.IsValid && player.PlayerPawn.Value != null && player.PlayerPawn.Value.IsValid)
{
var createdWeapon = player.PlayerPawn.Value?.ItemServices?.As<CCSPlayer_ItemServices>().GiveNamedItem<CEntityInstance>(weaponToGive.Replace("_script", ""));
if (createdWeapon != null && createdWeapon.IsValid && weaponToGive.EndsWith("_script"))
{
CBasePlayerWeapon weapon = createdWeapon.As<CBasePlayerWeapon>();
if (weapon?.AttributeManager.Item.NetworkedDynamicAttributes != null)
weapon.AttributeManager.Item.CustomName = player.GetTranslation("sniperelite_customname");
lock (setLock)
{
if (!playerAWPIndexes.ContainsKey(steamID))
playerAWPIndexes.TryAdd(steamID, []);
if (playerAWPIndexes.TryGetValue(steamID, out var list))
list.Add(createdWeapon.Index);
}
}
}
DeleteDroppedAWP(player);
isProcessing.TryRemove(steamID, out _);
});
}
catch { }
catch {
isProcessing.TryRemove(steamID, out _);
}
}
private static void DeleteDroppedAWP(CCSPlayerController player)
private static void DeleteDroppedAWP(CCSPlayerController? player)
{
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return;
var weaponServices = pawn.WeaponServices;
if (weaponServices == null) return;
if (player == null || !player.IsValid) return;
ConcurrentBag<uint> playerWeapons = [.. weaponServices.MyWeapons.Where(w => w != null && w.IsValid && w.Value != null && w.Value.IsValid)
.Select(w => w.Value!.Index)];
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.WeaponServices == null) return;
var myWeapons = pawn.WeaponServices.MyWeapons;
ConcurrentBag<uint> myWeaponsIndexes = [.. myWeapons
.Where(w => w != null && w.IsValid && w.Value != null && w.Value.IsValid)
.Select(w => w.Value!.Index)];
lock (setLock)
{
if (playerAWPs.TryGetValue(player.SteamID, out var AWPs))
foreach (var awp in AWPs.ToList())
{
if (awp != null && awp.IsValid)
if (playerAWPIndexes.TryGetValue(player.SteamID, out var AWPs))
foreach (var index in AWPs.ToList())
if (!myWeaponsIndexes.Contains(index))
{
if (!playerWeapons.Contains(awp.Index))
{
awp.AcceptInput("Kill");
AWPs.Remove(awp);
}
var ent = Utilities.GetEntityFromIndex<CBaseEntity>((int)index);
if (ent != null && ent.IsValid)
ent.AcceptInput("Kill");
AWPs.Remove(index);
}
else
AWPs.Remove(awp!);
}
}
}
private static CBasePlayerWeapon? GetActiveRifle(CCSPlayerController player)
{
CBasePlayerWeapon? rifle = null;
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return rifle;
var weaponServices = pawn.WeaponServices;
if (weaponServices == null) return rifle;
foreach (var weapon in weaponServices.MyWeapons)
if (weapon != null && weapon.IsValid && weapon.Value != null && weapon.Value.IsValid)
if (rifles.Contains(weapon.Value.DesignerName))
rifle = weapon.Value;
return rifle;
}
private static void RemoveWeapon(CCSPlayerController player, string designerName)
{
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.WeaponServices == null) return;
foreach (var item in pawn.WeaponServices.MyWeapons)
if (item != null && item.IsValid && item.Value != null && item.Value.IsValid && item.Value.DesignerName == designerName)
item.Value.AcceptInput("Kill");
if (pawn == null || !pawn.IsValid || pawn.WeaponServices == null) return null;
var activeWeapon = pawn.WeaponServices?.ActiveWeapon.Value;
if (activeWeapon != null && activeWeapon.IsValid && rifles.Contains(activeWeapon.DesignerName))
return activeWeapon;
return null;
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#e0873a", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)

View file

@ -5,6 +5,7 @@ using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
using static src.jRandomSkills;
namespace src.player.skills
@ -19,7 +20,8 @@ namespace src.player.skills
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void NewRound()

View file

@ -21,11 +21,6 @@ namespace src.player.skills
bombPlanted = false;
}
public static void DisableSkill(CCSPlayerController player)
{
SkillUtils.ResetPrintHTML(player);
}
public static void BombPlanted(EventBombPlanted _)
{
bombPlanted = true;
@ -56,30 +51,10 @@ namespace src.player.skills
else
Localization.PrintTranslationToChatAll($" {ChatColors.LightBlue}{{0}}", ["watchmaker_ct"], [roundTime]);
player.EmitSound(SkillsInfo.GetValue<string>(skillName, "SoundEvent"));
}
public static void OnTick()
{
if (bombPlanted) return;
if (SkillUtils.IsFreezeTime()) return;
foreach (var player in Utilities.GetPlayers())
{
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo?.Skill == skillName)
UpdateHUD(player);
}
}
private static void UpdateHUD(CCSPlayerController player)
{
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName);
if (skillData == null || Instance?.GameRules == null || Instance?.GameRules?.RoundTime == null || Instance.GameRules?.RoundStartTime == null) return;
int seconds = 1 + (int)(Instance.GameRules.RoundTime - (Server.CurrentTime - Instance.GameRules.RoundStartTime));
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
if (playerInfo == null) return;
playerInfo.PrintHTML = SkillUtils.SecondsToTimer(seconds);
var proxy = Utilities.FindAllEntitiesByDesignerName<CCSGameRulesProxy>("cs_gamerules").FirstOrDefault();
if (proxy == null) return;
Utilities.SetStateChanged(proxy, "CCSGameRulesProxy", "m_pGameRules");
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff462e", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int changeRoundTime = 7, string soundEvent = "UIPanorama.sidemenu_select") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)