v1.2.2.b1

This commit is contained in:
Juzlus 2026-05-24 23:13:56 +02:00
parent 0fb3d63cd8
commit 46195c2663
147 changed files with 3470 additions and 2161 deletions

View file

@ -6,17 +6,20 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Remove="tools\**" />
<None Remove="tools\**" />
<None Remove="src\command\Command.cs~RF4f34d1e7.TMP" /> <None Remove="src\command\Command.cs~RF4f34d1e7.TMP" />
<None Remove="src\player\PlayerOnTick.cs~RF38b6229.TMP" /> <None Remove="src\player\PlayerOnTick.cs~RF38b6229.TMP" />
<None Remove="src\player\skills\RespWroga.cs~RF528d210.TMP" /> <None Remove="src\player\skills\RespWroga.cs~RF528d210.TMP" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.367" /> <PackageReference Include="CounterStrikeSharp.API" Version="1.0.368" />
<PackageReference Include="MaxMind.Db" Version="5.0.0"> <PackageReference Include="MaxMind.Db" Version="5.1.0">
</PackageReference> </PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup> </ItemGroup>
@ -29,7 +32,7 @@
<!-- Relative path to the WASDMenuAPI source code --> <!-- Relative path to the WASDMenuAPI source code -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="../WASDMenuAPI - SRC Files/WASDMenuAPI.csproj" /> <ProjectReference Include="..\WASDMenuAPI - SRC Files\WASDMenuAPI.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -3,7 +3,6 @@ using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Admin;
using CounterStrikeSharp.API.Modules.Commands; using CounterStrikeSharp.API.Modules.Commands;
using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.menu; using src.menu;
using src.player; using src.player;
@ -76,19 +75,23 @@ namespace src.command
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)] [CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
private static void Command_UseTypeSkill(CCSPlayerController? player, CommandInfo _) private static void Command_UseTypeSkill(CCSPlayerController? player, CommandInfo _)
{ {
if (player == null) return; player = PlayerManager.GetPlayerEvent(player);
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (player == null || !player.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
if (playerInfo == null || playerInfo.IsDrawing) return; if (playerInfo == null || playerInfo.IsDrawing) return;
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return; if (playerPawn?.CBodyComponent == null) return;
if (!player.IsValid || !player.PawnIsAlive) return;
if (!player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
if (SkillsInfo.GetValue<bool>(playerInfo.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime()) if (SkillsInfo.GetValue<bool>(playerInfo.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
return; return;
string[] commands = _.ArgString.Trim().Split(" ", StringSplitOptions.RemoveEmptyEntries); string[] commands = _.ArgString.Trim().Split(" ", StringSplitOptions.RemoveEmptyEntries);
Debug.WriteToDebug($"Player {player.PlayerName} used the skill: {playerInfo.Skill}"); Debug.WriteToDebug($"Player {player.PlayerName} used the skill: {playerInfo.Skill}");
if (commands == null || commands.Length == 0) if (commands == null || commands.Length == 0)
Instance.SkillAction(playerInfo.Skill.ToString(), "UseSkill", [player]); Instance.SkillAction(playerInfo.Skill.ToString(), "UseSkill", [player]);
else else
@ -100,9 +103,9 @@ namespace src.command
{ {
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_setskill {command.ArgString} command."); Debug.WriteToDebug($"Player {player?.PlayerName} used the css_setskill {command.ArgString} command.");
if (!string.IsNullOrEmpty(config.NormalCommands.SetSkillCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.SetSkillCommand.Permissions)) return; if (!string.IsNullOrEmpty(config.NormalCommands.SetSkillCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.SetSkillCommand.Permissions)) return;
var targetPlayer = Utilities.GetPlayers().FirstOrDefault(p => !p.IsBot var targetPlayer = Utilities.GetPlayers().FirstOrDefault(p => p != null && p.IsValid
&& (p.SteamID.ToString().Equals(command.GetArg(1), StringComparison.CurrentCultureIgnoreCase) && (p.SteamID.ToString().Equals(command.GetArg(1), StringComparison.CurrentCultureIgnoreCase)
|| p.PlayerName.Equals(command.GetArg(1), StringComparison.CurrentCultureIgnoreCase))); || p.PlayerName.Equals(command.GetArg(1), StringComparison.OrdinalIgnoreCase)));
if (command.ArgCount < 2) if (command.ArgCount < 2)
{ {
@ -140,7 +143,7 @@ namespace src.command
return; return;
} }
var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == targetPlayer.SteamID); var skillPlayer = PlayerManager.GetPlayerByIndex(targetPlayer.Index);
if (skillPlayer != null) if (skillPlayer != null)
{ {
Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [targetPlayer]); Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [targetPlayer]);
@ -246,7 +249,7 @@ namespace src.command
else else
{ {
Server.ExecuteCommand("mp_restartgame 2"); Server.ExecuteCommand("mp_restartgame 2");
Instance?.AddTimer(2.0f, () => Localization.PrintTranslationToChatAll($" {ChatColors.Green}{{0}}", ["game_start"])); Instance?.AddTimer(2.0f, () => Localization.PrintTranslationToChatAll($" {ChatColors.Green}{{0}}", ["game_start"]), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
} }
} }
@ -269,7 +272,7 @@ namespace src.command
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
if (Instance.IsPlayerValid(player) && new CsTeam[] { CsTeam.CounterTerrorist, CsTeam.Terrorist }.Contains(player.Team)) if (Instance.IsPlayerValid(player) && new CsTeam[] { CsTeam.CounterTerrorist, CsTeam.Terrorist }.Contains(player.Team))
player.SwitchTeam(player.Team == CsTeam.Terrorist ? CsTeam.CounterTerrorist : CsTeam.Terrorist); player.SwitchTeam(player.Team == CsTeam.Terrorist ? CsTeam.CounterTerrorist : CsTeam.Terrorist);
Server.ExecuteCommand($"mp_restartgame 1"); Server.ExecuteCommand($"endround");
} }
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)] [CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
@ -374,7 +377,7 @@ namespace src.command
if (!string.IsNullOrEmpty(config.NormalCommands.BotPlace.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.BotPlace.Permissions)) return; if (!string.IsNullOrEmpty(config.NormalCommands.BotPlace.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.BotPlace.Permissions)) return;
var pawn = player.PlayerPawn.Value; var pawn = player.PlayerPawn.Value;
if (!player.PawnIsAlive || pawn.AbsOrigin == null || pawn.AbsRotation == null) return; if (player.LifeState != (byte)LifeState_t.LIFE_ALIVE || pawn.AbsOrigin == null || pawn.AbsRotation == null) return;
if (!int.TryParse(command.GetArg(1), out int botSlot)) if (!int.TryParse(command.GetArg(1), out int botSlot))
botSlot = -1; botSlot = -1;
@ -403,7 +406,7 @@ namespace src.command
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return; if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return;
if (!string.IsNullOrEmpty(config.NormalCommands.HudCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.HudCommand.Permissions)) return; if (!string.IsNullOrEmpty(config.NormalCommands.HudCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.HudCommand.Permissions)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.DisplayHUD = !playerInfo.DisplayHUD; playerInfo.DisplayHUD = !playerInfo.DisplayHUD;
@ -452,9 +455,9 @@ namespace src.command
{ {
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_setstaticskill {command.ArgString} command."); Debug.WriteToDebug($"Player {player?.PlayerName} used the css_setstaticskill {command.ArgString} command.");
if (!string.IsNullOrEmpty(config.NormalCommands.SetStaticSkillCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.SetStaticSkillCommand.Permissions)) return; if (!string.IsNullOrEmpty(config.NormalCommands.SetStaticSkillCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.SetStaticSkillCommand.Permissions)) return;
var targetPlayer = Utilities.GetPlayers().FirstOrDefault(p => !p.IsBot var targetPlayer = Utilities.GetPlayers().FirstOrDefault(p => p != null && p.IsValid
&& (p.SteamID.ToString().Equals(command.GetArg(1), StringComparison.CurrentCultureIgnoreCase) && (p.SteamID.ToString().Equals(command.GetArg(1), StringComparison.CurrentCultureIgnoreCase)
|| p.PlayerName.Equals(command.GetArg(1), StringComparison.CurrentCultureIgnoreCase))); || p.PlayerName.Equals(command.GetArg(1), StringComparison.OrdinalIgnoreCase)));
if (command.ArgCount < 2) if (command.ArgCount < 2)
{ {
@ -495,7 +498,7 @@ namespace src.command
return; return;
} }
var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == targetPlayer.SteamID); var skillPlayer = PlayerManager.GetPlayerByIndex(targetPlayer.Index);
if (skillPlayer != null) if (skillPlayer != null)
{ {
Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [targetPlayer]); Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [targetPlayer]);
@ -504,9 +507,9 @@ namespace src.command
skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration); skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration);
if (skill.Skill == src.player.Skills.None) if (skill.Skill == src.player.Skills.None)
Event.staticSkills.TryRemove(targetPlayer.SteamID, out _); Event.staticSkills.TryRemove(targetPlayer.Index, out _);
else else
Event.staticSkills.TryAdd(targetPlayer.SteamID, skill); Event.staticSkills.TryAdd(targetPlayer.Index, skill);
Instance.SkillAction(skill.Skill.ToString(), "EnableSkill", [targetPlayer]); Instance.SkillAction(skill.Skill.ToString(), "EnableSkill", [targetPlayer]);
if (player == null) if (player == null)
@ -593,32 +596,58 @@ namespace src.command
var skillsList = SkillData.Skills.OrderBy(s => s.Skill.ToString()).ToList(); var skillsList = SkillData.Skills.OrderBy(s => s.Skill.ToString()).ToList();
if (skillsList.Count == 0) return; if (skillsList.Count == 0) return;
nextSkill.TryGetValue(player.Index, out int currentIndex); string playerString = command.GetArg(1);
CCSPlayerController? targetPlayer = null;
if (!string.IsNullOrEmpty(playerString))
{
targetPlayer = Utilities.GetPlayers().FirstOrDefault(p => p != null && p.IsValid
&& (p.SteamID.ToString().Equals(playerString, StringComparison.CurrentCultureIgnoreCase)
|| p.PlayerName.Equals(playerString, StringComparison.OrdinalIgnoreCase)));
if (targetPlayer == null)
{
if (player == null)
{
Server.PrintToConsole(Localization.GetTranslation("player_not_found_setskill"));
return;
}
SkillUtils.PrintToChat(player, player.GetTranslation("player_not_found_setskill"));
return;
}
}
if (targetPlayer == null)
return;
nextSkill.TryGetValue(targetPlayer.Index, out int currentIndex);
int nextIndex = (currentIndex + 1) % skillsList.Count; int nextIndex = (currentIndex + 1) % skillsList.Count;
string arg = command.GetArg(1); string arg = command.GetArg(2);
if (!string.IsNullOrEmpty(arg)) if (!string.IsNullOrEmpty(arg))
{ {
if (arg == "-1") if (arg == "-1")
nextIndex--; nextIndex--;
else if (int.TryParse(arg, out int newIndex))
nextIndex = newIndex;
else else
nextIndex = int.Parse(arg); return;
} }
var skill = skillsList[nextIndex]; var skill = skillsList[nextIndex];
player.PrintToChat(nextIndex.ToString()); player.PrintToChat(nextIndex.ToString());
var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var skillPlayer = PlayerManager.GetPlayerByIndex(targetPlayer!.Index);
if (skillPlayer == null) return; if (skillPlayer == null) return;
Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [player]); Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [targetPlayer]);
skillPlayer.Skill = skill.Skill; skillPlayer.Skill = skill.Skill;
skillPlayer.SpecialSkill = Skills.None; skillPlayer.SpecialSkill = Skills.None;
nextSkill[player.Index] = nextIndex; nextSkill[targetPlayer.Index] = nextIndex;
Instance.SkillAction(skill.Skill.ToString(), "EnableSkill", [player]); Instance.SkillAction(skill.Skill.ToString(), "EnableSkill", [targetPlayer]);
skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration); skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration);
if (skill.Display) if (skill.Display)

View file

@ -22,7 +22,7 @@ namespace src.command
vote.SetActive(false); vote.SetActive(false);
vote.TimeToNextSameVoting = vote.TimeToNextVoting; vote.TimeToNextSameVoting = vote.TimeToNextVoting;
Localization.PrintTranslationToChatAll($" {ChatColors.Red}{{0}}", ["vote_timeout"], [commandName]); Localization.PrintTranslationToChatAll($" {ChatColors.Red}{{0}}", ["vote_timeout"], [commandName]);
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
} }
private static VoteData? CreateVote(VoteType voteType, string? args = null) private static VoteData? CreateVote(VoteType voteType, string? args = null)
@ -49,7 +49,7 @@ namespace src.command
{ {
if (!votes.ContainsKey(vote)) return; if (!votes.ContainsKey(vote)) return;
votes.TryRemove(vote, out _); votes.TryRemove(vote, out _);
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
return vote; return vote;
} }

View file

