v1.2.3.b1

Revive skills (Second Chance / Phoenix / Re-Zombie) — unified "on death" logic:
- Intercept the lethal hit before it is applied. Previously they reacted after the death was already committed, so one-shots, fall damage and skill-based kills were missed (Phoenix and Re-Zombie were rewritten from a post-death handler to pre-damage interception).

Killer Flash:
- Kills through real damage instead of forcing a suicide, so revive skills can intercept.

Baseball:
- Fixed a rare server crash from decoy grenades: a freed decoy's entity index could be reused by another entity and written to (use-after-free). Decoy tracking is now validated per tick (DesignerName gate) and cleared every round.

Native crash hardening:
- Aimbot: guard the hit-group native pointer before writing (avoids writing to freed/null memory).
- Wallhack: detach the glow when the target dies or disconnects (stale FollowEntity on a freed pawn).
- Spectator / Cypher / FalconEye / ThirdEye: null-guard the camera SceneNode walk and re-validate the target before teleport/parent (cross-frame freed-entity deref).
- CServerSideClient.ForceFullUpdate now bails on a null client handle.

Performance:
- Added a per-tick player/bomb cache (PlayerManager.GetTickPlayers / GetTickBomb).
- Migrated 82 skills from per-skill Utilities.GetPlayers() to the one shared per-tick scan, and the HUD loop reuses it. Much lower per-tick cost at high player counts (verified 10v10).

RayTrace:
- Prints a single notice when the module is not installed; dependent skills (Long Zeus, Long Knife, Iana, Cypher, Noclip, Shade + the skill-use aim check) no-op instead of failing silently (#43).
This commit is contained in:
ByDexter 2026-07-26 17:49:36 +03:00
parent c7ee500957
commit 0e86f54e0a
113 changed files with 717 additions and 437 deletions

View file

@ -31,7 +31,7 @@ namespace src
public override string ModuleName => "[CS2] [ jRandomSkills ]"; public override string ModuleName => "[CS2] [ jRandomSkills ]";
public override string ModuleAuthor => "D3X (Original), Juzlus (Modifier), ByDexterTR (Contributor)"; public override string ModuleAuthor => "D3X (Original), Juzlus (Modifier), ByDexterTR (Contributor)";
public override string ModuleDescription => "Plugin adds random skills every round for CS2 by D3X. Modified by Juzlus."; public override string ModuleDescription => "Plugin adds random skills every round for CS2 by D3X. Modified by Juzlus.";
public override string ModuleVersion => "1.2.2.b9"; public override string ModuleVersion => "1.2.3.b1";
public override void Load(bool hotReload) public override void Load(bool hotReload)
{ {

View file

@ -138,7 +138,7 @@ namespace src.player
return candidates[Random.Shared.Next(candidates.Count)]; return candidates[Random.Shared.Next(candidates.Count)];
} }
private static readonly Skills[] lateDamageSkills = [Skills.SecondLife]; private static readonly Skills[] lateDamageSkills = [Skills.SecondLife, Skills.Phoenix, Skills.ReZombie];
private static readonly HashSet<Skills> tickFailuresLogged = []; private static readonly HashSet<Skills> tickFailuresLogged = [];
@ -1083,7 +1083,8 @@ namespace src.player
var validPlayers = Utilities.GetPlayers() var validPlayers = Utilities.GetPlayers()
.Where(p => p != null && p.IsValid && !p.IsHLTV) .Where(p => p != null && p.IsValid && !p.IsHLTV)
.Where(p => { .Where(p =>
{
try { return p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist; } try { return p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist; }
catch { return false; } catch { return false; }
}).ToList(); }).ToList();
@ -1350,18 +1351,25 @@ namespace src.player
long perfStart = PerfLog.Start(); long perfStart = PerfLog.Start();
lock (setLock) lock (setLock)
{ {
// Keep dying entities out of snapshots until the engine processes the kill. try
var dying = EntityManager.GetRecentlyDestroyedSnapshot();
if (dying.Count > 0)
{ {
foreach (var (info, player) in infoList) // Keep dying entities out of snapshots until the engine processes the kill.
var dying = EntityManager.GetRecentlyDestroyedSnapshot();
if (dying.Count > 0)
{ {
if (player == null || !player.IsValid) continue; foreach (var (info, player) in infoList)
foreach (var entityIndex in dying) {
if (info.TransmitEntities.Contains(entityIndex)) if (player == null || !player.IsValid) continue;
info.TransmitEntities.Remove(entityIndex); foreach (var entityIndex in dying)
if (info.TransmitEntities.Contains(entityIndex))
info.TransmitEntities.Remove(entityIndex);
}
} }
} }
catch (Exception ex)
{
Server.PrintToConsole($"[jRandomSkills] CheckTransmit dying-filter failed: {ex.Message}");
}
DispatchToActiveSkills("CheckTransmit", infoList); DispatchToActiveSkills("CheckTransmit", infoList);
} }

View file

@ -25,7 +25,9 @@ namespace src.player
} }
long perfStart = PerfLog.Start(); long perfStart = PerfLog.Start();
foreach (var player in Utilities.GetPlayers()) // Shared per-tick controller snapshot: the skill OnTick loop already scans the
// player list this frame, so reuse that native scan instead of running a second one.
foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (player != null && player.IsValid) if (player != null && player.IsValid)
UpdatePlayerHud(player); UpdatePlayerHud(player);

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using System.Collections.Concurrent; using System.Collections.Concurrent;
@ -25,7 +25,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (player == null || !player.IsValid) continue; if (player == null || !player.IsValid) continue;
@ -105,7 +105,7 @@ namespace src.player.skills
var myEyePos = new Vector(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z); var myEyePos = new Vector(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z);
var enemy = Utilities.GetPlayers() var enemy = PlayerManager.GetTickPlayers()
.Where(p => p.IsValid && p.PawnIsAlive && p.Team != player.Team && p.PlayerPawn.Value != null && p.PlayerPawn.Value.AbsOrigin != null) .Where(p => p.IsValid && p.PawnIsAlive && p.Team != player.Team && p.PlayerPawn.Value != null && p.PlayerPawn.Value.AbsOrigin != null)
.OrderBy(p => (p.PlayerPawn.Value!.AbsOrigin! - pawn.AbsOrigin).LengthSqr()) .OrderBy(p => (p.PlayerPawn.Value!.AbsOrigin! - pawn.AbsOrigin).LengthSqr())
.FirstOrDefault(); .FirstOrDefault();

View file

@ -2,7 +2,6 @@
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Collections.Concurrent;
using src.utils; using src.utils;
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
@ -11,7 +10,6 @@ namespace src.player.skills
public class Aimbot : ISkill public class Aimbot : ISkill
{ {
private const Skills skillName = Skills.Aimbot; private const Skills skillName = Skills.Aimbot;
private static readonly ConcurrentDictionary<nint, int> hitGroups = [];
public static void LoadSkill() public static void LoadSkill()
{ {
@ -35,10 +33,11 @@ namespace src.player.skills
var attackerController = attackerPawn.Controller.Value; var attackerController = attackerPawn.Controller.Value;
if (attackerController == null || !attackerController.IsValid) return; if (attackerController == null || !attackerController.IsValid) return;
var attacker = PlayerManager.GetPlayerEvent(attackerController.As<CCSPlayerController>())!; var attacker = PlayerManager.GetPlayerEvent(attackerController.As<CCSPlayerController>());
if (attacker == null) return;
var playerInfo = PlayerManager.GetPlayerByIndex(attacker.Index); var playerInfo = PlayerManager.GetPlayerByIndex(attacker.Index);
if (playerInfo == null) return; if (playerInfo == null || playerInfo.Skill != skillName) return;
int offset = GameData.GetOffset("CTakeDamageInfo_HitGroup"); int offset = GameData.GetOffset("CTakeDamageInfo_HitGroup");
if (offset <= 0) return; if (offset <= 0) return;
@ -46,32 +45,10 @@ namespace src.player.skills
nint hitGroupPointer = Marshal.ReadIntPtr(param2.Handle, offset); nint hitGroupPointer = Marshal.ReadIntPtr(param2.Handle, offset);
if (hitGroupPointer == nint.Zero) return; if (hitGroupPointer == nint.Zero) return;
nint hitGroupOffset = Marshal.ReadIntPtr(hitGroupPointer, 16); nint hitGroupData = Marshal.ReadIntPtr(hitGroupPointer, 16);
if (hitGroupOffset == nint.Zero) return; if (hitGroupData == nint.Zero) return;
if (playerInfo.Skill == skillName) Marshal.WriteInt32(hitGroupData, 56, (int)HitGroup_t.HITGROUP_HEAD);
{
hitGroups.TryAdd(hitGroupOffset, Marshal.ReadInt32(hitGroupOffset, 56));
Marshal.WriteInt32(hitGroupOffset, 56, (int)HitGroup_t.HITGROUP_HEAD);
}
else if (hitGroups.TryGetValue(hitGroupOffset, out var hitGroup))
Marshal.WriteInt32(hitGroupOffset, 56, hitGroup);
}
public static void NewRound()
{
hitGroups.Clear();
}
public static void DisableSkill(CCSPlayerController _)
{
foreach (var hit in hitGroups)
{
if (hit.Key != nint.Zero)
Marshal.WriteInt32(hit.Key, 56, hit.Value);
}
hitGroups.Clear();
} }
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff0000", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = Rarity.Common) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity) public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff0000", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = Rarity.Common) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
@ -27,7 +27,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (player == null || !player.IsValid) continue; if (player == null || !player.IsValid) continue;

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
@ -20,7 +20,7 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (player != null && player.IsValid) if (player != null && player.IsValid)
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
@ -65,7 +65,7 @@ namespace src.player.skills
playersToTarget[player.Index] = targetSite.Index; playersToTarget[player.Index] = targetSite.Index;
string siteLetter = site == 0 ? "A" : "B"; string siteLetter = site == 0 ? "A" : "B";
foreach (var ct in Utilities.GetPlayers().Where(p => p != null && p.IsValid && !p.IsHLTV && p.Team == CsTeam.CounterTerrorist)) foreach (var ct in PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid && !p.IsHLTV && p.Team == CsTeam.CounterTerrorist))
ct.PrintToChat($" {ChatColors.Green}" + ct.GetTranslation("areareaper_teammates_info", siteLetter)); ct.PrintToChat($" {ChatColors.Green}" + ct.GetTranslation("areareaper_teammates_info", siteLetter));
} }
} }
@ -111,7 +111,7 @@ namespace src.player.skills
{ {
if (Server.TickCount % 16 != 0) return; if (Server.TickCount % 16 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
var playerEvent = PlayerManager.GetPlayerFromEvent(player); var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid || player == null || !player.IsValid || player.Team != CsTeam.Terrorist || player.PlayerPawn?.Value?.Health <= 0) continue; if (playerEvent == null || !playerEvent.IsValid || player == null || !player.IsValid || player.Team != CsTeam.Terrorist || player.PlayerPawn?.Value?.Health <= 0) continue;

View file

@ -28,7 +28,7 @@ namespace src.player.skills
newScale = (float)Math.Round(newScale, 2); newScale = (float)Math.Round(newScale, 2);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newScale)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newScale)}",
border: !Utilities.GetPlayers().Any(p => p.IsValid && p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p.IsValid && p.Team == player.Team && p != player) ? "tb" : "t");
} }
public static void OnTakeDamage(DynamicHook h) public static void OnTakeDamage(DynamicHook h)

View file

@ -22,7 +22,7 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (player != null && player.IsValid) if (player != null && player.IsValid)
DisableSkill(player); DisableSkill(player);
@ -54,7 +54,7 @@ namespace src.player.skills
playerInfo.SkillChance = gravityModifier; playerInfo.SkillChance = gravityModifier;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, gravityModifier)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, gravityModifier)}",
border: !Utilities.GetPlayers().Any(p => p.IsValid && p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p.IsValid && p.Team == player.Team && p != player) ? "tb" : "t");
pawn.ActualGravityScale = gravityModifier; pawn.ActualGravityScale = gravityModifier;
} }

View file

@ -17,7 +17,7 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (player != null && player.IsValid) if (player != null && player.IsValid)
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
@ -28,14 +28,14 @@ namespace src.player.skills
{ {
if (Server.TickCount % 32 != 0) return; if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (player == null || !player.IsValid || !SkillUtils.HasMenu(player)) continue; if (player == null || !player.IsValid || !SkillUtils.HasMenu(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue; if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = []; ConcurrentBag<(string, string)> menuItems = [];
foreach (var e in enemies) foreach (var e in enemies)
@ -58,7 +58,7 @@ namespace src.player.skills
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p => p.IsValid && p.PlayerPawn?.Value?.Health > 0 && p.Team != player.Team && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p.IsValid && p.PlayerPawn?.Value?.Health > 0 && p.Team != player.Team && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"\u202A{e.PlayerName}\u202C : {(e.InGameMoneyServices?.Account ?? 0)}$", e.Index.ToString()))]; ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"\u202A{e.PlayerName}\u202C : {(e.InGameMoneyServices?.Account ?? 0)}$", e.Index.ToString()))];

View file