@ -28,7 +28,7 @@ namespace src
public override string ModuleName => "[CS2] [ jRandomSkills ]"; public override string ModuleName => "[CS2] [ jRandomSkills ]";
public override string ModuleAuthor => "D3X, Juzlus"; public override string ModuleAuthor => "D3X, Juzlus";
public override string ModuleDescription => "Plugin adds random skills every round for CS2 by D3X. Modified by Juzlus."; public override string ModuleDescription => "Plugin adds random skills every round for CS2 by D3X. Modified by Juzlus.";
public override string ModuleVersion => "1.2.1.b9"; public override string ModuleVersion => "1.2.2.b1";
public override void Load(bool hotReload) public override void Load(bool hotReload)
{ {
@ -43,6 +43,7 @@ namespace src
Command.Load(); Command.Load();
WASDMenuAPI.WASDMenuAPI.LoadPlugin(Instance, hotReload); WASDMenuAPI.WASDMenuAPI.LoadPlugin(Instance, hotReload);
LoadAllSkills(); LoadAllSkills();
PlayerManager.SyncWithPlugin(Instance);
Instance.RegisterListener<OnServerPrecacheResources>(LoadManifest); Instance.RegisterListener<OnServerPrecacheResources>(LoadManifest);
@ -217,7 +218,7 @@ namespace src
Console.ForegroundColor = (ConsoleColor)CS2ConsoleColors.Cyan; Console.ForegroundColor = (ConsoleColor)CS2ConsoleColors.Cyan;
Console.Write(", HtmlHudFix: "); Console.Write(", HtmlHudFix: ");
Console.ForegroundColor = (ConsoleColor)CS2ConsoleColors.LightBlue; Console.ForegroundColor = (ConsoleColor)CS2ConsoleColors.LightBlue;
Console.WriteLine(Config.LoadedConfig.FlashingHtmlHudFix); Console.WriteLine(Config.LoadedConfig.EnableFlashingHtmlHudFix);
// Dependences // Dependences
Console.ForegroundColor = (ConsoleColor)CS2ConsoleColors.Cyan; Console.ForegroundColor = (ConsoleColor)CS2ConsoleColors.Cyan;
@ -295,12 +296,21 @@ namespace src
return null; return null;
} }
} }
/// <summary>
/// Gets a player info by index. O(n) lookup - consider caching if called frequently.
/// </summary>
internal jSkill_PlayerInfo? GetPlayerInfoByIndex(uint playerIndex)
{
return SkillPlayer.FirstOrDefault(p => p.PlayerIndex == playerIndex);
}
} }
public class jSkill_PlayerInfo public class jSkill_PlayerInfo
{ {
public required ulong SteamID { get; set; } public required bool IsBot { get; set; }
public required string PlayerName { get; set; } public required string PlayerName { get; set; }
public required uint PlayerIndex { get; set; }
public Skills Skill { get; set; } public Skills Skill { get; set; }
public Skills SpecialSkill { get; set; } public Skills SpecialSkill { get; set; }
public float? SkillChance { get; set; } public float? SkillChance { get; set; }

View file

@ -0,0 +1,77 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Timers;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
namespace src.utils
{
public static class BotManager
{
private static Timer? _skillTimer;
private static Timer? _rotationTimer;
private static readonly Random _random = new();
private const float SkillInterval = 2f;
private const float RotationInterval = 45f;
public static void Initialize()
{
if (!Config.LoadedConfig.EnableBotSkills) return;
Stop();
_skillTimer = Instance.AddTimer(SkillInterval, OnBotUseSkillTimer, TimerFlags.REPEAT | TimerFlags.STOP_ON_MAPCHANGE);
if (!Config.LoadedConfig.EnableBotKickDebug) return;
_rotationTimer = Instance.AddTimer(RotationInterval, OnBotRotationTimer, TimerFlags.REPEAT | TimerFlags.STOP_ON_MAPCHANGE);
}
public static void Stop()
{
if (!Config.LoadedConfig.EnableBotSkills) return;
_skillTimer?.Kill();
_skillTimer = null;
if (!Config.LoadedConfig.EnableBotKickDebug) return;
_rotationTimer?.Kill();
_rotationTimer = null;
}
private static void OnBotUseSkillTimer()
{
var activeBots = Utilities.GetPlayers()
.Where(p => p != null && p.IsValid && p.IsBot && !p.IsHLTV && p.LifeState == (byte)LifeState_t.LIFE_ALIVE && p.Team != CsTeam.Spectator)
.ToList();
if (activeBots.Count == 0) return;
var randomBot = activeBots[_random.Next(activeBots.Count)];
if (randomBot == null || !randomBot.IsValid) return;
if (randomBot.PlayerPawn?.Value == null || !randomBot.PlayerPawn.Value.IsValid || randomBot.PlayerPawn.Value.IsDefusing) return;
var bot_info = PlayerManager.GetPlayerByIndex(randomBot.Index);
if (bot_info == null) return;
Instance.SkillAction(bot_info.Skill.ToString(), "UseSkill", [randomBot]);
}
private static void OnBotRotationTimer()
{
var allBots = Utilities.GetPlayers()
.Where(p => p != null && p.IsValid && p.IsBot && !p.IsHLTV)
.ToList();
if (allBots.Count > 0)
{
var botToKick = allBots[_random.Next(allBots.Count)];
Server.ExecuteCommand($"kickid {botToKick.UserId}");
}
Server.NextFrame(() => Server.ExecuteCommand("bot_add"));
}
}
}

View file

@ -19,7 +19,7 @@ namespace src.player
sessionId = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}"; sessionId = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}";
Instance.RegisterEventHandler<EventPlayerConnectFull>((@event, info) => Instance.RegisterEventHandler<EventPlayerConnectFull>((@event, info) =>
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return HookResult.Continue; if (player == null || !player.IsValid) return HookResult.Continue;
WriteToDebug($"{(player.IsBot ? "Bot" : "Player")} {player.PlayerName} joined the game."); WriteToDebug($"{(player.IsBot ? "Bot" : "Player")} {player.PlayerName} joined the game.");
return HookResult.Continue; return HookResult.Continue;
@ -27,7 +27,7 @@ namespace src.player
Instance.RegisterEventHandler<EventPlayerDisconnect>((@event, info) => Instance.RegisterEventHandler<EventPlayerDisconnect>((@event, info) =>
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return HookResult.Continue; if (player == null || !player.IsValid) return HookResult.Continue;
WriteToDebug($"{(player.IsBot ? "Bot" : "Player")} {player.PlayerName} disconnected."); WriteToDebug($"{(player.IsBot ? "Bot" : "Player")} {player.PlayerName} disconnected.");
return HookResult.Continue; return HookResult.Continue;
@ -59,8 +59,8 @@ namespace src.player
Instance.RegisterEventHandler<EventPlayerDeath>((@event, info) => Instance.RegisterEventHandler<EventPlayerDeath>((@event, info) =>
{ {
var victim = @event.Userid; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
if (victim != null) if (victim != null)
{ {
if (attacker != null) if (attacker != null)
@ -90,7 +90,7 @@ namespace src.player
Instance.RegisterEventHandler<EventPlayerShoot>((@event, info) => Instance.RegisterEventHandler<EventPlayerShoot>((@event, info) =>
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return HookResult.Continue; if (player == null || !player.IsValid) return HookResult.Continue;
WriteToDebug($"{(player.IsBot ? "Bot" : "Player")} {player.PlayerName} fired a shot."); WriteToDebug($"{(player.IsBot ? "Bot" : "Player")} {player.PlayerName} fired a shot.");
return HookResult.Continue; return HookResult.Continue;
@ -116,10 +116,10 @@ namespace src.player
if (attackerPawn == null || attackerPawn.Controller?.Value == null || victimPawn == null || victimPawn.Controller?.Value == null) if (attackerPawn == null || attackerPawn.Controller?.Value == null || victimPawn == null || victimPawn.Controller?.Value == null)
return HookResult.Continue; return HookResult.Continue;
CCSPlayerController attacker = attackerPawn.Controller.Value.As<CCSPlayerController>(); CCSPlayerController attacker = PlayerManager.GetPlayerEvent(attackerPawn.Controller.Value.As<CCSPlayerController>())!;
CCSPlayerController victim = victimPawn.Controller.Value.As<CCSPlayerController>(); CCSPlayerController victim = PlayerManager.GetPlayerEvent(victimPawn.Controller.Value.As<CCSPlayerController>())!;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
if (playerInfo == null) return HookResult.Continue; if (playerInfo == null) return HookResult.Continue;
WriteToDebug($"{(victim.IsBot ? "Bot" : "Player")} {victim.PlayerName} took damage from {(attacker.IsBot ? "bot" : "player")} {attacker.PlayerName}."); WriteToDebug($"{(victim.IsBot ? "Bot" : "Player")} {victim.PlayerName} took damage from {(attacker.IsBot ? "bot" : "player")} {attacker.PlayerName}.");
@ -131,11 +131,33 @@ namespace src.player
if (Config.LoadedConfig.DebugMode != true) if (Config.LoadedConfig.DebugMode != true)
return; return;
// GetAllEntityIndexes();
string filename = $"debug_{sessionId}.txt"; string filename = $"debug_{sessionId}.txt";
string path = Path.Combine(debugFolder, filename); string path = Path.Combine(debugFolder, filename);
Directory.CreateDirectory(debugFolder); Directory.CreateDirectory(debugFolder);
File.AppendAllText(path, $"[{DateTime.Now:dd.MM.yyyy HH:mm:ss}] {message}{Environment.NewLine}", System.Text.Encoding.UTF8); File.AppendAllText(path, $"[{DateTime.Now:dd.MM.yyyy HH:mm:ss}] {message}{Environment.NewLine}", System.Text.Encoding.UTF8);
} }
private static void GetAllEntityIndexes()
{
if (Instance.GameRules == null) return;
var entities = Utilities.GetAllEntities();
foreach (var entity in entities)
if (entity != null && entity.IsValid && !string.IsNullOrEmpty(entity.DesignerName))
{
string text = $"Entity: {entity.DesignerName}, ID: {entity.Index}";
Console.WriteLine(text);
string filename = $"debug_{sessionId}.txt";
string path = Path.Combine(debugFolder, filename);
Directory.CreateDirectory(debugFolder);
File.AppendAllText(path, text, System.Text.Encoding.UTF8);
}
}
} }
} }

View file

@ -85,7 +85,6 @@ public enum Skills
Dracula, Dracula,
Duplicator, Duplicator,
Dwarf, Dwarf,
Earthquake,
EnemySpawn, EnemySpawn,
ExplosiveShot, ExplosiveShot,
FalconEye, FalconEye,
@ -102,7 +101,6 @@ public enum Skills
Glue, Glue,
GodMode, GodMode,
Grenadier, Grenadier,
HealingChicken,
HealingSmoke, HealingSmoke,
Hermit, Hermit,
HolyHandGrenade, HolyHandGrenade,

View file

@ -2,12 +2,14 @@ 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.Admin; using CounterStrikeSharp.API.Modules.Admin;
using CounterStrikeSharp.API.Modules.Commands.Targeting;
using CounterStrikeSharp.API.Modules.Cvars; using CounterStrikeSharp.API.Modules.Cvars;
using CounterStrikeSharp.API.Modules.Events; using CounterStrikeSharp.API.Modules.Events;
using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.UserMessages; using CounterStrikeSharp.API.Modules.UserMessages;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using Microsoft.Extensions.Logging;
using RayTraceAPI; using RayTraceAPI;
using src.player.skills; using src.player.skills;
using src.utils; using src.utils;
@ -34,8 +36,8 @@ namespace src.player
public static readonly SkillsInfo.DefaultSkillInfo[] counterterroristSkills = [.. SkillsInfo.LoadedConfig.Where(s => s.OnlyTeam == (int)CsTeam.CounterTerrorist)]; public static readonly SkillsInfo.DefaultSkillInfo[] counterterroristSkills = [.. SkillsInfo.LoadedConfig.Where(s => s.OnlyTeam == (int)CsTeam.CounterTerrorist)];
private static readonly SkillsInfo.DefaultSkillInfo[] allTeamsSkills = [.. SkillsInfo.LoadedConfig.Where(s => s.OnlyTeam == 0)]; private static readonly SkillsInfo.DefaultSkillInfo[] allTeamsSkills = [.. SkillsInfo.LoadedConfig.Where(s => s.OnlyTeam == 0)];
private static readonly ConcurrentDictionary<ulong, ConcurrentBag<jSkill_SkillInfo>> playersSkills = []; private static readonly ConcurrentDictionary<uint, ConcurrentBag<jSkill_SkillInfo>> playersSkills = [];
public static readonly ConcurrentDictionary<ulong, jSkill_SkillInfo> staticSkills = []; public static readonly ConcurrentDictionary<uint, jSkill_SkillInfo> staticSkills = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
private static readonly MemoryFunctionVoid<CBasePlayerPawn, CBasePlayerWeapon> DropWeaponFunc = new(GameData.GetSignature("CCSPlayerController_HandleCommandDrop")); private static readonly MemoryFunctionVoid<CBasePlayerPawn, CBasePlayerWeapon> DropWeaponFunc = new(GameData.GetSignature("CCSPlayerController_HandleCommandDrop"));
@ -74,6 +76,7 @@ namespace src.player
Instance.RegisterListener<OnPlayerButtonsChanged>(CheckUseSkill); Instance.RegisterListener<OnPlayerButtonsChanged>(CheckUseSkill);
Instance.RegisterListener<OnEntitySpawned>(EntitySpawned); Instance.RegisterListener<OnEntitySpawned>(EntitySpawned);
Instance.RegisterListener<OnTick>(OnTick); Instance.RegisterListener<OnTick>(OnTick);
Instance.RegisterListener<OnClientPutInServer>(OnPlayerConnectedBot);
Instance.HookUserMessage(208, PlayerMakeSound); Instance.HookUserMessage(208, PlayerMakeSound);
VirtualFunctions.CBaseEntity_TakeDamageOldFunc.Hook(OnTakeDamage, HookMode.Pre); VirtualFunctions.CBaseEntity_TakeDamageOldFunc.Hook(OnTakeDamage, HookMode.Pre);
@ -96,7 +99,7 @@ namespace src.player
const int attempts = 6; const int attempts = 6;
for (int attempt = 0; attempt < attempts; attempt++) for (int attempt = 0; attempt < attempts; attempt++)
{ {
var rolled = RarityManager.RollRarity(); var (roll, rolled) = RarityManager.RollRarity();
var filtered = candidates.Where(s => var filtered = candidates.Where(s =>
{ {
@ -117,7 +120,7 @@ namespace src.player
}).ToList(); }).ToList();
if (filtered.Count > 0) if (filtered.Count > 0)
return filtered[Instance.Random.Next(filtered.Count)]; return filtered[Random.Shared.Next(filtered.Count)];
} }
var fallback = candidates.Where(s => var fallback = candidates.Where(s =>
@ -131,9 +134,9 @@ namespace src.player
}).ToList(); }).ToList();
if (fallback.Count > 0) if (fallback.Count > 0)
return fallback[Instance.Random.Next(fallback.Count)]; return fallback[Random.Shared.Next(fallback.Count)];
return candidates[Instance.Random.Next(candidates.Count)]; return candidates[Random.Shared.Next(candidates.Count)];
} }
private static HookResult PlayerMakeSound(UserMessage um) private static HookResult PlayerMakeSound(UserMessage um)
@ -402,6 +405,10 @@ namespace src.player
foreach (string skillName in activeSkills) foreach (string skillName in activeSkills)
Instance.SkillAction(skillName, "OnTakeDamage", [h]); Instance.SkillAction(skillName, "OnTakeDamage", [h]);
if (Fortnite.skillInThisRound == true && !activeSkills.Any(s => s == "Fortnite"))
Instance.SkillAction("Fortnite", "OnTakeDamage", [h]);
return HookResult.Continue; return HookResult.Continue;
} }
} }
@ -526,17 +533,21 @@ namespace src.player
} }
} }
private static HookResult PlayerConnectFull(EventPlayerConnectFull @event, GameEventInfo info) private static void OnPlayerConnectedBot(int playerSlot)
{ {
lock (setLock) lock (setLock)
{ {
var player = @event.Userid; var player = Utilities.GetPlayerFromSlot(playerSlot);
if (player == null || !player.IsValid) return HookResult.Continue; if (player == null || !player.IsValid) return;
Instance.SkillPlayer.Add(new jSkill_PlayerInfo if (player.IsBot && !Config.LoadedConfig.EnableBotSkills)
return;
var playerInfo = new jSkill_PlayerInfo
{ {
SteamID = player.SteamID, IsBot = player.IsBot,
PlayerName = player.PlayerName, PlayerName = player.PlayerName,
PlayerIndex = player.Index,
Skill = Skills.None, Skill = Skills.None,
SpecialSkill = Skills.None, SpecialSkill = Skills.None,
IsDrawing = false, IsDrawing = false,
@ -544,7 +555,18 @@ namespace src.player
PrintHTML = null, PrintHTML = null,
DisplayHUD = true, DisplayHUD = true,
SkillUsed = false, SkillUsed = false,
}); };
Instance.SkillPlayer.Add(playerInfo);
PlayerManager.Register(playerInfo);
}
}
private static HookResult PlayerConnectFull(EventPlayerConnectFull @event, GameEventInfo info)
{
lock (setLock)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return HookResult.Continue;
string welcomeMsg = player.GetTranslation("welcome_message", "welcome"); string welcomeMsg = player.GetTranslation("welcome_message", "welcome");
foreach (string line in welcomeMsg.Split("\n")) foreach (string line in welcomeMsg.Split("\n"))
@ -562,16 +584,18 @@ namespace src.player
{ {
lock (setLock) lock (setLock)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return HookResult.Continue; if (player == null || !player.IsValid) return HookResult.Continue;
var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var skillPlayer = PlayerManager.GetPlayerByIndex(player!.Index);
if (skillPlayer == null) return HookResult.Continue; if (skillPlayer == null) return HookResult.Continue;
Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [player]); Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [player]);
var items = Instance.SkillPlayer.ToList(); var items = Instance.SkillPlayer.ToList();
Instance.SkillPlayer = [.. items.Where(p => p.SteamID != skillPlayer.SteamID)]; Instance.SkillPlayer = [.. items.Where(p => p.PlayerIndex != player.Index)];
PlayerManager.UnregisterPlayer(player.Index);
EntityManager.DestroyPlayerEntities(player.Index);
return HookResult.Continue; return HookResult.Continue;
} }
@ -586,16 +610,10 @@ namespace src.player
string commandName = text.StartsWith('!') || text.StartsWith('/') ? text[1..] : text; string commandName = text.StartsWith('!') || text.StartsWith('/') ? text[1..] : text;
foreach (var cmd in Instance.CommandDefinitions)
Server.PrintToChatAll("1. " + cmd.Name);
foreach (var cmd in Instance.CommandListeners.Keys)
Server.PrintToChatAll("2. " + cmd?.Target?.ToString());
var player = Utilities.GetPlayerFromUserid(userID); var player = Utilities.GetPlayerFromUserid(userID);
if (player == null || !player.IsValid) return HookResult.Continue; if (player == null || !player.IsValid) return HookResult.Continue;
var skillPlayer = Instance?.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var skillPlayer = PlayerManager.GetPlayerByIndex(player!.Index);
if (skillPlayer == null) return HookResult.Continue; if (skillPlayer == null) return HookResult.Continue;
var temp = skillPlayer.SkillHudExpired; var temp = skillPlayer.SkillHudExpired;
@ -605,7 +623,7 @@ namespace src.player
{ {
if (skillPlayer.SkillHudExpired == DateTime.MinValue) if (skillPlayer.SkillHudExpired == DateTime.MinValue)
skillPlayer.SkillHudExpired = temp; skillPlayer.SkillHudExpired = temp;
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
return HookResult.Continue; return HookResult.Continue;
} }
@ -614,10 +632,10 @@ namespace src.player
{ {
lock (setLock) lock (setLock)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return HookResult.Continue; if (player == null || !player.IsValid) return HookResult.Continue;
var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var skillPlayer = PlayerManager.GetPlayerByIndex(player!.Index);
if (skillPlayer == null) return HookResult.Continue; if (skillPlayer == null) return HookResult.Continue;
if (setSkillTimer != null) if (setSkillTimer != null)
@ -642,11 +660,11 @@ namespace src.player
{ {
bool isWarmup = Instance.GameRules != null && Instance.GameRules.WarmupPeriod == true; bool isWarmup = Instance.GameRules != null && Instance.GameRules.WarmupPeriod == true;
isTransmitRegistered = false; isTransmitRegistered = false;
Instance.AddTimer(.1f, () => DisableAll()); Instance.AddTimer(.1f, () => DisableAll(), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid && !p.IsBot && !p.IsHLTV && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist)) foreach (var player in Utilities.GetPlayers().Where(p => p != null && p.IsValid && !p.IsHLTV && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist))
{ {
var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var skillPlayer = PlayerManager.GetPlayerByIndex(player!.Index);
if (skillPlayer == null) continue; if (skillPlayer == null) continue;
skillPlayer.IsDrawing = !isWarmup; skillPlayer.IsDrawing = !isWarmup;
skillPlayer.PrintHTML = null; skillPlayer.PrintHTML = null;
@ -659,7 +677,7 @@ namespace src.player
setSkillTimer?.Kill(); setSkillTimer?.Kill();
float timeToDraw = (Instance?.GameRules?.TeamIntroPeriod == true ? 7 : 0) + Math.Max(freezetime - Config.LoadedConfig.SkillTimeBeforeStart, 0) + .3f; float timeToDraw = (Instance?.GameRules?.TeamIntroPeriod == true ? 7 : 0) + Math.Max(freezetime - Config.LoadedConfig.SkillTimeBeforeStart, 0) + .3f;
setSkillTimer = Instance?.AddTimer(timeToDraw, SetSkill); setSkillTimer = Instance?.AddTimer(timeToDraw, SetSkill, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
return HookResult.Continue; return HookResult.Continue;
} }
} }
@ -668,9 +686,14 @@ namespace src.player
{ {
lock (setLock) lock (setLock)
{ {
foreach (var player in Utilities.GetPlayers().Where(p => p != null && !p.IsBot && p.IsValid)) Fortnite.skillInThisRound = false;
EntityManager.DestroyAllTracked();
foreach (var player in Utilities.GetPlayers().Where(p => p != null && p.IsValid))
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (player == null || !player.IsValid) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) continue; if (playerInfo == null) continue;
Instance.SkillAction(playerInfo.Skill.ToString(), "DisableSkill", [player]); Instance.SkillAction(playerInfo.Skill.ToString(), "DisableSkill", [player]);
@ -681,10 +704,28 @@ namespace src.player
playerInfo.PrintHTML = null; playerInfo.PrintHTML = null;
playerInfo.SkillChance = 1; playerInfo.SkillChance = 1;
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
RestorePlayer(player);
} }
} }
} }
public static void RestorePlayer(CCSPlayerController? player)
{
if (player == null || !player.IsValid) return;
var pawn = player.PlayerPawn?.Value;
if (pawn == null || !pawn.IsValid) return;
pawn.HideHUD = (uint)(pawn.HideHUD & ~(1 << 8));
Utilities.SetStateChanged(pawn, "CBasePlayerPawn", "m_iHideHUD");
player.ReplicateConVar("sv_disable_radar", "0");
player.DesiredFOV = 0;
Utilities.SetStateChanged(player, "CBasePlayerController", "m_iDesiredFOV");
}
public static void OnMapChange() public static void OnMapChange()
{ {
lock (setLock) lock (setLock)
@ -693,19 +734,21 @@ namespace src.player
Instance.AddTimer(.1f, () => { Instance.AddTimer(.1f, () => {
DisableAll(); DisableAll();
ConVar.Find("sv_legacy_jump")?.SetValue("1"); ConVar.Find("sv_legacy_jump")?.SetValue("1");
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
Instance.RemoveListener<CheckTransmit>(CheckTransmit); Instance.RemoveListener<CheckTransmit>(CheckTransmit);
playersSkills.Clear(); playersSkills.Clear();
staticSkills.Clear(); staticSkills.Clear();
ctSkill = noneSkill; ctSkill = noneSkill;
tSkill = noneSkill; tSkill = noneSkill;
allSkill = noneSkill; allSkill = noneSkill;
PlayerManager.Clear();
} }
} }
private static HookResult RoundEnd(EventRoundEnd @event, GameEventInfo info) private static HookResult RoundEnd(EventRoundEnd @event, GameEventInfo info)
{ {
Illiterate.Disable(); Illiterate.Disable();
lock (setLock) lock (setLock)
{ {
foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid)) foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid))
@ -717,7 +760,7 @@ namespace src.player
string skillsText = ""; string skillsText = "";
foreach (var _player in _players) foreach (var _player in _players)
{ {
var _playerSkill = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == _player.SteamID); var _playerSkill = PlayerManager.GetPlayerByIndex(_player.Index);
if (_playerSkill != null) if (_playerSkill != null)
{ {
var skillInfo = SkillData.Skills.FirstOrDefault(p => p.Skill == _playerSkill.Skill); var skillInfo = SkillData.Skills.FirstOrDefault(p => p.Skill == _playerSkill.Skill);
@ -735,13 +778,13 @@ namespace src.player
SkillUtils.PrintToChat(player, text, title: player.GetTranslation("teammate_skills"), border: ""); SkillUtils.PrintToChat(player, text, title: player.GetTranslation("teammate_skills"), border: "");
SkillUtils.PrintToChat(player, string.Empty, border: "b"); SkillUtils.PrintToChat(player, string.Empty, border: "b");
} }
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
} }
if (Config.LoadedConfig.DisableSkillsOnRoundEnd) if (Config.LoadedConfig.DisableSkillsOnRoundEnd)
{ {
isTransmitRegistered = false; isTransmitRegistered = false;
Instance.AddTimer(1f, () => DisableAll()); Instance.AddTimer(1f, () => DisableAll(), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
Instance.RemoveListener<CheckTransmit>(CheckTransmit); Instance.RemoveListener<CheckTransmit>(CheckTransmit);
} }
return HookResult.Continue; return HookResult.Continue;
@ -760,18 +803,18 @@ namespace src.player
foreach (string skillName in activeSkills) foreach (string skillName in activeSkills)
Instance.SkillAction(skillName, "PlayerDeath", [@event]); Instance.SkillAction(skillName, "PlayerDeath", [@event]);
var victim = @event.Userid; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
if (victim == null || attacker == null) return HookResult.Continue; if (victim == null || attacker == null) return HookResult.Continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == victim.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(victim.Index);
if (playerInfo == null || playerInfo.IsDrawing) return HookResult.Continue; if (playerInfo == null || playerInfo.IsDrawing) return HookResult.Continue;
Instance.SkillAction(playerInfo.Skill.ToString(), "DisableSkill", [victim]); Instance.SkillAction(playerInfo.Skill.ToString(), "DisableSkill", [victim]);
if (victim == attacker) return HookResult.Continue; if (victim == attacker) return HookResult.Continue;
if (Config.LoadedConfig.KillerSkillChatInfo) if (Config.LoadedConfig.KillerSkillChatInfo)
{ {
var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); var attackerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
if (attackerInfo != null) if (attackerInfo != null)
{ {
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == attackerInfo.Skill); var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == attackerInfo.Skill);
@ -790,7 +833,7 @@ namespace src.player
private static void CheckUseSkill(CCSPlayerController player, PlayerButtons pressed, PlayerButtons released) private static void CheckUseSkill(CCSPlayerController player, PlayerButtons pressed, PlayerButtons released)
{ {
if (player == null || !player.IsValid || !player.PawnIsAlive) return; if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
lock (setLock) lock (setLock)
{ {
@ -802,7 +845,7 @@ namespace src.player
if ((pressed & skillButton) == 0) return; if ((pressed & skillButton) == 0) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.IsDrawing) return; if (playerInfo == null || playerInfo.IsDrawing) return;
if (SkillsInfo.GetValue<bool>(playerInfo.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime()) if (SkillsInfo.GetValue<bool>(playerInfo.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
@ -872,14 +915,16 @@ namespace src.player
setSkillTimer = null; setSkillTimer = null;
lock (setLock) lock (setLock)
{ {
if (Instance?.GameRules != null && Instance.GameRules.WarmupPeriod == true) if (Instance == null) return;
if (Instance.GameRules != null && Instance.GameRules.WarmupPeriod == true)
{ {
setSkillTimer?.Kill(); setSkillTimer?.Kill();
return; return;
} }
var validPlayers = Utilities.GetPlayers() var validPlayers = Utilities.GetPlayers()
.Where(p => p != null && p.IsValid && !p.IsBot && !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; }
@ -918,7 +963,7 @@ namespace src.player
var teammates = validPlayers.Where(p => p != null && p.IsValid && p.Team == player.Team && p != player).ToList(); var teammates = validPlayers.Where(p => p != null && p.IsValid && p.Team == player.Team && p != player).ToList();
string teammateSkills = ""; string teammateSkills = "";
var skillPlayer = Instance?.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var skillPlayer = PlayerManager.GetPlayerByIndex(player!.Index);
if (skillPlayer == null) continue; if (skillPlayer == null) continue;
skillPlayer.IsDrawing = false; skillPlayer.IsDrawing = false;
@ -935,6 +980,7 @@ namespace src.player
{ {
List<jSkill_SkillInfo> skillList = [.. SkillData.Skills]; List<jSkill_SkillInfo> skillList = [.. SkillData.Skills];
skillList.RemoveAll(s => s?.Skill == Skills.None); skillList.RemoveAll(s => s?.Skill == Skills.None);
if (!player.IsBot)
skillList.RemoveAll(s => !string.IsNullOrEmpty(SkillsInfo.GetValue<string>(s.Skill, "requiredPermission")) && !AdminManager.PlayerHasPermissions(player, SkillsInfo.GetValue<string>(s.Skill, "requiredPermission"))); skillList.RemoveAll(s => !string.IsNullOrEmpty(SkillsInfo.GetValue<string>(s.Skill, "requiredPermission")) && !AdminManager.PlayerHasPermissions(player, SkillsInfo.GetValue<string>(s.Skill, "requiredPermission")));
if (gameMode != Config.GameModes.FullRandom) if (gameMode != Config.GameModes.FullRandom)
@ -951,7 +997,7 @@ namespace src.player
else else
skillList.RemoveAll(s => terroristSkills.Any(s2 => s2.Name == s.Skill.ToString())); skillList.RemoveAll(s => terroristSkills.Any(s2 => s2.Name == s.Skill.ToString()));
if (gameMode == Config.GameModes.NoRepeat && playersSkills.TryGetValue(player.SteamID, out ConcurrentBag<jSkill_SkillInfo>? skills)) if (gameMode == Config.GameModes.NoRepeat && playersSkills.TryGetValue(player.Index, out ConcurrentBag<jSkill_SkillInfo>? skills))
{ {
skillList.RemoveAll(s => skills.Any(s2 => s2.Skill == s.Skill)); skillList.RemoveAll(s => skills.Any(s2 => s2.Skill == s.Skill));
if (skillList.Count == 0) skills.Clear(); if (skillList.Count == 0) skills.Clear();
@ -961,10 +1007,10 @@ namespace src.player
if (gameMode == Config.GameModes.NoRepeat) if (gameMode == Config.GameModes.NoRepeat)
{ {
if (playersSkills.TryGetValue(player.SteamID, out ConcurrentBag<jSkill_SkillInfo>? value)) if (playersSkills.TryGetValue(player.Index, out ConcurrentBag<jSkill_SkillInfo>? value))
value.Add(randomSkill); value.Add(randomSkill);
else else
playersSkills.TryAdd(player.SteamID, [randomSkill]); playersSkills.TryAdd(player.Index, [randomSkill]);
} }
} }
else if (gameMode == Config.GameModes.TeamSkills) else if (gameMode == Config.GameModes.TeamSkills)
@ -984,7 +1030,7 @@ namespace src.player
skillPlayer.Skill = randomSkill.Skill; skillPlayer.Skill = randomSkill.Skill;
skillPlayer.SpecialSkill = Skills.None; skillPlayer.SpecialSkill = Skills.None;
if (randomSkill != null && randomSkill.Skill != Skills.None) if (randomSkill.Skill != Skills.None)
{ {
if (assignmentCounts.TryGetValue(randomSkill.Skill, out var cnt)) assignmentCounts[randomSkill.Skill] = cnt + 1; if (assignmentCounts.TryGetValue(randomSkill.Skill, out var cnt)) assignmentCounts[randomSkill.Skill] = cnt + 1;
else assignmentCounts[randomSkill.Skill] = 1; else assignmentCounts[randomSkill.Skill] = 1;
@ -999,17 +1045,19 @@ namespace src.player
if (randomSkill.Display) if (randomSkill.Display)
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(randomSkill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(randomSkill.Skill)}", SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(randomSkill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(randomSkill.Skill)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t"); border: !Utilities.GetPlayers().Any(p => p != null && p.IsValid && p.Team == player.Team && p != player) ? "tb" : "t");
if (SkillsInfo.GetValue<bool>(randomSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime()) if (SkillsInfo.GetValue<bool>(randomSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
Instance?.AddTimer(Config.LoadedConfig.SkillTimeBeforeStart, () => Instance?.AddTimer(Config.LoadedConfig.SkillTimeBeforeStart, () =>
{ {
if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID && p.Skill == randomSkill.Skill) == null) return; if (PlayerManager.GetPlayerByIndex(player!.Index)?.Skill != randomSkill.Skill) return;
Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]); Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]);
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
else else
{
Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]); Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]);
}); }
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
Debug.WriteToDebug($"Player {skillPlayer.PlayerName} has got the skill \"{player.GetSkillName(randomSkill.Skill)}\"."); Debug.WriteToDebug($"Player {skillPlayer.PlayerName} has got the skill \"{player.GetSkillName(randomSkill.Skill)}\".");
@ -1027,7 +1075,7 @@ namespace src.player
foreach (var teammate in teammates) foreach (var teammate in teammates)
{ {
var teammateInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == teammate.SteamID); var teammateInfo = PlayerManager.GetPlayerByIndex(teammate.Index);
if (teammateInfo != null && teammateInfo?.Skill != null) if (teammateInfo != null && teammateInfo?.Skill != null)
{ {
var skillInfo = SkillData.Skills.FirstOrDefault(p => p.Skill == teammateInfo.Skill); var skillInfo = SkillData.Skills.FirstOrDefault(p => p.Skill == teammateInfo.Skill);
@ -1043,7 +1091,7 @@ namespace src.player
SkillUtils.PrintToChat(player, text, title: player.GetTranslation("teammate_skills"), border: ""); SkillUtils.PrintToChat(player, text, title: player.GetTranslation("teammate_skills"), border: "");
SkillUtils.PrintToChat(player, string.Empty, title: player.GetTranslation("teammate_skills"), border: "b"); SkillUtils.PrintToChat(player, string.Empty, title: player.GetTranslation("teammate_skills"), border: "b");
} }
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
} }
} }
} }
@ -1053,7 +1101,7 @@ namespace src.player
{ {
lock (setLock) lock (setLock)
{ {
var validPlayers = Utilities.GetPlayers().Where(p => p.IsValid && !p.IsBot && !p.IsHLTV && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist).ToList(); var validPlayers = Utilities.GetPlayers().Where(p => p != null && p.IsValid && !p.IsHLTV && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist).ToList();
if (Config.LoadedConfig.GameMode == (int)Config.GameModes.TeamSkills) if (Config.LoadedConfig.GameMode == (int)Config.GameModes.TeamSkills)
{ {
@ -1067,7 +1115,7 @@ namespace src.player
} }
if (player == null) return; if (player == null) return;
var skillPlayer = Instance?.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var skillPlayer = PlayerManager.GetPlayerByIndex(player!.Index);
if (skillPlayer == null) return; if (skillPlayer == null) return;
skillPlayer.IsDrawing = false; skillPlayer.IsDrawing = false;
@ -1081,12 +1129,13 @@ namespace src.player
if (Instance?.GameRules != null && Instance?.GameRules.WarmupPeriod == false) if (Instance?.GameRules != null && Instance?.GameRules.WarmupPeriod == false)
{ {
Config.GameModes gameMode = (Config.GameModes)Config.LoadedConfig.GameMode; Config.GameModes gameMode = (Config.GameModes)Config.LoadedConfig.GameMode;
if (staticSkills.TryGetValue(player.SteamID, out var staticSkill)) if (staticSkills.TryGetValue(player.Index, out var staticSkill))
randomSkill = staticSkill; randomSkill = staticSkill;
else if (gameMode == Config.GameModes.Normal || gameMode == Config.GameModes.FullRandom || gameMode == Config.GameModes.NoRepeat) else if (gameMode == Config.GameModes.Normal || gameMode == Config.GameModes.FullRandom || gameMode == Config.GameModes.NoRepeat)
{ {
List<jSkill_SkillInfo> skillList = [.. SkillData.Skills]; List<jSkill_SkillInfo> skillList = [.. SkillData.Skills];
skillList.RemoveAll(s => s?.Skill == Skills.None); skillList.RemoveAll(s => s?.Skill == Skills.None);
if (!player.IsBot)
skillList.RemoveAll(s => !string.IsNullOrEmpty(SkillsInfo.GetValue<string>(s.Skill, "requiredPermission")) && !AdminManager.PlayerHasPermissions(player, SkillsInfo.GetValue<string>(s.Skill, "requiredPermission"))); skillList.RemoveAll(s => !string.IsNullOrEmpty(SkillsInfo.GetValue<string>(s.Skill, "requiredPermission")) && !AdminManager.PlayerHasPermissions(player, SkillsInfo.GetValue<string>(s.Skill, "requiredPermission")));
if (gameMode != Config.GameModes.FullRandom) if (gameMode != Config.GameModes.FullRandom)
@ -1103,7 +1152,7 @@ namespace src.player
else else
skillList.RemoveAll(s => terroristSkills.Any(s2 => s2.Name == s.Skill.ToString())); skillList.RemoveAll(s => terroristSkills.Any(s2 => s2.Name == s.Skill.ToString()));
if (gameMode == Config.GameModes.NoRepeat && playersSkills.TryGetValue(player.SteamID, out ConcurrentBag<jSkill_SkillInfo>? skills)) if (gameMode == Config.GameModes.NoRepeat && playersSkills.TryGetValue(player.Index, out ConcurrentBag<jSkill_SkillInfo>? skills))
{ {
skillList.RemoveAll(s => skills.Any(s2 => s2.Skill == s.Skill)); skillList.RemoveAll(s => skills.Any(s2 => s2.Skill == s.Skill));
if (skillList.Count == 0) skills.Clear(); if (skillList.Count == 0) skills.Clear();
@ -1133,13 +1182,13 @@ namespace src.player
} }
} }
if (randomSkill.Display && Config.LoadedConfig.YourSkillChatInfo)
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(randomSkill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(randomSkill.Skill)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
skillPlayer.Skill = randomSkill.Skill; skillPlayer.Skill = randomSkill.Skill;
skillPlayer.SpecialSkill = Skills.None; skillPlayer.SpecialSkill = Skills.None;
if (randomSkill.Display && Config.LoadedConfig.YourSkillChatInfo)
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(randomSkill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(randomSkill.Skill)}",
border: !Utilities.GetPlayers().Any(p => p != null && p.IsValid && p.Team == player.Team && p != player) ? "tb" : "t");
if (randomSkill.Skill == Skills.Illiterate) if (randomSkill.Skill == Skills.Illiterate)
Illiterate.Enable(); Illiterate.Enable();
@ -1148,12 +1197,12 @@ namespace src.player
if (SkillsInfo.GetValue<bool>(randomSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime()) if (SkillsInfo.GetValue<bool>(randomSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
Instance?.AddTimer(Config.LoadedConfig.SkillTimeBeforeStart, () => Instance?.AddTimer(Config.LoadedConfig.SkillTimeBeforeStart, () =>
{ {
if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID && p.Skill == randomSkill.Skill) == null) return; if (PlayerManager.GetPlayerByIndex(player!.Index)?.Skill != randomSkill.Skill) return;
Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]); Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]);
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
else else
Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]); Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]);
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
Debug.WriteToDebug($"Player {skillPlayer.PlayerName} has got the skill \"{player.GetSkillName(randomSkill.Skill)}\"."); Debug.WriteToDebug($"Player {skillPlayer.PlayerName} has got the skill \"{player.GetSkillName(randomSkill.Skill)}\".");
skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration); skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration);

View file

@ -3,7 +3,6 @@ using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Admin;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using System.Linq;
using static CounterStrikeSharp.API.Core.Listeners; using static CounterStrikeSharp.API.Core.Listeners;
using static src.jRandomSkills; using static src.jRandomSkills;
@ -16,49 +15,62 @@ namespace src.player
Instance.RegisterListener<OnTick>(() => Instance.RegisterListener<OnTick>(() =>
{ {
UpdateGameRules(); UpdateGameRules();
var players = Utilities.GetPlayers().ToArray();
foreach (var player in players) foreach (var player in Utilities.GetPlayers())
{
if (player != null && player.IsValid) if (player != null && player.IsValid)
UpdatePlayerHud(player); UpdatePlayerHud(player);
}
}); });
Instance.RegisterListener<OnMapStart>(OnMapStart); Instance.RegisterListener<OnMapStart>(OnMapStart);
Instance.RegisterListener<OnMapEnd>(OnMapEnd);
} }
private static void OnMapStart(string mapName) private static void OnMapStart(string mapName)
{ {
Instance.GameRules = null; Instance.GameRules = null;
Event.OnMapChange(); Event.OnMapChange();
BotManager.Initialize();
}
private static void OnMapEnd()
{
BotManager.Stop();
} }
private static void InitializeGameRules() private static void InitializeGameRules()
{ {
if (Instance.GameRules != null) return; if (Instance.GameRules != null) return;
var gameRulesProxy = Utilities.FindAllEntitiesByDesignerName<CCSGameRulesProxy>("cs_gamerules").FirstOrDefault(); var gameRulesProxy = Utilities.FindAllEntitiesByDesignerName<CCSGameRulesProxy>("cs_gamerules").FirstOrDefault();
if (gameRulesProxy != null) if (gameRulesProxy != null)
Instance.GameRules = gameRulesProxy?.GameRules; Instance.GameRules = gameRulesProxy.GameRules;
} }
private static void UpdateGameRules() private static void UpdateGameRules()
{ {
if (Instance?.GameRules == null || Instance?.GameRules?.Handle == IntPtr.Zero) if (Instance?.GameRules == null || Instance.GameRules.Handle == IntPtr.Zero)
InitializeGameRules(); InitializeGameRules();
else if (Instance != null && Config.LoadedConfig.FlashingHtmlHudFix && !Instance.GameRules.WarmupPeriod) else if (Instance != null && Config.LoadedConfig.EnableFlashingHtmlHudFix && !Instance.GameRules.WarmupPeriod)
Instance.GameRules.GameRestart = Instance.GameRules?.RestartRoundTime < Server.CurrentTime; Instance.GameRules.GameRestart = Instance.GameRules.RestartRoundTime < Server.CurrentTime;
} }
private static void UpdatePlayerHud(CCSPlayerController player) private static void UpdatePlayerHud(CCSPlayerController player)
{ {
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid || player.IsBot) return;
var skillPlayer = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
if (skillPlayer == null || !skillPlayer.DisplayHUD) return;
var now = DateTime.Now; var now = DateTime.Now;
var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (skillPlayer == null || !skillPlayer.DisplayHUD) return;
if (player.PawnIsAlive && skillPlayer.SkillHudExpired < now) return; if (player.PawnIsAlive && skillPlayer.SkillHudExpired < now) return;
string infoLine = string.Empty; string infoLine = string.Empty;
string skillLine = string.Empty; string skillLine = string.Empty;
string remainingLine = string.Empty; string remainingLine = string.Empty;
bool showDescriptionHUD = skillPlayer.SkillDescriptionHudExpired >= now; bool showDescriptionHUD = skillPlayer.SkillDescriptionHudExpired >= now;
bool isDescription = true; bool isDescription = true;
@ -72,10 +84,12 @@ namespace src.player
else if (skillPlayer.IsDrawing && player.PawnIsAlive) else if (skillPlayer.IsDrawing && player.PawnIsAlive)
{ {
int skillCount = skills.Count; int skillCount = skills.Count;
if (skillCount > 0) if (skillCount > 0)
{ {
var skillsArray = skills.ToArray(); var skillsArray = skills.ToArray();
var randomSkill = skillsArray[Instance.Random.Next(skillCount)]; var randomSkill = skillsArray[Instance.Random.Next(skillCount)];
infoLine = player.GetTranslation("drawing_skill"); infoLine = player.GetTranslation("drawing_skill");
skillLine = $"<font color='{randomSkill.Color}'>{player.GetSkillName(randomSkill.Skill)}</font>"; skillLine = $"<font color='{randomSkill.Color}'>{player.GetSkillName(randomSkill.Skill)}</font>";
} }
@ -85,61 +99,70 @@ namespace src.player
if (player.PawnIsAlive) if (player.PawnIsAlive)
{ {
var skillInfo = skills.FirstOrDefault(s => s.Skill == skillPlayer.Skill); var skillInfo = skills.FirstOrDefault(s => s.Skill == skillPlayer.Skill);
if (skillInfo != null) if (skillInfo != null)
{ {
infoLine = player.GetTranslation("your_skill"); infoLine = player.GetTranslation("your_skill");
skillLine = $"<font color='{skillInfo.Color}'>{player.GetSkillName(skillInfo.Skill, skillPlayer.SkillChance)}</font>"; skillLine = $"<font color='{skillInfo.Color}'>{player.GetSkillName(skillInfo.Skill, skillPlayer.SkillChance)}</font>";
if (skillInfo.Skill != Skills.None) if (skillInfo.Skill != Skills.None)
{ {
remainingLine = string.IsNullOrEmpty(skillPlayer.PrintHTML) remainingLine = string.IsNullOrEmpty(skillPlayer.PrintHTML)
? (showDescriptionHUD ? player.GetSkillDescription(skillInfo.Skill, skillPlayer.SkillChance) : "") ? (showDescriptionHUD ? player.GetSkillDescription(skillInfo.Skill, skillPlayer.SkillChance) : "")
: skillPlayer.PrintHTML; : skillPlayer.PrintHTML;
isDescription = string.IsNullOrEmpty(skillPlayer.PrintHTML); isDescription = string.IsNullOrEmpty(skillPlayer.PrintHTML);
} }
} }
} }
else else
{ {
if ((player.Team is CsTeam.Spectator or CsTeam.None && Config.LoadedConfig.DisableSpectateHUD) || AdminManager.PlayerHasPermissions(player, Config.LoadedConfig.DisableHUDOnDeathPermission)) if ((player.Team is CsTeam.Spectator or CsTeam.None && Config.LoadedConfig.DisableSpectateHUD)
|| AdminManager.PlayerHasPermissions(player, Config.LoadedConfig.DisableHUDOnDeathPermission))
return; return;
var pawn = player.Pawn.Value; var pawn = player.Pawn.Value;
if (pawn == null || pawn.ObserverServices == null) return; if (pawn?.ObserverServices == null) return;
var observerTarget = pawn.ObserverServices.ObserverTarget?.Value; var observerTarget = pawn.ObserverServices.ObserverTarget?.Value;
if (observerTarget == null || !observerTarget.IsValid) return; if (observerTarget == null || !observerTarget.IsValid) return;
var players = Utilities.GetPlayers(); var observedPlayer = Utilities.GetPlayers().FirstOrDefault(p =>
var targetHandle = observerTarget.Handle; p != null && p.IsValid && p.Pawn?.Value?.Handle == observerTarget.Handle);
var observedPlayer = players.FirstOrDefault(p => p?.IsValid == true && p?.Pawn?.Value?.Handle == targetHandle);
if (observedPlayer == null) return; if (observedPlayer == null) return;
var observeredPlayerSkill = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == observedPlayer.SteamID); var observedEvent = PlayerManager.GetPlayerEvent(observedPlayer);
if (observeredPlayerSkill == null) return; if (observedEvent == null || !observedEvent.IsValid) return;
var observeredPlayerSkillInfo = skills.FirstOrDefault(s => s.Skill == observeredPlayerSkill.Skill); var observedSkill = PlayerManager.GetPlayerByIndex(observedEvent.Index);
var observeredPlayerSpecialSkillInfo = observeredPlayerSkill.SpecialSkill != Skills.None ? skills.FirstOrDefault(s => s.Skill == observeredPlayerSkill.SpecialSkill) : null; if (observedSkill == null) return;
string primaryName = player.GetSkillName(observeredPlayerSkill.Skill, observeredPlayerSkill.SkillChance); var observedSkillInfo = skills.FirstOrDefault(s => s.Skill == observedSkill.Skill);
string primaryColor = observeredPlayerSkillInfo?.Color ?? SkillsInfo.GetValue<string>(Skills.None, "color"); var observedSpecialInfo = observedSkill.SpecialSkill != Skills.None
? skills.FirstOrDefault(s => s.Skill == observedSkill.SpecialSkill)
: null;
string primaryName = player.GetSkillName(observedSkill.Skill, observedSkill.SkillChance);
string primaryColor = observedSkillInfo?.Color ?? SkillsInfo.GetValue<string>(Skills.None, "color");
string pName = System.Net.WebUtility.HtmlEncode(observedSkill.PlayerName);
string pName = System.Net.WebUtility.HtmlEncode(observeredPlayerSkill.PlayerName);
if (pName.Length > 18) if (pName.Length > 18)
pName = $"{pName[..17]}..."; pName = $"{pName[..17]}...";
var observerSkill = player.GetTranslation("observer_skill"); var observerSkill = player.GetTranslation("observer_skill");
infoLine = string.IsNullOrEmpty(observerSkill) ? pName : $"{observerSkill} {pName}"; infoLine = string.IsNullOrEmpty(observerSkill) ? pName : $"{observerSkill} {pName}";
if (observeredPlayerSkill.SpecialSkill == Skills.None || observeredPlayerSpecialSkillInfo == null) if (observedSkill.SpecialSkill == Skills.None || observedSpecialInfo == null)
skillLine = $"<font color='{primaryColor}'>{primaryName}</font>"; skillLine = $"<font color='{primaryColor}'>{primaryName}</font>";
else else
{ {
string specialName = player.GetSkillName(observeredPlayerSpecialSkillInfo.Skill); string specialName = player.GetSkillName(observedSpecialInfo.Skill);
skillLine = $"<font color='{observeredPlayerSpecialSkillInfo.Color}'>{specialName}({primaryName})</font>"; skillLine = $"<font color='{observedSpecialInfo.Color}'>{specialName}({primaryName})</font>";
} }
if (showDescriptionHUD) if (showDescriptionHUD)
remainingLine = player.GetSkillDescription(observeredPlayerSkill.Skill, observeredPlayerSkill.SkillChance); remainingLine = player.GetSkillDescription(observedSkill.Skill, observedSkill.SkillChance);
} }
} }

View file

@ -1,7 +1,6 @@
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 System.Collections.Concurrent; using System.Collections.Concurrent;
using src.utils; using src.utils;
@ -10,7 +9,7 @@ namespace src.player.skills
public class AimLock : ISkill public class AimLock : ISkill
{ {
private const Skills skillName = Skills.AimLock; private const Skills skillName = Skills.AimLock;
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = []; private static readonly ConcurrentDictionary<uint, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
public static void LoadSkill() public static void LoadSkill()
@ -28,23 +27,28 @@ namespace src.player.skills
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (player == null || !player.IsValid) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) {
if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
{ {
UpdateHUD(player, skillInfo); UpdateHUD(player, skillInfo);
if (skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue<float>(skillName, "duration")) > DateTime.Now) if (skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue<float>(skillName, "duration")) > DateTime.Now)
LookAtEnemey(player); LookAtEnemy(player);
}
} }
} }
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo if (player == null || !player.IsValid) return;
SkillPlayerInfo.TryAdd(player.Index, new PlayerSkillInfo
{ {
SteamID = player.SteamID, PlayerIndex = player.Index,
CanUse = true, CanUse = true,
Cooldown = DateTime.MinValue, Cooldown = DateTime.MinValue,
}); });
@ -52,23 +56,22 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryRemove(player.SteamID, out _); if (player == null || !player.IsValid) return;
SkillPlayerInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player); SkillUtils.ResetPrintHTML(player);
} }
private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo)
{ {
float cooldown = 0; if (player == null || !player.IsValid || skillInfo == null) return;
if (skillInfo != null)
{
float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue<float>(skillName, "cooldown")) - DateTime.Now).TotalSeconds); float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue<float>(skillName, "cooldown")) - DateTime.Now).TotalSeconds);
cooldown = Math.Max(time, 0); float cooldown = Math.Max(time, 0);
if (cooldown == 0 && skillInfo?.CanUse == false) if (cooldown == 0 && !skillInfo.CanUse)
skillInfo.CanUse = true; skillInfo.CanUse = true;
}
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
if (cooldown == 0) if (cooldown == 0)
@ -79,48 +82,38 @@ namespace src.player.skills
public static void UseSkill(CCSPlayerController player) public static void UseSkill(CCSPlayerController player)
{ {
var playerPawn = player.PlayerPawn.Value; if (player == null || !player.IsValid) return;
if (playerPawn?.CBodyComponent == null) return;
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
{ {
if (!player.IsValid || !player.PawnIsAlive) return; if (!skillInfo.CanUse) return;
if (skillInfo.CanUse)
{
skillInfo.CanUse = false;
skillInfo.Cooldown = DateTime.Now; skillInfo.Cooldown = DateTime.Now;
LookAtEnemey(player); skillInfo.CanUse = false;
}
} }
} }
private static void LookAtEnemey(CCSPlayerController player) private static void LookAtEnemy(CCSPlayerController player)
{ {
if (player == null || !player.IsValid) return;
var pawn = player.PlayerPawn.Value; var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return; if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
CCSPlayerController? closetEnemy = null; var myEyePos = new Vector(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z);
double minDist = double.MaxValue;
var enemy = Utilities.GetPlayers()
.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())
.FirstOrDefault();
if (enemy == null) return;
foreach (var enemy in Utilities.GetPlayers().Where(p => p.IsValid && p.PawnIsAlive && p.Team != player.Team))
{
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 || enemyPawn.ViewOffset == null) return;
double dist = SkillUtils.GetDistance(enemyPawn.AbsOrigin, pawn.AbsOrigin);
if (dist < minDist)
{
minDist = dist;
closetEnemy = enemy;
}
}
if (closetEnemy != null)
{
var enemyPawn = closetEnemy.PlayerPawn.Value;
if (enemyPawn == null || enemyPawn.AbsOrigin == null) return;
Vector myEyePos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z);
Vector diff = SkillUtils.GetForwardVector(enemyPawn.AbsRotation!) * 5; Vector diff = SkillUtils.GetForwardVector(enemyPawn.AbsRotation!) * 5;
Vector enemyHead = new( Vector enemyHead = new(
@ -134,7 +127,6 @@ namespace src.player.skills
pawn.Look(angle); pawn.Look(angle);
} }
}
private static QAngle VectorToAngle(Vector direction) private static QAngle VectorToAngle(Vector direction)
{ {
@ -146,7 +138,7 @@ namespace src.player.skills
public class PlayerSkillInfo public class PlayerSkillInfo
{ {
public ulong SteamID { get; set; } public uint PlayerIndex { get; set; }
public bool CanUse { get; set; } public bool CanUse { get; set; }
public DateTime Cooldown { get; set; } public DateTime Cooldown { get; set; }
} }

View file

@ -2,9 +2,9 @@
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 static src.jRandomSkills;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using src.utils; using src.utils;
using CounterStrikeSharp.API;
namespace src.player.skills namespace src.player.skills
{ {
@ -23,61 +23,35 @@ namespace src.player.skills
CEntityInstance param = h.GetParam<CEntityInstance>(0); CEntityInstance param = h.GetParam<CEntityInstance>(0);
CTakeDamageInfo param2 = h.GetParam<CTakeDamageInfo>(1); CTakeDamageInfo param2 = h.GetParam<CTakeDamageInfo>(1);
if (param == null || !param.IsValid || param.Entity == null) if (param == null || !param.IsValid || param2 == null || param2.Handle == nint.Zero) return;
return; if (param2.Attacker == null || !param2.Attacker.IsValid || param2.Attacker.Value == null) return;
if (param2 == null || param2.Handle == nint.Zero || param2.Attacker == null || !param2.Attacker.IsValid) var attackerEnt = param2.Attacker.Value;
return; if (attackerEnt == null || !attackerEnt.IsValid) return;
var attackerHandle = param2.Attacker; var attackerPawn = attackerEnt.As<CCSPlayerPawn>();
if (attackerHandle.Value == null || !attackerHandle.IsValid) if (attackerPawn == null || !attackerPawn.IsValid) return;
return;
var attackerEnt = attackerHandle.Value; var attackerController = attackerPawn.Controller.Value;
var victimEnt = param; if (attackerController == null || !attackerController.IsValid) return;
if (attackerEnt == null || victimEnt == null || !victimEnt.IsValid || !attackerEnt.IsValid) var attacker = PlayerManager.GetPlayerEvent(attackerController.As<CCSPlayerController>())!;
return;
CCSPlayerPawn attackerPawn = new(attackerEnt.Handle); var playerInfo = PlayerManager.GetPlayerByIndex(attacker.Index);
CCSPlayerPawn victimPawn = new(victimEnt.Handle);
if (attackerPawn == null || !attackerPawn.IsValid || victimPawn == null || !victimPawn.IsValid)
return;
if (attackerPawn.DesignerName != "player" || victimPawn.DesignerName != "player")
return;
var attackerController = attackerPawn.Controller?.Value;
var victimController = victimPawn.Controller?.Value;
if (!attackerController.IsValid() || !victimController.IsValid())
return;
CCSPlayerController attacker = attackerController!.As<CCSPlayerController>();
CCSPlayerController victim = victimController!.As<CCSPlayerController>();
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID);
if (playerInfo == null) return; if (playerInfo == null) return;
if (!attacker.CheckPlayer())
return;
int offset = GameData.GetOffset("CTakeDamageInfo_HitGroup"); int offset = GameData.GetOffset("CTakeDamageInfo_HitGroup");
if (offset <= 0) if (offset <= 0) return;
return;
nint hitGroupPointer = Marshal.ReadIntPtr(param2.Handle, offset); nint hitGroupPointer = Marshal.ReadIntPtr(param2.Handle, offset);
if (hitGroupPointer == nint.Zero) if (hitGroupPointer == nint.Zero) return;
return;
nint hitGroupOffset = Marshal.ReadIntPtr(hitGroupPointer, 16); nint hitGroupOffset = Marshal.ReadIntPtr(hitGroupPointer, 16);
if (hitGroupOffset == nint.Zero) if (hitGroupOffset == nint.Zero) return;
return;
if (playerInfo.Skill == skillName) if (playerInfo.Skill == skillName)
{ {
hitGroups[hitGroupOffset] = Marshal.ReadInt32(hitGroupOffset, 56); hitGroups.TryAdd(hitGroupOffset, Marshal.ReadInt32(hitGroupOffset, 56));
Marshal.WriteInt32(hitGroupOffset, 56, (int)HitGroup_t.HITGROUP_HEAD); Marshal.WriteInt32(hitGroupOffset, 56, (int)HitGroup_t.HITGROUP_HEAD);
} }
else if (hitGroups.TryGetValue(hitGroupOffset, out var hitGroup)) else if (hitGroups.TryGetValue(hitGroupOffset, out var hitGroup))
@ -87,10 +61,13 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController _) public static void DisableSkill(CCSPlayerController _)
{ {
foreach (var hit in hitGroups) foreach (var hit in hitGroups)
{
if (hit.Key != nint.Zero)
Marshal.WriteInt32(hit.Key, 56, hit.Value); Marshal.WriteInt32(hit.Key, 56, hit.Value);
} }
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff0000", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Epic) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, 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 = "", int maxPerServer = -1, Rarity rarity = Rarity.Common) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{ {
} }
} }

View file