@ -18,6 +18,12 @@ namespace src.player.skills
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color")); SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
} }
public static void NewRound()
{
decoys.Clear();
playersWithSkill.Clear();
}
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var victim = PlayerManager.GetPlayerEvent(@event.Userid); var victim = PlayerManager.GetPlayerEvent(@event.Userid);
@ -93,7 +99,7 @@ namespace src.player.skills
{ {
var decoy = Utilities.GetEntityFromIndex<CDecoyProjectile>((int)decoyIndex); var decoy = Utilities.GetEntityFromIndex<CDecoyProjectile>((int)decoyIndex);
if (decoy == null || !decoy.IsValid) if (decoy == null || !decoy.IsValid || decoy.DesignerName != "decoy_projectile")
{ {
decoys.TryRemove(decoyIndex, out _); decoys.TryRemove(decoyIndex, out _);
continue; continue;

View file

@ -35,7 +35,7 @@ namespace src.player.skills
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom"); float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
playerInfo.SkillChance = newChance; playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
private static void RotateEnemy(CCSPlayerController player) private static void RotateEnemy(CCSPlayerController player)

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
@ -20,7 +20,7 @@ namespace src.player.skills
{ {
var modifier = SkillsInfo.GetValue<float>(skillName, "velocityModifier"); var modifier = SkillsInfo.GetValue<float>(skillName, "velocityModifier");
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (player == null || !player.IsValid) continue; if (player == null || !player.IsValid) continue;

View file

@ -18,7 +18,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (player == null || !player.IsValid) continue; if (player == null || !player.IsValid) continue;

View file

@ -67,11 +67,9 @@ namespace src.player.skills
{ {
if (Server.TickCount % 2 != 0) return; if (Server.TickCount % 2 != 0) return;
var bomb = invisiblePlayers.IsEmpty var bomb = invisiblePlayers.IsEmpty ? null : PlayerManager.GetTickBomb();
? null
: Utilities.FindAllEntitiesByDesignerName<CC4>("weapon_c4").FirstOrDefault();
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (player.PlayerPawn?.Value?.Health <= 0 && invisiblePlayers.ContainsKey(player.Index)) if (player.PlayerPawn?.Value?.Health <= 0 && invisiblePlayers.ContainsKey(player.Index))
{ {
@ -105,8 +103,7 @@ namespace src.player.skills
{ {
if (invisiblePlayers.IsEmpty) return; if (invisiblePlayers.IsEmpty) return;
var bomb = Utilities.FindAllEntitiesByDesignerName<CC4>("weapon_c4").FirstOrDefault(); var bomb = PlayerManager.GetTickBomb();
if (bomb != null && !bomb.IsValid) bomb = null;
foreach (var (info, player) in infoList) foreach (var (info, player) in infoList)
{ {

View file

@ -26,7 +26,7 @@ namespace src.player.skills
{ {
lock (setLock) lock (setLock)
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
DisableSkill(player); DisableSkill(player);
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
@ -42,13 +42,13 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
if (Server.TickCount % 32 != 0) return; if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue; if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))]; ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))];
SkillUtils.UpdateMenu(player, menuItems); SkillUtils.UpdateMenu(player, menuItems);
@ -72,7 +72,8 @@ namespace src.player.skills
string enemyId = commands[0]; string enemyId = commands[0];
if (!uint.TryParse(enemyId, out uint enemyIndex)) { if (!uint.TryParse(enemyId, out uint enemyIndex))
{
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")); playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index"));
return; return;
} }
@ -105,7 +106,7 @@ namespace src.player.skills
var playerEvent = PlayerManager.GetPlayerFromEvent(player); var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return; if (playerEvent == null || !playerEvent.IsValid) return;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))]; ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))];
@ -121,7 +122,7 @@ namespace src.player.skills
if (eventPlayer == null || !eventPlayer.IsValid) return; if (eventPlayer == null || !eventPlayer.IsValid) return;
var player = PlayerManager.GetPlayerEvent(@event.Userid); var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return; if (playerPawn == null || !playerPawn.IsValid) return;
@ -146,7 +147,7 @@ namespace src.player.skills
{ {
if (lastShot.TryRemove(playerIndex, out bool didHit) && !didHit) if (lastShot.TryRemove(playerIndex, out bool didHit) && !didHit)
{ {
eventPlayer.ExecuteClientCommand($"play player/player_damagebody_0{Instance.Random.Next(4,8)}"); eventPlayer.ExecuteClientCommand($"play player/player_damagebody_0{Instance.Random.Next(4, 8)}");
SkillUtils.TakeHealth(playerPawn, SkillsInfo.GetValue<int>(skillName, "damageAfterMiss")); SkillUtils.TakeHealth(playerPawn, SkillsInfo.GetValue<int>(skillName, "damageAfterMiss"));
} }
lastShot.TryRemove(playerIndex, out _); lastShot.TryRemove(playerIndex, out _);

View file

@ -39,7 +39,7 @@ namespace src.player.skills
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "chanceTo") - SkillsInfo.GetValue<float>(skillName, "chanceFrom")) + SkillsInfo.GetValue<float>(skillName, "chanceFrom"); float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "chanceTo") - SkillsInfo.GetValue<float>(skillName, "chanceFrom")) + SkillsInfo.GetValue<float>(skillName, "chanceFrom");
playerInfo.SkillChance = newChance; playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FF4500", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = Rarity.Common, float chanceFrom = .2f, float chanceTo = .4f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity) public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FF4500", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = Rarity.Common, float chanceFrom = .2f, float chanceTo = .4f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)

View file

@ -29,7 +29,7 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
SetWeaponAttack(player, false); SetWeaponAttack(player, false);
var chickenIndices = chickens.Values.ToArray(); var chickenIndices = chickens.Values.ToArray();

View file

@ -73,7 +73,7 @@ namespace src.player.skills
float currentTime = Server.CurrentTime; float currentTime = Server.CurrentTime;
float extraTime = SkillsInfo.GetValue<float>(skillName, "bombArmedTime"); float extraTime = SkillsInfo.GetValue<float>(skillName, "bombArmedTime");
foreach (var player in Utilities.GetPlayers().Where(p => p.Team == CsTeam.Terrorist)) foreach (var player in PlayerManager.GetTickPlayers().Where(p => p.Team == CsTeam.Terrorist))
{ {
if (player == null || !player.IsValid) continue; if (player == null || !player.IsValid) continue;

View file

@ -194,7 +194,7 @@ namespace src.player.skills
Timer? cameraTimer = null; Timer? cameraTimer = null;
cameraTimer = jRandomSkills.Instance.AddTimer(2f, () => cameraTimer = jRandomSkills.Instance.AddTimer(2f, () =>
{ {
var target = Utilities.GetPlayers().FirstOrDefault(p => p.IsValid && p.Index == playerIndex); var target = PlayerManager.GetTickPlayers().FirstOrDefault(p => p.IsValid && p.Index == playerIndex);
if (target == null || !target.IsValid || target.LifeState != (byte)LifeState_t.LIFE_ALIVE) if (target == null || !target.IsValid || target.LifeState != (byte)LifeState_t.LIFE_ALIVE)
{ {
cameraTimer?.Kill(); cameraTimer?.Kill();
@ -259,6 +259,7 @@ namespace src.player.skills
Vector diffVector = SkillUtils.GetForwardVector(cameraProp.AbsRotation) * 25; Vector diffVector = SkillUtils.GetForwardVector(cameraProp.AbsRotation) * 25;
Vector finalPos = cameraProp.AbsOrigin + diffVector; Vector finalPos = cameraProp.AbsOrigin + diffVector;
var camRot = new QAngle(cameraProp.AbsRotation.X, cameraProp.AbsRotation.Y, cameraProp.AbsRotation.Z);
uint ownerIndex = EntityManager.SystemOwnerIndex; uint ownerIndex = EntityManager.SystemOwnerIndex;
if (!string.IsNullOrEmpty(cameraProp.Globalname)) if (!string.IsNullOrEmpty(cameraProp.Globalname))
@ -274,11 +275,15 @@ namespace src.player.skills
Server.NextFrame(() => Server.NextFrame(() =>
{ {
if (camera == null || !camera.IsValid) return; if (camera == null || !camera.IsValid) return;
camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
var camNode = camera.CBodyComponent?.SceneNode?.Owner?.Entity;
if (camNode != null)
camNode.Flags = (uint)(camNode.Flags & ~(1 << 2));
camera.SetModel(cameraViewModel); camera.SetModel(cameraViewModel);
camera.Render = Color.FromArgb(1, 255, 255, 255); camera.Render = Color.FromArgb(1, 255, 255, 255);
camera.Teleport(finalPos, cameraProp.AbsRotation); camera.Teleport(finalPos, camRot);
camera.DispatchSpawn(); camera.DispatchSpawn();
EntityManager.RegisterExisting(camera, ownerIndex, "prop_dynamic"); EntityManager.RegisterExisting(camera, ownerIndex, "prop_dynamic");
}); });

View file

@ -38,7 +38,7 @@ namespace src.player.skills
{ {
lock (setLock) lock (setLock)
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (playersInDark.ContainsKey(player.Index)) if (playersInDark.ContainsKey(player.Index))
DisableSkill(player); DisableSkill(player);
@ -52,13 +52,13 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
if (Server.TickCount % 32 != 0) return; if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue; if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 && !p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))]; ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))];
SkillUtils.UpdateMenu(player, menuItems); SkillUtils.UpdateMenu(player, menuItems);
@ -82,7 +82,8 @@ namespace src.player.skills
string enemyId = commands[0]; string enemyId = commands[0];
if (!uint.TryParse(enemyId, out uint enemyIndex)) { if (!uint.TryParse(enemyId, out uint enemyIndex))
{
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")); playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index"));
return; return;
} }
@ -128,7 +129,7 @@ namespace src.player.skills
var playerEvent = PlayerManager.GetPlayerFromEvent(player); var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return; if (playerEvent == null || !playerEvent.IsValid) return;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))]; ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))];
@ -183,7 +184,8 @@ namespace src.player.skills
ApplyColor(player); ApplyColor(player);
Timer? darkTimer = null; Timer? darkTimer = null;
darkTimer = Instance.AddTimer(5f, () => { darkTimer = Instance.AddTimer(5f, () =>
{
if (!playersInDark.ContainsKey(playerIndex)) if (!playersInDark.ContainsKey(playerIndex))
{ {
darkTimer?.Kill(); darkTimer?.Kill();

View file

@ -67,7 +67,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;

View file

@ -18,20 +18,20 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
public static void OnTick() public static void OnTick()
{ {
if (Server.TickCount % 32 != 0) return; if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue; if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = []; ConcurrentBag<(string, string)> menuItems = [];
foreach (var enemy in enemies) foreach (var enemy in enemies)
@ -62,7 +62,8 @@ namespace src.player.skills
string enemyId = commands[0]; string enemyId = commands[0];
if (!uint.TryParse(enemyId, out uint enemyIndex)) { if (!uint.TryParse(enemyId, out uint enemyIndex))
{
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")); playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index"));
return; return;
} }
@ -83,7 +84,7 @@ namespace src.player.skills
var playerEvent = PlayerManager.GetPlayerFromEvent(player); var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return; if (playerEvent == null || !playerEvent.IsValid) return;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = []; ConcurrentBag<(string, string)> menuItems = [];

View file

@ -40,7 +40,7 @@ namespace src.player.skills
deafPlayers.Clear(); deafPlayers.Clear();
playersToTarget.Clear(); playersToTarget.Clear();
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
@ -57,13 +57,13 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
if (Server.TickCount % 32 != 0) return; if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue; if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))]; ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))];
SkillUtils.UpdateMenu(player, menuItems); SkillUtils.UpdateMenu(player, menuItems);
@ -87,7 +87,8 @@ namespace src.player.skills
string enemyId = commands[0]; string enemyId = commands[0];
if (!uint.TryParse(enemyId, out uint enemyIndex)) { if (!uint.TryParse(enemyId, out uint enemyIndex))
{
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")); playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index"));
return; return;
} }
@ -120,7 +121,7 @@ namespace src.player.skills
var playerEvent = PlayerManager.GetPlayerFromEvent(player); var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return; if (playerEvent == null || !playerEvent.IsValid) return;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString())));

View file

@ -37,7 +37,7 @@ namespace src.player.skills
if (player == null || !player.IsValid || player.Team != lastTeam) return; if (player == null || !player.IsValid || player.Team != lastTeam) return;
var pawn = player.PlayerPawn.Value; var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.Health == pawn.MaxHealth) return; if (pawn == null || !pawn.IsValid || pawn.Health == pawn.MaxHealth) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
@ -55,9 +55,9 @@ namespace src.player.skills
SkillUtils.CreateHEGrenadeProjectile(pos, angle, new Vector(0, 0, -10), player.TeamNum); SkillUtils.CreateHEGrenadeProjectile(pos, angle, new Vector(0, 0, -10), player.TeamNum);
foreach (var _p in Utilities.GetPlayers().Where(p => p.IsValid && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist)) foreach (var _p in PlayerManager.GetTickPlayers().Where(p => p.IsValid && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist))
SkillUtils.PrintToChat(_p, $"{ChatColors.DarkRed}\u202A{player.PlayerName}\u202C: {ChatColors.Lime}{_p.GetTranslation("deathbomb_explosion")}", SkillUtils.PrintToChat(_p, $"{ChatColors.DarkRed}\u202A{player.PlayerName}\u202C: {ChatColors.Lime}{_p.GetTranslation("deathbomb_explosion")}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
var fileNames = new[] { "radiobotfallback01", "radiobotfallback02", "radiobotfallback04" }; var fileNames = new[] { "radiobotfallback01", "radiobotfallback02", "radiobotfallback04" };
var randomFile = fileNames[new Random().Next(fileNames.Length)]; var randomFile = fileNames[new Random().Next(fileNames.Length)];

View file

@ -44,7 +44,7 @@ namespace src.player.skills
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "chanceTo") - SkillsInfo.GetValue<float>(skillName, "chanceFrom")) + SkillsInfo.GetValue<float>(skillName, "chanceFrom"); float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "chanceTo") - SkillsInfo.GetValue<float>(skillName, "chanceFrom")) + SkillsInfo.GetValue<float>(skillName, "chanceFrom");
playerInfo.SkillChance = newChance; playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FF4500", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = Rarity.Common, float chanceFrom = .2f, float chanceTo = .35f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity) public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FF4500", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = Rarity.Common, float chanceFrom = .2f, float chanceTo = .35f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)