@ -3,7 +3,6 @@ using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills namespace src.player.skills
{ {
@ -11,7 +10,8 @@ namespace src.player.skills
{ {
private const Skills skillName = Skills.Anomaly; private const Skills skillName = Skills.Anomaly;
private static readonly float tickRate = 64; private static readonly float tickRate = 64;
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly ConcurrentDictionary<uint, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
public static void LoadSkill() public static void LoadSkill()
@ -29,18 +29,24 @@ namespace src.player.skills
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (player == null || !player.IsValid) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) {
if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
{ {
UpdateHUD(player, skillInfo); UpdateHUD(player, skillInfo);
if (Server.TickCount % tickRate != 0) return; if (Server.TickCount % tickRate != 0) continue;
var pawn = player.PlayerPawn.Value; var pawn = player.PlayerPawn.Value;
if (pawn != null && pawn.IsValid && pawn.AbsOrigin != null) if (pawn != null && pawn.IsValid && pawn.AbsOrigin != null)
{ {
if (skillInfo.LastRotations == null || skillInfo.LastPositions == null) continue; if (skillInfo.LastRotations == null || skillInfo.LastPositions == null) continue;
skillInfo.LastPositions.Enqueue(new Vector(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z)); skillInfo.LastPositions.Enqueue(new Vector(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z));
skillInfo.LastRotations.Enqueue(new QAngle(pawn.V_angle.X, pawn.V_angle.Y, 0)); skillInfo.LastRotations.Enqueue(new QAngle(pawn.V_angle.X, pawn.V_angle.Y, 0));
if (skillInfo.LastRotations.Count > SkillsInfo.GetValue<int>(skillName, "secondsInBack")) if (skillInfo.LastRotations.Count > SkillsInfo.GetValue<int>(skillName, "secondsInBack"))
{ {
skillInfo.LastPositions.TryDequeue(out _); skillInfo.LastPositions.TryDequeue(out _);
@ -50,38 +56,40 @@ namespace src.player.skills
} }
} }
} }
}
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo if (player == null || !player.IsValid) return;
SkillPlayerInfo.TryAdd(player.Index, new PlayerSkillInfo
{ {
SteamID = player.SteamID, PlayerIndex = player.Index,
CanUse = true, CanUse = true,
Cooldown = DateTime.MinValue, Cooldown = DateTime.MinValue,
LastPositions = [], LastPositions = new ConcurrentQueue<Vector>(),
LastRotations = [], LastRotations = new ConcurrentQueue<QAngle>()
}); });
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryRemove(player.SteamID, out _); if (player == null || !player.IsValid) return;
SkillPlayerInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player); SkillUtils.ResetPrintHTML(player);
} }
private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo)
{ {
if (player == null || !player.IsValid || skillInfo == null) return;
float cooldown = 0; float cooldown = 0;
if (skillInfo != null)
{
float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue<float>(skillName, "cooldown")) - DateTime.Now).TotalSeconds); float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue<float>(skillName, "cooldown")) - DateTime.Now).TotalSeconds);
cooldown = Math.Max(time, 0); cooldown = Math.Max(time, 0);
if (cooldown == 0 && skillInfo?.CanUse == false) if (cooldown == 0 && !skillInfo.CanUse)
skillInfo.CanUse = true; skillInfo.CanUse = true;
}
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
if (cooldown == 0) if (cooldown == 0)
@ -92,19 +100,27 @@ namespace src.player.skills
public static void UseSkill(CCSPlayerController player) public static void UseSkill(CCSPlayerController player)
{ {
var playerPawn = player.PlayerPawn.Value; if (player == null || !player.IsValid) return;
if (playerPawn?.CBodyComponent == null) return;
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
{ {
if (!player.IsValid || !player.PawnIsAlive) return; if (!skillInfo.CanUse) return;
if (skillInfo.CanUse)
{
skillInfo.CanUse = false;
skillInfo.Cooldown = DateTime.Now; skillInfo.Cooldown = DateTime.Now;
if (skillInfo.LastRotations == null || skillInfo.LastRotations.IsEmpty || skillInfo.LastPositions == null || skillInfo.LastPositions.IsEmpty) return; skillInfo.CanUse = false;
var playerPawn = player.PlayerPawn.Value;
if (playerPawn != null && playerPawn.IsValid)
{
if (skillInfo.LastPositions == null || skillInfo.LastPositions.IsEmpty) return;
if (skillInfo.LastRotations == null || skillInfo.LastRotations.IsEmpty) return;
Vector? lastPosition = skillInfo.LastPositions.FirstOrDefault(); Vector? lastPosition = skillInfo.LastPositions.FirstOrDefault();
QAngle? lastRotation = skillInfo.LastRotations.FirstOrDefault(); QAngle? lastRotation = skillInfo.LastRotations.FirstOrDefault();
if (lastPosition != null && lastRotation != null) if (lastPosition != null && lastRotation != null)
{ {
playerPawn.Teleport(lastPosition, null, null); playerPawn.Teleport(lastPosition, null, null);
@ -116,7 +132,7 @@ namespace src.player.skills
public class PlayerSkillInfo public class PlayerSkillInfo
{ {
public ulong SteamID { get; set; } public uint PlayerIndex { get; set; }
public bool CanUse { get; set; } public bool CanUse { get; set; }
public DateTime Cooldown { get; set; } public DateTime Cooldown { get; set; }
public ConcurrentQueue<Vector>? LastPositions { get; set; } public ConcurrentQueue<Vector>? LastPositions { get; set; }

View file

@ -2,7 +2,6 @@ using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using static src.jRandomSkills;
namespace src.player.skills namespace src.player.skills
{ {
@ -17,25 +16,31 @@ namespace src.player.skills
public static void PlayerBlind(EventPlayerBlind @event) public static void PlayerBlind(EventPlayerBlind @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return; if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
if (attacker == null || !attacker.IsValid) return;
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return; if (playerPawn == null || !playerPawn.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
{
playerPawn.FlashDuration = 0.0f; playerPawn.FlashDuration = 0.0f;
else if (attackerInfo?.Skill == skillName) }
else if (attacker != null && attacker.IsValid)
{
var attackerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
if (attackerInfo?.Skill == skillName)
playerPawn.FlashDuration = SkillsInfo.GetValue<float>(skillName, "flashDuration"); playerPawn.FlashDuration = SkillsInfo.GetValue<float>(skillName, "flashDuration");
} }
}
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
if (player == null || !player.IsValid) return;
SkillUtils.TryGiveWeapon(player, CsItem.FlashbangGrenade); SkillUtils.TryGiveWeapon(player, CsItem.FlashbangGrenade);
} }

View file

@ -1,7 +1,6 @@
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using static src.jRandomSkills;
namespace src.player.skills namespace src.player.skills
{ {
@ -16,12 +15,13 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = @event.Userid; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
int hitgroup = @event.Hitgroup; int hitgroup = @event.Hitgroup;
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return; if (victim == null || !victim.IsValid || attacker == null || !attacker.IsValid || attacker == victim) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == victim?.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(victim.Index);
if (playerInfo?.Skill == skillName && hitgroup == (int)HitGroup_t.HITGROUP_HEAD) if (playerInfo?.Skill == skillName && hitgroup == (int)HitGroup_t.HITGROUP_HEAD)
SkillUtils.RestoreHealth(victim); SkillUtils.RestoreHealth(victim);
} }

View file

@ -2,7 +2,7 @@
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using static src.jRandomSkills; using System.Collections.Concurrent;
namespace src.player.skills namespace src.player.skills
{ {
@ -11,6 +11,7 @@ namespace src.player.skills
private const Skills skillName = Skills.AreaReaper; private const Skills skillName = Skills.AreaReaper;
private static readonly string[] bombsiteA = ["A", "a"]; private static readonly string[] bombsiteA = ["A", "a"];
private static readonly string[] bombsiteB = ["B", "b"]; private static readonly string[] bombsiteB = ["B", "b"];
private static readonly ConcurrentDictionary<uint, uint> playersToTarget = [];
public static void LoadSkill() public static void LoadSkill()
{ {
@ -20,12 +21,19 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{
if (player != null && player.IsValid)
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
playersToTarget.Clear();
}
public static void TypeSkill(CCSPlayerController player, string[] commands) public static void TypeSkill(CCSPlayerController player, string[] commands)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (player == null || !player.IsValid || commands == null || commands.Length == 0) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed) if (playerInfo.SkillUsed)
@ -35,7 +43,8 @@ namespace src.player.skills
} }
int site = bombsiteA.Contains(commands[0]) ? 0 : bombsiteB.Contains(commands[0]) ? 1 : -1; int site = bombsiteA.Contains(commands[0]) ? 0 : bombsiteB.Contains(commands[0]) ? 1 : -1;
if (site == -1) { if (site == -1)
{
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("areareaper_incorrect_site")}"); player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("areareaper_incorrect_site")}");
return; return;
} }
@ -43,38 +52,45 @@ namespace src.player.skills
var bombTargets = Utilities.FindAllEntitiesByDesignerName<CBombTarget>("func_bomb_target").ToArray(); var bombTargets = Utilities.FindAllEntitiesByDesignerName<CBombTarget>("func_bomb_target").ToArray();
if (bombTargets.Length == 2) if (bombTargets.Length == 2)
{ {
bombTargets[site].BombPlantedHere = true; var targetSite = bombTargets[site];
Utilities.SetStateChanged(bombTargets[site], "CBombTarget", "m_bBombPlantedHere"); if (targetSite != null && targetSite.IsValid)
{
targetSite.BombPlantedHere = true;
Utilities.SetStateChanged(targetSite, "CBombTarget", "m_bBombPlantedHere");
playerInfo.SkillUsed = true; playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("areareaper_site_disabled", (site == 0 ? 'A' : 'B'))}");
playersToTarget[player.Index] = targetSite.Index;
}
} }
else
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("areareaper_no_site")}");
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (player == null || !player.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
SkillUtils.CreateMenu(player, [(player.GetTranslation("bombsite_a"), "a")], (player.GetTranslation("bombsite_b"), "b", true)); SkillUtils.CreateMenu(player, [(player.GetTranslation("bombsite_a"), "a")], (player.GetTranslation("bombsite_b"), "b", true));
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
SkillUtils.CloseMenu(player);
Server.NextWorldUpdate(() => Server.NextWorldUpdate(() =>
{ {
if (Instance.SkillPlayer.FirstOrDefault(p => p.Skill == skillName) != null) return; if (PlayerManager.GetPlayerCountBySkill(skillName) != 0) return;
EnableBombsite(); EnableBombsite();
}); });
SkillUtils.CloseMenu(player);
} }
private static void EnableBombsite() private static void EnableBombsite(uint? bombsiteIndex = null)
{ {
var bombTargets = Utilities.FindAllEntitiesByDesignerName<CBombTarget>("func_bomb_target"); var bombTargets = Utilities.FindAllEntitiesByDesignerName<CBombTarget>("func_bomb_target");
foreach (var bombTarget in bombTargets) foreach (var bombTarget in bombTargets)
if (bombTarget != null && bombTarget.IsValid)
{ {
bombTarget.BombPlantedHere = false; bombTarget.BombPlantedHere = false;
Utilities.SetStateChanged(bombTarget, "CBombTarget", "m_bBombPlantedHere"); Utilities.SetStateChanged(bombTarget, "CBombTarget", "m_bBombPlantedHere");
@ -83,18 +99,18 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
var bombTargets = Utilities.FindAllEntitiesByDesignerName<CBombTarget>("func_bomb_target"); if (Server.TickCount % 16 != 0) return;
foreach (var player in Utilities.GetPlayers().Where(p => p.Team == CsTeam.Terrorist))
{
if (!Instance.IsPlayerValid(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); foreach (var player in Utilities.GetPlayers())
{
if (player == null || !player.IsValid || player.Team != CsTeam.Terrorist) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == null) continue; if (playerInfo?.Skill == null) continue;
var pawn = player.PlayerPawn.Value; var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) continue; if (pawn == null || !pawn.IsValid || pawn.WeaponServices == null) continue;
if (pawn.WeaponServices == null) continue;
var activeWeapon = pawn.WeaponServices.ActiveWeapon.Value; var activeWeapon = pawn.WeaponServices.ActiveWeapon.Value;
if (activeWeapon == null || !activeWeapon.IsValid || activeWeapon.DesignerName != "weapon_c4") continue; if (activeWeapon == null || !activeWeapon.IsValid || activeWeapon.DesignerName != "weapon_c4") 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.Memory.DynamicFunctions; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
@ -18,14 +18,17 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (player == null || !player.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
float newScale = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom"); float newScale = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
playerInfo.SkillChance = newScale; playerInfo.SkillChance = newScale;
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.IsBot && p != player) ? "tb" : "t"); border: !Utilities.GetPlayers().Any(p => p.IsValid && p.Team == player.Team && p != player) ? "tb" : "t");
} }
public static void OnTakeDamage(DynamicHook h) public static void OnTakeDamage(DynamicHook h)
@ -33,22 +36,18 @@ namespace src.player.skills
CEntityInstance param = h.GetParam<CEntityInstance>(0); CEntityInstance param = h.GetParam<CEntityInstance>(0);
CTakeDamageInfo param2 = h.GetParam<CTakeDamageInfo>(1); CTakeDamageInfo param2 = h.GetParam<CTakeDamageInfo>(1);
if (param == null || param.Entity == null || param2 == null || param2.Attacker == null || param2.Attacker.Value == null) if (param == null || !param.IsValid || param2 == null) return;
return;
CCSPlayerPawn attackerPawn = new(param2.Attacker.Value.Handle); var victimPawn = param.As<CCSPlayerPawn>();
CCSPlayerPawn victimPawn = new(param.Handle); if (victimPawn == null || !victimPawn.IsValid || victimPawn.DesignerName != "player") return;
if (attackerPawn.DesignerName != "player" || victimPawn.DesignerName != "player") var victimController = victimPawn.Controller.Value;
return; if (victimController == null || !victimController.IsValid) return;
if (attackerPawn == null || attackerPawn.Controller?.Value == null || victimPawn == null || victimPawn.Controller?.Value == null) var victim = victimController.As<CCSPlayerController>();
return; if (victim == null || !victim.IsValid) return;
CCSPlayerController attacker = attackerPawn.Controller.Value.As<CCSPlayerController>(); var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(victim)!.Index);
CCSPlayerController victim = victimPawn.Controller.Value.As<CCSPlayerController>();
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == victim.SteamID);
if (playerInfo == null) return; if (playerInfo == null) return;
if (playerInfo.Skill == skillName && victim.PawnIsAlive) if (playerInfo.Skill == skillName && victim.PawnIsAlive)

View file

@ -1,7 +1,6 @@
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using static src.jRandomSkills;
namespace src.player.skills namespace src.player.skills
{ {
@ -18,29 +17,34 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var damage = @event.DmgHealth; var damage = @event.DmgHealth;
var victim = @event.Userid; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var weapon = @event.Weapon; var weapon = @event.Weapon;
HitGroup_t hitgroup = (HitGroup_t)@event.Hitgroup;
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return; if (victim == null || !victim.IsValid || attacker == null || !attacker.IsValid || attacker == victim) return;
if (nades.Contains(weapon)) return; if (string.IsNullOrEmpty(weapon) || nades.Contains(weapon)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (IsBehind(attacker!, victim!)) if (IsBehind(attacker, victim))
SkillUtils.TakeHealth(victim!.PlayerPawn.Value, (int)(damage * (SkillsInfo.GetValue<float>(skillName, "damageMultiplier") - 1f))); {
var victimPawn = victim.PlayerPawn.Value;
if (victimPawn != null && victimPawn.IsValid)
SkillUtils.TakeHealth(victimPawn, (int)(damage * (SkillsInfo.GetValue<float>(skillName, "damageMultiplier") - 1)));
}
} }
private static bool IsBehind(CCSPlayerController attacker, CCSPlayerController victim) private static bool IsBehind(CCSPlayerController attacker, CCSPlayerController victim)
{ {
var attackerPawn = attacker.PlayerPawn.Value; var attackerPawn = attacker.PlayerPawn.Value;
var victimPawn = victim.PlayerPawn.Value; var victimPawn = victim.PlayerPawn.Value;
if (attackerPawn == null || !attackerPawn.IsValid || victimPawn == null || !victimPawn.IsValid) return false; if (attackerPawn == null || !attackerPawn.IsValid || victimPawn == null || !victimPawn.IsValid) return false;
if (victimPawn.AbsRotation == null || attackerPawn.AbsRotation == null) return false; if (victimPawn.AbsRotation == null || attackerPawn.AbsRotation == null) return false;
var angles = GetAngleRange(victimPawn.AbsRotation.Y); var angles = GetAngleRange(victimPawn.AbsRotation.Y);
return IsBeetween(angles.Item1, angles.Item2, attackerPawn.AbsRotation.Y); return IsBetween(angles.Item1, angles.Item2, attackerPawn.AbsRotation.Y);
} }
private static (float, float) GetAngleRange(float angle) private static (float, float) GetAngleRange(float angle)
@ -55,7 +59,7 @@ namespace src.player.skills
return (min, max); return (min, max);
} }
private static bool IsBeetween(float a, float b, float target) private static bool IsBetween(float a, float b, float target)
{ {
if (a <= b) if (a <= b)
return (target >= a && target <= b); return (target >= a && target <= b);

View file

@ -23,29 +23,40 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{
if (player != null && player.IsValid)
DisableSkill(player); DisableSkill(player);
} }
}
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
player.PlayerPawn.Value.ActualGravityScale = 1; pawn.ActualGravityScale = 1.0f;
} }
private static void ApplyGravityModifier(CCSPlayerController player) private static void ApplyGravityModifier(CCSPlayerController player)
{ {
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
float gravityModifier = (float)Math.Round(Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "chanceFrom")) + SkillsInfo.GetValue<float>(skillName, "chanceFrom"), 1); float gravityModifier = (float)Math.Round(Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "chanceFrom")) + SkillsInfo.GetValue<float>(skillName, "chanceFrom"), 1);
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.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t"); border: !Utilities.GetPlayers().Any(p => p.IsValid && p.Team == player.Team && p != player) ? "tb" : "t");
player.PlayerPawn.Value.ActualGravityScale = gravityModifier;
pawn.ActualGravityScale = gravityModifier;
} }
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#7E10AD", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float chanceFrom = .1f, float chanceTo = .7f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity) public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#7E10AD", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float chanceFrom = .1f, float chanceTo = .7f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)

View file

@ -1,9 +1,8 @@
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 System.Collections.Concurrent;
using src.utils; using src.utils;
using System.Collections.Concurrent;
namespace src.player.skills namespace src.player.skills
{ {
@ -19,65 +18,87 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{
if (player != null && player.IsValid)
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 Utilities.GetPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (player == null || !player.IsValid || !SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
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.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account)}$", e.Index.ToString()))); 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();
ConcurrentBag<(string, string)> menuItems = [];
foreach (var e in enemies)
{
int money = e.InGameMoneyServices?.Account ?? 0;
menuItems.Add(($"{e.PlayerName} : {money}$", e.Index.ToString()));
}
if (!menuItems.IsEmpty)
SkillUtils.UpdateMenu(player, menuItems); SkillUtils.UpdateMenu(player, menuItems);
} }
} }
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p => p.IsValid && p.PawnIsAlive && p.Team != player.Team && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0)
{
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices?.Account ?? 0)}$", e.Index.ToString()))];
SkillUtils.CreateMenu(player, menuItems);
}
else
{
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("selectplayerskill_incorrect_enemy_index")}");
}
}
public static void TypeSkill(CCSPlayerController player, string[] commands) public static void TypeSkill(CCSPlayerController player, string[] commands)
{ {
if (player == null || !player.IsValid || !player.PawnIsAlive) return; if (player == null || !player.IsValid || commands.Length < 1) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
string option = commands[0];
if (string.IsNullOrEmpty(option)) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed) if (playerInfo.SkillUsed)
{ {
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("areareaper_used_info")}"); player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("selectplayerskill_used_info")}");
return; return;
} }
string enemyId = commands[0]; if (uint.TryParse(option, out uint enemyIndex))
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Team != player.Team && p.Index.ToString() == enemyId); {
var enemy = Utilities.GetEntityFromIndex<CCSPlayerController>((int)enemyIndex);
if (enemy == null) if (enemy != null && enemy.IsValid && enemy.PawnIsAlive && enemy.Team != player.Team)
{ {
player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("selectplayerskill_incorrect_enemy_index"));
return;
}
ResetMoney(enemy); ResetMoney(enemy);
playerInfo.SkillUsed = true; playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("bankrupt_player_info", enemy.PlayerName)); SkillUtils.CloseMenu(player);
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("bankrupt_enemy_info")); player.PrintToChat($" {ChatColors.Lime}{player.GetTranslation("bankrupt_player_info", enemy.PlayerName)}");
enemy.PrintToChat($" {ChatColors.Red}{enemy.GetTranslation("bankrupt_enemy_info")}");
return;
} }
public static void EnableSkill(CCSPlayerController player)
{
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo == null) return;
playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0)
{
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account)}$", e.Index.ToString())));
SkillUtils.CreateMenu(player, menuItems);
} }
else
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("selectplayerskill_incorrect_enemy_index")}"); player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("selectplayerskill_incorrect_enemy_index")}");
} }
@ -93,6 +114,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
if (player != null && player.IsValid)
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }

View file

@ -1,10 +1,10 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils; using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills namespace src.player.skills
{ {
@ -20,14 +20,14 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var victim = @event.Userid; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var weapon = @event.Weapon; var weapon = @event.Weapon;
if (weapon != "decoy") return; if (weapon != "decoy") return;
if (!Instance.IsPlayerValid(victim) || !Instance.IsPlayerValid(attacker)) return; if (!Instance.IsPlayerValid(victim) || !Instance.IsPlayerValid(attacker)) return;
var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID); var attackerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(attacker)!.Index);
if (attackerInfo?.Skill != skillName) return; if (attackerInfo?.Skill != skillName) return;
SkillUtils.TakeHealth(victim!.PlayerPawn.Value, SkillsInfo.GetValue<int>(skillName, "damageDeal")); SkillUtils.TakeHealth(victim!.PlayerPawn.Value, SkillsInfo.GetValue<int>(skillName, "damageDeal"));
@ -48,7 +48,7 @@ namespace src.player.skills
var player = pawn.Controller.Value.As<CCSPlayerController>(); var player = pawn.Controller.Value.As<CCSPlayerController>();
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
decoys.TryAdd(decoy.Index, 0); decoys.TryAdd(decoy.Index, 0);
@ -58,10 +58,10 @@ namespace src.player.skills
public static void DecoyStarted(EventDecoyStarted @event) public static void DecoyStarted(EventDecoyStarted @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
uint key = (uint)@event.Entityid; uint key = (uint)@event.Entityid;
@ -69,7 +69,7 @@ namespace src.player.skills
{ {
var decoy = Utilities.GetEntityFromIndex<CDecoyProjectile>(@event.Entityid); var decoy = Utilities.GetEntityFromIndex<CDecoyProjectile>(@event.Entityid);
if (decoy != null && decoy.IsValid) if (decoy != null && decoy.IsValid)
decoy.AcceptInput("Kill"); decoy.AddEntityIOEvent("Kill", decoy, delay: 0.1f);
decoys.TryRemove(key, out _); decoys.TryRemove(key, out _);
} }
} }

View file

@ -17,11 +17,11 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var attacker = @event!.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event!.Attacker);
var victim = @event!.Userid; var victim = PlayerManager.GetPlayerEvent(@event!.Userid);
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return; if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
if (playerInfo?.Skill == skillName && victim!.PawnIsAlive) if (playerInfo?.Skill == skillName && victim!.PawnIsAlive)
if (Instance.Random.NextDouble() <= playerInfo.SkillChance) if (Instance.Random.NextDouble() <= playerInfo.SkillChance)
@ -30,12 +30,12 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
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.IsBot && p != player) ? "tb" : "t"); border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
private static void RotateEnemy(CCSPlayerController player) private static void RotateEnemy(CCSPlayerController player)

View file

@ -18,58 +18,71 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
var modifier = SkillsInfo.GetValue<float>(skillName, "velocityModifier");
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
if (!Instance.IsPlayerValid(player)) continue; if (player == null || !player.IsValid) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) continue; if (playerInfo?.Skill != skillName) continue;
var playerPawn = player.PlayerPawn?.Value; var playerPawn = player.PlayerPawn?.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.VelocityModifier == 0) continue; if (playerPawn == null || !playerPawn.IsValid || playerPawn.VelocityModifier == 0) continue;
var weaponServices = playerPawn.WeaponServices; var weaponServices = playerPawn.WeaponServices;
if (weaponServices == null) return; if (weaponServices == null) continue;
if (weaponServices.ActiveWeapon == null || !weaponServices.ActiveWeapon.IsValid || weaponServices.ActiveWeapon.Value == null || !weaponServices.ActiveWeapon.Value.IsValid || (weaponServices.ActiveWeapon.Value.DesignerName != "weapon_knife" && weaponServices.ActiveWeapon.Value.DesignerName != "weapon_bayonet"))
return;
playerPawn.VelocityModifier = SkillsInfo.GetValue<float>(skillName, "velocityModifier"); if (weaponServices.ActiveWeapon == null
|| !weaponServices.ActiveWeapon.IsValid
|| weaponServices.ActiveWeapon.Value == null
|| !weaponServices.ActiveWeapon.Value.IsValid
|| (weaponServices.ActiveWeapon.Value.DesignerName != "weapon_knife"
&& weaponServices.ActiveWeapon.Value.DesignerName != "weapon_bayonet"))
continue;
playerPawn.VelocityModifier = modifier;
} }
} }
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var victim = @event.Userid; var damage = @event.DmgHealth;
int damage = @event.DmgHealth; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
HitGroup_t hitGroup = (HitGroup_t)@event.Hitgroup; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
string weapon = @event.Weapon; var weapon = @event.Weapon;
int hitgroup = @event.Hitgroup;
if (noReflectionWeapon.Contains(weapon) || !Instance.IsPlayerValid(victim)) return; if (victim == null || !victim.IsValid || attacker == null || !attacker.IsValid || attacker == victim) return;
var victimInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == victim?.SteamID);
if (victimInfo == null || victimInfo.Skill != skillName) return;
int chance = Instance.Random.Next(0, 101); var playerInfo = PlayerManager.GetPlayerByIndex(victim.Index);
if (hitGroup == HitGroup_t.HITGROUP_LEFTLEG || hitGroup == HitGroup_t.HITGROUP_RIGHTLEG) if (playerInfo?.Skill != skillName) return;
{
if (chance > SkillsInfo.GetValue<float>(skillName, "legReflectionChance") * 100) if (string.IsNullOrEmpty(weapon) || noReflectionWeapon.Contains(weapon)) return;
return;
} float chance = (hitgroup == (int)HitGroup_t.HITGROUP_LEFTLEG || hitgroup == (int)HitGroup_t.HITGROUP_RIGHTLEG)
else ? SkillsInfo.GetValue<float>(skillName, "legReflectionChance")
if (chance > SkillsInfo.GetValue<float>(skillName, "torseReflectionChance") * 100) : SkillsInfo.GetValue<float>(skillName, "torseReflectionChance");
var victimPawn = victim.PlayerPawn?.Value;
if (victimPawn == null || !victimPawn.IsValid || Instance.Random.NextDouble() > chance)
return; return;
var pawn = victim!.PlayerPawn.Value; var weaponServices = victimPawn.WeaponServices;
if (pawn == null || !pawn.IsValid) return;
var weaponServices = pawn.WeaponServices;
if (weaponServices == null) return; if (weaponServices == null) return;
if (weaponServices.ActiveWeapon == null || !weaponServices.ActiveWeapon.IsValid || weaponServices.ActiveWeapon.Value == null || !weaponServices.ActiveWeapon.Value.IsValid || (weaponServices.ActiveWeapon.Value.DesignerName != "weapon_knife" && weaponServices.ActiveWeapon.Value.DesignerName != "weapon_bayonet"))
if (weaponServices.ActiveWeapon == null
|| !weaponServices.ActiveWeapon.IsValid
|| weaponServices.ActiveWeapon.Value == null
|| !weaponServices.ActiveWeapon.Value.IsValid
|| (weaponServices.ActiveWeapon.Value.DesignerName != "weapon_knife"
&& weaponServices.ActiveWeapon.Value.DesignerName != "weapon_bayonet"))
return; return;
SkillUtils.RestoreHealth(victim); SkillUtils.RestoreHealth(victim);
} }
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#cc7504", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float torseReflectionChance = .95f, float legReflectionChance = .80f, float velocityModifier = .85f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity) public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#cc7504", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float torseReflectionChance = .95f, float legReflectionChance = .70f, float velocityModifier = .85f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{ {
public float TorseReflectionChance { get; set; } = torseReflectionChance; public float TorseReflectionChance { get; set; } = torseReflectionChance;
public float LegReflectionChance { get; set; } = legReflectionChance; public float LegReflectionChance { get; set; } = legReflectionChance;

View file

@ -3,14 +3,13 @@ using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills namespace src.player.skills
{ {
public class BunnyHop : ISkill public class BunnyHop : ISkill
{ {
private const Skills skillName = Skills.BunnyHop; private const Skills skillName = Skills.BunnyHop;
private static readonly ConcurrentDictionary<ulong, int> playersLastJump = []; private static readonly ConcurrentDictionary<uint, int> playersLastJump = [];
public static void LoadSkill() public static void LoadSkill()
{ {
@ -21,7 +20,9 @@ namespace src.player.skills
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (player == null || !player.IsValid) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
GiveBunnyHop(player); GiveBunnyHop(player);
} }
@ -29,26 +30,31 @@ namespace src.player.skills
private static void GiveBunnyHop(CCSPlayerController player) private static void GiveBunnyHop(CCSPlayerController player)
{ {
var eventPlayer = PlayerManager.GetPlayerEvent(player);
var eventPlayerPawn = eventPlayer?.PlayerPawn?.Value;
if (eventPlayerPawn == null || !eventPlayerPawn.IsValid) return;
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return; if (playerPawn == null || !playerPawn.IsValid) return;
if (JumpBan.bannedPlayers.ContainsKey(player.Index)) return; if (JumpBan.bannedPlayers.ContainsKey(player.Index)) return;
var flags = (PlayerFlags)playerPawn.Flags; var flags = (PlayerFlags)eventPlayerPawn.Flags;
var buttons = player.Buttons; var buttons = player.Buttons;
if ((playerPawn.MovementServices?.QueuedButtonChangeMask & (ulong)PlayerButtons.Jump) != 0) if ((playerPawn.MovementServices?.QueuedButtonChangeMask & (ulong)PlayerButtons.Jump) != 0)
playersLastJump.AddOrUpdate(player.SteamID, Server.TickCount, (_, _) => Server.TickCount); playersLastJump.AddOrUpdate(eventPlayer!.Index, Server.TickCount, (_, _) => Server.TickCount);
bool jumpPressed = buttons.HasFlag(PlayerButtons.Jump) bool jumpPressed = buttons.HasFlag(PlayerButtons.Jump)
|| (playersLastJump.TryGetValue(player.SteamID, out int tick) && tick + 20 >= Server.TickCount); || (playersLastJump.TryGetValue(eventPlayer!.Index, out int tick) && tick + 20 >= Server.TickCount);
if (jumpPressed && flags.HasFlag(PlayerFlags.FL_ONGROUND) && !playerPawn.MoveType.HasFlag(MoveType_t.MOVETYPE_LADDER)) if (jumpPressed && flags.HasFlag(PlayerFlags.FL_ONGROUND) && !eventPlayerPawn.MoveType.HasFlag(MoveType_t.MOVETYPE_LADDER))
{ {
playerPawn.AbsVelocity.Z = SkillsInfo.GetValue<float>(skillName, "jumpVelocity"); eventPlayerPawn.AbsVelocity.Z = SkillsInfo.GetValue<float>(skillName, "jumpVelocity");
var maxSpeed = SkillsInfo.GetValue<float>(skillName, "maxSpeed"); var maxSpeed = SkillsInfo.GetValue<float>(skillName, "maxSpeed");
var vX = playerPawn.AbsVelocity.X; var vX = eventPlayerPawn.AbsVelocity.X;
var vY = playerPawn.AbsVelocity.Y; var vY = eventPlayerPawn.AbsVelocity.Y;
var speed2D = Math.Sqrt(vX * vX + vY * vY); var speed2D = Math.Sqrt(vX * vX + vY * vY);
var scale = 1d; var scale = 1d;
@ -60,8 +66,8 @@ namespace src.player.skills
else if (speed2D > maxSpeed) else if (speed2D > maxSpeed)
scale = maxSpeed / speed2D; scale = maxSpeed / speed2D;
playerPawn.AbsVelocity.X = (float)(vX * scale); eventPlayerPawn.AbsVelocity.X = (float)(vX * scale);
playerPawn.AbsVelocity.Y = (float)(vY * scale); eventPlayerPawn.AbsVelocity.Y = (float)(vY * scale);
} }
} }

View file

@ -4,6 +4,7 @@ using CounterStrikeSharp.API.Core.Attributes;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Drawing;
using static src.jRandomSkills; using static src.jRandomSkills;
namespace src.player.skills namespace src.player.skills
@ -13,11 +14,13 @@ namespace src.player.skills
private const Skills skillName = Skills.C4Camouflage; private const Skills skillName = Skills.C4Camouflage;
private static readonly ConcurrentDictionary<uint, byte> invisiblePlayers = []; private static readonly ConcurrentDictionary<uint, byte> invisiblePlayers = [];
private const string bloodParticle = "particles/blood_impact/blood_impact_high.vpcf"; private const string bloodParticle = "particles/blood_impact/blood_impact_high.vpcf";
private const string cameraViewModel = "models/sprays/spray_plane.vmdl";
public static void LoadSkill() public static void LoadSkill()
{ {
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color")); SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
Instance.AddToManifest(bloodParticle); Instance.AddToManifest(bloodParticle);
Instance.AddToManifest(cameraViewModel);
} }
public static void NewRound() public static void NewRound()
@ -27,40 +30,74 @@ namespace src.player.skills
public static void WeaponPickup(EventItemPickup @event) public static void WeaponPickup(EventItemPickup @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(player)) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
EnableSkill(player!);
Event.EnableTransmit();
if (EntityManager.GetPlayerEntities(player.Index, "empty_prop").Count == 0)
CreatePlayerPosProp(player);
} }
public static void WeaponEquip(EventItemEquip @event) public static void WeaponEquip(EventItemEquip @event)
{ {
var player = @event.Userid!; var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item; var weapon = @event.Item;
if (!Instance.IsPlayerValid(player)) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (weapon == "c4") if (weapon == "c4")
{
invisiblePlayers.TryAdd(player.Index, 0); invisiblePlayers.TryAdd(player.Index, 0);
SkillUtils.SetPlayerInvisibility(player, .5f);
}
else else
{
invisiblePlayers.TryRemove(player.Index, out _); invisiblePlayers.TryRemove(player.Index, out _);
SkillUtils.SetPlayerInvisibility(player, 0);
}
} }
public static void OnTick() public static void OnTick()
{ {
if (Server.TickCount % 2 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
if (!player.PawnIsAlive) {
if (player.LifeState != (byte)LifeState_t.LIFE_ALIVE && invisiblePlayers.ContainsKey(player.Index))
{
invisiblePlayers.TryRemove(player.Index, out _); invisiblePlayers.TryRemove(player.Index, out _);
SkillUtils.SetPlayerInvisibility(player, 0);
}
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) continue;
var props = EntityManager.GetPlayerEntities(player.Index, "empty_prop");
if (props.Count == 0) continue;
var prop = Utilities.GetEntityFromIndex<CDynamicProp>((int)props[0]);
if (prop == null || !prop.IsValid) continue;
var pawn = player.PlayerPawn?.Value;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue;
Vector newPos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + 30);
QAngle newAngle = new(0, pawn.V_angle.Y, 0);
prop.Teleport(newPos, newAngle, null);
}
} }
public static void CheckTransmit([CastFrom(typeof(nint))] CCheckTransmitInfoList infoList) public static void CheckTransmit([CastFrom(typeof(nint))] CCheckTransmitInfoList infoList)
{ {
foreach (var (info, player) in infoList) foreach (var (info, player) in infoList)
{ {
if (player == null || !player.IsValid) continue; if (player == null || !player.IsValid || player.Team == CsTeam.Spectator) continue;
var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero; var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero;
bool isObservingC4Camouflage = false; bool isObservingC4Camouflage = false;
@ -68,14 +105,17 @@ namespace src.player.skills
if (targetHandle != nint.Zero) if (targetHandle != nint.Zero)
{ {
var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle); var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle);
var targetInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == target?.SteamID); var targetInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(target)?.Index);
if (targetInfo?.Skill == skillName) isObservingC4Camouflage = true; if (targetInfo?.Skill == skillName) isObservingC4Camouflage = true;
} }
foreach (var playerIndex in invisiblePlayers.Keys) foreach (var playerIndex in invisiblePlayers.Keys)
{ {
var playerController = Utilities.GetPlayerFromIndex((int)playerIndex); var playerController = PlayerManager.GetPlayerEvent(Utilities.GetPlayerFromIndex((int)playerIndex));
if (playerController == null || !playerController.IsValid || playerController.SteamID == player.SteamID) if (playerController == null || !playerController.IsValid || playerController.Index == player.Index)
continue;
if (player.Team == playerController.Team)
continue; continue;
if (!isObservingC4Camouflage) if (!isObservingC4Camouflage)
@ -105,6 +145,10 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return; if (playerPawn == null || !playerPawn.IsValid) return;
if (EntityManager.GetPlayerEntities(player.Index, "empty_prop").Count == 0)
CreatePlayerPosProp(player);
if (playerPawn.WeaponServices == null || playerPawn.WeaponServices.ActiveWeapon == null || !playerPawn.WeaponServices.ActiveWeapon.IsValid) return; if (playerPawn.WeaponServices == null || playerPawn.WeaponServices.ActiveWeapon == null || !playerPawn.WeaponServices.ActiveWeapon.IsValid) return;
if (playerPawn.WeaponServices.ActiveWeapon.Value == null || !playerPawn.WeaponServices.ActiveWeapon.Value.IsValid) return; if (playerPawn.WeaponServices.ActiveWeapon.Value == null || !playerPawn.WeaponServices.ActiveWeapon.Value.IsValid) return;
@ -112,32 +156,55 @@ namespace src.player.skills
if (activeWeapon.DesignerName != "weapon_c4") return; if (activeWeapon.DesignerName != "weapon_c4") return;
invisiblePlayers.TryAdd(player.Index, 0); invisiblePlayers.TryAdd(player.Index, 0);
SkillUtils.SetPlayerInvisibility(player, .5f);
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
invisiblePlayers.TryRemove(player.Index, out _); invisiblePlayers.TryRemove(player.Index, out _);
SkillUtils.SetPlayerInvisibility(player, 0);
EntityManager.DestroyPlayerEntities(player.Index);
}
private static void CreatePlayerPosProp(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
var emptyProp = EntityManager.CreateTrackedDynamicProp(player.Index);
if (emptyProp == null || !emptyProp.IsValid) return;
var playerPawn = player.PlayerPawn?.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null || playerPawn.AbsRotation == null) return;
emptyProp.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(emptyProp.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
emptyProp.SetModel(cameraViewModel);
emptyProp.Render = Color.FromArgb(1, 255, 255, 255);
Vector newPos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 30);
QAngle newAngle = new(playerPawn.AbsRotation.X, playerPawn.AbsRotation.Y, playerPawn.AbsRotation.Z);
emptyProp.Teleport(newPos, newAngle);
emptyProp.DispatchSpawn();
Utilities.SetStateChanged(emptyProp, "CBaseEntity", "m_CBodyComponent");
EntityManager.RegisterExisting(emptyProp, player.Index, "empty_prop");
} }
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
if (!invisiblePlayers.ContainsKey(player.Index)) return; if (!invisiblePlayers.ContainsKey(player.Index)) return;
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return; if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return;
CParticleSystem particle = Utilities.CreateEntityByName<CParticleSystem>("info_particle_system")!; var particle = EntityManager.CreateTrackedParticleSystem(player.Index, bloodParticle, autoDestroySeconds: 3f);
if (particle == null) return; if (particle == null) return;
particle.EffectName = bloodParticle;
particle.StartActive = true;
Vector pos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 50); Vector pos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 50);
particle.Teleport(pos); particle.Teleport(pos);
particle.DispatchSpawn();
particle.AcceptInput("Start"); particle.AcceptInput("Start");
} }

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
@ -11,9 +11,10 @@ namespace src.player.skills
public class CarefulBullets : ISkill public class CarefulBullets : ISkill
{ {
private const Skills skillName = Skills.CarefulBullets; private const Skills skillName = Skills.CarefulBullets;
private static readonly ConcurrentDictionary<ulong, byte> targetPlayers = []; private static readonly ConcurrentDictionary<uint, byte> targetPlayers = [];
private static readonly ConcurrentDictionary<ulong, bool> lastShot = []; private static readonly ConcurrentDictionary<uint, bool> lastShot = [];
private static readonly ConcurrentDictionary<ulong, int> hitPlayer = []; private static readonly ConcurrentDictionary<uint, int> hitPlayer = [];
private static readonly ConcurrentDictionary<uint, uint> playersToTarget = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
public static void LoadSkill() public static void LoadSkill()
@ -25,22 +26,17 @@ namespace src.player.skills
{ {
lock (setLock) lock (setLock)
{ {
targetPlayers.Clear();
lastShot.Clear();
hitPlayer.Clear();
}
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
DisableSkill(player); DisableSkill(player);
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
}
public static void PlayerDeath(EventPlayerDeath @event) targetPlayers.Clear();
{ lastShot.Clear();
var player = @event.Userid; hitPlayer.Clear();
if (player == null) return; playersToTarget.Clear();
DisableSkill(player); }
} }
public static void OnTick() public static void OnTick()
@ -49,10 +45,10 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); 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.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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);
@ -61,8 +57,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands) public static void TypeSkill(CCSPlayerController player, string[] commands)
{ {
if (player == null || !player.IsValid || !player.PawnIsAlive) return; if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed) if (playerInfo.SkillUsed)
@ -72,7 +68,8 @@ namespace src.player.skills
} }
string enemyId = commands[0]; string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Team != player.Team && p.Index.ToString() == enemyId); if (!uint.TryParse(enemyId, out uint enemyIndex)) { player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("selectplayerskill_incorrect_enemy_index")); return; }
var enemy = Utilities.GetPlayerFromIndex((int)enemyIndex);
if (enemy == null) if (enemy == null)
{ {
@ -80,19 +77,21 @@ namespace src.player.skills
return; return;
} }
targetPlayers.TryAdd(enemy.SteamID, 0); targetPlayers.TryAdd(enemy.Index, 0);
playersToTarget[player.Index] = enemy.Index;
playerInfo.SkillUsed = true; playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("carefulbullets_player_info", enemy.PlayerName)); player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("carefulbullets_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("carefulbullets_enemy_info")); enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("carefulbullets_enemy_info"));
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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()))];
@ -104,37 +103,37 @@ namespace src.player.skills
public static void BulletImpact(EventBulletImpact @event) public static void BulletImpact(EventBulletImpact @event)
{ {
var player = @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;
if (!targetPlayers.ContainsKey(player.SteamID) || !player.PawnIsAlive) if (!targetPlayers.ContainsKey(player.Index) || player.LifeState != (byte)LifeState_t.LIFE_ALIVE)
return; return;
ulong steamID = player.SteamID; uint playerIndex = player.Index;
Server.NextFrame(() => Server.NextFrame(() =>
{ {
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
if (playerPawn == null || !playerPawn.IsValid) return; if (playerPawn == null || !playerPawn.IsValid) return;
bool ishitPlayer = hitPlayer.TryGetValue(steamID, out int tick) && tick + 10 >= Server.TickCount; bool ishitPlayer = hitPlayer.TryGetValue(playerIndex, out int tick) && tick + 10 >= Server.TickCount;
if (!lastShot.ContainsKey(steamID)) if (!lastShot.ContainsKey(playerIndex))
{ {
lastShot.TryAdd(steamID, ishitPlayer); lastShot.TryAdd(playerIndex, ishitPlayer);
Instance.AddTickTimer(1, () => Instance.AddTickTimer(1, () =>
{ {
if (lastShot.TryRemove(steamID, out bool didHit) && !didHit) if (lastShot.TryRemove(playerIndex, out bool didHit) && !didHit)
SkillUtils.TakeHealth(playerPawn, SkillsInfo.GetValue<int>(skillName, "damageAfterMiss")); SkillUtils.TakeHealth(playerPawn, SkillsInfo.GetValue<int>(skillName, "damageAfterMiss"));
lastShot.TryRemove(steamID, out _); lastShot.TryRemove(playerIndex, out _);
}); });
} }
else if (ishitPlayer) else if (ishitPlayer)
lastShot.TryUpdate(steamID, true, false); lastShot.TryUpdate(playerIndex, true, false);
}); });
} }
@ -155,17 +154,37 @@ namespace src.player.skills
if (attackerPawn == null || attackerPawn.Controller?.Value == null || victimPawn == null || victimPawn.Controller?.Value == null) if (attackerPawn == null || attackerPawn.Controller?.Value == null || victimPawn == null || victimPawn.Controller?.Value == null)
return; return;
CCSPlayerController attacker = attackerPawn.Controller.Value.As<CCSPlayerController>(); CCSPlayerController attacker = PlayerManager.GetPlayerEvent(attackerPawn.Controller.Value.As<CCSPlayerController>())!;
if (!targetPlayers.ContainsKey(attacker.SteamID)) return; if (!targetPlayers.ContainsKey(attacker.Index)) return;
hitPlayer.AddOrUpdate(attacker.SteamID, Server.TickCount, (_, _) => Server.TickCount); hitPlayer.AddOrUpdate(attacker.Index, Server.TickCount, (_, _) => Server.TickCount);
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
targetPlayers.TryRemove(player.SteamID, out _); targetPlayers.TryRemove(player.Index, out _);
lastShot.TryRemove(player.SteamID, out _); lastShot.TryRemove(player.Index, out _);
hitPlayer.TryRemove(player.SteamID, out _); hitPlayer.TryRemove(player.Index, out _);
if (playersToTarget.TryRemove(player.Index, out uint targetIndex))
{
targetPlayers.TryRemove(targetIndex, out _);
lastShot.TryRemove(targetIndex, out _);
hitPlayer.TryRemove(targetIndex, out _);
}
SkillUtils.CloseMenu(player);
}
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null || !player.IsValid) return;
targetPlayers.TryRemove(player.Index, out _);
lastShot.TryRemove(player.Index, out _);
hitPlayer.TryRemove(player.Index, out _);
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }

View file

@ -17,11 +17,11 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = @event.Userid; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return; if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return;
var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID); var attackerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
if (attackerInfo?.Skill == skillName && victim!.PawnIsAlive) if (attackerInfo?.Skill == skillName && victim!.PawnIsAlive)
if (Instance.Random.NextDouble() <= attackerInfo.SkillChance) if (Instance.Random.NextDouble() <= attackerInfo.SkillChance)
@ -34,12 +34,12 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
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.IsBot && p != player) ? "tb" : "t"); border: !Utilities.GetPlayers().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 = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float chanceFrom = .2f, float chanceTo = .4f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, 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 = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float chanceFrom = .2f, float chanceTo = .4f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)

View file

@ -42,10 +42,10 @@ namespace src.player.skills
public static void WeaponPickup(EventItemPickup @event) public static void WeaponPickup(EventItemPickup @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
SetWeaponAttack(player, true); SetWeaponAttack(player, true);
@ -120,7 +120,7 @@ namespace src.player.skills
{ {
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return; if (playerPawn == null || !playerPawn.IsValid) return;
var chickenModel = Utilities.CreateEntityByName<CDynamicProp>("prop_dynamic"); var chickenModel = EntityManager.CreateTrackedDynamicProp(player.Index);
if (chickenModel == null) if (chickenModel == null)
return; return;
@ -172,7 +172,7 @@ namespace src.player.skills
var pawn = player.PlayerPawn.Value; var pawn = player.PlayerPawn.Value;
if (pawn.WeaponServices == null || pawn.WeaponServices.ActiveWeapon == null || !pawn.WeaponServices.ActiveWeapon.IsValid || pawn.WeaponServices.ActiveWeapon.Value == null || !pawn.WeaponServices.ActiveWeapon.Value.IsValid) return; if (pawn.WeaponServices == null || pawn.WeaponServices.ActiveWeapon == null || !pawn.WeaponServices.ActiveWeapon.IsValid || pawn.WeaponServices.ActiveWeapon.Value == null || !pawn.WeaponServices.ActiveWeapon.Value.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
var weapon = pawn.WeaponServices.ActiveWeapon.Value; var weapon = pawn.WeaponServices.ActiveWeapon.Value;

View file

@ -1,6 +1,7 @@
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 Microsoft.Extensions.Logging;
using src.utils; using src.utils;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using static src.jRandomSkills; using static src.jRandomSkills;
@ -10,7 +11,7 @@ namespace src.player.skills
public class ChillOut : ISkill public class ChillOut : ISkill
{ {
private const Skills skillName = Skills.ChillOut; private const Skills skillName = Skills.ChillOut;
private static readonly ConcurrentDictionary<ulong, float> plantingPlayers = []; private static readonly ConcurrentDictionary<uint, float> plantingPlayers = [];
public static void LoadSkill() public static void LoadSkill()
{ {
@ -25,25 +26,27 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
plantingPlayers.TryRemove(player.SteamID, out _); plantingPlayers.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player); SkillUtils.ResetPrintHTML(player);
} }
public static void BombAbortplant(EventBombAbortplant @event) public static void BombAbortplant(EventBombAbortplant @event)
{ {
var user = @event.Userid; var user = PlayerManager.GetPlayerEvent(@event.Userid);
if (user == null || !user.IsValid || !user.PawnIsAlive) return; if (!Instance.IsPlayerValid(user)) return;
plantingPlayers.TryRemove(user.SteamID, out _);
plantingPlayers.TryRemove(user.Index, out _);
SkillUtils.ResetPrintHTML(user); SkillUtils.ResetPrintHTML(user);
} }
public static void BombBeginplant(EventBombBeginplant @event) public static void BombBeginplant(EventBombBeginplant @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(player)) return; if (!Instance.IsPlayerValid(player)) return;
plantingPlayers.TryAdd(player!.SteamID, Server.CurrentTime);
var anyChillOut = Instance.SkillPlayer.FirstOrDefault(p => p.Skill == skillName); plantingPlayers.TryAdd(player!.Index, Server.CurrentTime);
var anyChillOut = PlayerManager.GetAllPlayers().FirstOrDefault(p => p.Skill == skillName);
if (anyChillOut != null) if (anyChillOut != null)
{ {
var bombEntities = Utilities.FindAllEntitiesByDesignerName<CC4>("weapon_c4").ToList(); var bombEntities = Utilities.FindAllEntitiesByDesignerName<CC4>("weapon_c4").ToList();
@ -58,9 +61,10 @@ namespace src.player.skills
public static void BombPlanted(EventBombPlanted @event) public static void BombPlanted(EventBombPlanted @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(player)) return; if (!Instance.IsPlayerValid(player)) return;
plantingPlayers.TryRemove(player!.SteamID, out _);
plantingPlayers.TryRemove(player!.Index, out _);
SkillUtils.ResetPrintHTML(player); SkillUtils.ResetPrintHTML(player);
} }
@ -71,9 +75,9 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers().Where(p => p.Team == CsTeam.Terrorist)) foreach (var player in Utilities.GetPlayers().Where(p => p.Team == CsTeam.Terrorist))
{ {
if (!Instance.IsPlayerValid(player)) continue; if (player == null || !player.IsValid) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
if (playerInfo == null) continue; if (playerInfo == null) continue;
var pawn = player.PlayerPawn.Value; var pawn = player.PlayerPawn.Value;
@ -83,7 +87,7 @@ namespace src.player.skills
var activeWeapon = pawn.WeaponServices.ActiveWeapon.Value; var activeWeapon = pawn.WeaponServices.ActiveWeapon.Value;
if (activeWeapon == null || !activeWeapon.IsValid || activeWeapon.DesignerName != "weapon_c4") continue; if (activeWeapon == null || !activeWeapon.IsValid || activeWeapon.DesignerName != "weapon_c4") continue;
if (plantingPlayers.TryGetValue(player.SteamID, out float plantTime)) if (plantingPlayers.TryGetValue(player.Index, out float plantTime))
{ {
float remaining = plantTime + extraTime - currentTime; float remaining = plantTime + extraTime - currentTime;
playerInfo.PrintHTML = $"{player.GetTranslation("planter_planting", $"<font color='#00FF00'>{Math.Max(0, remaining):0.0}s</font>")}"; playerInfo.PrintHTML = $"{player.GetTranslation("planter_planting", $"<font color='#00FF00'>{Math.Max(0, remaining):0.0}s</font>")}";

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using static src.jRandomSkills; using static src.jRandomSkills;
@ -17,12 +17,12 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var damage = @event.DmgHealth; var damage = @event.DmgHealth;
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = @event.Userid; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Weapon; var weapon = @event.Weapon;
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return; if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (weapon == "knife" || weapon == "bayonet") if (weapon == "knife" || weapon == "bayonet")

View file

@ -1,5 +1,6 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Commands.Targeting;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Timers; using CounterStrikeSharp.API.Modules.Timers;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
@ -178,15 +179,18 @@ namespace src.player.skills
if (cameraView == null || !cameraView.IsValid) return; if (cameraView == null || !cameraView.IsValid) return;
pawn!.CameraServices!.ViewEntity.Raw = cameraView.EntityHandle.Raw; pawn!.CameraServices!.ViewEntity.Raw = cameraView.EntityHandle.Raw;
SkillUtils.ApplyScreenColor(player, 0, 0, 255, 20, 100, 1020);
ulong playerSteamID = player.SteamID; var eventTarget = PlayerManager.GetPlayerFromEvent(player);
if (eventTarget != null && eventTarget.IsValid)
SkillUtils.ApplyScreenColor(eventTarget, 0, 0, 255, 20, 100, 1020);
uint playerIndex = player.Index;
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.SteamID == playerSteamID); var target = Utilities.GetPlayers().FirstOrDefault(p => p.IsValid && p.Index == playerIndex);
if (target == null || !target.IsValid || !target.PawnIsAlive) if (target == null || !target.IsValid || target.LifeState != (byte)LifeState_t.LIFE_ALIVE)
{ {
cameraTimer?.Kill(); cameraTimer?.Kill();
return; return;
@ -198,7 +202,14 @@ namespace src.player.skills
return; return;
} }
SkillUtils.ApplyScreenColor(target, 0, 0, 255, 20, 100, 1020); var eventTarget = PlayerManager.GetPlayerFromEvent(player);
if (eventTarget == null || !eventTarget.IsValid)
{
cameraTimer?.Kill();
return;
}
SkillUtils.ApplyScreenColor(eventTarget, 0, 0, 255, 20, 100, 1020);
}, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT); }, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT);
} }
else else
@ -222,12 +233,12 @@ namespace src.player.skills
if (!CheckCameraPosition(finalPos, player)) if (!CheckCameraPosition(finalPos, player))
return null; return null;
var camera = Utilities.CreateEntityByName<CDynamicProp>("prop_dynamic_override"); var camera = EntityManager.CreateTrackedPropOverride(player.Index);
if (camera == null || !camera.IsValid) return null; if (camera == null || !camera.IsValid) return null;
camera.Collision.SolidType = SolidType_t.SOLID_VPHYSICS; camera.Collision.SolidType = SolidType_t.SOLID_VPHYSICS;
camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2)); camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
camera.Entity!.Name = camera.Globalname = $"CypherCamera_{Server.TickCount}_{player.SteamID}"; camera.Entity!.Name = camera.Globalname = $"CypherCamera_{Server.TickCount}_{player.Index}";
camera.SetModel(cameraPropModel); camera.SetModel(cameraPropModel);
camera.Teleport(cameraVector, new QAngle(0, playerPawn.V_angle.Y + 180, 0)); camera.Teleport(cameraVector, new QAngle(0, playerPawn.V_angle.Y + 180, 0));
@ -244,17 +255,27 @@ 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 camera = Utilities.CreateEntityByName<CDynamicProp>("prop_dynamic"); uint ownerIndex = EntityManager.SystemOwnerIndex;
if (!string.IsNullOrEmpty(cameraProp.Globalname))
{
var parts = cameraProp.Globalname.Split('_');
if (parts.Length >= 3 && uint.TryParse(parts[^1], out var idx))
ownerIndex = idx;
}
var camera = EntityManager.CreateTrackedDynamicProp(ownerIndex);
if (camera == null || !camera.IsValid) return null; if (camera == null || !camera.IsValid) return null;
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));
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, cameraProp.AbsRotation);
camera.DispatchSpawn(); camera.DispatchSpawn();
EntityManager.RegisterExisting(camera, ownerIndex, "prop_dynamic");
}); });
return camera; return camera;
@ -272,10 +293,10 @@ namespace src.player.skills
if (!param.Entity.Name.StartsWith("CypherCamera_")) return; if (!param.Entity.Name.StartsWith("CypherCamera_")) return;
var nameParams = param.Entity.Name.Split('_')[2]; var nameParams = param.Entity.Name.Split('_')[2];
_ = ulong.TryParse(nameParams, out ulong steamID); _ = uint.TryParse(nameParams, out uint userIndex);
if (steamID == 0) return; if (userIndex == 0) return;
var player = Utilities.GetPlayerFromSteamId(steamID); var player = Utilities.GetPlayerFromIndex((int)userIndex);
if (player == null) return; if (player == null) return;
if (playersInfo.TryGetValue(player.Index, out var playerSkill)) if (playersInfo.TryGetValue(player.Index, out var playerSkill))
@ -355,7 +376,7 @@ namespace src.player.skills
var player = Utilities.GetPlayerFromIndex((int)playerSkill.Player); var player = Utilities.GetPlayerFromIndex((int)playerSkill.Player);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
float ticksLeft = playerSkill.NextCamera - Server.TickCount; float ticksLeft = playerSkill.NextCamera - Server.TickCount;

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Timers; using CounterStrikeSharp.API.Modules.Timers;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
@ -12,7 +12,8 @@ namespace src.player.skills
public class Darkness : ISkill public class Darkness : ISkill
{ {
private const Skills skillName = Skills.Darkness; private const Skills skillName = Skills.Darkness;
private static readonly ConcurrentDictionary<ulong, byte> playersInDark = []; private static readonly ConcurrentDictionary<uint, byte> playersInDark = [];
private static readonly ConcurrentDictionary<uint, uint> playersToTarget = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
public static void LoadSkill() public static void LoadSkill()
@ -26,31 +27,25 @@ namespace src.player.skills
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
if (playersInDark.ContainsKey(player.SteamID)) if (playersInDark.ContainsKey(player.Index))
DisableSkill(player); DisableSkill(player);
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
playersInDark.Clear(); playersInDark.Clear();
playersToTarget.Clear();
} }
} }
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null) return;
DisableSkill(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 Utilities.GetPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); 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.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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);
@ -59,8 +54,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands) public static void TypeSkill(CCSPlayerController player, string[] commands)
{ {
if (player == null || !player.IsValid || !player.PawnIsAlive) return; if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed) if (playerInfo.SkillUsed)
@ -70,7 +65,8 @@ namespace src.player.skills
} }
string enemyId = commands[0]; string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Team != player.Team && p.Index.ToString() == enemyId); if (!uint.TryParse(enemyId, out uint enemyIndex)) { player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("selectplayerskill_incorrect_enemy_index")); return; }
var enemy = Utilities.GetPlayerFromIndex((int)enemyIndex);
if (enemy == null) if (enemy == null)
{ {
@ -79,18 +75,20 @@ namespace src.player.skills
} }
SetUpPostProcessing(enemy); SetUpPostProcessing(enemy);
playersToTarget[player.Index] = enemy.Index;
playerInfo.SkillUsed = true; playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("darkness_player_info", enemy.PlayerName)); player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("darkness_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("darkness_enemy_info")); enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("darkness_enemy_info"));
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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()))];
@ -104,34 +102,50 @@ namespace src.player.skills
{ {
lock (setLock) lock (setLock)
{ {
SetUpPostProcessing(player, true); if (playersToTarget.TryRemove(player.Index, out uint targetIndex))
{
var target = Utilities.GetPlayerFromIndex((int)targetIndex);
if (target != null && target.IsValid)
SetUpPostProcessing(target, true);
playersInDark.TryRemove(targetIndex, out _);
}
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
} }
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null || !player.IsValid) return;
SetUpPostProcessing(player, true);
playersInDark.TryRemove(player.Index, out _);
SkillUtils.CloseMenu(player);
}
private static void SetUpPostProcessing(CCSPlayerController player, bool turnOff = false) private static void SetUpPostProcessing(CCSPlayerController player, bool turnOff = false)
{ {
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
ulong? playerSteamID = player?.SteamID; uint playerIndex = player.Index;
if (playerSteamID == null) return;
lock (setLock) lock (setLock)
{ {
if (!turnOff) if (!turnOff)
{ {
playersInDark.TryAdd((ulong)playerSteamID, 0); playersInDark.TryAdd(playerIndex, 0);
ApplyColor(player); ApplyColor(player);
Timer? darkTimer = null; Timer? darkTimer = null;
darkTimer = Instance.AddTimer(5f, () => { darkTimer = Instance.AddTimer(5f, () => {
if (!playersInDark.ContainsKey((ulong)playerSteamID)) if (!playersInDark.ContainsKey(playerIndex))
{ {
darkTimer?.Kill(); darkTimer?.Kill();
return; return;
} }
var target = Utilities.GetPlayers().FirstOrDefault(p => p.IsValid && p.SteamID == playerSteamID); var target = Utilities.GetPlayerFromIndex((int)playerIndex);
if (target == null || !target.IsValid) if (target == null || !target.IsValid)
{ {
darkTimer?.Kill(); darkTimer?.Kill();
@ -145,7 +159,7 @@ namespace src.player.skills
else else
{ {
SkillUtils.ApplyScreenColor(player, r: 0, g: 0, b: 0, a: 0, duration: 200, holdTime: 0); SkillUtils.ApplyScreenColor(player, r: 0, g: 0, b: 0, a: 0, duration: 200, holdTime: 0);
playersInDark.TryRemove((ulong)playerSteamID, out _); playersInDark.TryRemove(playerIndex, out _);
} }
} }
} }
@ -161,7 +175,7 @@ namespace src.player.skills
holdTime: 3000); holdTime: 3000);
} }
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#383838", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Uncommon, int r = 0, int g = 0, int b = 0, int a = 230) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity) public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#383838", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Rare, int r = 0, int g = 0, int b = 0, int a = 230) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{ {
public int R { get; set; } = r; public int R { get; set; } = r;
public int G { get; set; } = g; public int G { get; set; } = g;

View file

@ -1,16 +1,15 @@
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;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills namespace src.player.skills
{ {
public class Dash : ISkill public class Dash : ISkill
{ {
private const Skills skillName = Skills.Dash; private const Skills skillName = Skills.Dash;
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = []; private static readonly ConcurrentDictionary<uint, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
public static void LoadSkill() public static void LoadSkill()
@ -26,37 +25,22 @@ namespace src.player.skills
} }
} }
public static void OnTick()
{
foreach (var player in Utilities.GetPlayers())
{
if (!Instance.IsPlayerValid(player)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo?.Skill == skillName)
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
{
UpdateHUD(player, skillInfo);
HandleDash(player, skillInfo);
}
}
}
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo SkillPlayerInfo.TryAdd(player.Index, new PlayerSkillInfo
{ {
SteamID = player.SteamID, Username = player.PlayerName,
CanUse = true, CanUse = true,
Cooldown = DateTime.MinValue, Cooldown = DateTime.MinValue,
LastFlags = 0,
Jumps = 0, Jumps = 0,
LastButtons = 0 WasOnGround = true,
JumpReleasedTicks = 10
}); });
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryRemove(player.SteamID, out _); SkillPlayerInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player); SkillUtils.ResetPrintHTML(player);
} }
@ -72,7 +56,7 @@ namespace src.player.skills
skillInfo.CanUse = true; skillInfo.CanUse = true;
} }
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
if (cooldown == 0) if (cooldown == 0)
@ -81,31 +65,49 @@ namespace src.player.skills
playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}"; playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
} }
public static void OnTick()
{
foreach (var player in Utilities.GetPlayers())
{
if (player == null || !player.IsValid) return;
var eventPlayer = PlayerManager.GetPlayerEvent(player);
var playerInfo = PlayerManager.GetPlayerByIndex(eventPlayer!.Index);
if (playerInfo?.Skill == skillName)
if (SkillPlayerInfo.TryGetValue(eventPlayer!.Index, out var skillInfo))
{
UpdateHUD(player, skillInfo);
HandleDash(player, skillInfo);
}
}
}
private static void HandleDash(CCSPlayerController player, PlayerSkillInfo skillInfo) private static void HandleDash(CCSPlayerController player, PlayerSkillInfo skillInfo)
{ {
var playerPawn = player.PlayerPawn.Value; var eventPlayer = PlayerManager.GetPlayerEvent(player);
var eventPlayerPawn = eventPlayer?.PlayerPawn?.Value;
if (eventPlayerPawn == null || !eventPlayerPawn.IsValid) return;
var playerPawn = player.PlayerPawn?.Value;
if (playerPawn == null || !playerPawn.IsValid) return; if (playerPawn == null || !playerPawn.IsValid) return;
var flags = (PlayerFlags)playerPawn.Flags;
var buttons = player.Buttons; var buttons = player.Buttons;
bool jumpPressed = (buttons & PlayerButtons.Jump) != 0 bool jumpPressed = (buttons & PlayerButtons.Jump) != 0
|| (playerPawn.MovementServices?.QueuedButtonChangeMask & (ulong)PlayerButtons.Jump) != 0; || (playerPawn.MovementServices?.QueuedButtonChangeMask & (ulong)PlayerButtons.Jump) != 0;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); bool isOnGround =
if (playerPawn == null || playerInfo == null) return; eventPlayerPawn.GroundEntity != null
&& eventPlayerPawn.GroundEntity.IsValid;
bool wasOnGround = (skillInfo.LastFlags & PlayerFlags.FL_ONGROUND) != 0; if (skillInfo.WasOnGround && !isOnGround && jumpPressed)
bool isOnGround = (flags & PlayerFlags.FL_ONGROUND) != 0;
if (wasOnGround && !isOnGround && jumpPressed)
skillInfo.Jumps = 0; skillInfo.Jumps = 0;
else if (isOnGround) else if (isOnGround)
skillInfo.Jumps = 0; skillInfo.Jumps = 0;
else if (!isOnGround && jumpPressed && skillInfo.Jumps < 1) else if (!isOnGround && jumpPressed && skillInfo.Jumps < 1)
{ {
bool lastJumpPressed = (skillInfo.LastButtons & PlayerButtons.Jump) != 0; if (skillInfo.JumpReleasedTicks >= 3 && skillInfo.CanUse)
if (!lastJumpPressed && skillInfo.CanUse)
{ {
skillInfo.Jumps++; skillInfo.Jumps++;
skillInfo.CanUse = false; skillInfo.CanUse = false;
@ -133,29 +135,33 @@ namespace src.player.skills
moveY = 1; moveY = 1;
float moveAngle = MathF.Atan2(moveX, moveY) * (180f / MathF.PI); float moveAngle = MathF.Atan2(moveX, moveY) * (180f / MathF.PI);
QAngle dashAngles = new(0, playerPawn.EyeAngles.Y + moveAngle, 0); QAngle dashAngles = new(0, eventPlayerPawn.EyeAngles.Y + moveAngle, 0);
Vector newVelocity = SkillUtils.GetForwardVector(dashAngles) * SkillsInfo.GetValue<float>(skillName, "pushVelocity"); Vector newVelocity = SkillUtils.GetForwardVector(dashAngles) * SkillsInfo.GetValue<float>(skillName, "pushVelocity");
newVelocity.Z = playerPawn.AbsVelocity.Z + SkillsInfo.GetValue<float>(skillName, "jumpVelocity"); newVelocity.Z = eventPlayerPawn.AbsVelocity.Z + SkillsInfo.GetValue<float>(skillName, "jumpVelocity");
playerPawn.AbsVelocity.X = newVelocity.X; eventPlayerPawn.AbsVelocity.X = newVelocity.X;
playerPawn.AbsVelocity.Y = newVelocity.Y; eventPlayerPawn.AbsVelocity.Y = newVelocity.Y;
playerPawn.AbsVelocity.Z = newVelocity.Z; eventPlayerPawn.AbsVelocity.Z = newVelocity.Z;
} }
} }
skillInfo.LastFlags = flags; skillInfo.WasOnGround = isOnGround;
skillInfo.LastButtons = buttons;
if (!jumpPressed)
skillInfo.JumpReleasedTicks++;
else
skillInfo.JumpReleasedTicks = 0;
} }
public class PlayerSkillInfo public class PlayerSkillInfo
{ {
public ulong SteamID { get; set; } public string? Username { get; set; }
public bool CanUse { get; set; } public bool CanUse { get; set; }
public DateTime Cooldown { get; set; } public DateTime Cooldown { get; set; }
public PlayerFlags LastFlags { get; set; }
public int Jumps { get; set; } public int Jumps { get; set; }
public PlayerButtons LastButtons { get; set; } public bool WasOnGround { get; set; }
public int JumpReleasedTicks { get; set; }
} }
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#42bbfc", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float jumpVelocity = 150f, float pushVelocity = 600f, bool anyDirection = true, float cooldown = 2f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity) public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#42bbfc", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float jumpVelocity = 150f, float pushVelocity = 600f, bool anyDirection = true, float cooldown = 2f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, 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 static src.jRandomSkills; using static src.jRandomSkills;
@ -28,15 +28,15 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); 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.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
ConcurrentBag<(string, string)> menuItems = []; ConcurrentBag<(string, string)> menuItems = [];
foreach (var enemy in enemies) foreach (var enemy in enemies)
{ {
var enemyInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == enemy.SteamID); var enemyInfo = PlayerManager.GetPlayerByIndex(enemy.Index);
if (enemyInfo == null) continue; if (enemyInfo == null) continue;
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill); var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill);
if (skillData == null) continue; if (skillData == null) continue;
@ -50,15 +50,16 @@ namespace src.player.skills
{ {
if (player == null) return; if (player == null) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return; if (playerPawn?.CBodyComponent == null) return;
if (!player.IsValid || !player.PawnIsAlive) return; if (!player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
string enemyId = commands[0]; string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Team != player.Team && p.Index.ToString() == enemyId); if (!uint.TryParse(enemyId, out uint enemyIndex)) { player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("selectplayerskill_incorrect_enemy_index")); return; }
var enemy = Utilities.GetPlayerFromIndex((int)enemyIndex);
if (enemy == null) if (enemy == null)
{ {
@ -71,13 +72,13 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = []; ConcurrentBag<(string, string)> menuItems = [];
foreach (var enemy in enemies) foreach (var enemy in enemies)
{ {
var enemyInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == enemy.SteamID); var enemyInfo = PlayerManager.GetPlayerByIndex(enemy.Index);
if (enemyInfo == null) continue; if (enemyInfo == null) continue;
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill); var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill);
if (skillData == null) continue; if (skillData == null) continue;
@ -91,7 +92,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SpecialSkill = Skills.None; playerInfo.SpecialSkill = Skills.None;
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
@ -99,8 +100,8 @@ namespace src.player.skills
private static void DeacitvateSkill(CCSPlayerController player, CCSPlayerController enemy) private static void DeacitvateSkill(CCSPlayerController player, CCSPlayerController enemy)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
var enemyInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == enemy.SteamID); var enemyInfo = PlayerManager.GetPlayerByIndex(enemy.Index);
if (playerInfo != null) if (playerInfo != null)
{ {

View file

@ -1,8 +1,7 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.UserMessages; using CounterStrikeSharp.API.Modules.UserMessages;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using src.utils; using src.utils;
@ -12,6 +11,7 @@ namespace src.player.skills
{ {
private const Skills skillName = Skills.Deaf; private const Skills skillName = Skills.Deaf;
private static readonly ConcurrentDictionary<uint, byte> deafPlayers = []; private static readonly ConcurrentDictionary<uint, byte> deafPlayers = [];
private static readonly ConcurrentDictionary<uint, uint> playersToTarget = [];
public static void LoadSkill() public static void LoadSkill()
{ {
@ -28,6 +28,8 @@ namespace src.player.skills
} }
deafPlayers.Clear(); deafPlayers.Clear();
playersToTarget.Clear();
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
@ -48,10 +50,10 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); 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.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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);
@ -60,8 +62,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands) public static void TypeSkill(CCSPlayerController player, string[] commands)
{ {
if (player == null || !player.IsValid || !player.PawnIsAlive) return; if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed) if (playerInfo.SkillUsed)
@ -71,7 +73,8 @@ namespace src.player.skills
} }
string enemyId = commands[0]; string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Team != player.Team && p.Index.ToString() == enemyId); if (!uint.TryParse(enemyId, out uint enemyIndex)) { player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("selectplayerskill_incorrect_enemy_index")); return; }
var enemy = Utilities.GetPlayerFromIndex((int)enemyIndex);
if (enemy == null) if (enemy == null)
{ {
@ -80,18 +83,20 @@ namespace src.player.skills
} }
deafPlayers.TryAdd(enemy.Index, 0); deafPlayers.TryAdd(enemy.Index, 0);
playersToTarget[player.Index] = enemy.Index;
playerInfo.SkillUsed = true; playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("deaf_player_info", enemy.PlayerName)); player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("deaf_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("deaf_enemy_info")); enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("deaf_enemy_info"));
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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())));
@ -103,8 +108,19 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
if (playersToTarget.TryRemove(player.Index, out uint targetIndex))
deafPlayers.TryRemove(targetIndex, out _);
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
}
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null || !player.IsValid) return;
deafPlayers.TryRemove(player.Index, out _); deafPlayers.TryRemove(player.Index, out _);
SkillUtils.CloseMenu(player);
} }
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#dae01f", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity) public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#dae01f", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)

View file

@ -17,11 +17,11 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = @event.Userid; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return; if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
if (playerInfo?.Skill == skillName && victim!.PawnIsAlive) if (playerInfo?.Skill == skillName && victim!.PawnIsAlive)
{ {
@ -39,12 +39,12 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
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.IsBot && p != player) ? "tb" : "t"); border: !Utilities.GetPlayers().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 = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float chanceFrom = .2f, float chanceTo = .35f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, 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 = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float chanceFrom = .2f, float chanceTo = .35f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, 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;
@ -31,7 +31,7 @@ namespace src.player.skills
var player = Utilities.GetPlayerFromIndex((int)playerIndex); var player = Utilities.GetPlayerFromIndex((int)playerIndex);
if (player == null || !player.IsValid) continue; if (player == null || !player.IsValid) continue;
var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) continue; if (playerInfo == null) continue;
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;

View file

@ -17,11 +17,11 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = @event.Userid; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return; if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
if (playerInfo?.Skill == skillName && victim!.PawnIsAlive) if (playerInfo?.Skill == skillName && victim!.PawnIsAlive)
HealAttacker(attacker!, @event.DmgHealth); HealAttacker(attacker!, @event.DmgHealth);

View file