View file

@ -41,7 +41,7 @@ namespace src.player.skills
string closetEnemy = "Bot"; string closetEnemy = "Bot";
double closetDistance = double.MaxValue; double closetDistance = double.MaxValue;
foreach (var enemy in Utilities.GetPlayers().Where(p => p.Team != player.Team)) foreach (var enemy in PlayerManager.GetTickPlayers().Where(p => p.Team != player.Team))
{ {
var enemyPawn = enemy.PlayerPawn.Value; var enemyPawn = enemy.PlayerPawn.Value;
if (enemyPawn == null || !enemyPawn.IsValid) continue; if (enemyPawn == null || !enemyPawn.IsValid) continue;

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
@ -18,20 +18,20 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
public static void OnTick() public static void OnTick()
{ {
if (Server.TickCount % 32 != 0) return; if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue; if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Index != player.Index && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Index != player.Index && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = []; ConcurrentBag<(string, string)> menuItems = [];
foreach (var enemy in enemies) foreach (var enemy in enemies)
@ -63,7 +63,7 @@ namespace src.player.skills
if (playerEvent == null || !playerEvent.IsValid) return; if (playerEvent == null || !playerEvent.IsValid) return;
string enemyId = commands[0]; string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Index.ToString() == enemyId); var enemy = PlayerManager.GetTickPlayers().FirstOrDefault(p => p.Index.ToString() == enemyId);
if (enemy == null) if (enemy == null)
{ {
@ -79,7 +79,7 @@ namespace src.player.skills
var playerEvent = PlayerManager.GetPlayerFromEvent(player); var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return; if (playerEvent == null || !playerEvent.IsValid) return;
var enemies = Utilities.GetPlayers().Where(p => p != null && p.IsValid && p != player && p.PlayerPawn?.Value?.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid && p != player && p.PlayerPawn?.Value?.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<string> skills = []; ConcurrentBag<string> skills = [];
@ -107,7 +107,7 @@ namespace src.player.skills
SkillUtils.CreateMenu(player, menuItems); SkillUtils.CreateMenu(player, menuItems);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{playerEvent.GetSkillName(skillName)}{ChatColors.Lime}: {playerEvent.GetSkillDescription(skillName)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{playerEvent.GetSkillName(skillName)}{ChatColors.Lime}: {playerEvent.GetSkillDescription(skillName)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
else else
playerEvent.PrintToChat($" {ChatColors.Red}{playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")}"); playerEvent.PrintToChat($" {ChatColors.Red}{playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")}");
@ -160,7 +160,8 @@ namespace src.player.skills
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
if (SkillsInfo.GetValue<bool>(enemySkill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime()) if (SkillsInfo.GetValue<bool>(enemySkill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
Instance?.AddTimer(Math.Max((float)(Event.GetFreezeTimeEnd() - DateTime.Now).TotalSeconds, 0), () => { Instance?.AddTimer(Math.Max((float)(Event.GetFreezeTimeEnd() - DateTime.Now).TotalSeconds, 0), () =>
{
var player = Utilities.GetPlayerFromIndex((int)playerIndex); var player = Utilities.GetPlayerFromIndex((int)playerIndex);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;

View file

@ -17,7 +17,7 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!Instance.IsPlayerValid(player)) continue; if (!Instance.IsPlayerValid(player)) continue;
DisableSkill(player); DisableSkill(player);
@ -38,7 +38,7 @@ namespace src.player.skills
SkillUtils.ChangePlayerScale(player, newSize); SkillUtils.ChangePlayerScale(player, newSize);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newSize)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newSize)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
} }

View file

@ -51,7 +51,7 @@ namespace src.player.skills
//public static void OnTick() //public static void OnTick()
//{ //{
// foreach (var player in Utilities.GetPlayers()) // foreach (var player in PlayerManager.GetTickPlayers())
// { // {
// var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); // var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
// if (playerInfo?.Skill == skillName) // if (playerInfo?.Skill == skillName)
@ -100,7 +100,7 @@ namespace src.player.skills
//private static void MakeShake(CCSPlayerController player) //private static void MakeShake(CCSPlayerController player)
//{ //{
// foreach (var enemy in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.PawnIsAlive)) // foreach (var enemy in PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid && p.PawnIsAlive))
// CreateShake(player); // CreateShake(player);
//} //}

View file

@ -26,12 +26,12 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
if (SkillUtils.IsFreezeTime()) return; if (SkillUtils.IsFreezeTime()) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo)) if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
UpdateHUD(player, skillInfo); UpdateHUD(player, skillInfo);
} }
} }

View file

@ -28,7 +28,7 @@ namespace src.player.skills
playerInfo.SkillChance = newChance; playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
private static void SpawnExplosion(Vector vector) private static void SpawnExplosion(Vector vector)
@ -58,7 +58,7 @@ namespace src.player.skills
}); });
} }
private static bool NearlyEquals(float a, float b, float epsilon = 0.001f) => Math.Abs(a -b) < epsilon; private static bool NearlyEquals(float a, float b, float epsilon = 0.001f) => Math.Abs(a - b) < epsilon;
public static void BulletImpact(EventBulletImpact @event) public static void BulletImpact(EventBulletImpact @event)
{ {

View file

@ -32,7 +32,7 @@ namespace src.player.skills
if (!Instance.IsPlayerValid(player)) return; if (!Instance.IsPlayerValid(player)) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return ; if (playerInfo?.Skill != skillName) return;
var pawn = player!.PlayerPawn.Value; var pawn = player!.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.CameraServices == null) return; if (pawn == null || !pawn.IsValid || pawn.CameraServices == null) return;
@ -58,11 +58,11 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
if (cameras.TryGetValue(player.Index, out var cameraInfo) && cameraInfo.Item2 != 0) if (cameras.TryGetValue(player.Index, out var cameraInfo) && cameraInfo.Item2 != 0)
{ {
var pawn = player.PlayerPawn.Value; var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue; if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue;
if (pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE) if (pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
{ {
@ -122,7 +122,11 @@ namespace src.player.skills
Server.NextFrame(() => Server.NextFrame(() =>
{ {
if (camera == null || !camera.IsValid) return; if (camera == null || !camera.IsValid) return;
camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
var camNode = camera.CBodyComponent?.SceneNode?.Owner?.Entity;
if (camNode != null)
camNode.Flags = (uint)(camNode.Flags & ~(1 << 2));
camera.SetModel("models/sprays/spray_plane.vmdl"); camera.SetModel("models/sprays/spray_plane.vmdl");
camera.Render = Color.FromArgb(0, 255, 255, 255); camera.Render = Color.FromArgb(0, 255, 255, 255);
camera.Teleport(pos, new QAngle(90, 0, 0)); camera.Teleport(pos, new QAngle(90, 0, 0));

View file

@ -31,7 +31,7 @@ namespace src.player.skills
if (userIndex == 0) return; if (userIndex == 0) return;
if (!Instance.footstepSoundEvents.Contains(soundevent)) return; if (!Instance.footstepSoundEvents.Contains(soundevent)) return;
var player = Utilities.GetPlayers().FirstOrDefault(p => p.Pawn?.Value != null && p.Pawn.Value.IsValid && p.Pawn.Value.Index == userIndex); var player = PlayerManager.GetTickPlayers().FirstOrDefault(p => p.Pawn?.Value != null && p.Pawn.Value.IsValid && p.Pawn.Value.Index == userIndex);
if (!Instance.IsPlayerValid(player)) return; if (!Instance.IsPlayerValid(player)) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
@ -62,7 +62,7 @@ namespace src.player.skills
jumpedPlayers.TryAdd(player.Index, 0); jumpedPlayers.TryAdd(player.Index, 0);
playerPawn.VelocityModifier = newSpeed; playerPawn.VelocityModifier = newSpeed;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newSpeed)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newSpeed)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
@ -75,7 +75,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!Instance.IsPlayerValid(player)) continue; if (!Instance.IsPlayerValid(player)) continue;

View file

@ -34,7 +34,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)

View file

@ -49,7 +49,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (Vector decoyPos in decoys.Keys) foreach (Vector decoyPos in decoys.Keys)
foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist)) foreach (var player in PlayerManager.GetTickPlayers().Where(p => p.IsValid && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist))
{ {
var eventPlayer = PlayerManager.GetPlayerEvent(player); var eventPlayer = PlayerManager.GetPlayerEvent(player);
if (eventPlayer == null || !eventPlayer.IsValid) continue; if (eventPlayer == null || !eventPlayer.IsValid) continue;

View file

@ -18,7 +18,7 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
@ -60,7 +60,8 @@ namespace src.player.skills
playerInfo.SkillUsed = true; playerInfo.SkillUsed = true;
if (SkillsInfo.GetValue<bool>(skill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime()) if (SkillsInfo.GetValue<bool>(skill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
Instance?.AddTimer(Math.Max((float)(Event.GetFreezeTimeEnd() - DateTime.Now).TotalSeconds, 0), () => { Instance?.AddTimer(Math.Max((float)(Event.GetFreezeTimeEnd() - DateTime.Now).TotalSeconds, 0), () =>
{
var player = Utilities.GetPlayerFromIndex((int)playerIndex); var player = Utilities.GetPlayerFromIndex((int)playerIndex);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
@ -120,7 +121,7 @@ namespace src.player.skills
List<jSkill_SkillInfo> skillList = [.. SkillData.Skills]; List<jSkill_SkillInfo> skillList = [.. SkillData.Skills];
skillList.RemoveAll(s => s?.Skill == skillPlayer?.Skill || s?.Skill == skillPlayer?.SpecialSkill || s?.Skill == Skills.None); skillList.RemoveAll(s => s?.Skill == skillPlayer?.Skill || s?.Skill == skillPlayer?.SpecialSkill || s?.Skill == Skills.None);
if (Utilities.GetPlayers().FindAll(p => p.Team == player.Team && p.IsValid && !p.IsHLTV && p.Team != CsTeam.Spectator).Count == 1) if (PlayerManager.GetTickPlayers().FindAll(p => p.Team == player.Team && p.IsValid && !p.IsHLTV && p.Team != CsTeam.Spectator).Count == 1)
{ {
SkillsInfo.DefaultSkillInfo[] skillsNeedsTeammates = SkillsInfo.LoadedConfig.Where(s => s.NeedsTeammates).ToArray(); SkillsInfo.DefaultSkillInfo[] skillsNeedsTeammates = SkillsInfo.LoadedConfig.Where(s => s.NeedsTeammates).ToArray();
skillList.RemoveAll(s => skillsNeedsTeammates.Any(s2 => s2.Name == s.Skill.ToString())); skillList.RemoveAll(s => skillsNeedsTeammates.Any(s2 => s2.Name == s.Skill.ToString()));

View file

@ -29,7 +29,7 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
SetWeaponAttack(player, false); SetWeaponAttack(player, false);
invisiblePlayers.Clear(); invisiblePlayers.Clear();
} }
@ -58,7 +58,7 @@ namespace src.player.skills
{ {
if (invisiblePlayers.IsEmpty) return; if (invisiblePlayers.IsEmpty) return;
var bomb = Utilities.FindAllEntitiesByDesignerName<CC4>("weapon_c4").FirstOrDefault(); var bomb = PlayerManager.GetTickBomb();
uint? bombOwnerIndex = bomb != null && bomb.IsValid ? bomb.OwnerEntity?.Index : null; uint? bombOwnerIndex = bomb != null && bomb.IsValid ? bomb.OwnerEntity?.Index : null;
foreach (var (info, player) in infoList) foreach (var (info, player) in infoList)
@ -151,7 +151,7 @@ namespace src.player.skills
{ {
if (Server.TickCount % 2 != 0) return; if (Server.TickCount % 2 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)

View file

@ -41,10 +41,10 @@ namespace src.player.skills
{ {
foreach (var (info, player) in infoList) foreach (var (info, player) in infoList)
{ {
if (player == null) continue; if (player == null || !player.IsValid) continue;
var playerInfo = PlayerManager.GetPlayerByIndex((PlayerManager.GetPlayerEvent(player)?.Index ?? player.Index)); var playerInfo = PlayerManager.GetPlayerByIndex((PlayerManager.GetPlayerEvent(player)?.Index ?? player.Index));
var observedPlayer = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == player?.Pawn?.Value?.ObserverServices?.ObserverTarget?.Value?.Handle); var observedPlayer = PlayerManager.GetTickPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == player?.Pawn?.Value?.ObserverServices?.ObserverTarget?.Value?.Handle);
var observerInfo = observedPlayer != null ? PlayerManager.GetPlayerByIndex(observedPlayer.Index) : null; var observerInfo = observedPlayer != null ? PlayerManager.GetPlayerByIndex(observedPlayer.Index) : null;
if (playerInfo?.Skill != skillName && observerInfo?.Skill != skillName) continue; if (playerInfo?.Skill != skillName && observerInfo?.Skill != skillName) continue;

View file

@ -35,7 +35,7 @@ namespace src.player.skills
{ {
lock (setLock) lock (setLock)
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
DisableSkill(player); DisableSkill(player);
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
@ -49,13 +49,13 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
if (Server.TickCount % 32 != 0) return; if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue; if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString())));
SkillUtils.UpdateMenu(player, menuItems); SkillUtils.UpdateMenu(player, menuItems);
@ -79,7 +79,8 @@ namespace src.player.skills
string enemyId = commands[0]; string enemyId = commands[0];
if (!uint.TryParse(enemyId, out uint enemyIndex)) { if (!uint.TryParse(enemyId, out uint enemyIndex))
{
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")); playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index"));
return; return;
} }
@ -127,7 +128,7 @@ namespace src.player.skills
var playerEvent = PlayerManager.GetPlayerFromEvent(player); var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return; if (playerEvent == null || !playerEvent.IsValid) return;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString())));

View file

@ -42,7 +42,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
@ -101,7 +101,8 @@ namespace src.player.skills
PlayerManager.GetPlayerFromEvent(player)?.PrintToChat($" {ChatColors.Green} {player.GetTranslation("godmode_on")}"); PlayerManager.GetPlayerFromEvent(player)?.PrintToChat($" {ChatColors.Green} {player.GetTranslation("godmode_on")}");
player.PlayerPawn.Value.TakesDamage = false; player.PlayerPawn.Value.TakesDamage = false;
Instance.AddTimer(SkillsInfo.GetValue<float>(skillName, "duration"), () => { Instance.AddTimer(SkillsInfo.GetValue<float>(skillName, "duration"), () =>
{
if (SkillPlayerInfo.TryGetValue(playerIndex, out var skillInfo)) if (SkillPlayerInfo.TryGetValue(playerIndex, out var skillInfo))
skillInfo.HaveGodMode = false; skillInfo.HaveGodMode = false;
@ -125,7 +126,7 @@ namespace src.player.skills
{ {
public ulong SteamID { get; set; } public ulong SteamID { get; set; }
public bool CanUse { get; set; } public bool CanUse { get; set; }
public bool HaveGodMode { get; set; } public bool HaveGodMode { get; set; }
public DateTime Cooldown { get; set; } public DateTime Cooldown { get; set; }
} }

View file

@ -82,7 +82,7 @@ namespace src.player.skills
int smokeHeal = SkillsInfo.GetValue<int>(skillName, "smokeHeal"); int smokeHeal = SkillsInfo.GetValue<int>(skillName, "smokeHeal");
foreach (Vector smokePos in smokes.Keys) foreach (Vector smokePos in smokes.Keys)
foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid)) foreach (var player in PlayerManager.GetTickPlayers().Where(p => p.IsValid))
{ {
var eventPlayer = PlayerManager.GetPlayerEvent(player); var eventPlayer = PlayerManager.GetPlayerEvent(player);
if (eventPlayer == null || !eventPlayer.IsValid) continue; if (eventPlayer == null || !eventPlayer.IsValid) continue;

View file

@ -32,7 +32,7 @@ namespace src.player.skills
var playerPawn = hegrenade.Thrower.Value; var playerPawn = hegrenade.Thrower.Value;
if (playerPawn == null || !playerPawn.IsValid) return; if (playerPawn == null || !playerPawn.IsValid) return;
var player = Utilities.GetPlayers().FirstOrDefault(p => p.PlayerPawn.Index == playerPawn.Index); var player = PlayerManager.GetTickPlayers().FirstOrDefault(p => p.PlayerPawn.Index == playerPawn.Index);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;

View file

@ -75,7 +75,7 @@ namespace src.player.skills
double minDistance = int.MaxValue; double minDistance = int.MaxValue;
Vector nadePos = nade.AbsOrigin; Vector nadePos = nade.AbsOrigin;
foreach (var enemy in Utilities.GetPlayers().Where(p => p.IsValid && p.PawnIsAlive && p.TeamNum != team)) foreach (var enemy in PlayerManager.GetTickPlayers().Where(p => p.IsValid && p.PawnIsAlive && p.TeamNum != team))
{ {
var pawn = enemy.PlayerPawn.Value; var pawn = enemy.PlayerPawn.Value;
if (pawn?.IsValid != true || pawn.AbsOrigin == null) continue; if (pawn?.IsValid != true || pawn.AbsOrigin == null) continue;

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Commands.Targeting; using CounterStrikeSharp.API.Modules.Commands.Targeting;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
@ -26,7 +26,7 @@ namespace src.player.skills
if (players.IsEmpty || jRandomSkills.Instance.GameRules?.FreezePeriod == true) return; if (players.IsEmpty || jRandomSkills.Instance.GameRules?.FreezePeriod == true) return;
int damage = SkillsInfo.GetValue<int>(skillName, "damage"); int damage = SkillsInfo.GetValue<int>(skillName, "damage");
foreach (var player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.Team == CsTeam.Terrorist && p.PlayerPawn?.Value?.Health > 0)) foreach (var player in PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid && p.Team == CsTeam.Terrorist && p.PlayerPawn?.Value?.Health > 0))
{ {
var playerEvent = PlayerManager.GetPlayerFromEvent(player); var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid) continue; if (playerEvent == null || !playerEvent.IsValid) continue;
@ -91,7 +91,7 @@ namespace src.player.skills
if (players.IsEmpty) if (players.IsEmpty)
{ {
ChangeC4Color(Color.Red); ChangeC4Color(Color.Red);
foreach (var enemy in Utilities.GetPlayers().Where(p => p.IsValid && p.Team == CsTeam.Terrorist && p.PlayerPawn?.Value?.Health > 0)) foreach (var enemy in PlayerManager.GetTickPlayers().Where(p => p.IsValid && p.Team == CsTeam.Terrorist && p.PlayerPawn?.Value?.Health > 0))
enemy.PrintToCenterAlert(enemy.GetTranslation("hotbomb_hint")); enemy.PrintToCenterAlert(enemy.GetTranslation("hotbomb_hint"));
} }
@ -105,7 +105,7 @@ namespace src.player.skills
if (players.IsEmpty && !SkillUtils.IsFreezeTime()) if (players.IsEmpty && !SkillUtils.IsFreezeTime())
{ {
ChangeC4Color(Color.White); ChangeC4Color(Color.White);
foreach (var enemy in Utilities.GetPlayers().Where(p => p.IsValid && p.Team == CsTeam.Terrorist && p.PlayerPawn?.Value?.Health > 0)) foreach (var enemy in PlayerManager.GetTickPlayers().Where(p => p.IsValid && p.Team == CsTeam.Terrorist && p.PlayerPawn?.Value?.Health > 0))
enemy.PrintToCenterAlert(enemy.GetTranslation("hotbomb_disable_info")); enemy.PrintToCenterAlert(enemy.GetTranslation("hotbomb_disable_info"));
} }
} }

View file

@ -52,7 +52,7 @@ namespace src.player.skills
var playersWithSkill = jRandomSkills.Instance.SkillPlayer.Where(p => p.Skill == skillName).Select(p => p.PlayerIndex).ToHashSet(); var playersWithSkill = jRandomSkills.Instance.SkillPlayer.Where(p => p.Skill == skillName).Select(p => p.PlayerIndex).ToHashSet();
if (playersWithSkill.Count == 0) return false; if (playersWithSkill.Count == 0) return false;
return Utilities.GetPlayers().Any( return PlayerManager.GetTickPlayers().Any(
p => p != null && p => p != null &&
p.IsValid && p.IsValid &&
p.Pawn?.Value != null && p.Pawn?.Value != null &&

View file

@ -42,9 +42,9 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (player == null || !player.IsValid ) continue; if (player == null || !player.IsValid) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
@ -137,7 +137,8 @@ namespace src.player.skills
Vector forwardVec = SkillUtils.GetForwardVector(angle); Vector forwardVec = SkillUtils.GetForwardVector(angle);
int replicaIndex = (int)replica.Index; int replicaIndex = (int)replica.Index;
Instance.AddTickTimer(10, () => { Instance.AddTickTimer(10, () =>
{
var moveTimer = Instance.AddTickTimer(1, () => var moveTimer = Instance.AddTickTimer(1, () =>
{ {
if (replica == null || !replica.IsValid) if (replica == null || !replica.IsValid)

View file

@ -43,7 +43,7 @@ namespace src.player.skills
private static string GetEnemyModel(CCSPlayerController player) private static string GetEnemyModel(CCSPlayerController player)
{ {
CCSPlayerController[] models = [.. Utilities.GetPlayers().FindAll(p => p.IsValid && p.PawnIsAlive && p.Team != player.Team)]; CCSPlayerController[] models = [.. PlayerManager.GetTickPlayers().FindAll(p => p.IsValid && p.PawnIsAlive && p.Team != player.Team)];
if (models != null && models.Length > 0) if (models != null && models.Length > 0)
{ {
var model = models[Instance.Random.Next(models.Length)]; var model = models[Instance.Random.Next(models.Length)];

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes; using CounterStrikeSharp.API.Core.Attributes;
using CounterStrikeSharp.API.Modules.Entities; using CounterStrikeSharp.API.Modules.Entities;
@ -54,7 +54,7 @@ namespace src.player.skills
var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero; var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero;
if (targetHandle != nint.Zero) if (targetHandle != nint.Zero)
{ {
var observed = Utilities.GetPlayers() var observed = PlayerManager.GetTickPlayers()
.FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle); .FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle);
if (observed != null && observed.IsValid) if (observed != null && observed.IsValid)
{ {
@ -135,7 +135,7 @@ namespace src.player.skills
Event.EnableTransmit(); Event.EnableTransmit();
playersInAction.TryAdd(player.Index, 0); playersInAction.TryAdd(player.Index, 0);
var opponents = Utilities.GetPlayers() var opponents = PlayerManager.GetTickPlayers()
.Where(p => p != null .Where(p => p != null
&& p.IsValid && p.IsValid
&& p.Team != player.Team && p.Team != player.Team
@ -151,7 +151,7 @@ namespace src.player.skills
private static void UpdateAllTrails() private static void UpdateAllTrails()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
CreatePlayerTrail(player); CreatePlayerTrail(player);
} }

View file

@ -50,20 +50,20 @@ namespace src.player.skills
jammerToTarget.Clear(); jammerToTarget.Clear();
} }
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
public static void OnTick() public static void OnTick()
{ {
if (Server.TickCount % 32 != 0) return; if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue; if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString())));
SkillUtils.UpdateMenu(player, menuItems); SkillUtils.UpdateMenu(player, menuItems);
@ -87,7 +87,8 @@ namespace src.player.skills
string enemyId = commands[0]; string enemyId = commands[0];
if (!uint.TryParse(enemyId, out uint enemyIndex)) { if (!uint.TryParse(enemyId, out uint enemyIndex))
{
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")); playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index"));
return; return;
} }
@ -149,7 +150,7 @@ namespace src.player.skills
var playerEvent = PlayerManager.GetPlayerFromEvent(player); var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return; if (playerEvent == null || !playerEvent.IsValid) return;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString())));

View file

@ -92,7 +92,8 @@ namespace src.player.skills
jester.Timer = null; jester.Timer = null;
} }
jester.Timer = Instance.AddTimer(1, () => { jester.Timer = Instance.AddTimer(1, () =>
{
ChangeMode(playerIndex, false); ChangeMode(playerIndex, false);
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
} }
@ -112,7 +113,8 @@ namespace src.player.skills
jester.Timer = null; jester.Timer = null;
} }
jester.Timer = Instance.AddTimer(1, () => { jester.Timer = Instance.AddTimer(1, () =>
{
if (player != null && player.IsValid) if (player != null && player.IsValid)
ChangeMode(playerIndex, false); ChangeMode(playerIndex, false);
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
@ -254,7 +256,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
if (SkillUtils.IsFreezeTime()) return; if (SkillUtils.IsFreezeTime()) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
var playeEvent = PlayerManager.GetPlayerEvent(player); var playeEvent = PlayerManager.GetPlayerEvent(player);
if (playeEvent == null || !playeEvent.IsValid || playeEvent.PlayerPawn.Value == null || !playeEvent.PlayerPawn.Value.IsValid) continue; if (playeEvent == null || !playeEvent.IsValid || playeEvent.PlayerPawn.Value == null || !playeEvent.PlayerPawn.Value.IsValid) continue;

View file

@ -32,7 +32,7 @@ namespace src.player.skills
bannedPlayers.Clear(); bannedPlayers.Clear();
playersToTarget.Clear(); playersToTarget.Clear();
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
@ -62,13 +62,13 @@ namespace src.player.skills
} }
if (Server.TickCount % 32 != 0) return; if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue; if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))]; ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))];
SkillUtils.UpdateMenu(player, menuItems); SkillUtils.UpdateMenu(player, menuItems);
@ -92,7 +92,8 @@ namespace src.player.skills
string enemyId = commands[0]; string enemyId = commands[0];
if (!uint.TryParse(enemyId, out uint enemyIndex)) { if (!uint.TryParse(enemyId, out uint enemyIndex))
{
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")); playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index"));
return; return;
} }
@ -125,7 +126,7 @@ namespace src.player.skills
var playerEvent = PlayerManager.GetPlayerFromEvent(player); var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return; if (playerEvent == null || !playerEvent.IsValid) return;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString())));

View file

@ -30,7 +30,7 @@ namespace src.player.skills
if (!SkillsInfo.GetValue<bool>(skillName, "friendlyFire") && player!.Team == attacker!.Team) return; if (!SkillsInfo.GetValue<bool>(skillName, "friendlyFire") && player!.Team == attacker!.Team) return;
if (attackerInfo?.Skill == skillName && playerInfo?.Skill != Skills.AntyFlash && player!.PlayerPawn.Value!.FlashDuration >= SkillsInfo.GetValue<float>(skillName, "flashDuration")) if (attackerInfo?.Skill == skillName && playerInfo?.Skill != Skills.AntyFlash && player!.PlayerPawn.Value!.FlashDuration >= SkillsInfo.GetValue<float>(skillName, "flashDuration"))
player?.PlayerPawn?.Value?.CommitSuicide(false, true); SkillUtils.TakeHealth(player.PlayerPawn.Value, 9999);
} }
public static void GrenadeThrown(EventGrenadeThrown @event) public static void GrenadeThrown(EventGrenadeThrown @event)

View file

@ -17,20 +17,20 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
public static void OnTick() public static void OnTick()
{ {
if (Server.TickCount % 32 != 0) return; if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue; if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"\u202A{e.PlayerName}\u202C : {e?.PlayerPawn?.Value?.Health ?? 0} HP", e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"\u202A{e.PlayerName}\u202C : {e?.PlayerPawn?.Value?.Health ?? 0} HP", e.Index.ToString())));
SkillUtils.UpdateMenu(player, menuItems); SkillUtils.UpdateMenu(player, menuItems);
@ -55,7 +55,8 @@ namespace src.player.skills
string enemyId = commands[0]; string enemyId = commands[0];
if (!uint.TryParse(enemyId, out uint enemyIndex)) { if (!uint.TryParse(enemyId, out uint enemyIndex))
{
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")); playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index"));
return; return;
} }
@ -84,7 +85,7 @@ namespace src.player.skills
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"\u202A{e.PlayerName}\u202C : {e.PawnHealth} HP", e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"\u202A{e.PlayerName}\u202C : {e.PawnHealth} HP", e.Index.ToString())));

View file

@ -125,7 +125,7 @@ namespace src.player.skills
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#c9f8ff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = Rarity.Common, float maxDistance = 4096f, bool friendlyFire = true) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity) public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#c9f8ff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = Rarity.Common, float maxDistance = 4096f, bool friendlyFire = true) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)
{ {
public float MaxDistance { get; set; } = maxDistance; public float MaxDistance { get; set; } = maxDistance;
public bool FriendlyFire { get; set; } = friendlyFire; public bool FriendlyFire { get; set; } = friendlyFire;
} }
} }
} }

View file

@ -49,7 +49,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (Vector decoyPos in decoys.Keys) foreach (Vector decoyPos in decoys.Keys)
foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist)) foreach (var player in PlayerManager.GetTickPlayers().Where(p => p.IsValid && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist))
{ {
var eventPlayer = PlayerManager.GetPlayerEvent(player); var eventPlayer = PlayerManager.GetPlayerEvent(player);
if (eventPlayer == null || !eventPlayer.IsValid) continue; if (eventPlayer == null || !eventPlayer.IsValid) continue;
@ -60,7 +60,7 @@ namespace src.player.skills
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue; if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue;
double distance = SkillUtils.GetDistance(decoyPos, pawn.AbsOrigin); double distance = SkillUtils.GetDistance(decoyPos, pawn.AbsOrigin);
if (distance <= decoyRadius && distance > 10) if (distance <= decoyRadius && distance > 10)
{ {
Vector direction = new(decoyPos.X - pawn.AbsOrigin.X, decoyPos.Y - pawn.AbsOrigin.Y, 0); Vector direction = new(decoyPos.X - pawn.AbsOrigin.X, decoyPos.Y - pawn.AbsOrigin.Y, 0);
float length = direction.Length(); float length = direction.Length();

View file

@ -39,20 +39,20 @@ namespace src.player.skills
playersFOV.Clear(); playersFOV.Clear();
playersToTarget.Clear(); playersToTarget.Clear();
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
public static void OnTick() public static void OnTick()
{ {
if (Server.TickCount % 32 != 0) return; if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue; if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString())));
SkillUtils.UpdateMenu(player, menuItems); SkillUtils.UpdateMenu(player, menuItems);
@ -70,13 +70,14 @@ namespace src.player.skills
if (playerInfo.SkillUsed) if (playerInfo.SkillUsed)
{ {
playerEvent.PrintToChat($" {ChatColors.Red}{playerEvent.GetTranslation("areareaper_used_info")}" ); playerEvent.PrintToChat($" {ChatColors.Red}{playerEvent.GetTranslation("areareaper_used_info")}");
return; return;
} }
string enemyId = commands[0]; string enemyId = commands[0];
if (!uint.TryParse(enemyId, out uint enemyIndex)) { if (!uint.TryParse(enemyId, out uint enemyIndex))
{
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")); playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index"));
return; return;
} }
@ -126,7 +127,7 @@ namespace src.player.skills
var playerEvent = PlayerManager.GetPlayerFromEvent(player); var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return; if (playerEvent == null || !playerEvent.IsValid) return;
var enemies = Utilities.GetPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString())));

View file

@ -27,7 +27,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
if (SkillUtils.IsFreezeTime()) return; if (SkillUtils.IsFreezeTime()) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)

View file

@ -42,7 +42,7 @@ namespace src.player.skills
if (nade.CreateTime + 3 > currentTime) return; if (nade.CreateTime + 3 > currentTime) return;
Vector currentPos = new(nade.AbsOrigin.X, nade.AbsOrigin.Y, nade.AbsOrigin.Z); 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)) foreach (var enemy in PlayerManager.GetTickPlayers().Where(p => p.IsValid && p.PawnIsAlive && p.TeamNum != nade.TeamNum))
{ {
var enemyPawn = enemy.PlayerPawn.Value; var enemyPawn = enemy.PlayerPawn.Value;
if (enemyPawn == null || !enemyPawn.IsValid || enemyPawn.AbsOrigin == null) continue; if (enemyPawn == null || !enemyPawn.IsValid || enemyPawn.AbsOrigin == null) continue;

View file

@ -17,20 +17,20 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
public static void OnTick() public static void OnTick()
{ {
if (Server.TickCount % 32 != 0) return; if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue; if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"\u202A{e.PlayerName}\u202C : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account + e.InGameMoneyServices.CashSpentThisRound)}$", e.Index.ToString()))]; ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"\u202A{e.PlayerName}\u202C : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account + e.InGameMoneyServices.CashSpentThisRound)}$", e.Index.ToString()))];
SkillUtils.UpdateMenu(player, menuItems); SkillUtils.UpdateMenu(player, menuItems);
@ -47,7 +47,7 @@ namespace src.player.skills
var playerEvent = PlayerManager.GetPlayerFromEvent(player); var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return; if (playerEvent == null || !playerEvent.IsValid) return;
if (playerInfo.SkillUsed) if (playerInfo.SkillUsed)
{ {
playerEvent.PrintToChat($" {ChatColors.Red}{playerEvent.GetTranslation("areareaper_used_info")}"); playerEvent.PrintToChat($" {ChatColors.Red}{playerEvent.GetTranslation("areareaper_used_info")}");
return; return;
@ -55,7 +55,8 @@ namespace src.player.skills
string enemyId = commands[0]; string enemyId = commands[0];
if (!uint.TryParse(enemyId, out uint enemyIndex)) { if (!uint.TryParse(enemyId, out uint enemyIndex))
{
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")); playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index"));
return; return;
} }
@ -83,7 +84,7 @@ namespace src.player.skills
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"\u202A{e.PlayerName}\u202C : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account + e.InGameMoneyServices.CashSpentThisRound)}$", e.Index.ToString()))]; ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"\u202A{e.PlayerName}\u202C : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account + e.InGameMoneyServices.CashSpentThisRound)}$", e.Index.ToString()))];