@ -1,6 +1,5 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using System.Collections.Concurrent; using System.Collections.Concurrent;
@ -29,18 +28,20 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); 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 != player && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
ConcurrentBag<(string, string)> menuItems = []; ConcurrentBag<(string, string)> menuItems = [];
foreach (var enemy in enemies) foreach (var enemy in enemies)
{ {
var enemyInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == enemy.SteamID); var enemyInfo = PlayerManager.GetPlayerByIndex(enemy.Index);
if (enemyInfo == null) continue; if (enemyInfo == null) continue;
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill); var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill);
if (skillData == null) continue; if (skillData == null) continue;
menuItems.Add(($"{enemy.PlayerName} : {player.GetSkillName(skillData.Skill)}", enemy.Index.ToString())); menuItems.Add(($"{enemy.PlayerName} : {player.GetSkillName(skillData.Skill)}", enemy.Index.ToString()));
} }
SkillUtils.UpdateMenu(player, menuItems); SkillUtils.UpdateMenu(player, menuItems);
@ -51,12 +52,12 @@ namespace src.player.skills
{ {
if (player == null) return; if (player == null) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return; if (playerPawn?.CBodyComponent == null) return;
if (!player.IsValid || !player.PawnIsAlive) return; if (!player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
string enemyId = commands[0]; string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Index.ToString() == enemyId); var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Index.ToString() == enemyId);
@ -72,14 +73,14 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p != player && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p != player && p.IsValid && !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 = [];
ConcurrentBag<(string, string)> menuItems = []; ConcurrentBag<(string, string)> menuItems = [];
foreach (var enemy in enemies) foreach (var enemy in enemies)
{ {
var enemyInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == enemy.SteamID); var enemyInfo = PlayerManager.GetPlayerByIndex(enemy.Index);
if (enemyInfo == null) continue; if (enemyInfo == null) continue;
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill); var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill);
if (skillData == null) continue; if (skillData == null) continue;
@ -89,6 +90,7 @@ namespace src.player.skills
int ctSkills = Event.counterterroristSkills.Count(s => skills.Contains(s.Name)); int ctSkills = Event.counterterroristSkills.Count(s => skills.Contains(s.Name));
int ttSkills = Event.terroristSkills.Count(s => skills.Contains(s.Name)); int ttSkills = Event.terroristSkills.Count(s => skills.Contains(s.Name));
if ((player.Team == CsTeam.Terrorist && ctSkills == skills.Count) || (player.Team == CsTeam.CounterTerrorist && ttSkills == skills.Count)) if ((player.Team == CsTeam.Terrorist && ctSkills == skills.Count) || (player.Team == CsTeam.CounterTerrorist && ttSkills == skills.Count))
{ {
Event.SetRandomSkill(player); Event.SetRandomSkill(player);
@ -97,7 +99,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.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t"); border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
else else
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("selectplayerskill_incorrect_enemy_index")}"); player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("selectplayerskill_incorrect_enemy_index")}");
@ -105,7 +107,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SpecialSkill = Skills.None; playerInfo.SpecialSkill = Skills.None;
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
@ -113,27 +115,27 @@ namespace src.player.skills
private static void DuplicateSkill(CCSPlayerController player, CCSPlayerController enemy) private static void DuplicateSkill(CCSPlayerController player, CCSPlayerController enemy)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
var enemyInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == enemy.SteamID); var enemyInfo = PlayerManager.GetPlayerByIndex(enemy.Index);
if (playerInfo == null || enemyInfo == null) return; if (playerInfo == null || enemyInfo == null) return;
var enemySkill = enemyInfo.Skill; var enemySkill = enemyInfo.Skill;
bool ctSkill = Event.counterterroristSkills.Any(s => s.Name == enemySkill.ToString()); bool ctSkill = Event.counterterroristSkills.Any(s => s.Name == enemySkill.ToString());
bool ttSkill = Event.terroristSkills.Any(s => s.Name == enemySkill.ToString()); bool ttSkill = Event.terroristSkills.Any(s => s.Name == enemySkill.ToString());
ulong steamID = player.SteamID; uint playerIndex = player.Index;
string enemyName = enemy.PlayerName; string enemyName = enemy.PlayerName;
if ((player.Team == CsTeam.Terrorist && ctSkill) || (player.Team == CsTeam.CounterTerrorist && ttSkill)) if ((player.Team == CsTeam.Terrorist && ctSkill) || (player.Team == CsTeam.CounterTerrorist && ttSkill))
{ {
Instance.AddTimer(.1f, () => Instance.AddTimer(.1f, () =>
{ {
var player = Utilities.GetPlayerFromSteamId(steamID); var player = Utilities.GetPlayerFromIndex((int)playerIndex);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
Instance.SkillAction(skillName.ToString(), "EnableSkill", [player]); Instance.SkillAction(skillName.ToString(), "EnableSkill", [player]);
player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("thief_incorrect_skill", enemyName)); player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("thief_incorrect_skill", enemyName));
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
return; return;
} }
@ -146,15 +148,16 @@ namespace src.player.skills
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.GetPlayerFromSteamId(steamID); var player = Utilities.GetPlayerFromIndex((int)playerIndex);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID && p.Skill == enemySkill) == null) return; var dupInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (dupInfo == null || dupInfo.Skill != enemySkill) return;
Instance?.SkillAction(enemySkill.ToString(), "EnableSkill", [player]); Instance?.SkillAction(enemySkill.ToString(), "EnableSkill", [player]);
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
else else
Instance?.SkillAction(enemySkill.ToString(), "EnableSkill", [player]); Instance?.SkillAction(enemySkill.ToString(), "EnableSkill", [player]);
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("duplicator_player_info", enemy.PlayerName)); player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("duplicator_player_info", enemy.PlayerName));
} }

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;
@ -26,7 +26,7 @@ namespace src.player.skills
public static unsafe void EnableSkill(CCSPlayerController player) public static unsafe void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
var playerPawn = player.PlayerPawn?.Value; var playerPawn = player.PlayerPawn?.Value;
@ -38,13 +38,13 @@ 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.IsBot && p != player) ? "tb" : "t"); border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
var playerPawn = player.PlayerPawn?.Value; var playerPawn = player.PlayerPawn?.Value;

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;
@ -9,136 +9,133 @@ namespace src.player.skills
{ {
public class Earthquake : ISkill public class Earthquake : ISkill
{ {
private const Skills skillName = Skills.Earthquake; //private const Skills skillName = Skills.Earthquake;
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = []; //private static readonly ConcurrentDictionary<uint, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new(); //private static readonly object setLock = new();
public static void LoadSkill() //public static void LoadSkill()
{ //{
// SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color")); // SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
} //}
public static void NewRound() //public static void NewRound()
{ //{
lock (setLock) // lock (setLock)
SkillPlayerInfo.Clear(); // SkillPlayerInfo.Clear();
} //}
public static void EnableSkill(CCSPlayerController player) //public static void EnableSkill(CCSPlayerController player)
{ //{
SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo // SkillPlayerInfo.TryAdd(player.Index, new PlayerSkillInfo
{ // {
SteamID = player.SteamID, // SteamID = player.Index,
CanUse = true, // CanUse = true,
Cooldown = DateTime.MinValue, // Cooldown = DateTime.MinValue,
}); // });
} //}
public static void DisableSkill(CCSPlayerController player) //public static void DisableSkill(CCSPlayerController player)
{ //{
SkillPlayerInfo.TryRemove(player.SteamID, out _); // SkillPlayerInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player); // SkillUtils.ResetPrintHTML(player);
} //}
public static void PlayerDeath(EventPlayerDeath @event) //public static void PlayerDeath(EventPlayerDeath @event)
{ //{
var player = @event.Userid; // var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; // if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); // var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) // if (playerInfo?.Skill == skillName)
SkillPlayerInfo.TryRemove(player.SteamID, out _); // SkillPlayerInfo.TryRemove(player.Index, out _);
} //}
public static void OnTick() //public static void OnTick()
{ //{
foreach (var player in Utilities.GetPlayers()) // foreach (var player in Utilities.GetPlayers())
{ // {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); // var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) // if (playerInfo?.Skill == skillName)
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) // if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
UpdateHUD(player, skillInfo); // UpdateHUD(player, skillInfo);
} // }
} //}
private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) //private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo)
{ //{
float cooldown = 0; // float cooldown = 0;
if (skillInfo != null) // if (skillInfo != null)
{ // {
float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue<float>(skillName, "cooldown")) - DateTime.Now).TotalSeconds); // float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue<float>(skillName, "cooldown")) - DateTime.Now).TotalSeconds);
cooldown = Math.Max(time, 0); // cooldown = Math.Max(time, 0);
if (cooldown == 0 && skillInfo?.CanUse == false) // if (cooldown == 0 && skillInfo?.CanUse == false)
skillInfo.CanUse = true; // skillInfo.CanUse = true;
} // }
if (cooldown == 0) // if (cooldown == 0)
return; // return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); // var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; // if (playerInfo == null) return;
string remainingLine = $"{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}"; // string remainingLine = $"{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
} //}
public static void UseSkill(CCSPlayerController player) //public static void UseSkill(CCSPlayerController player)
{ //{
var playerPawn = player.PlayerPawn.Value; // var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return; // if (playerPawn?.CBodyComponent == null) return;
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) // if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
{ // {
if (!player.IsValid || !player.PawnIsAlive) return; // if (!player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
if (skillInfo.CanUse) // if (skillInfo.CanUse)
{ // {
skillInfo.CanUse = false; // skillInfo.CanUse = false;
skillInfo.Cooldown = DateTime.Now; // skillInfo.Cooldown = DateTime.Now;
MakeShake(player); // MakeShake(player);
} // }
} // }
} //}
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 Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.PawnIsAlive))
CreateShake(player); // CreateShake(player);
} //}
private static void CreateShake(CCSPlayerController player) //private static void CreateShake(CCSPlayerController player)
{ //{
var pawn = player.PlayerPawn.Value; // var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return; // if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
var shake = Utilities.CreateEntityByName<CEnvShake>("env_shake"); // var shake = EntityManager.CreateTrackedEnvShake(player.Index);
if (shake == null) return; // if (shake == null || !shake.IsValid) return;
shake.DispatchSpawn(); // shake.Amplitude = SkillsInfo.GetValue<float>(skillName, "amplitude");
if (!shake.IsValid) return; // shake.Frequency = SkillsInfo.GetValue<float>(skillName, "frequency");
// shake.Duration = SkillsInfo.GetValue<float>(skillName, "duration");
shake.Amplitude = SkillsInfo.GetValue<float>(skillName, "amplitude"); // shake.Radius = SkillsInfo.GetValue<float>(skillName, "radius");
shake.Frequency = SkillsInfo.GetValue<float>(skillName, "frequency");
shake.Duration = SkillsInfo.GetValue<float>(skillName, "duration"); // shake.Teleport(new Vector(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z));
shake.Radius = SkillsInfo.GetValue<float>(skillName, "radius"); // shake.AcceptInput("SetParent", pawn, pawn, "!activator");
// shake.AcceptInput("StartShake");
shake.Teleport(new Vector(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z)); //}
shake.AcceptInput("SetParent", pawn, pawn, "!activator");
shake.AcceptInput("StartShake"); //public class PlayerSkillInfo
} //{
// public ulong SteamID { get; set; }
public class PlayerSkillInfo // public bool CanUse { get; set; }
{ // public DateTime Cooldown { get; set; }
public ulong SteamID { get; set; } //}
public bool CanUse { get; set; }
public DateTime Cooldown { get; set; } //public class SkillConfig(Skills skill = skillName, bool active = false, string color = "#42f59b", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float cooldown = 16f, float amplitude = 15f, float frequency = 500f, float duration = 8f, float radius = 50f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
} //{
// public float Cooldown { get; set; } = cooldown;
public class SkillConfig(Skills skill = skillName, bool active = false, string color = "#42f59b", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float cooldown = 16f, float amplitude = 15f, float frequency = 500f, float duration = 8f, float radius = 50f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity) // public float Amplitude { get; set; } = amplitude;
{ // public float Frequency { get; set; } = frequency;
public float Cooldown { get; set; } = cooldown; // public float Duration { get; set; } = duration;
public float Amplitude { get; set; } = amplitude; // public float Radius { get; set; } = radius;
public float Frequency { get; set; } = frequency; //}
public float Duration { get; set; } = duration;
public float Radius { get; set; } = radius;
}
} }
} }

View file

@ -1,7 +1,6 @@
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 System.Collections.Concurrent; using System.Collections.Concurrent;
using src.utils; using src.utils;
@ -10,7 +9,7 @@ namespace src.player.skills
public class EnemySpawn : ISkill public class EnemySpawn : ISkill
{ {
private const Skills skillName = Skills.EnemySpawn; private const Skills skillName = Skills.EnemySpawn;
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = []; private static readonly ConcurrentDictionary<uint, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
public static void LoadSkill() public static void LoadSkill()
@ -29,9 +28,9 @@ namespace src.player.skills
if (SkillUtils.IsFreezeTime()) return; if (SkillUtils.IsFreezeTime()) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
UpdateHUD(player, skillInfo); UpdateHUD(player, skillInfo);
} }
} }
@ -39,9 +38,9 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var cooldownBeforeUse = SkillsInfo.GetValue<float>(skillName, "cooldownBeforeUse"); var cooldownBeforeUse = SkillsInfo.GetValue<float>(skillName, "cooldownBeforeUse");
SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo SkillPlayerInfo.TryAdd(player.Index, new PlayerSkillInfo
{ {
SteamID = player.SteamID, SteamID = player.Index,
CanUse = false, CanUse = false,
Cooldown = cooldownBeforeUse <= 0 ? DateTime.MinValue : Event.GetFreezeTimeEnd().AddSeconds(cooldownBeforeUse - SkillsInfo.GetValue<float>(skillName, "cooldown")), Cooldown = cooldownBeforeUse <= 0 ? DateTime.MinValue : Event.GetFreezeTimeEnd().AddSeconds(cooldownBeforeUse - SkillsInfo.GetValue<float>(skillName, "cooldown")),
}); });
@ -49,7 +48,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryRemove(player.SteamID, out _); SkillPlayerInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player); SkillUtils.ResetPrintHTML(player);
} }
@ -65,7 +64,7 @@ namespace src.player.skills
skillInfo.CanUse = true; skillInfo.CanUse = true;
} }
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
if (cooldown == 0) if (cooldown == 0)
@ -79,9 +78,9 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return; if (playerPawn?.CBodyComponent == null) return;
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
{ {
if (!player.IsValid || !player.PawnIsAlive) return; if (!player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
if (skillInfo.CanUse) if (skillInfo.CanUse)
{ {
skillInfo.CanUse = false; skillInfo.CanUse = false;

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;
@ -21,14 +21,14 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
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.IsBot && p != player) ? "tb" : "t"); border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
private static void SpawnExplosion(Vector vector) private static void SpawnExplosion(Vector vector)
@ -64,12 +64,12 @@ namespace src.player.skills
{ {
if (lastTick == Server.TickCount) return; if (lastTick == Server.TickCount) return;
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var pos = new Vector(@event.X, @event.Y, @event.Z); var pos = new Vector(@event.X, @event.Y, @event.Z);
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) return; if (playerInfo == null || playerInfo.Skill != skillName) return;
if (Instance.Random.NextDouble() <= playerInfo.SkillChance) if (Instance.Random.NextDouble() <= playerInfo.SkillChance)

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.Drawing; using System.Drawing;
@ -11,7 +11,7 @@ namespace src.player.skills
public class FalconEye : ISkill public class FalconEye : ISkill
{ {
private const Skills skillName = Skills.FalconEye; private const Skills skillName = Skills.FalconEye;
private static readonly ConcurrentDictionary<ulong, (uint, uint)> cameras = []; private static readonly ConcurrentDictionary<uint, (uint, uint)> cameras = [];
public static void LoadSkill() public static void LoadSkill()
{ {
@ -21,28 +21,23 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
foreach (var cameraIndex in cameras.Values) foreach (var cameraIndex in cameras.Values)
{ EntityManager.DestroyEntity(cameraIndex.Item2);
var camera = Utilities.GetEntityFromIndex<CDynamicProp>((int)cameraIndex.Item2);
if (camera == null || !camera.IsValid) continue;
camera.AcceptInput("Kill");
}
cameras.Clear(); cameras.Clear();
} }
public static void WeaponPickup(EventItemPickup @event) public static void WeaponPickup(EventItemPickup @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(player)) return; if (!Instance.IsPlayerValid(player)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); 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;
if (cameras.TryGetValue(player!.SteamID, out var cameraInfo) && cameraInfo.Item1 == pawn.CameraServices.ViewEntity.Raw) if (cameras.TryGetValue(player!.Index, out var cameraInfo) && cameraInfo.Item1 == pawn.CameraServices.ViewEntity.Raw)
BlockWeapon(player, true); BlockWeapon(player, true);
} }
@ -55,13 +50,15 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
if (player == null) return;
ChangeCamera(player, true); ChangeCamera(player, true);
EntityManager.DestroyPlayerEntities(player.Index);
} }
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
if (cameras.TryGetValue(player.SteamID, 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;
@ -88,7 +85,7 @@ namespace src.player.skills
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;
if (cameras.TryGetValue(player.SteamID, out var cameraInfo) && cameraInfo.Item2 != 0) if (cameras.TryGetValue(player.Index, out var cameraInfo) && cameraInfo.Item2 != 0)
{ {
orginalCameraRaw = cameraInfo.Item1; orginalCameraRaw = cameraInfo.Item1;
@ -114,7 +111,7 @@ namespace src.player.skills
private static uint CreateCamera(CCSPlayerController player) private static uint CreateCamera(CCSPlayerController player)
{ {
var camera = Utilities.CreateEntityByName<CDynamicProp>("prop_dynamic"); var camera = EntityManager.CreateTrackedDynamicProp(player.Index);
if (camera == null || !camera.IsValid) return 0; if (camera == null || !camera.IsValid) return 0;
var pawn = player.PlayerPawn.Value; var pawn = player.PlayerPawn.Value;
@ -124,13 +121,14 @@ 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));
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));
camera.DispatchSpawn(); camera.DispatchSpawn();
}); });
cameras.AddOrUpdate(player.SteamID, (pawn.CameraServices!.ViewEntity.Raw, camera.Index), (k, v) => (pawn.CameraServices!.ViewEntity.Raw, camera.Index)); cameras.AddOrUpdate(player.Index, (pawn.CameraServices!.ViewEntity.Raw, camera.Index), (k, v) => (pawn.CameraServices!.ViewEntity.Raw, camera.Index));
return camera.EntityHandle.Raw; return camera.EntityHandle.Raw;
} }

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,9 +20,9 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return; if (playerPawn?.CBodyComponent == null) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (!player.IsValid || !player.PawnIsAlive) return; if (!player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
InstaReload(playerPawn); InstaReload(playerPawn);
} }

View file

@ -11,7 +11,7 @@ namespace src.player.skills
public class Flash : ISkill public class Flash : ISkill
{ {
private const Skills skillName = Skills.Flash; private const Skills skillName = Skills.Flash;
public static readonly ConcurrentDictionary<ulong, int> jumpedPlayers = []; public static readonly ConcurrentDictionary<uint, int> jumpedPlayers = [];
public static void LoadSkill() public static void LoadSkill()
{ {
@ -34,7 +34,7 @@ namespace src.player.skills
var player = Utilities.GetPlayers().FirstOrDefault(p => p.Pawn?.Value != null && p.Pawn.Value.IsValid && p.Pawn.Value.Index == userIndex); var player = Utilities.GetPlayers().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 = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (player!.Buttons.HasFlag(PlayerButtons.Speed) || player.Buttons.HasFlag(PlayerButtons.Duck)) if (player!.Buttons.HasFlag(PlayerButtons.Speed) || player.Buttons.HasFlag(PlayerButtons.Duck))
@ -43,26 +43,26 @@ namespace src.player.skills
public static void PlayerJump(EventPlayerJump @event) public static void PlayerJump(EventPlayerJump @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
if (!jumpedPlayers.TryGetValue(player.SteamID, out _)) return; if (!jumpedPlayers.TryGetValue(player.Index, out _)) return;
jumpedPlayers.AddOrUpdate(player.SteamID, Server.TickCount + 20, (k, v) => Server.TickCount + 20); jumpedPlayers.AddOrUpdate(player.Index, Server.TickCount + 20, (k, v) => Server.TickCount + 20);
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerPawn == null || playerInfo == null) return; if (playerPawn == null || playerInfo == null) return;
float newSpeed = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom"); float newSpeed = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
newSpeed = (float)Math.Round(newSpeed, 2); newSpeed = (float)Math.Round(newSpeed, 2);
playerInfo.SkillChance = newSpeed; playerInfo.SkillChance = newSpeed;
jumpedPlayers.TryAdd(player.SteamID, 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.IsBot && p != player) ? "tb" : "t"); border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
@ -70,7 +70,7 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null) return; if (playerPawn == null) return;
playerPawn.VelocityModifier = 1; playerPawn.VelocityModifier = 1;
jumpedPlayers.TryRemove(player.SteamID, out _); jumpedPlayers.TryRemove(player.Index, out _);
} }
public static void OnTick() public static void OnTick()
@ -79,7 +79,7 @@ namespace src.player.skills
{ {
if (!Instance.IsPlayerValid(player)) continue; if (!Instance.IsPlayerValid(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) continue; if (playerInfo?.Skill != skillName) continue;
var playerPawn = player.PlayerPawn?.Value; var playerPawn = player.PlayerPawn?.Value;
@ -90,7 +90,7 @@ namespace src.player.skills
if (buttons.HasFlag(PlayerButtons.Moveleft) || buttons.HasFlag(PlayerButtons.Moveright) || buttons.HasFlag(PlayerButtons.Forward) || buttons.HasFlag(PlayerButtons.Back)) if (buttons.HasFlag(PlayerButtons.Moveleft) || buttons.HasFlag(PlayerButtons.Moveright) || buttons.HasFlag(PlayerButtons.Forward) || buttons.HasFlag(PlayerButtons.Back))
playerPawn.VelocityModifier = newVelocity; playerPawn.VelocityModifier = newVelocity;
if (jumpedPlayers.TryGetValue(player.SteamID, out var time) && time > Server.TickCount) if (jumpedPlayers.TryGetValue(player.Index, out var time) && time > Server.TickCount)
continue; continue;
if (!((PlayerFlags)player.Flags).HasFlag(PlayerFlags.FL_ONGROUND)) if (!((PlayerFlags)player.Flags).HasFlag(PlayerFlags.FL_ONGROUND))

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
@ -11,8 +11,9 @@ namespace src.player.skills
public class Fortnite : ISkill public class Fortnite : ISkill
{ {
private const Skills skillName = Skills.Fortnite; private const Skills skillName = Skills.Fortnite;
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = []; private static readonly ConcurrentDictionary<uint, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly ConcurrentDictionary<ulong, int> barricades = []; private static readonly ConcurrentDictionary<uint, int> barricades = [];
public static bool skillInThisRound = false;
private static readonly object setLock = new(); private static readonly object setLock = new();
public static void LoadSkill() public static void LoadSkill()
@ -23,6 +24,7 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
skillInThisRound = false;
lock (setLock) lock (setLock)
{ {
SkillPlayerInfo.Clear(); SkillPlayerInfo.Clear();
@ -34,18 +36,19 @@ namespace src.player.skills
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
UpdateHUD(player, skillInfo); UpdateHUD(player, skillInfo);
} }
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo skillInThisRound = true;
SkillPlayerInfo.TryAdd(player.Index, new PlayerSkillInfo
{ {
SteamID = player.SteamID, SteamID = player.Index,
CanUse = true, CanUse = true,
Cooldown = DateTime.MinValue, Cooldown = DateTime.MinValue,
}); });
@ -53,7 +56,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryRemove(player.SteamID, out _); SkillPlayerInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player); SkillUtils.ResetPrintHTML(player);
} }
@ -69,7 +72,7 @@ namespace src.player.skills
skillInfo.CanUse = true; skillInfo.CanUse = true;
} }
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
if (cooldown == 0) if (cooldown == 0)
@ -83,9 +86,10 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return; if (playerPawn?.CBodyComponent == null) return;
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
{ {
if (!player.IsValid || !player.PawnIsAlive) return; if (!player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
if (skillInfo.CanUse) if (skillInfo.CanUse)
{ {
skillInfo.CanUse = false; skillInfo.CanUse = false;
@ -98,7 +102,7 @@ namespace src.player.skills
private static void CreateBox(CCSPlayerController player) private static void CreateBox(CCSPlayerController player)
{ {
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
var box = Utilities.CreateEntityByName<CDynamicProp>("prop_dynamic_override"); var box = EntityManager.CreateTrackedPropOverride(player.Index);
if (box == null || playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null || playerPawn.AbsRotation == null) return; if (box == null || playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null || playerPawn.AbsRotation == null) return;
float distance = 50; float distance = 50;
@ -140,12 +144,12 @@ namespace src.player.skills
if (newHealth <= 0) if (newHealth <= 0)
{ {
barricades.TryRemove(box.Index, out _); barricades.TryRemove(box.Index, out _);
box.AcceptInput("Kill"); EntityManager.DestroyEntity(box.Index);
} }
else else
barricades.AddOrUpdate(box.Index, newHealth, (k, v) => newHealth); barricades.AddOrUpdate(box.Index, newHealth, (k, v) => newHealth);
} }
else box.AcceptInput("Kill"); else EntityManager.DestroyEntity(box.Index);
} }
public class PlayerSkillInfo public class PlayerSkillInfo

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;
@ -40,7 +40,7 @@ namespace src.player.skills
plantedC4 = null; plantedC4 = null;
var plantedBomb = Utilities.FindAllEntitiesByDesignerName<CPlantedC4>("planted_c4").FirstOrDefault(); var plantedBomb = Utilities.FindAllEntitiesByDesignerName<CPlantedC4>("planted_c4").FirstOrDefault();
if (plantedBomb != null && plantedBomb.IsValid) if (plantedBomb != null && plantedBomb.IsValid)
plantedBomb.AcceptInput("Kill"); plantedBomb.AddEntityIOEvent("Kill", plantedBomb, delay: 0.1f);
SkillUtils.TerminateRound(CsTeam.CounterTerrorist); SkillUtils.TerminateRound(CsTeam.CounterTerrorist);
} }
@ -48,12 +48,12 @@ namespace src.player.skills
{ {
if (lastTick == Server.TickCount) return; if (lastTick == Server.TickCount) return;
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid || plantedC4 == null) return; if (player == null || !player.IsValid || plantedC4 == null) return;
var pos = new Vector(@event.X, @event.Y, @event.Z); var pos = new Vector(@event.X, @event.Y, @event.Z);
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) return; if (playerInfo == null || playerInfo.Skill != skillName) return;
if (SkillUtils.Distance(plantedC4, pos) >= 8) if (SkillUtils.Distance(plantedC4, pos) >= 8)

View file

@ -1,6 +1,5 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Cvars;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using static src.jRandomSkills; using static src.jRandomSkills;
@ -20,15 +19,14 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var damage = @event.DmgHealth; var damage = @event.DmgHealth;
var victim = @event.Userid; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var weapon = @event.Weapon; var weapon = @event.Weapon;
HitGroup_t hitgroup = (HitGroup_t)@event.Hitgroup;
if (nades.Contains(weapon)) return; if (nades.Contains(weapon)) return;
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return; if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
if (playerInfo?.Skill != skillName || attacker!.Team != victim!.Team) return; if (playerInfo?.Skill != skillName || attacker!.Team != victim!.Team) return;
Server.ExecuteCommand("mp_autokick 0"); Server.ExecuteCommand("mp_autokick 0");

View file

@ -1,10 +1,9 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills namespace src.player.skills
{ {
@ -25,10 +24,10 @@ namespace src.player.skills
public static void DecoyStarted(EventDecoyStarted @event) public static void DecoyStarted(EventDecoyStarted @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
decoys.TryAdd(new Vector(@event.X, @event.Y, @event.Z), 0); decoys.TryAdd(new Vector(@event.X, @event.Y, @event.Z), 0);
@ -36,10 +35,10 @@ namespace src.player.skills
public static void DecoyDetonate(EventDecoyDetonate @event) public static void DecoyDetonate(EventDecoyDetonate @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
foreach (var decoy in decoys.Keys.Where(v => v.X == @event.X && v.Y == @event.Y && v.Z == @event.Z)) foreach (var decoy in decoys.Keys.Where(v => v.X == @event.X && v.Y == @event.Y && v.Z == @event.Z))
@ -49,11 +48,16 @@ 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.PawnIsAlive && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist)) foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist))
{ {
var eventPlayer = PlayerManager.GetPlayerEvent(player);
if (eventPlayer == null || !eventPlayer.IsValid) continue;
var decoyRadius = SkillsInfo.GetValue<float>(skillName, "triggerRadius"); var decoyRadius = SkillsInfo.GetValue<float>(skillName, "triggerRadius");
var pawn = player.PlayerPawn.Value;
var pawn = eventPlayer.PlayerPawn.Value;
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) if (distance <= decoyRadius)
{ {

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;
@ -24,11 +24,11 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands) public static void TypeSkill(CCSPlayerController player, string[] commands)
{ {
if (player == null || !player.IsValid || !player.PawnIsAlive) return; if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
ulong steamID = player.SteamID; uint playerIndex = player.Index;
if (playerInfo.SkillUsed) if (playerInfo.SkillUsed)
{ {
@ -58,15 +58,16 @@ namespace src.player.skills
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.GetPlayerFromSteamId(steamID); var player = Utilities.GetPlayerFromIndex((int)playerIndex);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == steamID && p.Skill == skill.Skill) == null) return; var pi = PlayerManager.GetPlayerByIndex(playerIndex);
if (pi == null || pi.Skill != skill.Skill) return;
Instance?.SkillAction(skill.Skill.ToString(), "EnableSkill", [player]); Instance?.SkillAction(skill.Skill.ToString(), "EnableSkill", [player]);
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
else else
Instance?.SkillAction(skill.Skill.ToString(), "EnableSkill", [player]); Instance?.SkillAction(skill.Skill.ToString(), "EnableSkill", [player]);
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
} }
private static bool TakeMoney(CCSPlayerController player) private static bool TakeMoney(CCSPlayerController player)
@ -86,7 +87,7 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
@ -107,13 +108,13 @@ namespace src.player.skills
private static List<jSkill_SkillInfo> GetSkills(CCSPlayerController player) private static List<jSkill_SkillInfo> GetSkills(CCSPlayerController player)
{ {
var skillPlayer = Instance?.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var skillPlayer = PlayerManager.GetPlayerByIndex(player!.Index);
if (skillPlayer == null) return [Event.noneSkill]; if (skillPlayer == null) return [Event.noneSkill];
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.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator).Count == 1) if (Utilities.GetPlayers().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

@ -5,6 +5,7 @@ using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Drawing;
using static src.jRandomSkills; using static src.jRandomSkills;
namespace src.player.skills namespace src.player.skills
@ -26,11 +27,13 @@ namespace src.player.skills
]; ];
private static readonly ConcurrentDictionary<uint, byte> invisiblePlayers = []; private static readonly ConcurrentDictionary<uint, byte> invisiblePlayers = [];
private const string bloodParticle = "particles/blood_impact/blood_impact_high.vpcf"; private const string bloodParticle = "particles/blood_impact/blood_impact_high.vpcf";
private const string cameraViewModel = "models/sprays/spray_plane.vmdl";
public static void LoadSkill() public static void LoadSkill()
{ {
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color")); SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
Instance.AddToManifest(bloodParticle); Instance.AddToManifest(bloodParticle);
Instance.AddToManifest(cameraViewModel);
} }
public static void NewRound() public static void NewRound()
@ -42,9 +45,9 @@ namespace src.player.skills
public static void WeaponPickup(EventItemPickup @event) public static void WeaponPickup(EventItemPickup @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(player)) return; if (!Instance.IsPlayerValid(player)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
SetWeaponAttack(player!, true); SetWeaponAttack(player!, true);
@ -52,9 +55,9 @@ namespace src.player.skills
public static void WeaponEquip(EventItemEquip @event) public static void WeaponEquip(EventItemEquip @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(player)) return; if (!Instance.IsPlayerValid(player)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
SetWeaponAttack(player!, true); SetWeaponAttack(player!, true);
@ -64,7 +67,7 @@ namespace src.player.skills
{ {
foreach (var (info, player) in infoList) foreach (var (info, player) in infoList)
{ {
if (player == null || !player.IsValid) continue; if (player == null || !player.IsValid || player.Team == CsTeam.Spectator) continue;
var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero; var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero;
bool isObservingGhost = false; bool isObservingGhost = false;
@ -72,14 +75,17 @@ namespace src.player.skills
if (targetHandle != nint.Zero) if (targetHandle != nint.Zero)
{ {
var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle); var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle);
var targetInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == target?.SteamID); var targetInfo = PlayerManager.GetPlayerByIndex(target?.Index);
if (targetInfo?.Skill == skillName) isObservingGhost = true; if (targetInfo?.Skill == skillName) isObservingGhost = true;
} }
foreach (var playerIndex in invisiblePlayers.Keys) foreach (var playerIndex in invisiblePlayers.Keys)
{ {
var playerController = Utilities.GetPlayerFromIndex((int)playerIndex); var playerController = Utilities.GetPlayerFromIndex((int)playerIndex);
if (playerController == null || !playerController.IsValid || playerController.SteamID == player.SteamID) if (playerController == null || !playerController.IsValid || playerController.Index == player.Index)
continue;
if (player.Team == playerController.Team)
continue; continue;
if (!isObservingGhost) if (!isObservingGhost)
@ -108,48 +114,92 @@ namespace src.player.skills
{ {
Event.EnableTransmit(); Event.EnableTransmit();
SetWeaponAttack(player, true); SetWeaponAttack(player, true);
SkillUtils.SetPlayerInvisibility(player, .5f);
invisiblePlayers.TryAdd(player.Index, 0); invisiblePlayers.TryAdd(player.Index, 0);
if (EntityManager.GetPlayerEntities(player.Index, "empty_prop").Count == 0)
CreatePlayerPosProp(player);
}
private static void CreatePlayerPosProp(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
var emptyProp = EntityManager.CreateTrackedDynamicProp(player.Index);
if (emptyProp == null || !emptyProp.IsValid) return;
var playerPawn = player.PlayerPawn?.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null || playerPawn.AbsRotation == null) return;
emptyProp.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(emptyProp.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
emptyProp.SetModel(cameraViewModel);
emptyProp.Render = Color.FromArgb(1, 255, 255, 255);
Vector newPos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 30);
QAngle newAngle = new(playerPawn.AbsRotation.X, playerPawn.AbsRotation.Y, playerPawn.AbsRotation.Z);
emptyProp.Teleport(newPos, newAngle);
emptyProp.DispatchSpawn();
Utilities.SetStateChanged(emptyProp, "CBaseEntity", "m_CBodyComponent");
EntityManager.RegisterExisting(emptyProp, player.Index, "empty_prop");
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
SkillUtils.ResetPrintHTML(player); SkillUtils.ResetPrintHTML(player);
SetWeaponAttack(player, false); SetWeaponAttack(player, false);
SkillUtils.SetPlayerInvisibility(player, 0);
invisiblePlayers.TryRemove(player.Index, out _); invisiblePlayers.TryRemove(player.Index, out _);
EntityManager.DestroyPlayerEntities(player.Index);
} }
public static void OnTick() public static void OnTick()
{ {
if (Server.TickCount % 2 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
UpdateHUD(player); UpdateHUD(player);
if (!player.PawnIsAlive) if (player.LifeState != (byte)LifeState_t.LIFE_ALIVE)
invisiblePlayers.TryRemove(player.Index, out _); invisiblePlayers.TryRemove(player.Index, out _);
if (!invisiblePlayers.ContainsKey(player.Index)) continue;
var props = EntityManager.GetPlayerEntities(player.Index, "empty_prop");
if (props.Count == 0) continue;
var prop = Utilities.GetEntityFromIndex<CDynamicProp>((int)props[0]);
if (prop == null || !prop.IsValid) continue;
var pawn = player.PlayerPawn?.Value;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue;
Vector newPos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + 30);
QAngle newAngle = new(0, pawn.V_angle.Y, 0);
prop.Teleport(newPos, newAngle, null);
} }
} }
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
if (!invisiblePlayers.ContainsKey(player.Index)) return; if (!invisiblePlayers.ContainsKey(player.Index)) return;
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return; if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return;
CParticleSystem particle = Utilities.CreateEntityByName<CParticleSystem>("info_particle_system")!; var particle = EntityManager.CreateTrackedParticleSystem(player.Index, bloodParticle, autoDestroySeconds: 3f);
if (particle == null) return; if (particle == null) return;
particle.EffectName = bloodParticle;
particle.StartActive = true;
Vector pos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 50); Vector pos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 50);
particle.Teleport(pos); particle.Teleport(pos);
particle.DispatchSpawn();
particle.AcceptInput("Start"); particle.AcceptInput("Start");
} }
@ -177,7 +227,7 @@ namespace src.player.skills
var pawn = player.PlayerPawn.Value; var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.WeaponServices == null) return; if (pawn == null || !pawn.IsValid || pawn.WeaponServices == null) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
var weapon = pawn.WeaponServices.ActiveWeapon.Value; var weapon = pawn.WeaponServices.ActiveWeapon.Value;

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.Constants; using CounterStrikeSharp.API.Modules.Entities.Constants;
@ -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) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
var observedPlayer = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == player?.Pawn?.Value?.ObserverServices?.ObserverTarget?.Value?.Handle); var observedPlayer = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == player?.Pawn?.Value?.ObserverServices?.ObserverTarget?.Value?.Handle);
var observerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == observedPlayer?.SteamID); 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;
foreach (var entityIndex in smokes.Keys) foreach (var entityIndex in smokes.Keys)

View file

@ -1,16 +1,17 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Commands.Targeting;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils; using src.utils;
using System.Collections.Concurrent;
namespace src.player.skills namespace src.player.skills
{ {
public class Glitch : ISkill public class Glitch : ISkill
{ {
private const Skills skillName = Skills.Glitch; private const Skills skillName = Skills.Glitch;
private static readonly ConcurrentDictionary<CCSPlayerController, byte> glitchedPlayers = []; private static readonly ConcurrentDictionary<uint, byte> glitchedPlayers = [];
private static readonly ConcurrentDictionary<uint, uint> playersToTarget = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
public static void LoadSkill() public static void LoadSkill()
@ -21,30 +22,28 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
lock (setLock) lock (setLock)
glitchedPlayers.Clear(); {
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
DisableSkill(player); DisableSkill(player);
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
glitchedPlayers.Clear();
playersToTarget.Clear();
}
} }
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null) return;
DisableSkill(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 Utilities.GetPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); 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.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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);
@ -53,8 +52,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands) public static void TypeSkill(CCSPlayerController player, string[] commands)
{ {
if (player == null || !player.IsValid || !player.PawnIsAlive) return; if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed) if (playerInfo.SkillUsed)
@ -64,7 +63,8 @@ namespace src.player.skills
} }
string enemyId = commands[0]; string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Team != player.Team && p.Index.ToString() == enemyId); if (!uint.TryParse(enemyId, out uint enemyIndex)) { player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("selectplayerskill_incorrect_enemy_index")); return; }
var enemy = Utilities.GetPlayerFromIndex((int)enemyIndex);
if (enemy == null) if (enemy == null)
{ {
@ -72,20 +72,23 @@ namespace src.player.skills
return; return;
} }
glitchedPlayers.TryAdd(enemy, 0); glitchedPlayers.TryAdd(enemy.Index, 0);
playersToTarget[player.Index] = enemy.Index;
enemy.ReplicateConVar("sv_disable_radar", "1"); enemy.ReplicateConVar("sv_disable_radar", "1");
playerInfo.SkillUsed = true; playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("glitch_player_info", enemy.PlayerName)); player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("glitch_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("glitch_enemy_info")); enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("glitch_enemy_info"));
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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())));
@ -97,8 +100,24 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
if (playersToTarget.TryRemove(player.Index, out uint targetIndex))
{
var target = Utilities.GetPlayerFromIndex((int)targetIndex);
if (target != null && target.IsValid)
target.ReplicateConVar("sv_disable_radar", "0");
glitchedPlayers.TryRemove(targetIndex, out _);
}
SkillUtils.CloseMenu(player);
}
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null || !player.IsValid) return;
player.ReplicateConVar("sv_disable_radar", "0"); player.ReplicateConVar("sv_disable_radar", "0");
glitchedPlayers.TryRemove(player, out _); glitchedPlayers.TryRemove(player.Index, out _);
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }

View file