View file

@ -60,7 +60,7 @@ namespace src.player.skills
{ {
if (invisiblePlayers.IsEmpty) return; if (invisiblePlayers.IsEmpty) return;
var bomb = Utilities.FindAllEntitiesByDesignerName<CC4>("weapon_c4").FirstOrDefault(); var bomb = PlayerManager.GetTickBomb();
uint? bombOwnerIndex = bomb != null && bomb.IsValid ? bomb.OwnerEntity?.Index : null; uint? bombOwnerIndex = bomb != null && bomb.IsValid ? bomb.OwnerEntity?.Index : null;
foreach (var (info, player) in infoList) foreach (var (info, player) in infoList)
@ -103,7 +103,7 @@ namespace src.player.skills
{ {
if (Server.TickCount % 2 != 0) return; if (Server.TickCount % 2 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (player.PlayerPawn?.Value == null || player.PlayerPawn?.Value?.Health <= 0) if (player.PlayerPawn?.Value == null || player.PlayerPawn?.Value?.Health <= 0)
invisiblePlayers.TryRemove(player.Index, out _); invisiblePlayers.TryRemove(player.Index, out _);

View file

@ -52,7 +52,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!Instance.IsPlayerValid(player)) continue; if (!Instance.IsPlayerValid(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);

View file

@ -29,7 +29,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)

View file

@ -19,7 +19,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerEvent = PlayerManager.GetPlayerEvent(player); var playerEvent = PlayerManager.GetPlayerEvent(player);
@ -42,7 +42,7 @@ namespace src.player.skills
float extraJumps = (float)Instance.Random.Next(SkillsInfo.GetValue<int>(skillName, "extraJumpsMin"), SkillsInfo.GetValue<int>(skillName, "extraJumpsMax") + 1); float extraJumps = (float)Instance.Random.Next(SkillsInfo.GetValue<int>(skillName, "extraJumpsMin"), SkillsInfo.GetValue<int>(skillName, "extraJumpsMax") + 1);
playerInfo.SkillChance = extraJumps; playerInfo.SkillChance = extraJumps;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, extraJumps)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, extraJumps)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
private static void GiveAdditionalJump(CCSPlayerController player, CCSPlayerController playerEvent) private static void GiveAdditionalJump(CCSPlayerController player, CCSPlayerController playerEvent)

View file

@ -1,5 +1,6 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using System.Collections.Concurrent; using System.Collections.Concurrent;
@ -10,6 +11,7 @@ namespace src.player.skills
public class Phoenix : ISkill public class Phoenix : ISkill
{ {
private const Skills skillName = Skills.Phoenix; private const Skills skillName = Skills.Phoenix;
private const float DefaultHeadshotMultiplier = 4f;
private static readonly ConcurrentDictionary<uint, int> phoenixTicks = new(); private static readonly ConcurrentDictionary<uint, int> phoenixTicks = new();
public static void LoadSkill() public static void LoadSkill()
@ -17,38 +19,61 @@ namespace src.player.skills
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"), false); SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"), false);
} }
public static void PlayerHurt(EventPlayerHurt @event) public static void OnTakeDamage(DynamicHook h)
{ {
var user = @event.Userid; var victimEntity = h.GetParam<CEntityInstance>(0);
if (user == null || !user.IsValid) return; var info = h.GetParam<CTakeDamageInfo>(1);
if (victimEntity == null || !victimEntity.IsValid || info == null) return;
var victim = PlayerManager.GetPlayerEvent(@event.Userid); var victimPawn = victimEntity.As<CCSPlayerPawn>();
if (victim == null || !victim.IsValid) return; if (victimPawn == null || !victimPawn.IsValid || victimPawn.DesignerName != "player") return;
var pawn = victim.PlayerPawn.Value; var victimController = victimPawn.Controller.Value;
if (pawn == null || !pawn.IsValid) return; if (victimController == null || !victimController.IsValid) return;
bool isProtected = phoenixTicks.TryGetValue(victim.Index, out int tick); var victim = victimController.As<CCSPlayerController>();
if (isProtected && tick + 4 > Server.TickCount) if (victim == null || !victim.IsValid || !victim.PawnIsAlive) return;
{
SkillUtils.AddHealth(pawn, 100 - pawn.Health);
return;
}
var playerInfo = PlayerManager.GetPlayerByIndex(victim.Index); var victimInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(victim)?.Index ?? victim.Index);
if (playerInfo?.Skill != skillName || pawn.Health > 0) return; if (victimInfo == null || victimInfo.Skill != skillName) return;
if (Instance.Random.NextDouble() > playerInfo.SkillChance) return; if (SkillUtils.IsFriendlyFireBlocked(info, victimPawn)) return;
if (victim.TeamChanged) return;
float effectiveDamage = info.Damage;
if (SkillUtils.GetHitGroup(info) == HitGroup_t.HITGROUP_HEAD)
effectiveDamage *= GetHeadshotMultiplier(info);
if (effectiveDamage < victimPawn.Health) return;
if (TryConsumeRevive(victim, victimPawn))
info.Damage = 0;
}
public static bool TryConsumeRevive(CCSPlayerController? victim, CCSPlayerPawn? victimPawn)
{
if (victim == null || !victim.IsValid || !victim.PawnIsAlive) return false;
if (victimPawn == null || !victimPawn.IsValid) return false;
var victimInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(victim)?.Index ?? victim.Index);
if (victimInfo == null || victimInfo.Skill != skillName) return false;
if (phoenixTicks.TryGetValue(victim.Index, out int savedTick) && savedTick + 4 > Server.TickCount)
return true;
if (victim.TeamChanged) return false;
if (victimInfo.SkillChance is float chance && Instance.Random.NextDouble() > chance) return false; // roll failed -> die
phoenixTicks[victim.Index] = Server.TickCount; phoenixTicks[victim.Index] = Server.TickCount;
SkillUtils.AddHealth(pawn, 100 - pawn.Health); victimPawn.Health = 100;
SkillUtils.PrintToChat(user, user.GetTranslation("phoenix_respawn")); Utilities.SetStateChanged(victimPawn, "CBaseEntity", "m_iHealth");
SkillUtils.PrintToChat(victim, victim.GetTranslation("phoenix_respawn"));
Server.NextFrame(() => Server.NextFrame(() =>
{ {
if (victim == null || !victim.IsValid) return; if (victim == null || !victim.IsValid) return;
var pawn = victim.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return; if (pawn == null || !pawn.IsValid) return;
var spawnpoint = SkillUtils.GetSpawnPointVector(victim); var spawnpoint = SkillUtils.GetSpawnPointVector(victim);
@ -56,6 +81,22 @@ namespace src.player.skills
pawn.Teleport(spawnpoint); pawn.Teleport(spawnpoint);
}); });
return true;
}
private static float GetHeadshotMultiplier(CTakeDamageInfo info)
{
var ability = info.Ability?.Value;
if (ability == null || !ability.IsValid) return DefaultHeadshotMultiplier;
var weapon = ability.As<CCSWeaponBase>();
if (weapon == null || !weapon.IsValid) return DefaultHeadshotMultiplier;
var vdata = weapon.GetVData<CCSWeaponBaseVData>();
if (vdata == null || vdata.HeadshotMultiplier <= 0) return DefaultHeadshotMultiplier;
return vdata.HeadshotMultiplier;
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
@ -67,7 +108,7 @@ namespace src.player.skills
playerInfo.SkillChance = newChance; playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff5C0A", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = Rarity.Common, float chanceFrom = .2f, float chanceTo = .4f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity) public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff5C0A", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = Rarity.Common, float chanceFrom = .2f, float chanceTo = .4f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)

View file

@ -24,7 +24,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
@ -121,14 +121,14 @@ namespace src.player.skills
float fuelPercentage = maximumFuel; float fuelPercentage = maximumFuel;
string fuelColor = GetFuelColor(pilotInfo.Fuel); string fuelColor = GetFuelColor(pilotInfo.Fuel);
playerInfo.PrintHTML = $"{player.GetTranslation("pilot_hud_info")}: <font color='{fuelColor}'>{(pilotInfo.Fuel/maximumFuel)*100:F0}%</font>"; playerInfo.PrintHTML = $"{player.GetTranslation("pilot_hud_info")}: <font color='{fuelColor}'>{(pilotInfo.Fuel / maximumFuel) * 100:F0}%</font>";
} }
private static string GetFuelColor(float fuelPercentage) private static string GetFuelColor(float fuelPercentage)
{ {
var maximumFuel = SkillsInfo.GetValue<float>(skillName, "maximumFuel"); var maximumFuel = SkillsInfo.GetValue<float>(skillName, "maximumFuel");
if (fuelPercentage > (maximumFuel/2f)) return "#00FF00"; if (fuelPercentage > (maximumFuel / 2f)) return "#00FF00";
if (fuelPercentage > (maximumFuel/4f)) return "#FFFF00"; if (fuelPercentage > (maximumFuel / 4f)) return "#FFFF00";
return "#FF0000"; return "#FF0000";
} }

View file

@ -57,18 +57,19 @@ namespace src.player.skills
var plantedBomb = Utilities.FindAllEntitiesByDesignerName<CPlantedC4>("planted_c4").FirstOrDefault(); var plantedBomb = Utilities.FindAllEntitiesByDesignerName<CPlantedC4>("planted_c4").FirstOrDefault();
if (plantedBomb != null) if (plantedBomb != null)
Server.NextFrame(() => { Server.NextFrame(() =>
{
if (plantedBomb != null && plantedBomb.IsValid) if (plantedBomb != null && plantedBomb.IsValid)
plantedBomb.C4Blow = Server.CurrentTime + SkillsInfo.GetValue<int>(skillName, "extraC4BlowTime"); plantedBomb.C4Blow = Server.CurrentTime + SkillsInfo.GetValue<int>(skillName, "extraC4BlowTime");
}); });
foreach (var p in Utilities.GetPlayers().Where(p => p.IsValid)) foreach (var p in PlayerManager.GetTickPlayers().Where(p => p.IsValid))
p.PrintToCenterAlert(p.GetTranslation("bombplanted", SkillsInfo.GetValue<int>(skillName, "extraC4BlowTime"))); p.PrintToCenterAlert(p.GetTranslation("bombplanted", SkillsInfo.GetValue<int>(skillName, "extraC4BlowTime")));
} }
public static void NewRound() public static void NewRound()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
DisableSkill(player); DisableSkill(player);
plantingPlayers.Clear(); plantingPlayers.Clear();
@ -93,7 +94,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
float currentTime = Server.CurrentTime; float currentTime = Server.CurrentTime;
foreach (var player in Utilities.GetPlayers().Where(p => p.Team == CsTeam.Terrorist)) foreach (var player in PlayerManager.GetTickPlayers().Where(p => p.Team == CsTeam.Terrorist))
{ {
if (!Instance.IsPlayerValid(player)) continue; if (!Instance.IsPlayerValid(player)) continue;

View file

@ -67,13 +67,13 @@ namespace src.player.skills
} }
if (Server.TickCount % 32 != 0) return; if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue; if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString())));
SkillUtils.UpdateMenu(player, menuItems); SkillUtils.UpdateMenu(player, menuItems);
@ -97,7 +97,8 @@ namespace src.player.skills
string enemyId = commands[0]; string enemyId = commands[0];
if (!uint.TryParse(enemyId, out uint enemyIndex)) { if (!uint.TryParse(enemyId, out uint enemyIndex))
{
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")); playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index"));
return; return;
} }
@ -130,7 +131,7 @@ namespace src.player.skills
var playerEvent = PlayerManager.GetPlayerFromEvent(player); var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return; if (playerEvent == null || !playerEvent.IsValid) return;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString())));

View file

@ -48,7 +48,7 @@ namespace src.player.skills
bannedPlayers.Clear(); bannedPlayers.Clear();
playersToTarget.Clear(); playersToTarget.Clear();
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
} }
@ -68,13 +68,13 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
if (Server.TickCount % 32 != 0) return; if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue; if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString())));
SkillUtils.UpdateMenu(player, menuItems); SkillUtils.UpdateMenu(player, menuItems);
@ -98,7 +98,8 @@ namespace src.player.skills
string enemyId = commands[0]; string enemyId = commands[0];
if (!uint.TryParse(enemyId, out uint enemyIndex)) { if (!uint.TryParse(enemyId, out uint enemyIndex))
{
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")); playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index"));
return; return;
} }
@ -132,7 +133,7 @@ namespace src.player.skills
var playerEvent = PlayerManager.GetPlayerFromEvent(player); var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return; if (playerEvent == null || !playerEvent.IsValid) return;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString())));

View file

@ -39,7 +39,7 @@ namespace src.player.skills
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom"); float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
playerInfo.SkillChance = newChance; playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
private static void PushEnemy(CCSPlayerController player, QAngle attackerAngle) private static void PushEnemy(CCSPlayerController player, QAngle attackerAngle)

View file

@ -17,7 +17,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!Instance.IsPlayerValid(player)) continue; if (!Instance.IsPlayerValid(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);

View file

@ -18,7 +18,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
var playerEvent = PlayerManager.GetPlayerEvent(player); var playerEvent = PlayerManager.GetPlayerEvent(player);
if (!Instance.IsPlayerValid(playerEvent)) continue; if (!Instance.IsPlayerValid(playerEvent)) continue;
@ -36,7 +36,7 @@ namespace src.player.skills
// SpottedByMask is indexed by player slot (0-63), not entity index. // SpottedByMask is indexed by player slot (0-63), not entity index.
int slot = player.Slot; int slot = player.Slot;
foreach (var enemy in Utilities.GetPlayers().FindAll(p => p.Team != player.Team)) foreach (var enemy in PlayerManager.GetTickPlayers().FindAll(p => p.Team != player.Team))
{ {
var enemyEvent = PlayerManager.GetPlayerEvent(enemy); var enemyEvent = PlayerManager.GetPlayerEvent(enemy);
if (enemyEvent == null || !enemyEvent.IsValid) continue; if (enemyEvent == null || !enemyEvent.IsValid) continue;
@ -52,13 +52,9 @@ namespace src.player.skills
enemyPawn.EntitySpottedState.SpottedByMask[0] |= (1u << (slot % 32)); enemyPawn.EntitySpottedState.SpottedByMask[0] |= (1u << (slot % 32));
} }
var bombEntities = Utilities.FindAllEntitiesByDesignerName<CC4>("weapon_c4").ToList(); var bomb = PlayerManager.GetTickBomb();
if (bombEntities.Count != 0) if (bomb != null && bomb.IsValid)
{ bomb.EntitySpottedState.SpottedByMask[0] |= (1u << (slot % 32));
var bomb = bombEntities.FirstOrDefault();
if (bomb != null && bomb.IsValid)
bomb.EntitySpottedState.SpottedByMask[0] |= (1u << (slot % 32));
}
} }
public class SkillConfig : SkillsInfo.DefaultSkillInfo public class SkillConfig : SkillsInfo.DefaultSkillInfo

View file

@ -40,7 +40,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
var players = Utilities.GetPlayers().ToArray(); var players = PlayerManager.GetTickPlayers().ToArray();
foreach (var player in players) foreach (var player in players)
{ {
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);

View file

@ -11,6 +11,7 @@ namespace src.player.skills
public class ReZombie : ISkill public class ReZombie : ISkill
{ {
private const Skills skillName = Skills.ReZombie; private const Skills skillName = Skills.ReZombie;
private const float DefaultHeadshotMultiplier = 4f;
private static readonly ConcurrentDictionary<uint, int> zombies = []; private static readonly ConcurrentDictionary<uint, int> zombies = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
@ -68,40 +69,73 @@ namespace src.player.skills
zombies.Clear(); zombies.Clear();
} }
public static void PlayerHurt(EventPlayerHurt @event) public static void OnTakeDamage(DynamicHook h)
{ {
var victim = PlayerManager.GetPlayerEvent(@event.Userid); var victimEntity = h.GetParam<CEntityInstance>(0);
if (victim == null || !victim.IsValid) return; var info = h.GetParam<CTakeDamageInfo>(1);
if (victimEntity == null || !victimEntity.IsValid || info == null) return;
var pawn = victim.PlayerPawn.Value; var victimPawn = victimEntity.As<CCSPlayerPawn>();
if (pawn == null || !pawn.IsValid) return; if (victimPawn == null || !victimPawn.IsValid || victimPawn.DesignerName != "player") return;
bool isZombie = zombies.TryGetValue(victim.Index, out int tick); var victimController = victimPawn.Controller.Value;
if (victimController == null || !victimController.IsValid) return;
if (isZombie && tick + 4 < Server.TickCount) var victim = victimController.As<CCSPlayerController>();
return; if (victim == null || !victim.IsValid || !victim.PawnIsAlive) return;
var playerInfo = PlayerManager.GetPlayerByIndex(victim.Index); var victimInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(victim)?.Index ?? victim.Index);
if (playerInfo?.Skill != skillName) return; if (victimInfo == null || victimInfo.Skill != skillName) return;
var zombieHealth = SkillsInfo.GetValue<int>(skillName, "zombieHealth"); // Friendly-fire-off teammate hit deals 0 damage; don't zombify over a hit that never lands.
if (SkillUtils.IsFriendlyFireBlocked(info, victimPawn)) return;
if (pawn.Health <= 0) float effectiveDamage = info.Damage;
if (SkillUtils.GetHitGroup(info) == HitGroup_t.HITGROUP_HEAD)
effectiveDamage *= GetHeadshotMultiplier(info);
if (effectiveDamage < victimPawn.Health) return; // survivable, let it through
if (TryBecomeZombie(victim, victimPawn))
info.Damage = 0;
}
public static bool TryBecomeZombie(CCSPlayerController? victim, CCSPlayerPawn? victimPawn)
{
if (victim == null || !victim.IsValid || !victim.PawnIsAlive) return false;
if (victimPawn == null || !victimPawn.IsValid) return false;
var victimInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(victim)?.Index ?? victim.Index);
if (victimInfo == null || victimInfo.Skill != skillName) return false;
lock (setLock)
{ {
bool isBlock = victim.TeamChanged; if (zombies.ContainsKey(victim.Index)) return false;
if (victim.TeamChanged) return false;
zombies[victim.Index] = Server.TickCount; zombies[victim.Index] = Server.TickCount;
if (isBlock) return; int zombieHealth = SkillsInfo.GetValue<int>(skillName, "zombieHealth");
DropAllBotWeapons(victim); DropAllBotWeapons(victim);
SetPlayerColor(pawn, false); SetPlayerColor(victimPawn, false);
SkillUtils.SetHealth(pawn, zombieHealth, zombieHealth); SkillUtils.SetHealth(victimPawn, zombieHealth, zombieHealth);
victim.ExecuteClientCommand("slot3"); victim.ExecuteClientCommand("slot3");
return true;
} }
else if (isZombie && tick + 4 > Server.TickCount) }
SkillUtils.SetHealth(pawn, zombieHealth, zombieHealth);
private static float GetHeadshotMultiplier(CTakeDamageInfo info)
{
var ability = info.Ability?.Value;
if (ability == null || !ability.IsValid) return DefaultHeadshotMultiplier;
var weapon = ability.As<CCSWeaponBase>();
if (weapon == null || !weapon.IsValid) return DefaultHeadshotMultiplier;
var vdata = weapon.GetVData<CCSWeaponBaseVData>();
if (vdata == null || vdata.HeadshotMultiplier <= 0) return DefaultHeadshotMultiplier;
return vdata.HeadshotMultiplier;
} }
private static void DropAllBotWeapons(CCSPlayerController player) private static void DropAllBotWeapons(CCSPlayerController player)

View file

@ -25,7 +25,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)

View file

@ -18,7 +18,7 @@ namespace src.player.skills
{ {
int cooldown = Math.Max(1, (int)(64 * SkillsInfo.GetValue<float>(skillName, "cooldown"))); int cooldown = Math.Max(1, (int)(64 * SkillsInfo.GetValue<float>(skillName, "cooldown")));
if (Server.TickCount % cooldown != 0) return; if (Server.TickCount % cooldown != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) continue; if (playerInfo?.Skill != skillName) continue;

View file

@ -37,7 +37,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)

View file

@ -26,7 +26,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)

View file