@ -1,7 +1,6 @@
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using static src.jRandomSkills;
namespace src.player.skills namespace src.player.skills
{ {
@ -29,7 +28,7 @@ namespace src.player.skills
var player = pawn.Controller.Value.As<CCSPlayerController>(); var player = pawn.Controller.Value.As<CCSPlayerController>();
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
grenade.Bounces = 555; grenade.Bounces = 555;
} }

View file

@ -1,6 +1,5 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using System.Collections.Concurrent; using System.Collections.Concurrent;
@ -11,7 +10,7 @@ namespace src.player.skills
public class GodMode : ISkill public class GodMode : ISkill
{ {
private const Skills skillName = Skills.GodMode; private const Skills skillName = Skills.GodMode;
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = []; private static readonly ConcurrentDictionary<uint, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
public static void LoadSkill() public static void LoadSkill()
@ -27,9 +26,9 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo SkillPlayerInfo.TryAdd(player.Index, new PlayerSkillInfo
{ {
SteamID = player.SteamID, SteamID = player.Index,
CanUse = true, CanUse = true,
Cooldown = DateTime.MinValue, Cooldown = DateTime.MinValue,
}); });
@ -39,16 +38,16 @@ namespace src.player.skills
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
UpdateHUD(player, skillInfo); UpdateHUD(player, skillInfo);
} }
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryRemove(player.SteamID, out _); SkillPlayerInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player); SkillUtils.ResetPrintHTML(player);
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
@ -68,7 +67,7 @@ namespace src.player.skills
skillInfo.CanUse = true; skillInfo.CanUse = true;
} }
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
if (cooldown == 0) if (cooldown == 0)
@ -82,29 +81,29 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return; if (playerPawn?.CBodyComponent == null) return;
ulong steamID = player.SteamID; uint playerIndex = player.Index;
if (SkillPlayerInfo.TryGetValue(steamID, out var skillInfo)) if (SkillPlayerInfo.TryGetValue(playerIndex, out var skillInfo))
{ {
if (!player.IsValid || !player.PawnIsAlive || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return; if (!player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return;
if (skillInfo.CanUse) if (skillInfo.CanUse)
{ {
skillInfo.CanUse = false; skillInfo.CanUse = false;
skillInfo.Cooldown = DateTime.Now; skillInfo.Cooldown = DateTime.Now;
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"), () => {
var player = Utilities.GetPlayerFromIndex((int)playerIndex);
var player = Utilities.GetPlayerFromSteamId(steamID); if (player != null && player.IsValid)
if (player != null && player.IsValid && player.PawnIsAlive)
{ {
if (player.PlayerPawn == null || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return; if (player.PlayerPawn == null || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return;
player.PlayerPawn.Value.TakesDamage = true; player.PlayerPawn.Value.TakesDamage = true;
player.PrintToChat($" {ChatColors.Red} {player.GetTranslation("godmode_off")}"); PlayerManager.GetPlayerFromEvent(player)?.PrintToChat($" {ChatColors.Red} {player.GetTranslation("godmode_off")}");
} }
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
} }
} }
} }

View file

@ -24,11 +24,11 @@ namespace src.player.skills
public static void GrenadeThrown(EventGrenadeThrown @event) public static void GrenadeThrown(EventGrenadeThrown @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Weapon; var weapon = @event.Weapon;
if (weapon != "hegrenade" || !Instance.IsPlayerValid(player)) return; if (weapon != "hegrenade" || !Instance.IsPlayerValid(player)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
player!.GiveNamedItem($"weapon_{weapon}"); player!.GiveNamedItem($"weapon_{weapon}");
} }

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Timers; using CounterStrikeSharp.API.Modules.Timers;
@ -13,72 +13,70 @@ namespace src.player.skills
{ {
public class HealingChicken : ISkill public class HealingChicken : ISkill
{ {
private const Skills skillName = Skills.HealingChicken; //private const Skills skillName = Skills.HealingChicken;
private readonly static ConcurrentDictionary<ulong, List<Timer>> playerSmokes = []; //private readonly static ConcurrentDictionary<uint, List<Timer>> playerSmokes = [];
private static readonly object setLock = new(); //private static readonly object setLock = new();
public static void LoadSkill() //public static void LoadSkill()
{ //{
// SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color")); // SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
} //}
public static void NewRound() //public static void NewRound()
{ //{
} //}
public static void EnableSkill(CCSPlayerController player) //public static void EnableSkill(CCSPlayerController player)
{ //{
SpawnChicken(player); // SpawnChicken(player);
} //}
public static void DisableSkill(CCSPlayerController player) //public static void DisableSkill(CCSPlayerController player)
{ //{
} //}
private static void SpawnChicken(CCSPlayerController player) //private static void SpawnChicken(CCSPlayerController player)
{ //{
if (player == null || !player.IsValid) return; // if (player == null || !player.IsValid) return;
var pawn = player.PlayerPawn.Value; // var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return; // if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
int amount = SkillsInfo.GetValue<int>(skillName, "amount"); // int amount = SkillsInfo.GetValue<int>(skillName, "amount");
for (int i = 0; i < 1; i++) // for (int i = 0; i < 1; i++)
{ // {
CChicken? chicken = Utilities.CreateEntityByName<CChicken>("chicken"); // CChicken? chicken = EntityManager.CreateTrackedChicken(player.Index);
if (chicken == null || !chicken.IsValid) continue; // if (chicken == null || !chicken.IsValid) continue;
chicken.Render = Color.Green; // chicken.Render = Color.Green;
Vector offset = new ( // Vector offset = new (
(float)(100 * Math.Cos(2 * Math.PI * i / amount)), // (float)(100 * Math.Cos(2 * Math.PI * i / amount)),
(float)(100 * Math.Sin(2 * Math.PI * i / amount)), // (float)(100 * Math.Sin(2 * Math.PI * i / amount)),
0 // 0
); // );
chicken.DispatchSpawn(); // chicken.Teleport(pawn.AbsOrigin + offset);
chicken.Teleport(pawn.AbsOrigin + offset);
// Schema.SetSchemaValue(chicken.Handle, "CChicken", "m_leader", player.PlayerPawn.Raw); // // Schema.SetSchemaValue(chicken.Handle, "CChicken", "m_leader", player.PlayerPawn.Raw);
Vector spawn = SkillUtils.GetSpawnPointVector(player); // Vector? spawn = SkillUtils.GetSpawnPointVector(player);
Schema.SetSchemaValue(chicken.Handle, "CChicken", "m_vecPathGoal", spawn); // Schema.SetSchemaValue(chicken.Handle, "CChicken", "m_vecPathGoal", spawn);
float speed = 50; // Instance.AddTickTimer(1, () =>
Instance.AddTickTimer(1, () => // {
{ // if (chicken == null || !chicken.IsValid) return;
if (chicken == null || !chicken.IsValid) return;
Server.PrintToChatAll($"{chicken.PathGoal}, {chicken.UpdateTimer.Duration}, {chicken.UpdateTimer.Timescale}"); // Server.PrintToChatAll($"{chicken.PathGoal}, {chicken.UpdateTimer.Duration}, {chicken.UpdateTimer.Timescale}");
}, TimerFlags.REPEAT | TimerFlags.STOP_ON_MAPCHANGE); // }, TimerFlags.REPEAT | TimerFlags.STOP_ON_MAPCHANGE);
} // }
} //}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#b5ab8f", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, int amount = 3, int heal = 2, int tickCooldown = 16) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity) //public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#b5ab8f", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, int amount = 3, int heal = 2, int tickCooldown = 16) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{ //{
public int Amount { get; set; } = amount; // public int Amount { get; set; } = amount;
public int Heal { get; set; } = heal; // public int Heal { get; set; } = heal;
public int TickCooldown { get; set; } = tickCooldown; // public int TickCooldown { get; set; } = tickCooldown;
} //}
} }
} }

View file

@ -1,10 +1,9 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills namespace src.player.skills
{ {
@ -25,10 +24,10 @@ namespace src.player.skills
public static void SmokegrenadeDetonate(EventSmokegrenadeDetonate @event) public static void SmokegrenadeDetonate(EventSmokegrenadeDetonate @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
smokes.TryAdd(new Vector(@event.X, @event.Y, @event.Z), 0); smokes.TryAdd(new Vector(@event.X, @event.Y, @event.Z), 0);
@ -36,10 +35,10 @@ namespace src.player.skills
public static void SmokegrenadeExpired(EventSmokegrenadeExpired @event) public static void SmokegrenadeExpired(EventSmokegrenadeExpired @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
foreach (var smoke in smokes.Keys.Where(v => v.X == @event.X && v.Y == @event.Y && v.Z == @event.Z)) foreach (var smoke in smokes.Keys.Where(v => v.X == @event.X && v.Y == @event.Y && v.Z == @event.Z))
@ -60,7 +59,7 @@ namespace src.player.skills
var player = pawn.Controller.Value.As<CCSPlayerController>(); var player = pawn.Controller.Value.As<CCSPlayerController>();
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
Server.NextFrame(() => Server.NextFrame(() =>
@ -82,13 +81,17 @@ 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 && p.PawnIsAlive)) foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid))
{ {
var pawn = player.PlayerPawn.Value; var eventPlayer = PlayerManager.GetPlayerEvent(player);
if (eventPlayer == null || !eventPlayer.IsValid) continue;
var pawn = eventPlayer.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue; if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue;
if (SkillUtils.GetDistance(smokePos, pawn.AbsOrigin) <= smokeRadius) if (SkillUtils.GetDistance(smokePos, pawn.AbsOrigin) <= smokeRadius)
AddHealth(pawn, smokeHeal); if (SkillUtils.AddHealth(pawn, smokeHeal))
player.EmitSound("Healthshot.Success");
} }
} }
@ -97,18 +100,6 @@ namespace src.player.skills
SkillUtils.TryGiveWeapon(player, CsItem.SmokeGrenade); SkillUtils.TryGiveWeapon(player, CsItem.SmokeGrenade);
} }
private static void AddHealth(CCSPlayerPawn player, int health)
{
if (player.LifeState != (byte)LifeState_t.LIFE_ALIVE)
return;
if (player.Health != player.MaxHealth)
player.EmitSound("Healthshot.Success");
player.Health = Math.Min(player.Health + health, player.MaxHealth);
Utilities.SetStateChanged(player, "CBaseEntity", "m_iHealth");
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1fe070", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, int smokeHeal = 1, float smokeRadius = 180, int tickCooldown = 16) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity) public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1fe070", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, int smokeHeal = 1, float smokeRadius = 180, int tickCooldown = 16) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{ {
public int SmokeHeal { get; set; } = smokeHeal; public int SmokeHeal { get; set; } = smokeHeal;

View file

@ -31,10 +31,10 @@ namespace src.player.skills
public static void PlayerDeath(EventPlayerDeath @event) public static void PlayerDeath(EventPlayerDeath @event)
{ {
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
if (!Instance.IsPlayerValid(attacker)) return; if (!Instance.IsPlayerValid(attacker)) return;
var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID); var attackerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
if (attackerInfo?.Skill != skillName) return; if (attackerInfo?.Skill != skillName) return;
var pawn = attacker!.PlayerPawn.Value; var pawn = attacker!.PlayerPawn.Value;

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
@ -32,7 +32,7 @@ namespace src.player.skills
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 = Utilities.GetPlayers().FirstOrDefault(p => p.PlayerPawn.Index == playerPawn.Index);
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
hegrenade.Damage *= SkillsInfo.GetValue<float>(skillName, "damageMultiplier"); hegrenade.Damage *= SkillsInfo.GetValue<float>(skillName, "damageMultiplier");

View file

@ -1,10 +1,9 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills namespace src.player.skills
{ {
@ -41,13 +40,13 @@ namespace src.player.skills
Vector currentPos = new(nade.AbsOrigin.X, nade.AbsOrigin.Y, nade.AbsOrigin.Z); Vector currentPos = new(nade.AbsOrigin.X, nade.AbsOrigin.Y, nade.AbsOrigin.Z);
double distanceMoved = SkillUtils.GetDistance(currentPos, oldPos); double distanceMoved = SkillUtils.GetDistance(currentPos, oldPos);
Vector calculatedVelocity = CalculateVelocity(nade, nade.TeamNum); Vector? calculatedVelocity = CalculateVelocity(nade, nade.TeamNum);
bool isZero = calculatedVelocity.IsZero(); bool isZero = calculatedVelocity?.IsZero() == true;
if (distanceMoved < 4 || isZero) if (distanceMoved < 4 || calculatedVelocity == null || isZero)
{ {
nade.DetonateTime = isZero ? 0 : nade.CreateTime + 3; nade.DetonateTime = isZero ? 0f : nade.CreateTime + 1.5f;
Utilities.SetStateChanged(nade, "CBaseGrenade", "m_flDetonateTime"); Utilities.SetStateChanged(nade, "CBaseGrenade", "m_flDetonateTime");
nades.TryRemove(index, out _); nades.TryRemove(index, out _);
@ -67,9 +66,9 @@ namespace src.player.skills
} }
} }
private static Vector CalculateVelocity(CBaseCSGrenadeProjectile nade, int team) private static Vector? CalculateVelocity(CBaseCSGrenadeProjectile nade, int team)
{ {
if (nade.AbsOrigin == null) return Vector.Zero; if (nade.AbsOrigin == null) return null;
Vector? closetEnemyPos = null; Vector? closetEnemyPos = null;
double minDistance = int.MaxValue; double minDistance = int.MaxValue;
@ -95,7 +94,7 @@ namespace src.player.skills
} }
if (closetEnemyPos == null) if (closetEnemyPos == null)
return Vector.Zero; return null;
Vector direction = closetEnemyPos - nadePos; Vector direction = closetEnemyPos - nadePos;
float length = direction.Length(); float length = direction.Length();
@ -127,7 +126,7 @@ namespace src.player.skills
if (pawn.Controller.Value == null || !pawn.Controller.Value.IsValid) return; if (pawn.Controller.Value == null || !pawn.Controller.Value.IsValid) return;
var player = pawn.Controller.Value.As<CCSPlayerController>(); var player = pawn.Controller.Value.As<CCSPlayerController>();
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
Vector pos = new(grenade.AbsOrigin?.X, grenade.AbsOrigin?.Y, grenade.AbsOrigin?.Z); Vector pos = new(grenade.AbsOrigin?.X, grenade.AbsOrigin?.Y, grenade.AbsOrigin?.Z);
@ -136,7 +135,7 @@ namespace src.player.skills
Server.NextWorldUpdate(() => Server.NextWorldUpdate(() =>
{ {
if (grenade == null || !grenade.IsValid) return; if (grenade == null || !grenade.IsValid) return;
grenade.DetonateTime += 100f; grenade.DetonateTime += 30f;
Utilities.SetStateChanged(grenade, "CBaseGrenade", "m_flDetonateTime"); Utilities.SetStateChanged(grenade, "CBaseGrenade", "m_flDetonateTime");
}); });
} }

View file

@ -27,7 +27,10 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid && p.Team == CsTeam.Terrorist && p.PawnIsAlive)) foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid && p.Team == CsTeam.Terrorist && p.PawnIsAlive))
{ {
var pawn = player.PlayerPawn.Value; var playerEvent = PlayerManager.GetPlayerEvent(player);
if (playerEvent == null || !playerEvent.IsValid) continue;
var pawn = playerEvent.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.WeaponServices == null) continue; if (pawn == null || !pawn.IsValid || pawn.WeaponServices == null) continue;
bool hasC4 = pawn.WeaponServices.MyWeapons.Any(w => w.Value?.DesignerName == "weapon_c4"); bool hasC4 = pawn.WeaponServices.MyWeapons.Any(w => w.Value?.DesignerName == "weapon_c4");
@ -40,7 +43,7 @@ namespace src.player.skills
public static void WeaponPickup(EventItemPickup @event) public static void WeaponPickup(EventItemPickup @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var weapon = @event.Item; var weapon = @event.Item;
@ -66,7 +69,7 @@ namespace src.player.skills
public static void PlayerDeath(EventPlayerDeath @event) public static void PlayerDeath(EventPlayerDeath @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
players.TryRemove(player.Index, out _); players.TryRemove(player.Index, out _);
} }

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Timers; using CounterStrikeSharp.API.Modules.Timers;
@ -25,14 +25,16 @@ namespace src.player.skills
{ {
foreach (var playerSkill in playersInfo.Values) foreach (var playerSkill in playersInfo.Values)
KillClone(playerSkill); KillClone(playerSkill);
lock (setLock) lock (setLock)
playersInfo.Clear(); playersInfo.Clear();
} }
public static void WeaponPickup(EventItemPickup @event) public static void WeaponPickup(EventItemPickup @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null) return; if (player == null) return;
if (playersInfo.TryGetValue(player.Index, out var playerSkill)) if (playersInfo.TryGetValue(player.Index, out var playerSkill))
if (playerSkill.CloneProp != null) if (playerSkill.CloneProp != null)
BlockWeapon(player, true); BlockWeapon(player, true);
@ -40,8 +42,9 @@ namespace src.player.skills
public static void WeaponEquip(EventItemEquip @event) public static void WeaponEquip(EventItemEquip @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null) return; if (player == null) return;
if (playersInfo.TryGetValue(player.Index, out var playerSkill)) if (playersInfo.TryGetValue(player.Index, out var playerSkill))
if (playerSkill.CloneProp != null) if (playerSkill.CloneProp != null)
BlockWeapon(player, true); BlockWeapon(player, true);
@ -77,9 +80,11 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
if (player == null) return;
if (playersInfo.TryGetValue(player.Index, out var playerSkill)) if (playersInfo.TryGetValue(player.Index, out var playerSkill))
KillClone(playerSkill); KillClone(playerSkill);
playersInfo.TryRemove(player.Index, out _); playersInfo.TryRemove(player.Index, out _);
EntityManager.DestroyPlayerEntities(player.Index);
} }
private static void UpdateWeapons(CCSPlayerController player, PlayerSkill playerSkill) private static void UpdateWeapons(CCSPlayerController player, PlayerSkill playerSkill)
@ -119,12 +124,16 @@ namespace src.player.skills
playerPawn.Teleport(pos); playerPawn.Teleport(pos);
}); });
} }
cloneProp.AcceptInput("Kill"); EntityManager.DestroyEntity(cloneProp.Index);
playerSkill.CloneProp = null; playerSkill.CloneProp = null;
} }
SkillUtils.ApplyScreenColor(player, 0, 0, 0, 0, 10, 0, 2); var eventTarget = PlayerManager.GetPlayerFromEvent(player);
if (eventTarget != null && eventTarget.IsValid)
SkillUtils.ApplyScreenColor(eventTarget, 0, 0, 0, 0, 10, 0, 2);
SkillUtils.SetPlayerCollisions(player, true); SkillUtils.SetPlayerCollisions(player, true);
BlockWeapon(player, false); BlockWeapon(player, false);
playerSkill.NextUse = Server.TickCount + SkillsInfo.GetValue<float>(skillName, "Cooldown") * 64; playerSkill.NextUse = Server.TickCount + SkillsInfo.GetValue<float>(skillName, "Cooldown") * 64;
playerSkill.UseTime = 0; playerSkill.UseTime = 0;
@ -164,12 +173,12 @@ namespace src.player.skills
} }
} }
var clone = Utilities.CreateEntityByName<CDynamicProp>("prop_dynamic"); var clone = EntityManager.CreateTrackedDynamicProp(player.Index);
if (clone == null || !clone.IsValid) return null; if (clone == null || !clone.IsValid) return null;
clone.Collision.SolidType = SolidType_t.SOLID_VPHYSICS; clone.Collision.SolidType = SolidType_t.SOLID_VPHYSICS;
clone.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(clone.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2)); clone.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(clone.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
clone.Entity!.Name = clone.Globalname = $"IanaClone_{Server.TickCount}_{player.SteamID}"; clone.Entity!.Name = clone.Globalname = $"IanaClone_{Server.TickCount}_{player.Index}";
clone.DispatchSpawn(); clone.DispatchSpawn();
Server.NextFrame(() => Server.NextFrame(() =>
@ -183,7 +192,11 @@ namespace src.player.skills
clone.Teleport(playerPawn.AbsOrigin, new QAngle(0, playerPawn.V_angle.Y, 0)); clone.Teleport(playerPawn.AbsOrigin, new QAngle(0, playerPawn.V_angle.Y, 0));
playerPawn.Teleport(pos); playerPawn.Teleport(pos);
SkillUtils.ApplyScreenColor(player, r: 255, g: 255, b: 0, a: 20, duration: 100, holdTime: 1020);
var eventTarget = PlayerManager.GetPlayerFromEvent(player);
if (eventTarget != null && eventTarget.IsValid)
SkillUtils.ApplyScreenColor(eventTarget, r: 255, g: 255, b: 0, a: 20, duration: 100, holdTime: 1020);
BlockWeapon(player, true); BlockWeapon(player, true);
playerSkill.UseTime = Server.TickCount; playerSkill.UseTime = Server.TickCount;
@ -194,16 +207,15 @@ namespace src.player.skills
{ {
if (playerSkill.CloneProp != null) if (playerSkill.CloneProp != null)
KillClone(playerSkill); KillClone(playerSkill);
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
ulong? playerSteamID = player?.SteamID; uint playerIndex = player.Index;
if (playerSteamID == null) return;
Timer? cloneTimer = null; Timer? cloneTimer = null;
cloneTimer = jRandomSkills.Instance.AddTimer(2f, () => cloneTimer = jRandomSkills.Instance.AddTimer(2f, () =>
{ {
var target = Utilities.GetPlayers().FirstOrDefault(p => p.IsValid && p.SteamID == playerSteamID); var target = Utilities.GetPlayerFromIndex((int)playerIndex);
if (target == null || !target.IsValid || !target.PawnIsAlive) if (target == null || !target.IsValid || target.LifeState != (byte)LifeState_t.LIFE_ALIVE)
{ {
cloneTimer?.Kill(); cloneTimer?.Kill();
return; return;
@ -215,7 +227,14 @@ namespace src.player.skills
return; return;
} }
SkillUtils.ApplyScreenColor(target, r: 255, g: 255, b: 0, a: 20, duration: 100, holdTime: 1020); var eventTarget = PlayerManager.GetPlayerFromEvent(player);
if (eventTarget == null || !eventTarget.IsValid)
{
cloneTimer?.Kill();
return;
}
SkillUtils.ApplyScreenColor(eventTarget, r: 255, g: 255, b: 0, a: 20, duration: 100, holdTime: 1020);
}, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT); }, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT);
}); });
@ -247,14 +266,18 @@ namespace src.player.skills
float penetration = vdata.ArmorRatio * .5f; float penetration = vdata.ArmorRatio * .5f;
var eventPlayer = PlayerManager.GetPlayerFromEvent(player);
if (eventPlayer == null || !eventPlayer.IsValid)
return calculatedDamage;
if (isHeadshot) if (isHeadshot)
{ {
calculatedDamage *= vdata.HeadshotMultiplier; calculatedDamage *= vdata.HeadshotMultiplier;
if (player.PawnHasHelmet) if (eventPlayer.PawnHasHelmet)
calculatedDamage *= penetration; calculatedDamage *= penetration;
} }
else else
if (player.PawnArmor > 0) if (eventPlayer.PawnArmor > 0)
calculatedDamage *= penetration; calculatedDamage *= penetration;
return calculatedDamage; return calculatedDamage;
@ -272,11 +295,11 @@ namespace src.player.skills
if (!param.Entity.Name.StartsWith("IanaClone_")) return; if (!param.Entity.Name.StartsWith("IanaClone_")) return;
var nameParams = param.Entity.Name.Split('_')[2]; var nameParams = param.Entity.Name.Split('_')[2];
_ = ulong.TryParse(nameParams, out ulong steamID); _ = uint.TryParse(nameParams, out uint userIndex);
if (steamID == 0) return; if (userIndex == 0) return;
var player = Utilities.GetPlayerFromSteamId(steamID); var player = Utilities.GetPlayerFromIndex((int)userIndex);
if (player == null) return; if (player == null || !player.IsValid) return;
float dealDamage = param2.Damage; float dealDamage = param2.Damage;
@ -314,8 +337,8 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var victim = @event.Userid!; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
if (!jRandomSkills.Instance.IsPlayerValid(victim)) return; if (victim == null || !victim.IsValid) return;
if (playersInfo.TryGetValue(victim.Index, out var playerSkill) && playerSkill.CloneProp != null) if (playersInfo.TryGetValue(victim.Index, out var playerSkill) && playerSkill.CloneProp != null)
{ {
@ -356,7 +379,7 @@ namespace src.player.skills
float time2 = SkillsInfo.GetValue<float>(skillName, "Duration") - (Server.TickCount - playerSkill.UseTime) / 64; float time2 = SkillsInfo.GetValue<float>(skillName, "Duration") - (Server.TickCount - playerSkill.UseTime) / 64;
duration = (int)Math.Ceiling(Math.Max(time2, 0)); duration = (int)Math.Ceiling(Math.Max(time2, 0));
var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
if (playerSkill.InfoTime + (64 * 2) > Server.TickCount) if (playerSkill.InfoTime + (64 * 2) > Server.TickCount)
@ -374,7 +397,7 @@ namespace src.player.skills
string weaponName = vdata.Name; string weaponName = vdata.Name;
if (string.IsNullOrEmpty(weaponName)) return false; if (string.IsNullOrEmpty(weaponName)) return false;
var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return false; if (playerInfo?.Skill != skillName) return false;
if (playersInfo.TryGetValue(player.Index, out var playerSkill)) if (playersInfo.TryGetValue(player.Index, out var playerSkill))

View file

@ -10,6 +10,7 @@ namespace src.player.skills
private const Skills skillName = Skills.Illiterate; private const Skills skillName = Skills.Illiterate;
private static bool isActive = false; private static bool isActive = false;
private static int offset = 5; private static int offset = 5;
private static int lastChange = 0;
private static readonly object offsetLock = new(); private static readonly object offsetLock = new();
public static void LoadSkill() public static void LoadSkill()
@ -28,7 +29,7 @@ namespace src.player.skills
} }
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController _)
{ {
isActive = true; isActive = true;
} }
@ -48,24 +49,28 @@ namespace src.player.skills
if (!isActive || player == null || !player.IsValid) return false; if (!isActive || player == null || !player.IsValid) return false;
if (player.Team == CsTeam.Spectator) return false; if (player.Team == CsTeam.Spectator) return false;
var playersWithSkill = jRandomSkills.Instance.SkillPlayer.Where(p => p.Skill == skillName).Select(p => p.SteamID).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 Utilities.GetPlayers().Any(
p => p != null && p => p != null &&
p.IsValid && p.IsValid &&
p.Pawn?.Value != null && p.Pawn?.Value != null &&
p.PawnIsAlive && p.PlayerPawn?.Value != null &&
p.PlayerPawn.Value.Health > 0 &&
p.Team != player.Team && p.Team != player.Team &&
playersWithSkill.Contains(p.SteamID)); playersWithSkill.Contains(p.Index));
} }
public static string? GetRandomText(string? input) public static string? GetRandomText(string? input)
{ {
if (string.IsNullOrEmpty(input)) return null; if (string.IsNullOrEmpty(input)) return null;
if (Server.TickCount % 64 == 0 || offset == 0) if (Server.TickCount - lastChange > 64 || offset == 0)
{
EnsureOffset(); EnsureOffset();
lastChange = Server.TickCount;
}
var chars = input.Select(c => var chars = input.Select(c =>
{ {
@ -84,7 +89,6 @@ namespace src.player.skills
{ {
lock (offsetLock) lock (offsetLock)
{ {
if (offset != 0) return;
try try
{ {
offset = jRandomSkills.Instance?.Random?.Next(1, 26) ?? new Random().Next(1, 26); offset = jRandomSkills.Instance?.Random?.Next(1, 26) ?? new Random().Next(1, 26);

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
@ -13,7 +13,7 @@ namespace src.player.skills
public class Illusionist : ISkill public class Illusionist : ISkill
{ {
private const Skills skillName = Skills.Illusionist; private const Skills skillName = Skills.Illusionist;
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = []; private static readonly ConcurrentDictionary<uint, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly ConcurrentDictionary<int, Timer> ActiveTimers = []; private static readonly ConcurrentDictionary<int, Timer> ActiveTimers = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
@ -37,27 +37,27 @@ namespace src.player.skills
var entities = Utilities.FindAllEntitiesByDesignerName<CDynamicProp>("prop_dynamic_override"); var entities = Utilities.FindAllEntitiesByDesignerName<CDynamicProp>("prop_dynamic_override");
foreach (var entity in entities) foreach (var entity in entities)
if (entity != null && entity.IsValid && entity.Entity != null && !string.IsNullOrEmpty(entity.Entity.Name) && (entity.Entity.Name?.StartsWith("Illusionist_") ?? false)) if (entity != null && entity.IsValid && entity.Entity != null && !string.IsNullOrEmpty(entity.Entity.Name) && (entity.Entity.Name?.StartsWith("Illusionist_") ?? false))
entity.AcceptInput("Kill"); EntityManager.DestroyEntity(entity.Index);
} }
public static void OnTick() public static void OnTick()
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
if (player == null || !player.IsValid || player.IsBot) continue; if (player == null || !player.IsValid ) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
UpdateHUD(player, skillInfo); UpdateHUD(player, skillInfo);
} }
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo SkillPlayerInfo.TryAdd(player.Index, new PlayerSkillInfo
{ {
SteamID = player.SteamID, SteamID = player.Index,
CanUse = true, CanUse = true,
Cooldown = DateTime.MinValue, Cooldown = DateTime.MinValue,
}); });
@ -65,7 +65,9 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryRemove(player.SteamID, out _); if (player == null) return;
SkillPlayerInfo.TryRemove(player.Index, out _);
EntityManager.DestroyPlayerEntities(player.Index);
SkillUtils.ResetPrintHTML(player); SkillUtils.ResetPrintHTML(player);
} }
@ -81,7 +83,7 @@ namespace src.player.skills
skillInfo.CanUse = true; skillInfo.CanUse = true;
} }
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
if (cooldown == 0) if (cooldown == 0)
@ -92,9 +94,9 @@ namespace src.player.skills
public static void UseSkill(CCSPlayerController player) public static void UseSkill(CCSPlayerController player)
{ {
if (player == null || !player.IsValid || !player.PawnIsAlive) return; if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo) && skillInfo.CanUse) if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo) && skillInfo.CanUse)
{ {
skillInfo.CanUse = false; skillInfo.CanUse = false;
skillInfo.Cooldown = DateTime.Now; skillInfo.Cooldown = DateTime.Now;
@ -108,7 +110,7 @@ namespace src.player.skills
if (playerPawn == null || !playerPawn.IsValid) return; if (playerPawn == null || !playerPawn.IsValid) return;
if (playerPawn.AbsOrigin == null || playerPawn.AbsRotation == null) return; if (playerPawn.AbsOrigin == null || playerPawn.AbsRotation == null) return;
var replica = Utilities.CreateEntityByName<CDynamicProp>("prop_dynamic_override"); var replica = EntityManager.CreateTrackedPropOverride(player.Index);
if (replica == null || !replica.IsValid) return; if (replica == null || !replica.IsValid) return;
replica.Collision.SolidType = SolidType_t.SOLID_VPHYSICS; replica.Collision.SolidType = SolidType_t.SOLID_VPHYSICS;
@ -166,10 +168,10 @@ namespace src.player.skills
{ {
if (replica != null && replica.IsValid) if (replica != null && replica.IsValid)
{ {
replica.AcceptInput("Kill"); EntityManager.DestroyEntity(replica.Index);
if (ActiveTimers.TryRemove(replicaIndex, out var timer)) timer?.Kill(); if (ActiveTimers.TryRemove(replicaIndex, out var timer)) timer?.Kill();
} }
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
} }
public static void OnTakeDamage(DynamicHook h) public static void OnTakeDamage(DynamicHook h)
@ -188,7 +190,7 @@ namespace src.player.skills
replica.EmitSound("GlassBottle.BulletImpact", volume: 1f); replica.EmitSound("GlassBottle.BulletImpact", volume: 1f);
if (ActiveTimers.TryRemove((int)replica.Index, out var timer)) timer?.Kill(); if (ActiveTimers.TryRemove((int)replica.Index, out var timer)) timer?.Kill();
replica.AcceptInput("Kill"); EntityManager.DestroyEntity(replica.Index);
CCSPlayerPawn attackerPawn = new(param2.Attacker.Value.Handle); CCSPlayerPawn attackerPawn = new(param2.Attacker.Value.Handle);
if (attackerPawn.DesignerName != "player") return; if (attackerPawn.DesignerName != "player") return;

View file

@ -13,7 +13,7 @@ namespace src.player.skills
private const Skills skillName = Skills.Impostor; private const Skills skillName = Skills.Impostor;
private static readonly string defaultCTModel = "agents/models/ctm_sas/ctm_sas.vmdl"; private static readonly string defaultCTModel = "agents/models/ctm_sas/ctm_sas.vmdl";
private static readonly string defaultTModel = "agents/models/tm_phoenix/tm_phoenix.vmdl"; private static readonly string defaultTModel = "agents/models/tm_phoenix/tm_phoenix.vmdl";
private static readonly ConcurrentDictionary<ulong, string> originalModels = []; private static readonly ConcurrentDictionary<uint, string> originalModels = [];
public static void LoadSkill() public static void LoadSkill()
{ {
@ -29,16 +29,16 @@ namespace src.player.skills
{ {
string model = GetEnemyModel(player); string model = GetEnemyModel(player);
if (player.PlayerPawn.Value != null && player.PlayerPawn.Value.IsValid && player.PlayerPawn.Value.CBodyComponent != null && player.PlayerPawn.Value.CBodyComponent.SceneNode != null) if (player.PlayerPawn.Value != null && player.PlayerPawn.Value.IsValid && player.PlayerPawn.Value.CBodyComponent != null && player.PlayerPawn.Value.CBodyComponent.SceneNode != null)
originalModels.TryAdd(player.SteamID, player.PlayerPawn.Value.CBodyComponent.SceneNode.GetSkeletonInstance().ModelState.ModelName); originalModels.TryAdd(player.Index, player.PlayerPawn.Value.CBodyComponent.SceneNode.GetSkeletonInstance().ModelState.ModelName);
SetPlayerModel(player, model); SetPlayerModel(player, model);
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
var model = originalModels.TryGetValue(player.SteamID, out var originalModel) && !string.IsNullOrEmpty(originalModel) ? originalModel : var model = originalModels.TryGetValue(player.Index, out var originalModel) && !string.IsNullOrEmpty(originalModel) ? originalModel :
player.Team == CsTeam.Terrorist ? defaultTModel : defaultCTModel; player.Team == CsTeam.Terrorist ? defaultTModel : defaultCTModel;
SetPlayerModel(player, model); SetPlayerModel(player, model);
originalModels.TryRemove(player.SteamID, out _); originalModels.TryRemove(player.Index, out _);
} }
private static string GetEnemyModel(CCSPlayerController player) private static string GetEnemyModel(CCSPlayerController player)

View file

@ -16,10 +16,10 @@ namespace src.player.skills
public static void WeaponFire(EventWeaponFire @event) public static void WeaponFire(EventWeaponFire @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(player)) return; if (!Instance.IsPlayerValid(player)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
ApplyInfiniteAmmo(player!); ApplyInfiniteAmmo(player!);
@ -27,10 +27,10 @@ namespace src.player.skills
public static void GrenadeThrown(EventGrenadeThrown @event) public static void GrenadeThrown(EventGrenadeThrown @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(player)) return; if (!Instance.IsPlayerValid(player)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
player!.GiveNamedItem($"weapon_{@event.Weapon}"); player!.GiveNamedItem($"weapon_{@event.Weapon}");
@ -38,10 +38,10 @@ namespace src.player.skills
public static void WeaponReload(EventWeaponReload @event) public static void WeaponReload(EventWeaponReload @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(player)) return; if (!Instance.IsPlayerValid(player)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
ApplyInfiniteAmmo(player!); ApplyInfiniteAmmo(player!);
} }

View file

@ -1,9 +1,9 @@
using System.Collections.Concurrent; 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.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills; using static src.jRandomSkills;
using Timer = CounterStrikeSharp.API.Modules.Timers.Timer; using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
@ -12,9 +12,9 @@ namespace src.player.skills
public class Jackal : ISkill public class Jackal : ISkill
{ {
private const Skills skillName = Skills.Jackal; private const Skills skillName = Skills.Jackal;
private static readonly ConcurrentDictionary<ulong, byte> playersInAction = new(); private static Timer? mainSkillTimer = null;
private static readonly ConcurrentDictionary<uint, uint?> playersStep = new(); private static readonly ConcurrentDictionary<uint, uint?> activeTrails = [];
private static readonly ConcurrentDictionary<ulong, Timer?> activeTimers = new(); private static readonly ConcurrentDictionary<uint, byte> playersInAction = [];
public static void LoadSkill() public static void LoadSkill()
{ {
@ -24,134 +24,141 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
var particleIds = playersStep.Values.Where(v => v.HasValue).Select(v => v!.Value).ToArray(); if (mainSkillTimer != null)
foreach (var pid in particleIds) {
SkillUtils.SafeKillEntity<CParticleSystem>(pid); mainSkillTimer.Kill();
mainSkillTimer = null;
}
var timers = activeTimers.Values.ToArray(); foreach (var index in activeTrails.Keys)
foreach (var t in timers) EntityManager.DestroyPlayerEntities(index);
t?.Kill();
playersStep.Clear(); activeTrails.Clear();
playersInAction.Clear(); playersInAction.Clear();
activeTimers.Clear();
} }
public static void CheckTransmit([CastFrom(typeof(nint))] CCheckTransmitInfoList infoList) public static void CheckTransmit([CastFrom(typeof(nint))] CCheckTransmitInfoList infoList)
{ {
var snapshot = activeTrails.ToArray();
foreach (var (info, player) in infoList) foreach (var (info, player) in infoList)
{ {
if (player == null || !player.IsValid) continue; if (player == null || !player.IsValid) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
bool isJackalOwner = playerInfo?.Skill == skillName;
if (!isJackalOwner)
{
var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero; var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero;
bool isObservingJackal = false;
if (targetHandle != nint.Zero) if (targetHandle != nint.Zero)
{ {
var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle); var observed = Utilities.GetPlayers()
var targetInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == target?.SteamID); .FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle);
if (targetInfo?.Skill == skillName) isObservingJackal = true; if (observed != null && observed.IsValid)
{
var observedInfo = PlayerManager.GetPlayerByIndex(observed.Index);
if (observedInfo?.Skill == skillName)
isJackalOwner = true;
}
}
} }
bool hasSkill = playerInfo?.Skill == skillName || isObservingJackal; foreach (var (trackedPlayerIndex, relayIndex) in snapshot)
foreach (var kv in playersStep.ToArray())
{ {
var enemyIndex = kv.Key; if (relayIndex == null) continue;
var particleIndex = kv.Value;
if (particleIndex == null) continue;
var enemy = Utilities.GetPlayerFromIndex((int)enemyIndex); var trailOwner = Utilities.GetPlayerFromIndex((int)trackedPlayerIndex);
if (enemy == null || !enemy.IsValid) continue; if (trailOwner == null || !trailOwner.IsValid) continue;
var entity = Utilities.GetEntityFromIndex<CBaseEntity>((int)particleIndex); var relayEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)relayIndex);
if (entity == null || !entity.IsValid) continue; if (relayEntity == null || !relayEntity.IsValid) continue;
if (!hasSkill || enemy.Team == player.Team) if (player.Team == trailOwner.Team || !isJackalOwner)
info.TransmitEntities.Remove(entity.Index); info.TransmitEntities.Remove(relayEntity.Index);
} }
} }
} }
public static void CreatePlayerTrail(CCSPlayerController? player) public static void CreatePlayerTrail(CCSPlayerController? player)
{ {
if (player == null) return; if (player == null || !player.IsValid) return;
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null
|| playerPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE || playerPawn.Health <= 0) return; ;
ulong steamID = player.SteamID; var relay = EntityManager.CreateTrackedPhysicsProp(player.Index);
if (activeTimers.TryRemove(steamID, out var oldTimer)) if (relay == null || !relay.IsValid) return;
oldTimer?.Kill();
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null || playerPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE) return; CBaseEntity target = playerPawn;
if (!playersStep.ContainsKey(player.Index)) return; var entities = EntityManager.GetPlayerEntities(player.Index, "empty_prop");
CParticleSystem particle = Utilities.CreateEntityByName<CParticleSystem>("info_particle_system")!; if (entities.Count > 0)
if (particle == null) return; {
var entity = Utilities.GetEntityFromIndex<CDynamicProp>((int)entities[0]);
if (entity != null && entity.IsValid)
target = entity;
}
particle.EffectName = SkillsInfo.GetValue<string>(skillName, "particleName"); relay.AcceptInput("SetParent", target, relay, "!activator");
particle.StartActive = true;
particle.Teleport(playerPawn.AbsOrigin); var particle = EntityManager.CreateTrackedParticleSystem(
particle.DispatchSpawn(); player.Index,
SkillsInfo.GetValue<string>(skillName, "particleName"));
particle.AcceptInput("SetParent", playerPawn, particle, "!activator"); if (particle != null && particle.IsValid && target.AbsOrigin != null)
{
Vector pos = new(target.AbsOrigin.X, target.AbsOrigin.Y, target.AbsOrigin.Z);
if (entities.Count > 0) pos.Z -= 30;
particle.Teleport(pos);
particle.AcceptInput("SetParent", relay, particle, "!activator");
particle.AcceptInput("Start"); particle.AcceptInput("Start");
}
uint particleId = particle.Index; activeTrails[player.Index] = relay.Index;
playersStep.AddOrUpdate(player.Index, particle.Index, (k, v) => particle.Index);
var timer = Instance.AddTimer(2.5f, () =>
{
SkillUtils.SafeKillEntity<CParticleSystem>(particleId);
var pl = Utilities.GetPlayerFromSteamId(steamID);
if (pl != null && pl.IsValid && playersStep.ContainsKey(pl.Index))
CreatePlayerTrail(pl);
});
activeTimers.AddOrUpdate(player.SteamID, timer, (_, prev) =>
{
prev?.Kill();
return timer;
});
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
if (player == null || !player.IsValid) return;
Event.EnableTransmit(); Event.EnableTransmit();
playersInAction.TryAdd(player.SteamID, 0); playersInAction.TryAdd(player.Index, 0);
var opponents = Utilities.GetPlayers() var opponents = Utilities.GetPlayers()
.Where(p => p.Team != player.Team .Where(p => p != null
&& p.IsValid && p.IsValid
&& !p.IsBot && p.Team != player.Team
&& !p.IsHLTV
&& p.PawnIsAlive && p.PawnIsAlive
&& (p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist)) && (p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist))
.ToArray(); .ToArray();
foreach (var _player in opponents) mainSkillTimer ??= Instance.AddTimer(2.5f, () => UpdateAllTrails(),
{ CounterStrikeSharp.API.Modules.Timers.TimerFlags.REPEAT | CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
playersStep.TryAdd(_player.Index, null);
CreatePlayerTrail(_player);
} }
private static void UpdateAllTrails()
{
foreach (var player in Utilities.GetPlayers())
CreatePlayerTrail(player);
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
playersInAction.TryRemove(player.SteamID, out _); if (player == null || !player.IsValid) return;
uint playerIndex = player.Index;
if (playersStep.TryRemove(player.Index, out var particleIndex) && particleIndex != null) playersInAction.TryRemove(playerIndex, out _);
EntityManager.DestroyPlayerEntities(playerIndex);
activeTrails.TryRemove(playerIndex, out _);
if (playersInAction.IsEmpty && mainSkillTimer != null)
{ {
SkillUtils.SafeKillEntity<CParticleSystem>(particleIndex); mainSkillTimer.Kill();
mainSkillTimer = null;
} }
if (activeTimers.TryRemove(player.SteamID, out var t))
t?.Kill();
if (playersInAction.IsEmpty)
NewRound();
} }
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#f542ef", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = 1, Rarity rarity = Rarity.Common, string particleName = "particles/ui/hud/ui_map_def_utility_trail.vpcf") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity) public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#f542ef", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = 1, Rarity rarity = Rarity.Common, string particleName = "particles/ui/hud/ui_map_def_utility_trail.vpcf") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)

View file

@ -1,9 +1,9 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Commands.Targeting;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils; using src.utils;
using System.Collections.Concurrent;
namespace src.player.skills namespace src.player.skills
{ {
@ -11,6 +11,7 @@ namespace src.player.skills
{ {
private const Skills skillName = Skills.Jammer; private const Skills skillName = Skills.Jammer;
private static readonly ConcurrentDictionary<uint, byte> jammedPlayers = []; private static readonly ConcurrentDictionary<uint, byte> jammedPlayers = [];
private static readonly ConcurrentDictionary<uint, uint> jammerToTarget = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
public static void LoadSkill() public static void LoadSkill()
@ -29,7 +30,9 @@ namespace src.player.skills
SetCrosshair(player, true); SetCrosshair(player, true);
} }
jammedPlayers.Clear(); jammedPlayers.Clear();
jammerToTarget.Clear();
} }
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
@ -40,10 +43,10 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); 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.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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);
@ -52,8 +55,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands) public static void TypeSkill(CCSPlayerController player, string[] commands)
{ {
if (player == null || !player.IsValid || !player.PawnIsAlive) return; if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed) if (playerInfo.SkillUsed)
@ -63,7 +66,8 @@ namespace src.player.skills
} }
string enemyId = commands[0]; string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Team != player.Team && p.Index.ToString() == enemyId); if (!uint.TryParse(enemyId, out uint enemyIndex)) { player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("selectplayerskill_incorrect_enemy_index")); return; }
var enemy = Utilities.GetPlayerFromIndex((int)enemyIndex);
if (enemy == null) if (enemy == null)
{ {
@ -72,8 +76,11 @@ namespace src.player.skills
} }
jammedPlayers.TryAdd(enemy.Index, 0); jammedPlayers.TryAdd(enemy.Index, 0);
jammerToTarget[player.Index] = enemy.Index;
SetCrosshair(enemy, false); SetCrosshair(enemy, false);
playerInfo.SkillUsed = true; playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("jammer_player_info", enemy.PlayerName)); player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("jammer_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("jammer_enemy_info")); enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("jammer_enemy_info"));
} }
@ -90,11 +97,11 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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())));
@ -106,6 +113,22 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
if (jammerToTarget.TryRemove(player.Index, out uint targetIndex))
{
var target = Utilities.GetPlayerFromIndex((int)targetIndex);
if (target != null && target.IsValid)
SetCrosshair(target, true);
jammedPlayers.TryRemove(targetIndex, out _);
}
SkillUtils.CloseMenu(player);
}
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null || !player.IsValid) return;
SetCrosshair(player, true); SetCrosshair(player, true);
jammedPlayers.TryRemove(player.Index, out _); jammedPlayers.TryRemove(player.Index, out _);
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);