@ -7,7 +7,7 @@ using src.utils;
namespace src.player.skills namespace src.player.skills
{ {
public class Rubber: ISkill public class Rubber : ISkill
{ {
private const Skills skillName = Skills.Rubber; private const Skills skillName = Skills.Rubber;
private static readonly ConcurrentDictionary<uint, float> playersToSlow = []; private static readonly ConcurrentDictionary<uint, float> playersToSlow = [];
@ -40,7 +40,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach(var item in playersToSlow) foreach (var item in playersToSlow)
{ {
var playerIndex = item.Key; var playerIndex = item.Key;
var time = item.Value; var time = item.Value;

View file

@ -25,7 +25,8 @@ namespace src.player.skills
{ {
var plantedBomb = Utilities.FindAllEntitiesByDesignerName<CPlantedC4>("planted_c4").FirstOrDefault(); var plantedBomb = Utilities.FindAllEntitiesByDesignerName<CPlantedC4>("planted_c4").FirstOrDefault();
if (plantedBomb != null) if (plantedBomb != null)
Server.NextFrame(() => { Server.NextFrame(() =>
{
if (plantedBomb != null && plantedBomb.IsValid) if (plantedBomb != null && plantedBomb.IsValid)
plantedBomb.DefuseCountDown = 0; plantedBomb.DefuseCountDown = 0;
}); });

View file

@ -11,6 +11,7 @@ namespace src.player.skills
public class SecondLife : ISkill public class SecondLife : ISkill
{ {
private const Skills skillName = Skills.SecondLife; private const Skills skillName = Skills.SecondLife;
private const float DefaultHeadshotMultiplier = 4f;
private static readonly ConcurrentDictionary<nint, int> usedThisRound = []; private static readonly ConcurrentDictionary<nint, int> usedThisRound = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
@ -44,7 +45,13 @@ namespace src.player.skills
var victimInfo = PlayerManager.GetPlayerByIndex((PlayerManager.GetPlayerEvent(victim)?.Index ?? victim.Index)); var victimInfo = PlayerManager.GetPlayerByIndex((PlayerManager.GetPlayerEvent(victim)?.Index ?? victim.Index));
if (victimInfo == null || victimInfo.Skill != skillName) return; if (victimInfo == null || victimInfo.Skill != skillName) return;
if (info.Damage < victimPawn.Health) return; if (SkillUtils.IsFriendlyFireBlocked(info, victimPawn)) return;
float effectiveDamage = info.Damage;
if (SkillUtils.GetHitGroup(info) == HitGroup_t.HITGROUP_HEAD)
effectiveDamage *= GetHeadshotMultiplier(info);
if (effectiveDamage < victimPawn.Health) return;
if (usedThisRound.TryGetValue(victim.Handle, out int savedTick)) if (usedThisRound.TryGetValue(victim.Handle, out int savedTick))
{ {
@ -53,15 +60,39 @@ namespace src.player.skills
return; return;
} }
if (TryConsumeRevive(victim, victimPawn))
info.Damage = 0;
}
private static float GetHeadshotMultiplier(CTakeDamageInfo info)
{
var ability = info.Ability?.Value;
if (ability == null || !ability.IsValid) return DefaultHeadshotMultiplier;
var weapon = ability.As<CCSWeaponBase>();
if (weapon == null || !weapon.IsValid) return DefaultHeadshotMultiplier;
var vdata = weapon.GetVData<CCSWeaponBaseVData>();
if (vdata == null || vdata.HeadshotMultiplier <= 0) return DefaultHeadshotMultiplier;
return vdata.HeadshotMultiplier;
}
public static bool TryConsumeRevive(CCSPlayerController? victim, CCSPlayerPawn? victimPawn)
{
if (victim == null || !victim.IsValid) return false;
if (victimPawn == null || !victimPawn.IsValid) return false;
if (SkillUtils.IsFreezeTime()) return false;
lock (setLock) lock (setLock)
{ {
if (usedThisRound.ContainsKey(victim.Handle)) return; if (usedThisRound.ContainsKey(victim.Handle)) return false;
var spawnpoint = SkillUtils.GetSpawnPointVector(victim); var spawnpoint = SkillUtils.GetSpawnPointVector(victim);
if (spawnpoint == null) return; // no clean respawn point -> let the normal death happen if (spawnpoint == null) return false; // no clean respawn point -> let the normal death happen
usedThisRound.TryAdd(victim.Handle, Server.TickCount); usedThisRound.TryAdd(victim.Handle, Server.TickCount);
info.Damage = 0;
victimPawn.Health = SkillsInfo.GetValue<int>(skillName, "startHealth"); victimPawn.Health = SkillsInfo.GetValue<int>(skillName, "startHealth");
Utilities.SetStateChanged(victimPawn, "CBaseEntity", "m_iHealth"); Utilities.SetStateChanged(victimPawn, "CBaseEntity", "m_iHealth");
@ -69,11 +100,14 @@ namespace src.player.skills
Server.NextFrame(() => Server.NextFrame(() =>
{ {
if (victim == null || !victim.IsValid) return; if (victim == null || !victim.IsValid) return;
if (SkillUtils.IsFreezeTime()) return;
var pawn = victim.PlayerPawn.Value; var pawn = victim.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return; if (pawn == null || !pawn.IsValid) return;
pawn.Teleport(spawnpoint, null, new Vector(0, 0, 0)); pawn.Teleport(spawnpoint, null, new Vector(0, 0, 0));
}); });
return true;
} }
} }

View file

@ -48,7 +48,7 @@ namespace src.player.skills
playerInfo.SkillChance = newChance; playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)

View file

@ -45,12 +45,13 @@ namespace src.player.skills
var plantedBomb = Utilities.FindAllEntitiesByDesignerName<CPlantedC4>("planted_c4").FirstOrDefault(); var plantedBomb = Utilities.FindAllEntitiesByDesignerName<CPlantedC4>("planted_c4").FirstOrDefault();
if (plantedBomb != null) if (plantedBomb != null)
Server.NextFrame(() => { Server.NextFrame(() =>
{
if (plantedBomb != null && plantedBomb.IsValid) if (plantedBomb != null && plantedBomb.IsValid)
plantedBomb.C4Blow = Server.CurrentTime + SkillsInfo.GetValue<int>(skillName, "detonationTime"); plantedBomb.C4Blow = Server.CurrentTime + SkillsInfo.GetValue<int>(skillName, "detonationTime");
}); });
foreach (var p in Utilities.GetPlayers().Where(p => p.IsValid)) foreach (var p in PlayerManager.GetTickPlayers().Where(p => p.IsValid))
p.PrintToCenterAlert(p.GetTranslation("bombplanted", SkillsInfo.GetValue<int>(skillName, "detonationTime"))); p.PrintToCenterAlert(p.GetTranslation("bombplanted", SkillsInfo.GetValue<int>(skillName, "detonationTime")));
} }

View file

@ -24,7 +24,7 @@ namespace src.player.skills
if (!Instance.footstepSoundEvents.Contains(soundevent) && !Instance.silentSoundEvents.Contains(soundevent)) if (!Instance.footstepSoundEvents.Contains(soundevent) && !Instance.silentSoundEvents.Contains(soundevent))
return; return;
var player = Utilities.GetPlayers().FirstOrDefault(p => p.Pawn?.Value != null && p.Pawn.Value.IsValid && p.Pawn.Value.Index == userIndex); var player = PlayerManager.GetTickPlayers().FirstOrDefault(p => p.Pawn?.Value != null && p.Pawn.Value.IsValid && p.Pawn.Value.Index == userIndex);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex((PlayerManager.GetPlayerEvent(player)?.Index ?? player.Index)); var playerInfo = PlayerManager.GetPlayerByIndex((PlayerManager.GetPlayerEvent(player)?.Index ?? player.Index));

View file

@ -162,7 +162,8 @@ namespace src.player.skills
weaponToGive = weapon_awp + "_script"; weaponToGive = weapon_awp + "_script";
} }
Instance.AddTimer(.15f, () => { Instance.AddTimer(.15f, () =>
{
var player = Utilities.GetPlayerFromIndex((int)playerIndex); var player = Utilities.GetPlayerFromIndex((int)playerIndex);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
@ -191,7 +192,8 @@ namespace src.player.skills
isProcessing.TryRemove(playerIndex, out _); isProcessing.TryRemove(playerIndex, out _);
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
} }
catch { catch
{
isProcessing.TryRemove(playerIndex, out _); isProcessing.TryRemove(playerIndex, out _);
} }
} }

View file

@ -26,7 +26,7 @@ namespace src.player.skills
newScale = (float)Math.Round(newScale, 2); newScale = (float)Math.Round(newScale, 2);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newScale)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newScale)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
public static void OnTakeDamage(DynamicHook h) public static void OnTakeDamage(DynamicHook h)

View file

@ -57,7 +57,7 @@ namespace src.player.skills
if (entityIndex == 0) return; if (entityIndex == 0) return;
CCSPlayerController? emitter = null; CCSPlayerController? emitter = null;
foreach (var p in Utilities.GetPlayers().Where(p => p != null && p.IsValid)) foreach (var p in PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid))
{ {
if (p.PlayerPawn.Value?.Index == entityIndex) if (p.PlayerPawn.Value?.Index == entityIndex)
{ {
@ -75,12 +75,12 @@ namespace src.player.skills
if (emitter == null) if (emitter == null)
{ {
foreach (var p in Utilities.GetPlayers().Where(p => p != null && p.IsValid)) foreach (var p in PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid))
um.Recipients.Remove(p); um.Recipients.Remove(p);
return; return;
} }
foreach (var recipient in Utilities.GetPlayers().Where(p => p != null && p.IsValid)) foreach (var recipient in PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid))
{ {
bool hasSkill = SkillPlayerInfo.ContainsKey(recipient.Index); bool hasSkill = SkillPlayerInfo.ContainsKey(recipient.Index);
@ -98,7 +98,7 @@ namespace src.player.skills
{ {
if (Server.TickCount % (60 * SkillsInfo.GetValue<int>(skillName, "cooldown")) != 0) return; if (Server.TickCount % (60 * SkillsInfo.GetValue<int>(skillName, "cooldown")) != 0) return;
foreach (var player in Utilities.GetPlayers() foreach (var player in PlayerManager.GetTickPlayers()
.Where(p => p != null && p.IsValid && p.PlayerPawn.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0)) .Where(p => p != null && p.IsValid && p.PlayerPawn.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0))
{ {
var entities = EntityManager.GetPlayerEntities(player.Index, "empty_prop"); var entities = EntityManager.GetPlayerEntities(player.Index, "empty_prop");

View file

@ -56,7 +56,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
if (cameras.TryGetValue(player.Index, out var cameraInfo) && cameraInfo.Item2 != 0) if (cameras.TryGetValue(player.Index, out var cameraInfo) && cameraInfo.Item2 != 0)
{ {
if (player == null || !player.IsValid) continue; if (player == null || !player.IsValid) continue;
@ -100,7 +100,8 @@ namespace src.player.skills
if (!forceToDefault) if (!forceToDefault)
newCameraRaw = CreateCamera(player); newCameraRaw = CreateCamera(player);
} else }
else
{ {
orginalCameraRaw = pawn.CameraServices.ViewEntity.Raw; orginalCameraRaw = pawn.CameraServices.ViewEntity.Raw;
if (!forceToDefault) if (!forceToDefault)
@ -129,7 +130,7 @@ namespace src.player.skills
var camera = EntityManager.CreateTrackedDynamicProp(player.Index); var camera = EntityManager.CreateTrackedDynamicProp(player.Index);
if (camera == null || !camera.IsValid) return 0; if (camera == null || !camera.IsValid) return 0;
var enemies = Utilities.GetPlayers().Where(p => var enemies = PlayerManager.GetTickPlayers().Where(p =>
p != null && p != null &&
p.IsValid && p.IsValid &&
p.Team != player.Team && p.Team != player.Team &&
@ -153,13 +154,17 @@ namespace src.player.skills
Server.NextFrame(() => Server.NextFrame(() =>
{ {
if (camera == null || !camera.IsValid) return; if (camera == null || !camera.IsValid) return;
camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
var camNode = camera.CBodyComponent?.SceneNode?.Owner?.Entity;
if (camNode != null)
camNode.Flags = (uint)(camNode.Flags & ~(1 << 2));
camera.SetModel("models/sprays/spray_plane.vmdl"); camera.SetModel("models/sprays/spray_plane.vmdl");
camera.Render = Color.FromArgb(1, 255, 255, 255); camera.Render = Color.FromArgb(1, 255, 255, 255);
camera.Teleport(pos, angle); camera.Teleport(pos, angle);
camera.DispatchSpawn(); camera.DispatchSpawn();
CBaseEntity target = pawn; CBaseEntity? target = pawn != null && pawn.IsValid ? pawn : null;
var entities = EntityManager.GetPlayerEntities(enemy.Index, "empty_prop"); var entities = EntityManager.GetPlayerEntities(enemy.Index, "empty_prop");
if (entities.Count > 0) if (entities.Count > 0)
@ -169,6 +174,7 @@ namespace src.player.skills
target = entity; target = entity;
} }
if (target == null || !target.IsValid) return;
camera.AcceptInput("SetParent", target, target, "!activator"); camera.AcceptInput("SetParent", target, target, "!activator");
}); });

View file

@ -27,7 +27,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
if (SkillUtils.IsFreezeTime()) return; if (SkillUtils.IsFreezeTime()) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (player == null || !player.IsValid) continue; if (player == null || !player.IsValid) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
@ -68,7 +68,7 @@ namespace src.player.skills
private static void UpdateHUD(CCSPlayerController player, ZamianaMiejsc_PlayerInfo skillInfo, bool showInfo) private static void UpdateHUD(CCSPlayerController player, ZamianaMiejsc_PlayerInfo skillInfo, bool showInfo)
{ {
if(player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
float cooldown = 0; float cooldown = 0;
if (skillInfo != null) if (skillInfo != null)
@ -103,7 +103,7 @@ namespace src.player.skills
if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo)) if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
{ {
List<CCSPlayerController> enemy = Utilities.GetPlayers().FindAll(p => Instance.IsPlayerValid(p) && p.Team != player.Team && p.PawnIsAlive); List<CCSPlayerController> enemy = PlayerManager.GetTickPlayers().FindAll(p => Instance.IsPlayerValid(p) && p.Team != player.Team && p.PawnIsAlive);
if (enemy.Count == 0) if (enemy.Count == 0)
{ {
skillInfo.FindedEnemy = false; skillInfo.FindedEnemy = false;

View file

@ -25,7 +25,7 @@ namespace src.player.skills
playerInfo.SkillChance = newChance; playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills; using static src.jRandomSkills;
@ -20,12 +20,12 @@ namespace src.player.skills
{ {
if (Server.TickCount % 32 != 0) return; if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && SkillUtils.HasMenu(p))) foreach (var player in PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid && SkillUtils.HasMenu(p)))
{ {
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) continue; if (playerInfo?.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p => var enemies = PlayerManager.GetTickPlayers().Where(p =>
p != null && p != null &&
p.IsValid) p.IsValid)
.Select(p => PlayerManager.GetPlayerEvent(p)) .Select(p => PlayerManager.GetPlayerEvent(p))
@ -58,7 +58,7 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
foreach (var player in Utilities.GetPlayers().Where(p => p != null && p.IsValid)) foreach (var player in PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid))
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
@ -106,7 +106,7 @@ namespace src.player.skills
var playerEvent = PlayerManager.GetPlayerFromEvent(player); var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return; if (playerEvent == null || !playerEvent.IsValid) return;
var enemies = Utilities.GetPlayers() var enemies = PlayerManager.GetTickPlayers()
.Where(p => p != null .Where(p => p != null
&& p.IsValid && p.IsValid
&& p.Team != player.Team && p.Team != player.Team
@ -131,7 +131,7 @@ namespace src.player.skills
SkillUtils.CreateMenu(player, menuItems); SkillUtils.CreateMenu(player, menuItems);
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName)}",
border: !Utilities.GetPlayers().Any(p => p != null && p.Team == player.Team && p != player) ? "tb" : "t"); border: !PlayerManager.GetTickPlayers().Any(p => p != null && p.Team == player.Team && p != player) ? "tb" : "t");
} }
else else
playerEvent.PrintToChat($" {ChatColors.Red}{playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")}"); playerEvent.PrintToChat($" {ChatColors.Red}{playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")}");

View file

@ -44,7 +44,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
if (cameras.TryGetValue(player.Index, out var cameraInfo) && cameraInfo.Item2 != 0) if (cameras.TryGetValue(player.Index, out var cameraInfo) && cameraInfo.Item2 != 0)
{ {
var pawn = player.PlayerPawn.Value; var pawn = player.PlayerPawn.Value;
@ -108,10 +108,15 @@ namespace src.player.skills
Server.NextFrame(() => Server.NextFrame(() =>
{ {
if (camera == null || !camera.IsValid) return; if (camera == null || !camera.IsValid) return;
camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2)); if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
var camNode = camera.CBodyComponent?.SceneNode?.Owner?.Entity;
if (camNode != null)
camNode.Flags = (uint)(camNode.Flags & ~(1 << 2));
camera.SetModel("models/sprays/spray_plane.vmdl"); camera.SetModel("models/sprays/spray_plane.vmdl");
camera.Render = Color.FromArgb(0, 255, 255, 255); camera.Render = Color.FromArgb(0, 255, 255, 255);
camera.Teleport(pawn!.AbsOrigin, pawn.EyeAngles); camera.Teleport(pawn.AbsOrigin, pawn.EyeAngles);
camera.DispatchSpawn(); camera.DispatchSpawn();
}); });

View file

@ -25,7 +25,7 @@ namespace src.player.skills
var victimEvent = PlayerManager.GetPlayerEvent(victim); var victimEvent = PlayerManager.GetPlayerEvent(victim);
if (attackerEvent == null || !attackerEvent.IsValid) return; if (attackerEvent == null || !attackerEvent.IsValid) return;
if (victimEvent == null || !victimEvent.IsValid ) return; if (victimEvent == null || !victimEvent.IsValid) return;
var attackerPawn = attackerEvent.PlayerPawn.Value; var attackerPawn = attackerEvent.PlayerPawn.Value;
if (attackerPawn == null || !attackerPawn.IsValid || attackerPawn.Health == 0) return; if (attackerPawn == null || !attackerPawn.IsValid || attackerPawn.Health == 0) return;

View file

@ -50,7 +50,8 @@ namespace src.player.skills
float y = BitConverter.ToSingle(packedParams, 11); float y = BitConverter.ToSingle(packedParams, 11);
float z = BitConverter.ToSingle(packedParams, 15); float z = BitConverter.ToSingle(packedParams, 15);
soundPos = new Vector(x, y, z); soundPos = new Vector(x, y, z);
} catch { } }
catch { }
} }
if (soundPos == null) return; if (soundPos == null) return;
@ -136,6 +137,12 @@ namespace src.player.skills
DisableKnifeSkill(knifeInfo); DisableKnifeSkill(knifeInfo);
} }
public static void PlayerDisconnect(uint playerIndex)
{
if (knivesInfo.TryRemove(playerIndex, out KnifeInfo? knifeInfo) && knifeInfo != null)
DisableKnifeSkill(knifeInfo);
}
public static void DisableKnifeSkill(KnifeInfo knifeInfo) public static void DisableKnifeSkill(KnifeInfo knifeInfo)
{ {
if (knifeInfo.Timer != null) if (knifeInfo.Timer != null)
@ -185,7 +192,8 @@ namespace src.player.skills
if (weapon == null || !weapon.IsValid || (!weapon.DesignerName.Contains("knife") && !weapon.DesignerName.Contains("bayonet"))) return; if (weapon == null || !weapon.IsValid || (!weapon.DesignerName.Contains("knife") && !weapon.DesignerName.Contains("bayonet"))) return;
player.DropActiveWeapon(); player.DropActiveWeapon();
Server.NextFrame(() => { Server.NextFrame(() =>
{
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
if (weapon == null || !weapon.IsValid) return; if (weapon == null || !weapon.IsValid) return;
ThrowKnife(player, weapon); ThrowKnife(player, weapon);
@ -312,8 +320,14 @@ namespace src.player.skills
if (victimPawn.Index == throwerPawn.Index) if (victimPawn.Index == throwerPawn.Index)
return; return;
var victimController = victimPawn.Controller.Value?.As<CCSPlayerController>();
bool friendlyFire = SkillsInfo.GetValue<bool>(skillName, "friendlyFire"); bool friendlyFire = SkillsInfo.GetValue<bool>(skillName, "friendlyFire");
if (!friendlyFire && thrower.TeamNum == victimPawn.TeamNum) return; if (!friendlyFire)
{
if (thrower.TeamNum == victimPawn.TeamNum) return;
if (victimController != null && victimController.IsValid && thrower.Team == victimController.Team) return;
}
if (CheckHasKnife(thrower!)) return; if (CheckHasKnife(thrower!)) return;
@ -371,7 +385,7 @@ namespace src.player.skills
var obs = playerPawn.ObserverServices?.ObserverTarget?.Value; var obs = playerPawn.ObserverServices?.ObserverTarget?.Value;
if (obs != null && obs.IsValid) if (obs != null && obs.IsValid)
{ {
var observed = Utilities.GetPlayers().FirstOrDefault(p => var observed = PlayerManager.GetTickPlayers().FirstOrDefault(p =>
p != null && p.IsValid && p != null && p.IsValid &&
p.Pawn?.Value?.Handle == obs.Handle); p.Pawn?.Value?.Handle == obs.Handle);
if (observed != null) if (observed != null)

View file

@ -82,7 +82,7 @@ namespace src.player.skills
int smokeDamage = SkillsInfo.GetValue<int>(skillName, "smokeDamage"); int smokeDamage = SkillsInfo.GetValue<int>(skillName, "smokeDamage");
foreach (Vector smokePos in smokes.Keys) foreach (Vector smokePos in smokes.Keys)
foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid)) foreach (var player in PlayerManager.GetTickPlayers().Where(p => p.IsValid))
{ {
var eventPlayer = PlayerManager.GetPlayerEvent(player); var eventPlayer = PlayerManager.GetPlayerEvent(player);
if (eventPlayer == null || !eventPlayer.IsValid) continue; if (eventPlayer == null || !eventPlayer.IsValid) continue;

View file

@ -30,7 +30,7 @@ namespace src.player.skills
// One pawn->info map per frame instead of a GetPlayers scan per client. // One pawn->info map per frame instead of a GetPlayers scan per client.
var infoByPawnHandle = new Dictionary<nint, jSkill_PlayerInfo?>(); var infoByPawnHandle = new Dictionary<nint, jSkill_PlayerInfo?>();
foreach (var p in Utilities.GetPlayers()) foreach (var p in PlayerManager.GetTickPlayers())
{ {
var h = p?.Pawn?.Value?.Handle; var h = p?.Pawn?.Value?.Handle;
if (p != null && p.IsValid && h != null) if (p != null && p.IsValid && h != null)
@ -108,6 +108,29 @@ namespace src.player.skills
playersInAction.Clear(); playersInAction.Clear();
} }
public static void PlayerDeath(EventPlayerDeath @event)
{
var victim = @event.Userid;
if (victim == null || !victim.IsValid) return;
RemoveGlow(victim.Index);
}
public static void PlayerDisconnect(uint playerIndex)
{
RemoveGlow(playerIndex);
}
private static void RemoveGlow(uint enemyIndex)
{
if (!glows.TryRemove(enemyIndex, out var glowInfo)) return;
SkillUtils.SafeKillEntity<CDynamicProp>(glowInfo.GlowIndex);
SkillUtils.SafeKillEntity<CDynamicProp>(glowInfo.RelayIndex);
temporaryBlockList.TryAdd(glowInfo.RelayIndex, DateTime.Now.AddSeconds(2));
temporaryBlockList.TryAdd(glowInfo.GlowIndex, DateTime.Now.AddSeconds(2));
}
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
Event.EnableTransmit(); Event.EnableTransmit();
@ -132,7 +155,7 @@ namespace src.player.skills
private static void SetGlowEffectForAll() private static void SetGlowEffectForAll()
{ {
var enemies = Utilities.GetPlayers().Where(p => var enemies = PlayerManager.GetTickPlayers().Where(p =>
p != null && p != null &&
p.IsValid && p.IsValid &&
p.PlayerPawn?.Value != null && p.PlayerPawn?.Value != null &&

View file

@ -52,7 +52,7 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
var players = Utilities.GetPlayers().ToArray(); var players = PlayerManager.GetTickPlayers().ToArray();
foreach (var player in players) foreach (var player in players)
{ {
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
@ -222,7 +222,7 @@ namespace src.player.skills
private static CCSPlayerController? GetRandomEnemy(CCSPlayerController player) private static CCSPlayerController? GetRandomEnemy(CCSPlayerController player)
{ {
CCSPlayerController[] enemies = [.. Utilities.GetPlayers().FindAll(e => e.Team != player.Team && e.PawnIsAlive)]; CCSPlayerController[] enemies = [.. PlayerManager.GetTickPlayers().FindAll(e => e.Team != player.Team && e.PawnIsAlive)];
if (enemies.Length == 0) return null; if (enemies.Length == 0) return null;
return enemies[Instance.Random.Next(enemies.Length)]; return enemies[Instance.Random.Next(enemies.Length)];
} }

View file

@ -65,7 +65,8 @@ namespace src.player.skills
var playerInfo = PlayerManager.GetPlayerByIndex((PlayerManager.GetPlayerEvent(player)?.Index ?? player.Index)); var playerInfo = PlayerManager.GetPlayerByIndex((PlayerManager.GetPlayerEvent(player)?.Index ?? player.Index));
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
Server.NextFrame(() => { Server.NextFrame(() =>
{
if (grenade == null || !grenade.IsValid) return; if (grenade == null || !grenade.IsValid) return;
grenade.ActualGravityScale = .0001f; grenade.ActualGravityScale = .0001f;

View file

@ -25,7 +25,7 @@ namespace src.player.skills
{ {
if (infectedPlayers.IsEmpty && playersToTarget.IsEmpty) return; if (infectedPlayers.IsEmpty && playersToTarget.IsEmpty) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
DisableSkill(player); DisableSkill(player);
infectedPlayers.Clear(); infectedPlayers.Clear();
@ -42,7 +42,7 @@ namespace src.player.skills
var playerEvent = PlayerManager.GetPlayerFromEvent(player); var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return; if (playerEvent == null || !playerEvent.IsValid) return;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray(); var enemies = PlayerManager.GetTickPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => (e.PlayerName, e.Index.ToString())));
@ -78,13 +78,13 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
if (Server.TickCount % 32 != 0) return; if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in PlayerManager.GetTickPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue; if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p => var enemies = PlayerManager.GetTickPlayers().Where(p =>
p != null && p != null &&
p.IsValid) p.IsValid)
.Select(p => PlayerManager.GetPlayerEvent(p)) .Select(p => PlayerManager.GetPlayerEvent(p))
@ -122,7 +122,8 @@ namespace src.player.skills
string enemyId = commands[0]; string enemyId = commands[0];
if (!uint.TryParse(enemyId, out uint enemyIndex)) { if (!uint.TryParse(enemyId, out uint enemyIndex))
{
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index")); playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index"));
return; return;
} }
@ -166,7 +167,8 @@ namespace src.player.skills
if (!infectedPlayers.ContainsKey(player.Index)) return; if (!infectedPlayers.ContainsKey(player.Index)) return;
Server.NextFrame(() => { Server.NextFrame(() =>
{
if (grenade == null || !grenade.IsValid) return; if (grenade == null || !grenade.IsValid) return;
float forceMultiplier = (float)(Instance.Random.NextDouble() * .6 + .7); float forceMultiplier = (float)(Instance.Random.NextDouble() * .6 + .7);

View file

@ -100,7 +100,11 @@ namespace jRandomSkills.src.utils
set => Field<int>(m_nDeltaTick) = value; set => Field<int>(m_nDeltaTick) = value;
} }
public void ForceFullUpdate() => DeltaTick = -1; public void ForceFullUpdate()
{
if (Handle == nint.Zero) return;
DeltaTick = -1;
}
} }
#endregion #endregion

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