View file

@ -1,6 +1,5 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using System.Collections.Concurrent; using System.Collections.Concurrent;
@ -13,7 +12,7 @@ namespace src.player.skills
public class Jester : ISkill public class Jester : ISkill
{ {
private const Skills skillName = Skills.Jester; private const Skills skillName = Skills.Jester;
private static readonly ConcurrentDictionary<ulong, JesterInfo> jesters = []; private static readonly ConcurrentDictionary<uint, JesterInfo> jesters = [];
public static void LoadSkill() public static void LoadSkill()
{ {
@ -32,13 +31,13 @@ namespace src.player.skills
jester.Timer = null; jester.Timer = null;
} }
var player = Utilities.GetPlayerFromSteamId(jester.SteamId); var player = Utilities.GetPlayerFromIndex((int)jester.PlayerIndex);
if (player != null && player.IsValid) if (player != null && player.IsValid)
{ {
SkillUtils.ResetPrintHTML(player); SkillUtils.ResetPrintHTML(player);
var pawn = player.PlayerPawn.Value; var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || !player.PawnIsAlive) return; if (pawn == null || !pawn.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var color = Color.FromArgb(255, 255, 255, 255); var color = Color.FromArgb(255, 255, 255, 255);
pawn.Render = color; pawn.Render = color;
@ -51,7 +50,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
var jester = GetJesterInfo(player.SteamID); var jester = GetJesterInfo(player.Index);
if (jester == null) return; if (jester == null) return;
Server.NextWorldUpdate(() => Server.NextWorldUpdate(() =>
@ -69,11 +68,11 @@ namespace src.player.skills
public static void BombBegindefuse(EventBombBegindefuse @event) public static void BombBegindefuse(EventBombBegindefuse @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
ulong steamId = player.SteamID; uint playerIndex = player.Index;
var jester = GetJesterInfo(steamId); var jester = GetJesterInfo(playerIndex);
if (jester == null) return; if (jester == null) return;
if (jester.Timer != null) if (jester.Timer != null)
@ -83,17 +82,17 @@ namespace src.player.skills
} }
jester.Timer = Instance.AddTimer(1, () => { jester.Timer = Instance.AddTimer(1, () => {
ChangeMode(steamId, false); ChangeMode(playerIndex, false);
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
} }
public static void BombBeginplant(EventBombBeginplant @event) public static void BombBeginplant(EventBombBeginplant @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
ulong steamId = player.SteamID; uint playerIndex = player.Index;
var jester = GetJesterInfo(steamId); var jester = GetJesterInfo(playerIndex);
if (jester == null) return; if (jester == null) return;
if (jester.Timer != null) if (jester.Timer != null)
@ -104,18 +103,17 @@ namespace src.player.skills
jester.Timer = Instance.AddTimer(1, () => { jester.Timer = Instance.AddTimer(1, () => {
if (player != null && player.IsValid) if (player != null && player.IsValid)
ChangeMode(steamId, false); ChangeMode(playerIndex, false);
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
} }
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = @event.Userid; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
int hitgroup = @event.Hitgroup;
if (!Instance.IsPlayerValid(victim)) return; if (!Instance.IsPlayerValid(victim)) return;
var jesterVictim = GetJesterInfo(victim!.SteamID); var jesterVictim = GetJesterInfo(victim!.Index);
if (!Instance.IsPlayerValid(attacker)) if (!Instance.IsPlayerValid(attacker))
{ {
@ -124,7 +122,7 @@ namespace src.player.skills
return; return;
} }
var jesterAttacker = GetJesterInfo(attacker!.SteamID); var jesterAttacker = GetJesterInfo(attacker!.Index);
if ((jesterVictim != null && jesterVictim.Active) || (jesterAttacker != null && jesterAttacker.Active)) if ((jesterVictim != null && jesterVictim.Active) || (jesterAttacker != null && jesterAttacker.Active))
SkillUtils.RestoreHealth(victim); SkillUtils.RestoreHealth(victim);
} }
@ -135,18 +133,18 @@ namespace src.player.skills
var maxTime = SkillsInfo.GetValue<float>(skillName, "maxTime"); var maxTime = SkillsInfo.GetValue<float>(skillName, "maxTime");
float wait = (float)Instance.Random.NextDouble() * (maxTime - minTime) + minTime; float wait = (float)Instance.Random.NextDouble() * (maxTime - minTime) + minTime;
ulong steamId = player.SteamID; uint playerIndex = player.Index;
jesters.TryAdd(steamId, new JesterInfo { jesters.TryAdd(playerIndex, new JesterInfo {
SteamId = steamId, PlayerIndex = playerIndex,
Active = false, Active = false,
Timer = Instance.AddTimer(wait, () => ChangeMode(steamId)) Timer = Instance.AddTimer(wait, () => ChangeMode(playerIndex), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE)
}); });
} }
private static void ChangeMode(ulong steamId, bool? forceActive = null) private static void ChangeMode(uint playerIndex, bool? forceActive = null)
{ {
if (!jesters.TryGetValue(steamId, out var jester)) return; if (!jesters.TryGetValue(playerIndex, out var jester)) return;
if (jester.Timer != null) if (jester.Timer != null)
{ {
@ -154,10 +152,10 @@ namespace src.player.skills
jester.Timer = null; jester.Timer = null;
} }
var player = Utilities.GetPlayerFromSteamId(steamId); var player = Utilities.GetPlayerFromIndex((int)playerIndex);
if (player == null || !player.IsValid || !player.PawnIsAlive) if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE)
{ {
jesters.TryRemove(steamId, out _); jesters.TryRemove(playerIndex, out _);
return; return;
} }
@ -167,14 +165,17 @@ namespace src.player.skills
if (jester.Active != previousState) if (jester.Active != previousState)
{ {
SetPlayerColor(player); SetPlayerColor(player);
player.ExecuteClientCommand("play sounds/weapons/taser/taser_charge_ready");
var playerEvent = PlayerManager.GetPlayerFromEvent(player);
if (playerEvent != null && playerEvent.IsValid)
playerEvent.ExecuteClientCommand("play sounds/weapons/taser/taser_charge_ready");
} }
var minTime = SkillsInfo.GetValue<float>(skillName, "minTime"); var minTime = SkillsInfo.GetValue<float>(skillName, "minTime");
var maxTime = SkillsInfo.GetValue<float>(skillName, "maxTime"); var maxTime = SkillsInfo.GetValue<float>(skillName, "maxTime");
float wait = (float)Instance.Random.NextDouble() * (maxTime - minTime) + minTime; float wait = (float)Instance.Random.NextDouble() * (maxTime - minTime) + minTime;
jester.Timer = Instance.AddTimer(wait, () => ChangeMode(steamId)); jester.Timer = Instance.AddTimer(wait, () => ChangeMode(playerIndex), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
} }
private static void SetPlayerColor(CCSPlayerController? player, bool forceDisable = false) private static void SetPlayerColor(CCSPlayerController? player, bool forceDisable = false)
@ -184,7 +185,7 @@ namespace src.player.skills
var pawn = player.PlayerPawn.Value; var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return; if (pawn == null || !pawn.IsValid) return;
var jester = GetJesterInfo(player.SteamID); var jester = GetJesterInfo(player.Index);
if (jester == null) return; if (jester == null) return;
var color = jester.Active && !forceDisable ? Color.FromArgb(255, 128, 0, 128) : Color.FromArgb(255, 255, 255, 255); var color = jester.Active && !forceDisable ? Color.FromArgb(255, 128, 0, 128) : Color.FromArgb(255, 255, 255, 255);
@ -195,36 +196,39 @@ 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().Where(p => !p.IsBot && p.PawnIsAlive)) foreach (var player in Utilities.GetPlayers())
{ {
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) continue; var playeEvent = PlayerManager.GetPlayerEvent(player);
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); if (playeEvent == null || !playeEvent.IsValid || playeEvent.PlayerPawn.Value == null || !playeEvent.PlayerPawn.Value.IsValid) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(playeEvent.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
UpdateHUD(player); UpdateHUD(playeEvent);
} }
} }
private static void UpdateHUD(CCSPlayerController player) private static void UpdateHUD(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
var jester = GetJesterInfo(player.SteamID); var jester = GetJesterInfo(player.Index);
if (jester == null) return; if (jester == null) return;
playerInfo.PrintHTML = $"{player.GetTranslation("jester_mode")}: <font color='{(jester.Active ? "#00ff00" : "#ff0000")}'>{player.GetTranslation(jester.Active ? "jester_on" : "jester_off")}</font>"; playerInfo.PrintHTML = $"{player.GetTranslation("jester_mode")}: <font color='{(jester.Active ? "#00ff00" : "#ff0000")}'>{player.GetTranslation(jester.Active ? "jester_on" : "jester_off")}</font>";
} }
public static JesterInfo? GetJesterInfo(ulong steamID) public static JesterInfo? GetJesterInfo(uint playerIndex)
{ {
if (jesters.TryGetValue(steamID, value: out var info)) if (jesters.TryGetValue(playerIndex, value: out var info))
return info; return info;
return null; return null;
} }
public class JesterInfo() public class JesterInfo()
{ {
public required ulong SteamId { get; set; } public required uint PlayerIndex { get; set; }
public bool Active { get; set; } = false; public bool Active { get; set; } = false;
public Timer? Timer { get; set; } = null; public Timer? Timer { get; set; } = null;
} }

View file

@ -1,7 +1,6 @@
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 System.Collections.Concurrent; using System.Collections.Concurrent;
using src.utils; using src.utils;
@ -11,6 +10,7 @@ namespace src.player.skills
{ {
private const Skills skillName = Skills.JumpBan; private const Skills skillName = Skills.JumpBan;
public static readonly ConcurrentDictionary<uint, int> bannedPlayers = []; public static readonly ConcurrentDictionary<uint, int> bannedPlayers = [];
private static readonly ConcurrentDictionary<uint, uint> playersToTarget = [];
public static void LoadSkill() public static void LoadSkill()
{ {
@ -20,13 +20,15 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
bannedPlayers.Clear(); bannedPlayers.Clear();
playersToTarget.Clear();
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
public static void PlayerJump(EventPlayerJump @event) public static void PlayerJump(EventPlayerJump @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return; if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return;
if (!bannedPlayers.TryGetValue(player.Index, out _)) return; if (!bannedPlayers.TryGetValue(player.Index, out _)) return;
bannedPlayers.AddOrUpdate(player.Index, Server.TickCount + 10, (k, v) => Server.TickCount + 10); bannedPlayers.AddOrUpdate(player.Index, Server.TickCount + 10, (k, v) => Server.TickCount + 10);
@ -53,10 +55,10 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); 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.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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);
@ -65,8 +67,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands) public static void TypeSkill(CCSPlayerController player, string[] commands)
{ {
if (player == null || !player.IsValid || !player.PawnIsAlive) return; if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed) if (playerInfo.SkillUsed)
@ -76,7 +78,8 @@ namespace src.player.skills
} }
string enemyId = commands[0]; string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Team != player.Team && p.Index.ToString() == enemyId); if (!uint.TryParse(enemyId, out uint enemyIndex)) { player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("selectplayerskill_incorrect_enemy_index")); return; }
var enemy = Utilities.GetPlayerFromIndex((int)enemyIndex);
if (enemy == null || !enemy.IsValid || enemy.PlayerPawn.Value == null || !enemy.PlayerPawn.Value.IsValid) if (enemy == null || !enemy.IsValid || enemy.PlayerPawn.Value == null || !enemy.PlayerPawn.Value.IsValid)
{ {
@ -85,18 +88,20 @@ namespace src.player.skills
} }
bannedPlayers.AddOrUpdate(enemy.Index, 0, (k, v) => 0); bannedPlayers.AddOrUpdate(enemy.Index, 0, (k, v) => 0);
playersToTarget[player.Index] = enemy.Index;
playerInfo.SkillUsed = true; playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("jumpban_player_info", enemy.PlayerName)); player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("jumpban_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("jumpban_enemy_info")); enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("jumpban_enemy_info"));
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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())));
@ -108,7 +113,20 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return; if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid)
return;
if (playersToTarget.TryRemove(player.Index, out uint targetIndex))
bannedPlayers.TryRemove(targetIndex, out _);
SkillUtils.CloseMenu(player);
}
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null || !player.IsValid) return;
bannedPlayers.TryRemove(player.Index, out _); bannedPlayers.TryRemove(player.Index, out _);
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }

View file

@ -1,8 +1,6 @@
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;
using static src.jRandomSkills;
namespace src.player.skills namespace src.player.skills
{ {
@ -19,9 +17,14 @@ namespace src.player.skills
{ {
var player = @event.Userid; var player = @event.Userid;
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
var playerEvent = PlayerManager.GetPlayerEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(playerEvent.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
SkillUtils.AddHealth(player.PlayerPawn.Value, SkillsInfo.GetValue<int>(skillName, "healthToAdd"));
SkillUtils.AddHealth(playerEvent.PlayerPawn.Value, SkillsInfo.GetValue<int>(skillName, "healthToAdd"));
} }
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a86eff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, int healthToAdd = 3) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity) public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#a86eff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, int healthToAdd = 3) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Commands.Targeting; using CounterStrikeSharp.API.Modules.Commands.Targeting;
using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
@ -18,12 +18,12 @@ namespace src.player.skills
public static void PlayerBlind(EventPlayerBlind @event) public static void PlayerBlind(EventPlayerBlind @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
if (!Instance.IsPlayerValid(player) || !Instance.IsPlayerValid(attacker)) return; if (!Instance.IsPlayerValid(player) || !Instance.IsPlayerValid(attacker)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID); var attackerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
if (!SkillsInfo.GetValue<bool>(skillName, "friendlyFire") && player!.Team == attacker!.Team) return; if (!SkillsInfo.GetValue<bool>(skillName, "friendlyFire") && player!.Team == attacker!.Team) return;

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;
@ -28,20 +28,20 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); 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.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"{e.PlayerName} : {e.PawnHealth} HP", e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"{e.PlayerName} : {e?.PlayerPawn?.Value?.Health ?? 0} HP", e.Index.ToString())));
SkillUtils.UpdateMenu(player, menuItems); SkillUtils.UpdateMenu(player, menuItems);
} }
} }
public static void TypeSkill(CCSPlayerController player, string[] commands) public static void TypeSkill(CCSPlayerController player, string[] commands)
{ {
if (player == null || !player.IsValid || !player.PawnIsAlive) return; if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed) if (playerInfo.SkillUsed)
@ -51,7 +51,8 @@ namespace src.player.skills
} }
string enemyId = commands[0]; string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Team != player.Team && p.Index.ToString() == enemyId); if (!uint.TryParse(enemyId, out uint enemyIndex)) { player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("selectplayerskill_incorrect_enemy_index")); return; }
var enemy = Utilities.GetPlayerFromIndex((int)enemyIndex);
if (enemy == null) if (enemy == null)
{ {
@ -67,11 +68,11 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"{e.PlayerName} : {e.PawnHealth} HP", e.Index.ToString()))); ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"{e.PlayerName} : {e.PawnHealth} HP", e.Index.ToString())));

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
@ -14,7 +14,7 @@ namespace src.player.skills
private static bool hooked = false; private static bool hooked = false;
private const int actionCode = 503; private const int actionCode = 503;
private static readonly ConcurrentDictionary<ulong, byte> playersInAction = []; private static readonly ConcurrentDictionary<uint, byte> playersInAction = [];
private static readonly MemoryFunctionVoid<IntPtr, short> Shoot_Secondary = new(GameData.GetSignature("Shoot_Secondary")); private static readonly MemoryFunctionVoid<IntPtr, short> Shoot_Secondary = new(GameData.GetSignature("Shoot_Secondary"));
public static void LoadSkill() public static void LoadSkill()
@ -34,12 +34,12 @@ namespace src.player.skills
if (hooked) return; if (hooked) return;
hooked = true; hooked = true;
Shoot_Secondary.Hook(ShootSecondary, HookMode.Pre); Shoot_Secondary.Hook(ShootSecondary, HookMode.Pre);
playersInAction.TryAdd(player.SteamID, 0); playersInAction.TryAdd(player.Index, 0);
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
playersInAction.TryRemove(player.SteamID, out _); playersInAction.TryRemove(player.Index, out _);
if (playersInAction.IsEmpty) if (playersInAction.IsEmpty)
{ {
Shoot_Secondary.Unhook(ShootSecondary, HookMode.Pre); Shoot_Secondary.Unhook(ShootSecondary, HookMode.Pre);
@ -61,19 +61,22 @@ namespace src.player.skills
var player = pawn.Controller.Value.As<CCSPlayerController>(); var player = pawn.Controller.Value.As<CCSPlayerController>();
if (player == null || !player.IsValid) return HookResult.Continue; if (player == null || !player.IsValid) return HookResult.Continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var eventPlayer = PlayerManager.GetPlayerEvent(player);
if (eventPlayer == null || !eventPlayer.IsValid) return HookResult.Continue;
var playerInfo = PlayerManager.GetPlayerByIndex(eventPlayer.Index);
if (playerInfo == null || playerInfo.Skill != skillName) return HookResult.Continue; if (playerInfo == null || playerInfo.Skill != skillName) return HookResult.Continue;
KnifeHit(player, true); KnifeHit(eventPlayer, true);
return HookResult.Continue; return HookResult.Continue;
} }
public static void WeaponFire(EventWeaponFire @event) public static void WeaponFire(EventWeaponFire @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(player)) return; if (!Instance.IsPlayerValid(player)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); 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;

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
@ -17,10 +17,10 @@ namespace src.player.skills
public unsafe static void WeaponFire(EventWeaponFire @event) public unsafe static void WeaponFire(EventWeaponFire @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(player)) return; if (!Instance.IsPlayerValid(player)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); 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;

View file

@ -1,10 +1,9 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills namespace src.player.skills
{ {
@ -25,10 +24,10 @@ namespace src.player.skills
public static void DecoyStarted(EventDecoyStarted @event) public static void DecoyStarted(EventDecoyStarted @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
decoys.TryAdd(new Vector(@event.X, @event.Y, @event.Z), 0); decoys.TryAdd(new Vector(@event.X, @event.Y, @event.Z), 0);
@ -36,10 +35,10 @@ namespace src.player.skills
public static void DecoyDetonate(EventDecoyDetonate @event) public static void DecoyDetonate(EventDecoyDetonate @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
foreach (var decoy in decoys.Keys.Where(v => v.X == @event.X && v.Y == @event.Y && v.Z == @event.Z)) foreach (var decoy in decoys.Keys.Where(v => v.X == @event.X && v.Y == @event.Y && v.Z == @event.Z))
@ -49,11 +48,14 @@ 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.PawnIsAlive && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist)) foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist))
{ {
var eventPlayer = PlayerManager.GetPlayerEvent(player);
if (eventPlayer == null || !eventPlayer.IsValid) continue;
var decoyRadius = SkillsInfo.GetValue<float>(skillName, "triggerRadius"); var decoyRadius = SkillsInfo.GetValue<float>(skillName, "triggerRadius");
var pawn = player.PlayerPawn.Value; var pawn = eventPlayer.PlayerPawn.Value;
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);

View file

@ -40,7 +40,7 @@ namespace src.player.skills
foreach (var playerIndex in players.Keys) foreach (var playerIndex in players.Keys)
{ {
var player = Utilities.GetPlayerFromIndex((int)playerIndex); var player = Utilities.GetPlayerFromIndex((int)playerIndex);
if (player == null || !player.IsValid || !player.PawnIsAlive || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid)
{ {
players.TryRemove(playerIndex, out _); players.TryRemove(playerIndex, out _);
continue; continue;

View file

@ -1,9 +1,8 @@
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 System.Collections.Concurrent;
using src.utils; using src.utils;
using System.Collections.Concurrent;
namespace src.player.skills namespace src.player.skills
{ {
@ -11,6 +10,7 @@ namespace src.player.skills
{ {
private const Skills skillName = Skills.Magnifier; private const Skills skillName = Skills.Magnifier;
private static readonly ConcurrentDictionary<uint, uint> playersFOV = []; private static readonly ConcurrentDictionary<uint, uint> playersFOV = [];
private static readonly ConcurrentDictionary<uint, uint> playersToTarget = [];
public static void LoadSkill() public static void LoadSkill()
{ {
@ -27,27 +27,22 @@ namespace src.player.skills
} }
playersFOV.Clear(); playersFOV.Clear();
playersToTarget.Clear();
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null) return;
DisableSkill(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 Utilities.GetPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); 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.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); var enemies = Utilities.GetPlayers().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);
@ -56,8 +51,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands) public static void TypeSkill(CCSPlayerController player, string[] commands)
{ {
if (player == null || !player.IsValid || !player.PawnIsAlive) return; if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed) if (playerInfo.SkillUsed)
@ -67,7 +62,8 @@ namespace src.player.skills
} }
string enemyId = commands[0]; string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Team != player.Team && p.Index.ToString() == enemyId); if (!uint.TryParse(enemyId, out uint enemyIndex)) { player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("selectplayerskill_incorrect_enemy_index")); return; }
var enemy = Utilities.GetPlayerFromIndex((int)enemyIndex);
if (enemy == null) if (enemy == null)
{ {
@ -75,23 +71,24 @@ namespace src.player.skills
return; return;
} }
if (!playersFOV.ContainsKey(enemy.Index)) playersFOV.AddOrUpdate(enemy.Index, enemy.DesiredFOV, (k, v) => enemy.DesiredFOV);
playersFOV.TryAdd(enemy.Index, enemy.DesiredFOV); playersToTarget[player.Index] = enemy.Index;
enemy.DesiredFOV = SkillsInfo.GetValue<uint>(skillName, "customFOV"); enemy.DesiredFOV = SkillsInfo.GetValue<uint>(skillName, "customFOV");
Utilities.SetStateChanged(enemy, "CBasePlayerController", "m_iDesiredFOV"); Utilities.SetStateChanged(enemy, "CBasePlayerController", "m_iDesiredFOV");
playerInfo.SkillUsed = true; playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("magnifier_player_info", enemy.PlayerName)); player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("magnifier_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("magnifier_enemy_info")); enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("magnifier_enemy_info"));
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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())));
@ -103,13 +100,31 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
if (playersFOV.TryGetValue(player.Index, out uint fov)) if (player == null || !player.IsValid) return;
if (playersToTarget.TryRemove(player.Index, out uint targetIndex))
{ {
player.DesiredFOV = fov; var target = Utilities.GetPlayerFromIndex((int)targetIndex);
Utilities.SetStateChanged(player, "CBasePlayerController", "m_iDesiredFOV"); if (target != null && target.IsValid)
if (playersFOV.TryGetValue(targetIndex, out uint fov))
{
target.DesiredFOV = fov;
Utilities.SetStateChanged(target, "CBasePlayerController", "m_iDesiredFOV");
} }
playersFOV.TryRemove(player.Index, out _); playersFOV.TryRemove(targetIndex, out _);
SkillUtils.CloseMenu(player); }
SkillUtils.ResetPrintHTML(player);
}
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null || !player.IsValid) return;
player.DesiredFOV = 0;
Utilities.SetStateChanged(player, "CBasePlayerController", "m_iDesiredFOV");
SkillUtils.ResetPrintHTML(player);
} }
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#9ba882", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, uint customFOV = 50) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity) public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#9ba882", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, uint customFOV = 50) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)

View file

@ -10,7 +10,7 @@ namespace src.player.skills
public class Medic : ISkill public class Medic : ISkill
{ {
private const Skills skillName = Skills.Medic; private const Skills skillName = Skills.Medic;
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = []; private static readonly ConcurrentDictionary<uint, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
public static void LoadSkill() public static void LoadSkill()
@ -29,18 +29,18 @@ namespace src.player.skills
if (SkillUtils.IsFreezeTime()) return; if (SkillUtils.IsFreezeTime()) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
UpdateHUD(player, skillInfo); UpdateHUD(player, skillInfo);
} }
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo SkillPlayerInfo.TryAdd(player.Index, new PlayerSkillInfo
{ {
SteamID = player.SteamID, SteamID = player.Index,
CanUse = true, CanUse = true,
Cooldown = DateTime.MinValue, Cooldown = DateTime.MinValue,
Count = SkillsInfo.GetValue<int>(skillName, "healthShotLimit"), Count = SkillsInfo.GetValue<int>(skillName, "healthShotLimit"),
@ -49,7 +49,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryRemove(player.SteamID, out _); SkillPlayerInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player); SkillUtils.ResetPrintHTML(player);
} }
@ -68,7 +68,7 @@ namespace src.player.skills
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName);
if (skillData == null) return; if (skillData == null) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
string remainingLine = cooldown != 0 string remainingLine = cooldown != 0
@ -83,9 +83,9 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return; if (playerPawn?.CBodyComponent == null) return;
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
{ {
if (!player.IsValid || !player.PawnIsAlive) return; if (!player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
if (skillInfo.CanUse && skillInfo.Count != 0) if (skillInfo.CanUse && skillInfo.Count != 0)
{ {
skillInfo.CanUse = false; skillInfo.CanUse = false;

View file

@ -1,10 +1,9 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills namespace src.player.skills
{ {
@ -87,7 +86,7 @@ namespace src.player.skills
if (pawn.Controller.Value == null || !pawn.Controller.Value.IsValid) return; if (pawn.Controller.Value == null || !pawn.Controller.Value.IsValid) return;
var player = pawn.Controller.Value.As<CCSPlayerController>(); var player = pawn.Controller.Value.As<CCSPlayerController>();
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
nades.TryAdd(grenade.Index, 0); nades.TryAdd(grenade.Index, 0);

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;
@ -28,10 +28,10 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); 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.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account + e.InGameMoneyServices.CashSpentThisRound)}$", e.Index.ToString()))]; ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account + e.InGameMoneyServices.CashSpentThisRound)}$", e.Index.ToString()))];
SkillUtils.UpdateMenu(player, menuItems); SkillUtils.UpdateMenu(player, menuItems);
@ -40,8 +40,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands) public static void TypeSkill(CCSPlayerController player, string[] commands)
{ {
if (player == null || !player.IsValid || !player.PawnIsAlive) return; if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed) if (playerInfo.SkillUsed)
@ -51,7 +51,8 @@ namespace src.player.skills
} }
string enemyId = commands[0]; string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Team != player.Team && p.Index.ToString() == enemyId); if (!uint.TryParse(enemyId, out uint enemyIndex)) { player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("selectplayerskill_incorrect_enemy_index")); return; }
var enemy = Utilities.GetPlayerFromIndex((int)enemyIndex);
if (enemy == null) if (enemy == null)
{ {
@ -67,11 +68,11 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
if (enemies.Length > 0) if (enemies.Length > 0)
{ {
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account + e.InGameMoneyServices.CashSpentThisRound)}$", e.Index.ToString()))]; ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account + e.InGameMoneyServices.CashSpentThisRound)}$", e.Index.ToString()))];

View file

@ -27,7 +27,7 @@ namespace src.player.skills
public static void PlayerDeath(EventPlayerDeath @event) public static void PlayerDeath(EventPlayerDeath @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (!IsDeadPlayerValid(player)) return; if (!IsDeadPlayerValid(player)) return;
CsTeam lastTeam = player!.Team; CsTeam lastTeam = player!.Team;
@ -40,7 +40,7 @@ namespace src.player.skills
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 = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
SpawnExplosion(player!); SpawnExplosion(player!);
}); });
@ -56,9 +56,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 && !p.IsBot)) foreach (var _p in Utilities.GetPlayers().Where(p => p.IsValid && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist))
SkillUtils.PrintToChat(_p, $"{ChatColors.DarkRed}{player.PlayerName}: {ChatColors.Lime}{_p.GetTranslation("muhammed_explosion")}", SkillUtils.PrintToChat(_p, $"{ChatColors.DarkRed}{player.PlayerName}: {ChatColors.Lime}{_p.GetTranslation("muhammed_explosion")}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t"); border: !Utilities.GetPlayers().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

@ -1,4 +1,4 @@
/*using CounterStrikeSharp.API; /*using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using static jRandomSkills.jRandomSkills; using static jRandomSkills.jRandomSkills;
@ -26,7 +26,7 @@ namespace src.player.skills
var pawn = grenade.OwnerEntity.Value.As<CCSPlayerPawn>(); var pawn = grenade.OwnerEntity.Value.As<CCSPlayerPawn>();
var player = pawn.Controller.Value.As<CCSPlayerController>(); var player = pawn.Controller.Value.As<CCSPlayerController>();
var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
Server.NextFrame(() => { Server.NextFrame(() => {
@ -55,8 +55,8 @@ namespace src.player.skills
Instance.AddTimer(5f, () => Instance.AddTimer(5f, () =>
{ {
if (@event != null && @event.IsValid) if (@event != null && @event.IsValid)
@event.AcceptInput("Kill"); @event.AddEntityIOEvent("Kill", ent, delay: 0.1f);
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
}); });
}); });
} }

View file

@ -15,12 +15,14 @@ namespace src.player.skills
private static readonly ConcurrentDictionary<nint, float> invisibilityChanged = []; private static readonly ConcurrentDictionary<nint, float> invisibilityChanged = [];
private static readonly ConcurrentDictionary<uint, byte> invisiblePlayers = []; private static readonly ConcurrentDictionary<uint, byte> invisiblePlayers = [];
private const string bloodParticle = "particles/blood_impact/blood_impact_high.vpcf"; private const string bloodParticle = "particles/blood_impact/blood_impact_high.vpcf";
private const string cameraViewModel = "models/sprays/spray_plane.vmdl";
private static readonly object setLock = new(); private static readonly object setLock = new();
public static void LoadSkill() public static void LoadSkill()
{ {
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color")); SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
Instance.AddToManifest(bloodParticle); Instance.AddToManifest(bloodParticle);
Instance.AddToManifest(cameraViewModel);
} }
public static void NewRound() public static void NewRound()
@ -35,8 +37,9 @@ namespace src.player.skills
public static void WeaponEquip(EventItemEquip @event) public static void WeaponEquip(EventItemEquip @event)
{ {
var player = @event.Userid; var player = @event.Userid;
if (!Instance.IsPlayerValid(player)) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
UpdateNinja(player); UpdateNinja(player);
@ -45,8 +48,9 @@ namespace src.player.skills
public static void WeaponPickup(EventItemPickup @event) public static void WeaponPickup(EventItemPickup @event)
{ {
var player = @event.Userid; var player = @event.Userid;
if (!Instance.IsPlayerValid(player)) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
UpdateNinja(player); UpdateNinja(player);
@ -56,7 +60,7 @@ namespace src.player.skills
{ {
foreach (var (info, player) in infoList) foreach (var (info, player) in infoList)
{ {
if (player == null || !player.IsValid) continue; if (player == null || !player.IsValid || player.Team == CsTeam.Spectator) continue;
var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero; var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero;
bool isObservingNinja = false; bool isObservingNinja = false;
@ -64,14 +68,17 @@ namespace src.player.skills
if (targetHandle != nint.Zero) if (targetHandle != nint.Zero)
{ {
var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle); var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle);
var targetInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == target?.SteamID); var targetInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(target)?.Index);
if (targetInfo?.Skill == skillName) isObservingNinja = true; if (targetInfo?.Skill == skillName) isObservingNinja = true;
} }
foreach (var playerIndex in invisiblePlayers.Keys) foreach (var playerIndex in invisiblePlayers.Keys)
{ {
var playerController = Utilities.GetPlayerFromIndex((int)playerIndex); var playerController = PlayerManager.GetPlayerEvent(Utilities.GetPlayerFromIndex((int)playerIndex));
if (playerController == null || !playerController.IsValid || playerController.SteamID == player.SteamID) if (playerController == null || !playerController.IsValid || playerController.Index == player.Index)
continue;
if (player.Team == playerController.Team)
continue; continue;
if (!isObservingNinja) if (!isObservingNinja)
@ -95,31 +102,81 @@ namespace src.player.skills
public static void OnTick() public static void OnTick()
{ {
if (Server.TickCount % 2 != 0) return;
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); if (player.LifeState != (byte)LifeState_t.LIFE_ALIVE)
if (playerInfo?.Skill == skillName)
UpdateNinja(player);
if (!player.PawnIsAlive)
invisiblePlayers.TryRemove(player.Index, out _); invisiblePlayers.TryRemove(player.Index, out _);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) continue;
UpdateNinja(PlayerManager.GetPlayerFromEvent(player));
var props = EntityManager.GetPlayerEntities(PlayerManager.GetPlayerEvent(player)!.Index, "empty_prop");
if (props.Count == 0) continue;
var prop = Utilities.GetEntityFromIndex<CDynamicProp>((int)props[0]);
if (prop == null || !prop.IsValid) continue;
var pawn = player.PlayerPawn?.Value;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue;
Vector newPos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + 30);
QAngle newAngle = new(0, pawn.V_angle.Y, 0);
prop.Teleport(newPos, newAngle, null);
} }
} }
public static void EnableSkill(CCSPlayerController _) public static void EnableSkill(CCSPlayerController player)
{ {
Event.EnableTransmit(); Event.EnableTransmit();
if (EntityManager.GetPlayerEntities(player.Index, "empty_prop").Count == 0)
CreatePlayerPosProp(player);
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
SetPlayerVisibility(player, 0); SkillUtils.SetPlayerInvisibility(player, 0);
invisiblePlayers.TryRemove(player.Index, out _); invisiblePlayers.TryRemove(player.Index, out _);
EntityManager.DestroyPlayerEntities(player.Index);
}
private static void CreatePlayerPosProp(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
var emptyProp = EntityManager.CreateTrackedDynamicProp(player.Index);
if (emptyProp == null || !emptyProp.IsValid) return;
var playerPawn = player.PlayerPawn?.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null || playerPawn.AbsRotation == null) return;
emptyProp.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(emptyProp.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
emptyProp.SetModel(cameraViewModel);
emptyProp.Render = Color.FromArgb(1, 255, 255, 255);
Vector newPos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 30);
QAngle newAngle = new(playerPawn.AbsRotation.X, playerPawn.AbsRotation.Y, playerPawn.AbsRotation.Z);
emptyProp.Teleport(newPos, newAngle);
emptyProp.DispatchSpawn();
Utilities.SetStateChanged(emptyProp, "CBaseEntity", "m_CBodyComponent");
EntityManager.RegisterExisting(emptyProp, player.Index, "empty_prop");
} }
private static void UpdateNinja(CCSPlayerController? player) private static void UpdateNinja(CCSPlayerController? player)
{ {
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var pawn = player.PlayerPawn?.Value;
var playerEvent = PlayerManager.GetPlayerEvent(player);
if (playerEvent == null || !playerEvent.IsValid) return;
var pawn = playerEvent.PlayerPawn?.Value;
if (pawn == null || !pawn.IsValid || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE) return; if (pawn == null || !pawn.IsValid || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var flags = (PlayerFlags)pawn.Flags; var flags = (PlayerFlags)pawn.Flags;
@ -138,51 +195,35 @@ namespace src.player.skills
if (!buttons.HasFlag(PlayerButtons.Moveleft) && !buttons.HasFlag(PlayerButtons.Moveright) && !buttons.HasFlag(PlayerButtons.Forward) && !buttons.HasFlag(PlayerButtons.Back) && flags.HasFlag(PlayerFlags.FL_ONGROUND)) if (!buttons.HasFlag(PlayerButtons.Moveleft) && !buttons.HasFlag(PlayerButtons.Moveright) && !buttons.HasFlag(PlayerButtons.Forward) && !buttons.HasFlag(PlayerButtons.Back) && flags.HasFlag(PlayerFlags.FL_ONGROUND))
percentInvisibility += SkillsInfo.GetValue<float>(skillName, "idlePercentInvisibility"); percentInvisibility += SkillsInfo.GetValue<float>(skillName, "idlePercentInvisibility");
if (invisibilityChanged.TryGetValue(player.Handle, out float oldInvisibility)) if (invisibilityChanged.TryGetValue(playerEvent.Handle, out float oldInvisibility))
if (percentInvisibility == oldInvisibility) if (percentInvisibility == oldInvisibility)
return; return;
invisibilityChanged.AddOrUpdate(player.Handle, percentInvisibility, (_, _) => percentInvisibility); invisibilityChanged.AddOrUpdate(playerEvent.Handle, percentInvisibility, (_, _) => percentInvisibility);
if (percentInvisibility > .9) if (percentInvisibility > .9)
invisiblePlayers.TryAdd(player.Index, 0); invisiblePlayers.TryAdd(playerEvent.Index, 0);
else else
{ {
SetPlayerVisibility(player, percentInvisibility); SkillUtils.SetPlayerInvisibility(playerEvent, percentInvisibility);
invisiblePlayers.TryRemove(player.Index, out _); invisiblePlayers.TryRemove(playerEvent.Index, out _);
}
}
private static void SetPlayerVisibility(CCSPlayerController player, float percentInvisibility)
{
var playerPawn = player.PlayerPawn.Value;
if (playerPawn != null)
{
var color = Color.FromArgb(Math.Max(255 - (int)(255 * percentInvisibility), 0), 255, 255, 255);
playerPawn.Render = color;
Utilities.SetStateChanged(playerPawn, "CBaseModelEntity", "m_clrRender");
} }
} }
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
if (!invisiblePlayers.ContainsKey(player.Index)) return; if (!invisiblePlayers.ContainsKey(player.Index)) return;
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return; if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return;
CParticleSystem particle = Utilities.CreateEntityByName<CParticleSystem>("info_particle_system")!; var particle = EntityManager.CreateTrackedParticleSystem(player.Index, bloodParticle, autoDestroySeconds: 3f);
if (particle == null) return; if (particle == null) return;
particle.EffectName = bloodParticle;
particle.StartActive = true;
Vector pos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 50); Vector pos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 50);
particle.Teleport(pos); particle.Teleport(pos);
particle.DispatchSpawn();
particle.AcceptInput("Start"); particle.AcceptInput("Start");
} }

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,11 +18,11 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var damage = @event.DmgHealth; var damage = @event.DmgHealth;
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Weapon; var weapon = @event.Weapon;
if (!Instance.IsPlayerValid(player)) return; if (!Instance.IsPlayerValid(player)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (weapon == "hegrenade" || weapon == "inferno" || weapon == "decoy" || weapon == "flashbang" || weapon == "smokegrenade" || weapon == "molotov") if (weapon == "hegrenade" || weapon == "inferno" || weapon == "decoy" || weapon == "flashbang" || weapon == "smokegrenade" || weapon == "molotov")

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;
@ -25,13 +25,13 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
player.ReplicateConVar("weapon_accuracy_nospread", "1"); Server.ExecuteCommand("weapon_accuracy_nospread 1");
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
player.ReplicateConVar("weapon_accuracy_nospread", "0"); Server.ExecuteCommand("weapon_accuracy_nospread 0");
} }
public static void OnTick() public static void OnTick()
@ -39,7 +39,7 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
if (!Instance.IsPlayerValid(player)) continue; if (!Instance.IsPlayerValid(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
{ {

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities; using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Memory;
@ -13,7 +13,7 @@ namespace src.player.skills
public class Noclip : ISkill public class Noclip : ISkill
{ {
private const Skills skillName = Skills.Noclip; private const Skills skillName = Skills.Noclip;
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = []; private static readonly ConcurrentDictionary<uint, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
public static void LoadSkill() public static void LoadSkill()
@ -31,18 +31,18 @@ namespace src.player.skills
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
UpdateHUD(player, skillInfo); UpdateHUD(player, skillInfo);
} }
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo SkillPlayerInfo.TryAdd(player.Index, new PlayerSkillInfo
{ {
SteamID = player.SteamID, SteamID = player.Index,
CanUse = true, CanUse = true,
IsFlying = false, IsFlying = false,
Cooldown = DateTime.MinValue, Cooldown = DateTime.MinValue,
@ -52,7 +52,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
SkillPlayerInfo.TryRemove(player.SteamID, out _); SkillPlayerInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player); SkillUtils.ResetPrintHTML(player);
} }
@ -72,7 +72,7 @@ namespace src.player.skills
skillInfo.CanUse = true; skillInfo.CanUse = true;
} }
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
if (cooldown == 0) if (cooldown == 0)
@ -92,9 +92,9 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return; if (playerPawn?.CBodyComponent == null) return;
ulong steamId = player.SteamID; uint playerIndex = player.Index;
if (SkillPlayerInfo.TryGetValue(steamId, out var skillInfo)) if (SkillPlayerInfo.TryGetValue(playerIndex, out var skillInfo))
{ {
if (skillInfo.IsFlying) if (skillInfo.IsFlying)
{ {
@ -116,14 +116,14 @@ namespace src.player.skills
skillInfo.Timer = Instance.AddTimer(duration, () => skillInfo.Timer = Instance.AddTimer(duration, () =>
{ {
var player = Utilities.GetPlayerFromSteamId(steamId); var player = Utilities.GetPlayerFromIndex((int)playerIndex);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == steamId); var playerInfo = PlayerManager.GetPlayerByIndex(playerIndex);
if (playerInfo == null) return; if (playerInfo == null) return;
StopFlying(player, skillInfo); StopFlying(player, skillInfo);
}); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
} }
} }
} }
@ -133,7 +133,7 @@ namespace src.player.skills
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 || !player.PawnIsAlive) return; if (playerPawn == null || !playerPawn.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
playerPawn.MoveType = noclip ? MoveType_t.MOVETYPE_NOCLIP : MoveType_t.MOVETYPE_WALK; playerPawn.MoveType = noclip ? MoveType_t.MOVETYPE_NOCLIP : MoveType_t.MOVETYPE_WALK;
Schema.SetSchemaValue(playerPawn.Handle, "CBaseEntity", "m_nActualMoveType", (int)playerPawn.MoveType); Schema.SetSchemaValue(playerPawn.Handle, "CBaseEntity", "m_nActualMoveType", (int)playerPawn.MoveType);
@ -148,7 +148,7 @@ namespace src.player.skills
if (!skillInfo.IsFlying) return; if (!skillInfo.IsFlying) return;
skillInfo.IsFlying = false; skillInfo.IsFlying = false;
if (player == null || !player.IsValid || !player.PawnIsAlive) return; if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
SetNoclip(player, false); SetNoclip(player, false);
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
@ -32,13 +32,12 @@ namespace src.player.skills
if (attackerPawn == null || attackerPawn.Controller?.Value == null || victimPawn == null || victimPawn.Controller?.Value == null) if (attackerPawn == null || attackerPawn.Controller?.Value == null || victimPawn == null || victimPawn.Controller?.Value == null)
return; return;
CCSPlayerController attacker = attackerPawn.Controller.Value.As<CCSPlayerController>(); CCSPlayerController attacker = PlayerManager.GetPlayerEvent(attackerPawn.Controller.Value.As<CCSPlayerController>())!;
CCSPlayerController victim = victimPawn.Controller.Value.As<CCSPlayerController>();
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(attacker)!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
if (playerInfo.Skill == skillName && attacker.PawnIsAlive) if (playerInfo.Skill == skillName)
param2.Damage = 1000f; param2.Damage = 1000f;
} }

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;
@ -17,13 +17,13 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = @event.Userid; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
int damage = @event.DmgHealth; int damage = @event.DmgHealth;
var hitgroup = (HitGroup_t)@event.Hitgroup; var hitgroup = (HitGroup_t)@event.Hitgroup;
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim)) return; if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim)) return;
var victimInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == victim?.SteamID); var victimInfo = PlayerManager.GetPlayerByIndex(victim!.Index);
if (victimInfo == null || victimInfo.Skill != skillName) return; if (victimInfo == null || victimInfo.Skill != skillName) return;
HitGroup_t[] disabledHitbox = [HitGroup_t.HITGROUP_LEFTARM, HitGroup_t.HITGROUP_RIGHTARM, HitGroup_t.HITGROUP_LEFTLEG, HitGroup_t.HITGROUP_RIGHTLEG]; HitGroup_t[] disabledHitbox = [HitGroup_t.HITGROUP_LEFTARM, HitGroup_t.HITGROUP_RIGHTARM, HitGroup_t.HITGROUP_LEFTLEG, HitGroup_t.HITGROUP_RIGHTLEG];

View file

@ -21,17 +21,19 @@ namespace src.player.skills
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
if (!Instance.IsPlayerValid(player)) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerEvent = PlayerManager.GetPlayerEvent(player);
var playerInfo = PlayerManager.GetPlayerByIndex(playerEvent!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
GiveAdditionalJump(player); GiveAdditionalJump(player, playerEvent);
} }
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerPawn == null || playerInfo == null) return; if (playerPawn == null || playerInfo == null) return;
var skillConfig = SkillsInfo.LoadedConfig.FirstOrDefault(s => s.Name == skillName.ToString()); var skillConfig = SkillsInfo.LoadedConfig.FirstOrDefault(s => s.Name == skillName.ToString());
@ -40,15 +42,18 @@ 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.IsBot && p != player) ? "tb" : "t"); border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
} }
private static void GiveAdditionalJump(CCSPlayerController player) private static void GiveAdditionalJump(CCSPlayerController player, CCSPlayerController playerEvent)
{ {
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return; if (playerPawn == null || !playerPawn.IsValid) return;
var flags = (PlayerFlags)playerPawn.Flags; var playerEventPawn = playerEvent.PlayerPawn.Value;
if (playerEventPawn == null || !playerEventPawn.IsValid) return;
var flags = (PlayerFlags)playerEventPawn.Flags;
var buttons = player.Buttons; var buttons = player.Buttons;
bool isJumpDown = (playerPawn.MovementServices?.Buttons?.ButtonStates[0] & (ulong)PlayerButtons.Jump) != 0 || (buttons & PlayerButtons.Jump) != 0; bool isJumpDown = (playerPawn.MovementServices?.Buttons?.ButtonStates[0] & (ulong)PlayerButtons.Jump) != 0 || (buttons & PlayerButtons.Jump) != 0;
@ -57,8 +62,8 @@ namespace src.player.skills
bool jumpPressed = (isJumpDown && !wasJumpDown) bool jumpPressed = (isJumpDown && !wasJumpDown)
|| (playerPawn.MovementServices?.QueuedButtonChangeMask & (ulong)PlayerButtons.Jump) != 0; || (playerPawn.MovementServices?.QueuedButtonChangeMask & (ulong)PlayerButtons.Jump) != 0;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(playerEvent!.Index);
if (playerPawn == null || playerInfo == null) return; if (playerInfo == null) return;
bool isOnGround = (flags & PlayerFlags.FL_ONGROUND) != 0; bool isOnGround = (flags & PlayerFlags.FL_ONGROUND) != 0;
@ -67,7 +72,7 @@ namespace src.player.skills
else if (jumpPressed && J[player.Slot] < playerInfo.SkillChance + 1) else if (jumpPressed && J[player.Slot] < playerInfo.SkillChance + 1)
{ {
J[player.Slot]++; J[player.Slot]++;
playerPawn.AbsVelocity.Z = 300; playerEventPawn.AbsVelocity.Z = 300;
} }
LB[player.Slot] = buttons; LB[player.Slot] = buttons;

View file

@ -1,122 +1,60 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Timers;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
using src.utils; using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills; using static src.jRandomSkills;
using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
namespace src.player.skills 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 static readonly object setLock = new();
private static readonly ConcurrentDictionary<ulong, Timer> timers = [];
public static void LoadSkill() public static void LoadSkill()
{ {
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"), false); SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"), false);
} }
public static void PlayerDeath(EventPlayerDeath @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var player = @event.Userid; var user = @event.Userid;
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return; if (user == null || !user.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var victim = PlayerManager.GetPlayerEvent(@event.Userid);
if (playerInfo?.Skill == skillName) if (victim == null || !victim.IsValid) return;
{
if (Instance.Random.NextDouble() <= playerInfo.SkillChance)
{
lock (setLock)
{
ulong steamID = player.SteamID;
int team = player.TeamNum;
if (team != 2 && team != 3) return; var pawn = victim.PlayerPawn.Value;
player.Respawn();
Server.NextFrame(() => {
lock (setLock)
{
var player = Utilities.GetPlayerFromSteamId(steamID);
if (player == null || !player.IsValid || !player.PlayerPawn.IsValid) return;
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return; if (pawn == null || !pawn.IsValid) return;
bool isBlock = team != player.TeamNum || player.TeamChanged; var playerInfo = PlayerManager.GetPlayerByIndex(victim.Index);
if (playerInfo?.Skill != skillName || pawn.Health > 0) return;
player.Respawn(); if (Instance.Random.NextDouble() > playerInfo.SkillChance) return;
if (victim.TeamChanged) return;
if (isBlock) SkillUtils.AddHealth(pawn, 100 - pawn.Health);
{ SkillUtils.PrintToChat(user, user.GetTranslation("phoenix_respawn"));
pawn.Flags |= (uint)Flags_t.FL_FROZEN;
pawn.Teleport(new Vector(0, 0, -1000), new QAngle(90, 0, 0));
bool isFreezeTime = Instance.GameRules != null && Instance.GameRules.FreezePeriod == true;
if (!isFreezeTime)
{
Server.NextFrame(() => Server.NextFrame(() =>
{ {
if (victim == null || !victim.IsValid) return;
if (pawn == null || !pawn.IsValid) return; if (pawn == null || !pawn.IsValid) return;
pawn.CommitSuicide(false, true);
var spawnpoint = SkillUtils.GetSpawnPointVector(victim);
if (spawnpoint == null) return;
pawn.Teleport(spawnpoint);
}); });
return;
}
ulong steamId = player.SteamID;
if (!timers.ContainsKey(player.SteamID))
{
var timer = Instance.AddTimer(1f, () =>
{
if (player == null || !player.IsValid || pawn == null || !pawn.IsValid)
{
if (timers.TryRemove(steamId, out var t))
t.Kill();
return;
}
bool isFreezeTime = Instance.GameRules != null && Instance.GameRules.FreezePeriod == true;
if (!isFreezeTime)
{
if (timers.TryRemove(steamId, out var t))
t.Kill();
pawn.CommitSuicide(false, true);
return;
}
}, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT);
timers.TryAdd(player.SteamID, timer);
}
return;
}
}
});
SkillUtils.PrintToChat(player, player.GetTranslation("phoenix_respawn"));
}
}
}
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
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.IsBot && p != player) ? "tb" : "t"); border: !Utilities.GetPlayers().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 = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float chanceFrom = .2f, float chanceTo = .4f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, 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 = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float chanceFrom = .2f, float chanceTo = .4f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)

View file

@ -10,7 +10,7 @@ namespace src.player.skills
public class Pilot : ISkill public class Pilot : ISkill
{ {
private const Skills skillName = Skills.Pilot; private const Skills skillName = Skills.Pilot;
private static readonly ConcurrentDictionary<ulong, Pilot_PlayerInfo> PlayerPilotInfo = []; private static readonly ConcurrentDictionary<uint, Pilot_PlayerInfo> PlayerPilotInfo = [];
public static void LoadSkill() public static void LoadSkill()
{ {
@ -26,7 +26,7 @@ namespace src.player.skills
{ {
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
HandlePilot(player); HandlePilot(player);
} }
@ -34,12 +34,12 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
PlayerPilotInfo.TryAdd(player.SteamID, new Pilot_PlayerInfo { SteamID = player.SteamID }); PlayerPilotInfo.TryAdd(player.Index, new Pilot_PlayerInfo { SteamID = player.Index });
} }
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
PlayerPilotInfo.TryRemove(player.SteamID, out _); PlayerPilotInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player); SkillUtils.ResetPrintHTML(player);
} }
@ -48,7 +48,7 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value; var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return; if (playerPawn == null || !playerPawn.IsValid) return;
if (!PlayerPilotInfo.TryGetValue(player.SteamID, out var pilotInfo)) return; if (!PlayerPilotInfo.TryGetValue(player.Index, out var pilotInfo)) return;
var flags = (PlayerFlags)playerPawn.Flags; var flags = (PlayerFlags)playerPawn.Flags;
var buttons = player.Buttons; var buttons = player.Buttons;
@ -107,7 +107,7 @@ namespace src.player.skills
private static void UpdateHUD(CCSPlayerController player, Pilot_PlayerInfo pilotInfo) private static void UpdateHUD(CCSPlayerController player, Pilot_PlayerInfo pilotInfo)
{ {
if (pilotInfo == null) return; if (pilotInfo == null) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
var maximumFuel = SkillsInfo.GetValue<float>(skillName, "maximumFuel"); var maximumFuel = SkillsInfo.GetValue<float>(skillName, "maximumFuel");

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
@ -11,7 +11,7 @@ namespace src.player.skills
public class Planter : ISkill public class Planter : ISkill
{ {
private const Skills skillName = Skills.Planter; private const Skills skillName = Skills.Planter;
private static readonly ConcurrentDictionary<ulong, float> plantingPlayers = []; private static readonly ConcurrentDictionary<uint, float> plantingPlayers = [];
public static void LoadSkill() public static void LoadSkill()
{ {
@ -20,26 +20,26 @@ namespace src.player.skills
public static void BombBeginplant(EventBombBeginplant @event) public static void BombBeginplant(EventBombBeginplant @event)
{ {
var user = @event.Userid; var user = PlayerManager.GetPlayerEvent(@event.Userid);
if (user == null || !user.IsValid || !user.PawnIsAlive) return; if (user == null || !user.IsValid || !user.PawnIsAlive) return;
plantingPlayers.TryAdd(user.SteamID, Server.CurrentTime); plantingPlayers.TryAdd(user.Index, Server.CurrentTime);
} }
public static void BombAbortplant(EventBombAbortplant @event) public static void BombAbortplant(EventBombAbortplant @event)
{ {
var user = @event.Userid; var user = PlayerManager.GetPlayerEvent(@event.Userid);
if (user == null || !user.IsValid || !user.PawnIsAlive) return; if (user == null || !user.IsValid || !user.PawnIsAlive) return;
plantingPlayers.TryRemove(user.SteamID, out _); plantingPlayers.TryRemove(user.Index, out _);
SkillUtils.ResetPrintHTML(user); SkillUtils.ResetPrintHTML(user);
} }
public static void BombPlanted(EventBombPlanted @event) public static void BombPlanted(EventBombPlanted @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(player)) return; if (!Instance.IsPlayerValid(player)) return;
plantingPlayers.TryRemove(player!.SteamID, out _); plantingPlayers.TryRemove(player!.Index, out _);
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
playerInfo.PrintHTML = null; playerInfo.PrintHTML = null;
@ -64,7 +64,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
plantingPlayers.TryRemove(player.SteamID, out _); plantingPlayers.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player); SkillUtils.ResetPrintHTML(player);
var pawn = player.PlayerPawn.Value; var pawn = player.PlayerPawn.Value;
@ -80,7 +80,7 @@ namespace src.player.skills
{ {
if (!Instance.IsPlayerValid(player)) continue; if (!Instance.IsPlayerValid(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) continue; if (playerInfo?.Skill != skillName) continue;
var pawn = player.PlayerPawn.Value; var pawn = player.PlayerPawn.Value;
@ -93,7 +93,7 @@ namespace src.player.skills
pawn.InBombZone = true; pawn.InBombZone = true;
Schema.SetSchemaValue<bool>(pawn.Handle, "CCSPlayerPawn", "m_bInBombZone", true); Schema.SetSchemaValue<bool>(pawn.Handle, "CCSPlayerPawn", "m_bInBombZone", true);
if (plantingPlayers.TryGetValue(player.SteamID, out float plantTime)) if (plantingPlayers.TryGetValue(player.Index, out float plantTime))
{ {
float remaining = plantTime + 3f - currentTime; float remaining = plantTime + 3f - currentTime;
playerInfo.PrintHTML = $"{player.GetTranslation("planter_planting", $"<font color='#00FF00'>{Math.Max(0, remaining):0.0}s</font>")}"; playerInfo.PrintHTML = $"{player.GetTranslation("planter_planting", $"<font color='#00FF00'>{Math.Max(0, remaining):0.0}s</font>")}";

View file

@ -1,7 +1,6 @@
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 System.Collections.Concurrent; using System.Collections.Concurrent;
using src.utils; using src.utils;
@ -11,6 +10,7 @@ namespace src.player.skills
{ {
private const Skills skillName = Skills.Poison; private const Skills skillName = Skills.Poison;
private static readonly ConcurrentDictionary<uint, byte> poisonedPlayers = []; private static readonly ConcurrentDictionary<uint, byte> poisonedPlayers = [];
private static readonly ConcurrentDictionary<uint, uint> playersToTarget = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
public static void LoadSkill() public static void LoadSkill()
@ -21,7 +21,10 @@ namespace src.player.skills
public static void NewRound() public static void NewRound()
{ {
lock (setLock) lock (setLock)
{
poisonedPlayers.Clear(); poisonedPlayers.Clear();
playersToTarget.Clear();
}
} }
public static void OnTick() public static void OnTick()
@ -45,10 +48,10 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); 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.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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);
@ -57,8 +60,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands) public static void TypeSkill(CCSPlayerController player, string[] commands)
{ {
if (player == null || !player.IsValid || !player.PawnIsAlive) return; if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed) if (playerInfo.SkillUsed)
@ -68,7 +71,8 @@ namespace src.player.skills
} }
string enemyId = commands[0]; string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Team != player.Team && p.Index.ToString() == enemyId); if (!uint.TryParse(enemyId, out uint enemyIndex)) { player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("selectplayerskill_incorrect_enemy_index")); return; }
var enemy = Utilities.GetPlayerFromIndex((int)enemyIndex);
if (enemy == null) if (enemy == null)
{ {
@ -77,18 +81,20 @@ namespace src.player.skills
} }
poisonedPlayers.TryAdd(enemy.Index, 0); poisonedPlayers.TryAdd(enemy.Index, 0);
playersToTarget[player.Index] = enemy.Index;
playerInfo.SkillUsed = true; playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("poison_player_info", enemy.PlayerName)); player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("poison_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("poison_enemy_info")); enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("poison_enemy_info"));
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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())));
@ -100,6 +106,17 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
if (playersToTarget.TryRemove(player.Index, out uint targetIndex))
poisonedPlayers.TryRemove(targetIndex, out _);
SkillUtils.CloseMenu(player);
}
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null || !player.IsValid) return;
poisonedPlayers.TryRemove(player.Index, out _); poisonedPlayers.TryRemove(player.Index, out _);
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }

View file

@ -1,7 +1,6 @@
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 System.Collections.Concurrent; using System.Collections.Concurrent;
using src.utils; using src.utils;
@ -10,7 +9,8 @@ namespace src.player.skills
public class PrimaryBan : ISkill public class PrimaryBan : ISkill
{ {
private const Skills skillName = Skills.PrimaryBan; private const Skills skillName = Skills.PrimaryBan;
private static readonly ConcurrentDictionary<ulong, byte> bannedPlayers = []; private static readonly ConcurrentDictionary<uint, byte> bannedPlayers = [];
private static readonly ConcurrentDictionary<uint, uint> playersToTarget = [];
private static readonly object setLock = new(); private static readonly object setLock = new();
private static readonly string[] disabledWeapons = private static readonly string[] disabledWeapons =
[ [
@ -28,6 +28,8 @@ namespace src.player.skills
lock (setLock) lock (setLock)
{ {
bannedPlayers.Clear(); bannedPlayers.Clear();
playersToTarget.Clear();
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }
@ -35,10 +37,10 @@ namespace src.player.skills
public static void WeaponEquip(EventItemEquip @event) public static void WeaponEquip(EventItemEquip @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item; var weapon = @event.Item;
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
if (!bannedPlayers.ContainsKey(player.SteamID) || !disabledWeapons.Contains(weapon)) return; if (!bannedPlayers.ContainsKey(player.Index) || !disabledWeapons.Contains(weapon)) return;
player.ExecuteClientCommand("slot3"); player.ExecuteClientCommand("slot3");
} }
@ -48,10 +50,10 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers()) foreach (var player in Utilities.GetPlayers())
{ {
if (!SkillUtils.HasMenu(player)) continue; if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); 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.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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);
@ -60,8 +62,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands) public static void TypeSkill(CCSPlayerController player, string[] commands)
{ {
if (player == null || !player.IsValid || !player.PawnIsAlive) return; if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return; if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed) if (playerInfo.SkillUsed)
@ -71,7 +73,8 @@ namespace src.player.skills
} }
string enemyId = commands[0]; string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Team != player.Team && p.Index.ToString() == enemyId); if (!uint.TryParse(enemyId, out uint enemyIndex)) { player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("selectplayerskill_incorrect_enemy_index")); return; }
var enemy = Utilities.GetPlayerFromIndex((int)enemyIndex);
if (enemy == null) if (enemy == null)
{ {
@ -79,9 +82,11 @@ namespace src.player.skills
return; return;
} }
bannedPlayers.TryAdd(enemy.SteamID, 0); bannedPlayers.TryAdd(enemy.Index, 0);
playersToTarget[player.Index] = enemy.Index;
CheckWeapon(enemy); CheckWeapon(enemy);
playerInfo.SkillUsed = true; playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("primaryban_player_info", enemy.PlayerName)); player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("primaryban_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("primaryban_enemy_info")); enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("primaryban_enemy_info"));
} }
@ -92,17 +97,17 @@ namespace src.player.skills
if (activeWeapon == null || !activeWeapon.IsValid) return; if (activeWeapon == null || !activeWeapon.IsValid) return;
if (activeWeapon.DesignerName == null || string.IsNullOrEmpty(activeWeapon.DesignerName)) return; if (activeWeapon.DesignerName == null || string.IsNullOrEmpty(activeWeapon.DesignerName)) return;
if (!bannedPlayers.ContainsKey(player.SteamID) || !disabledWeapons.Contains(activeWeapon.DesignerName?.Replace("weapon_", ""))) return; if (!bannedPlayers.ContainsKey(player.Index) || !disabledWeapons.Contains(activeWeapon.DesignerName?.Replace("weapon_", ""))) return;
player.ExecuteClientCommand("slot3"); player.ExecuteClientCommand("slot3");
} }
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
playerInfo.SkillUsed = false; playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray(); 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();
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())));
@ -114,7 +119,18 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player) public static void DisableSkill(CCSPlayerController player)
{ {
bannedPlayers.TryRemove(player.SteamID, out _); if (playersToTarget.TryRemove(player.Index, out uint targetIndex))
bannedPlayers.TryRemove(targetIndex, out _);
SkillUtils.CloseMenu(player);
}
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null || !player.IsValid) return;
bannedPlayers.TryRemove(player.Index, out _);
SkillUtils.CloseMenu(player); SkillUtils.CloseMenu(player);
} }

View file

@ -1,4 +1,3 @@
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;
@ -17,13 +16,12 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = @event.Userid; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
int damage = @event.DmgHealth;
var hitgroup = (HitGroup_t)@event.Hitgroup; var hitgroup = (HitGroup_t)@event.Hitgroup;
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim)) return; if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim)) return;
var victimInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == victim?.SteamID); var victimInfo = PlayerManager.GetPlayerByIndex(victim!.Index);
if (victimInfo == null || victimInfo.Skill != skillName) return; if (victimInfo == null || victimInfo.Skill != skillName) return;
HitGroup_t[] disabledHitbox = [HitGroup_t.HITGROUP_LEFTARM, HitGroup_t.HITGROUP_RIGHTARM, HitGroup_t.HITGROUP_LEFTLEG, HitGroup_t.HITGROUP_RIGHTLEG]; HitGroup_t[] disabledHitbox = [HitGroup_t.HITGROUP_LEFTARM, HitGroup_t.HITGROUP_RIGHTARM, HitGroup_t.HITGROUP_LEFTLEG, HitGroup_t.HITGROUP_RIGHTLEG];

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;
@ -31,10 +31,10 @@ namespace src.player.skills
public static void PlayerDeath(EventPlayerDeath @event) public static void PlayerDeath(EventPlayerDeath @event)
{ {
var player = @event.Userid; var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return; if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName) if (playerInfo?.Skill == skillName)
SkillPlayerInfo.TryRemove(player.Index, out _); SkillPlayerInfo.TryRemove(player.Index, out _);
} }
@ -78,7 +78,7 @@ 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)
{ {
plantedBomb.AcceptInput("Kill"); plantedBomb.AddEntityIOEvent("Kill", plantedBomb, delay: 0.1f);
SkillUtils.TerminateRound(CsTeam.CounterTerrorist); SkillUtils.TerminateRound(CsTeam.CounterTerrorist);
} }
SkillUtils.ResetPrintHTML(player); SkillUtils.ResetPrintHTML(player);
@ -96,7 +96,7 @@ namespace src.player.skills
SkillPlayerInfo.TryAdd(player.Index, new PlayerSkillInfo SkillPlayerInfo.TryAdd(player.Index, new PlayerSkillInfo
{ {
SteamID = player.SteamID, SteamID = player.Index,
Defusing = false, Defusing = false,
DefusingTime = SkillsInfo.GetValue<float>(skillName, "defusingTime"), DefusingTime = SkillsInfo.GetValue<float>(skillName, "defusingTime"),
}); });
@ -113,7 +113,7 @@ namespace src.player.skills
if (!skillInfo.Defusing) return; if (!skillInfo.Defusing) return;
int cooldown = (int)Math.Ceiling(skillInfo.DefusingTime); int cooldown = (int)Math.Ceiling(skillInfo.DefusingTime);
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
if (cooldown == 0) if (cooldown == 0)

View file

@ -17,13 +17,13 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var attacker = @event.Attacker; var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = @event.Userid; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim)
return; return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
if (playerInfo?.Skill == skillName && victim!.PawnIsAlive) if (playerInfo?.Skill == skillName && victim!.PawnIsAlive)
{ {
@ -34,12 +34,12 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player) public static void EnableSkill(CCSPlayerController player)
{ {
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return; if (playerInfo == null) return;
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.IsBot && p != player) ? "tb" : "t"); border: !Utilities.GetPlayers().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

@ -1,4 +1,4 @@
using CounterStrikeSharp.API; using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants; using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils; using CounterStrikeSharp.API.Modules.Utils;
@ -18,12 +18,13 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event) public static void PlayerHurt(EventPlayerHurt @event)
{ {
var victim = @event.Userid; var victim = PlayerManager.GetPlayerEvent(@event.Userid);
int damage = @event.DmgHealth; int damage = @event.DmgHealth;
string weapon = @event.Weapon; string weapon = @event.Weapon;
if (weapon != "inferno" || !Instance.IsPlayerValid(victim)) return; if (weapon != "inferno" || !Instance.IsPlayerValid(victim)) return;
var victimInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == victim?.SteamID); var victimInfo = PlayerManager.GetPlayerByIndex(victim!.Index);
if (victimInfo == null || victimInfo.Skill != skillName) return; if (victimInfo == null || victimInfo.Skill != skillName) return;
var pawn = victim!.PlayerPawn.Value; var pawn = victim!.PlayerPawn.Value;

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