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

View file

@ -3,7 +3,6 @@ using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Admin;
using CounterStrikeSharp.API.Modules.Commands;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils;
using src.menu;
using src.player;
@ -76,19 +75,23 @@ namespace src.command
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
private static void Command_UseTypeSkill(CCSPlayerController? player, CommandInfo _)
{
if (player == null) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
player = PlayerManager.GetPlayerEvent(player);
if (player == null || !player.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
if (playerInfo == null || playerInfo.IsDrawing) return;
var playerPawn = player.PlayerPawn.Value;
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())
return;
string[] commands = _.ArgString.Trim().Split(" ", StringSplitOptions.RemoveEmptyEntries);
Debug.WriteToDebug($"Player {player.PlayerName} used the skill: {playerInfo.Skill}");
if (commands == null || commands.Length == 0)
Instance.SkillAction(playerInfo.Skill.ToString(), "UseSkill", [player]);
else
@ -100,9 +103,9 @@ namespace src.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;
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.PlayerName.Equals(command.GetArg(1), StringComparison.CurrentCultureIgnoreCase)));
|| p.PlayerName.Equals(command.GetArg(1), StringComparison.OrdinalIgnoreCase)));
if (command.ArgCount < 2)
{
@ -140,7 +143,7 @@ namespace src.command
return;
}
var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == targetPlayer.SteamID);
var skillPlayer = PlayerManager.GetPlayerByIndex(targetPlayer.Index);
if (skillPlayer != null)
{
Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [targetPlayer]);
@ -246,7 +249,7 @@ namespace src.command
else
{
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())
if (Instance.IsPlayerValid(player) && new CsTeam[] { CsTeam.CounterTerrorist, CsTeam.Terrorist }.Contains(player.Team))
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)]
@ -374,7 +377,7 @@ namespace src.command
if (!string.IsNullOrEmpty(config.NormalCommands.BotPlace.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.BotPlace.Permissions)) return;
var pawn = player.PlayerPawn.Value;
if (!player.PawnIsAlive || pawn.AbsOrigin == null || pawn.AbsRotation == null) return;
if (player.LifeState != (byte)LifeState_t.LIFE_ALIVE || pawn.AbsOrigin == null || pawn.AbsRotation == null) return;
if (!int.TryParse(command.GetArg(1), out int botSlot))
botSlot = -1;
@ -403,7 +406,7 @@ namespace src.command
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;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(player)!.Index);
if (playerInfo == null) return;
playerInfo.DisplayHUD = !playerInfo.DisplayHUD;
@ -452,9 +455,9 @@ namespace src.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;
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.PlayerName.Equals(command.GetArg(1), StringComparison.CurrentCultureIgnoreCase)));
|| p.PlayerName.Equals(command.GetArg(1), StringComparison.OrdinalIgnoreCase)));
if (command.ArgCount < 2)
{
@ -495,7 +498,7 @@ namespace src.command
return;
}
var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == targetPlayer.SteamID);
var skillPlayer = PlayerManager.GetPlayerByIndex(targetPlayer.Index);
if (skillPlayer != null)
{
Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [targetPlayer]);
@ -504,9 +507,9 @@ namespace src.command
skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration);
if (skill.Skill == src.player.Skills.None)
Event.staticSkills.TryRemove(targetPlayer.SteamID, out _);
Event.staticSkills.TryRemove(targetPlayer.Index, out _);
else
Event.staticSkills.TryAdd(targetPlayer.SteamID, skill);
Event.staticSkills.TryAdd(targetPlayer.Index, skill);
Instance.SkillAction(skill.Skill.ToString(), "EnableSkill", [targetPlayer]);
if (player == null)
@ -593,32 +596,58 @@ namespace src.command
var skillsList = SkillData.Skills.OrderBy(s => s.Skill.ToString()).ToList();
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;
string arg = command.GetArg(1);
string arg = command.GetArg(2);
if (!string.IsNullOrEmpty(arg))
{
if (arg == "-1")
nextIndex--;
else if (int.TryParse(arg, out int newIndex))
nextIndex = newIndex;
else
nextIndex = int.Parse(arg);
return;
}
var skill = skillsList[nextIndex];
player.PrintToChat(nextIndex.ToString());
var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
var skillPlayer = PlayerManager.GetPlayerByIndex(targetPlayer!.Index);
if (skillPlayer == null) return;
Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [player]);
Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [targetPlayer]);
skillPlayer.Skill = skill.Skill;
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);
if (skill.Display)

View file

@ -22,7 +22,7 @@ namespace src.command
vote.SetActive(false);
vote.TimeToNextSameVoting = vote.TimeToNextVoting;
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)
@ -49,7 +49,7 @@ namespace src.command
{
if (!votes.ContainsKey(vote)) return;
votes.TryRemove(vote, out _);
});
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
return vote;
}

View file

@ -28,7 +28,7 @@ namespace src
public override string ModuleName => "[CS2] [ jRandomSkills ]";
public override string ModuleAuthor => "D3X, Juzlus";
public override string ModuleDescription => "Plugin adds random skills every round for CS2 by D3X. Modified by Juzlus.";
public override string ModuleVersion => "1.2.1.b9";
public override string ModuleVersion => "1.2.2.b1";
public override void Load(bool hotReload)
{
@ -43,6 +43,7 @@ namespace src
Command.Load();
WASDMenuAPI.WASDMenuAPI.LoadPlugin(Instance, hotReload);
LoadAllSkills();
PlayerManager.SyncWithPlugin(Instance);
Instance.RegisterListener<OnServerPrecacheResources>(LoadManifest);
@ -217,7 +218,7 @@ namespace src
Console.ForegroundColor = (ConsoleColor)CS2ConsoleColors.Cyan;
Console.Write(", HtmlHudFix: ");
Console.ForegroundColor = (ConsoleColor)CS2ConsoleColors.LightBlue;
Console.WriteLine(Config.LoadedConfig.FlashingHtmlHudFix);
Console.WriteLine(Config.LoadedConfig.EnableFlashingHtmlHudFix);
// Dependences
Console.ForegroundColor = (ConsoleColor)CS2ConsoleColors.Cyan;
@ -295,12 +296,21 @@ namespace src
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 required ulong SteamID { get; set; }
public required bool IsBot { get; set; }
public required string PlayerName { get; set; }
public required uint PlayerIndex { get; set; }
public Skills Skill { get; set; }
public Skills SpecialSkill { 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}";
Instance.RegisterEventHandler<EventPlayerConnectFull>((@event, info) =>
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return HookResult.Continue;
WriteToDebug($"{(player.IsBot ? "Bot" : "Player")} {player.PlayerName} joined the game.");
return HookResult.Continue;
@ -27,7 +27,7 @@ namespace src.player
Instance.RegisterEventHandler<EventPlayerDisconnect>((@event, info) =>
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return HookResult.Continue;
WriteToDebug($"{(player.IsBot ? "Bot" : "Player")} {player.PlayerName} disconnected.");
return HookResult.Continue;
@ -59,8 +59,8 @@ namespace src.player
Instance.RegisterEventHandler<EventPlayerDeath>((@event, info) =>
{
var victim = @event.Userid;
var attacker = @event.Attacker;
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
if (victim != null)
{
if (attacker != null)
@ -90,7 +90,7 @@ namespace src.player
Instance.RegisterEventHandler<EventPlayerShoot>((@event, info) =>
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return HookResult.Continue;
WriteToDebug($"{(player.IsBot ? "Bot" : "Player")} {player.PlayerName} fired a shot.");
return HookResult.Continue;
@ -116,10 +116,10 @@ namespace src.player
if (attackerPawn == null || attackerPawn.Controller?.Value == null || victimPawn == null || victimPawn.Controller?.Value == null)
return HookResult.Continue;
CCSPlayerController attacker = attackerPawn.Controller.Value.As<CCSPlayerController>();
CCSPlayerController victim = victimPawn.Controller.Value.As<CCSPlayerController>();
CCSPlayerController attacker = PlayerManager.GetPlayerEvent(attackerPawn.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;
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)
return;
// GetAllEntityIndexes();
string filename = $"debug_{sessionId}.txt";
string path = Path.Combine(debugFolder, filename);
Directory.CreateDirectory(debugFolder);
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,
Duplicator,
Dwarf,
Earthquake,
EnemySpawn,
ExplosiveShot,
FalconEye,
@ -102,7 +101,6 @@ public enum Skills
Glue,
GodMode,
Grenadier,
HealingChicken,
HealingSmoke,
Hermit,
HolyHandGrenade,

View file

@ -2,12 +2,14 @@ using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes;
using CounterStrikeSharp.API.Modules.Admin;
using CounterStrikeSharp.API.Modules.Commands.Targeting;
using CounterStrikeSharp.API.Modules.Cvars;
using CounterStrikeSharp.API.Modules.Events;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.UserMessages;
using CounterStrikeSharp.API.Modules.Utils;
using Microsoft.Extensions.Logging;
using RayTraceAPI;
using src.player.skills;
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)];
private static readonly SkillsInfo.DefaultSkillInfo[] allTeamsSkills = [.. SkillsInfo.LoadedConfig.Where(s => s.OnlyTeam == 0)];
private static readonly ConcurrentDictionary<ulong, ConcurrentBag<jSkill_SkillInfo>> playersSkills = [];
public static readonly ConcurrentDictionary<ulong, jSkill_SkillInfo> staticSkills = [];
private static readonly ConcurrentDictionary<uint, ConcurrentBag<jSkill_SkillInfo>> playersSkills = [];
public static readonly ConcurrentDictionary<uint, jSkill_SkillInfo> staticSkills = [];
private static readonly object setLock = new();
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<OnEntitySpawned>(EntitySpawned);
Instance.RegisterListener<OnTick>(OnTick);
Instance.RegisterListener<OnClientPutInServer>(OnPlayerConnectedBot);
Instance.HookUserMessage(208, PlayerMakeSound);
VirtualFunctions.CBaseEntity_TakeDamageOldFunc.Hook(OnTakeDamage, HookMode.Pre);
@ -96,7 +99,7 @@ namespace src.player
const int attempts = 6;
for (int attempt = 0; attempt < attempts; attempt++)
{
var rolled = RarityManager.RollRarity();
var (roll, rolled) = RarityManager.RollRarity();
var filtered = candidates.Where(s =>
{
@ -117,7 +120,7 @@ namespace src.player
}).ToList();
if (filtered.Count > 0)
return filtered[Instance.Random.Next(filtered.Count)];
return filtered[Random.Shared.Next(filtered.Count)];
}
var fallback = candidates.Where(s =>
@ -131,9 +134,9 @@ namespace src.player
}).ToList();
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)
@ -402,6 +405,10 @@ namespace src.player
foreach (string skillName in activeSkills)
Instance.SkillAction(skillName, "OnTakeDamage", [h]);
if (Fortnite.skillInThisRound == true && !activeSkills.Any(s => s == "Fortnite"))
Instance.SkillAction("Fortnite", "OnTakeDamage", [h]);
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)
{
var player = @event.Userid;
if (player == null || !player.IsValid) return HookResult.Continue;
var player = Utilities.GetPlayerFromSlot(playerSlot);
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,
PlayerIndex = player.Index,
Skill = Skills.None,
SpecialSkill = Skills.None,
IsDrawing = false,
@ -544,7 +555,18 @@ namespace src.player
PrintHTML = null,
DisplayHUD = true,
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");
foreach (string line in welcomeMsg.Split("\n"))
@ -562,16 +584,18 @@ namespace src.player
{
lock (setLock)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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;
Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [player]);
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;
}
@ -586,16 +610,10 @@ namespace src.player
string commandName = text.StartsWith('!') || text.StartsWith('/') ? text[1..] : text;
foreach (var cmd in Instance.CommandDefinitions)
Server.PrintToChatAll("1. " + cmd.Name);
foreach (var cmd in Instance.CommandListeners.Keys)
Server.PrintToChatAll("2. " + cmd?.Target?.ToString());
var player = Utilities.GetPlayerFromUserid(userID);
if (player == null || !player.IsValid) return HookResult.Continue;
var skillPlayer = Instance?.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
var skillPlayer = PlayerManager.GetPlayerByIndex(player!.Index);
if (skillPlayer == null) return HookResult.Continue;
var temp = skillPlayer.SkillHudExpired;
@ -605,7 +623,7 @@ namespace src.player
{
if (skillPlayer.SkillHudExpired == DateTime.MinValue)
skillPlayer.SkillHudExpired = temp;
});
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
return HookResult.Continue;
}
@ -614,10 +632,10 @@ namespace src.player
{
lock (setLock)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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 (setSkillTimer != null)
@ -642,11 +660,11 @@ namespace src.player
{
bool isWarmup = Instance.GameRules != null && Instance.GameRules.WarmupPeriod == true;
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;
skillPlayer.IsDrawing = !isWarmup;
skillPlayer.PrintHTML = null;
@ -659,7 +677,7 @@ namespace src.player
setSkillTimer?.Kill();
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;
}
}
@ -668,9 +686,14 @@ namespace src.player
{
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;
Instance.SkillAction(playerInfo.Skill.ToString(), "DisableSkill", [player]);
@ -681,10 +704,28 @@ namespace src.player
playerInfo.PrintHTML = null;
playerInfo.SkillChance = 1;
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()
{
lock (setLock)
@ -693,19 +734,21 @@ namespace src.player
Instance.AddTimer(.1f, () => {
DisableAll();
ConVar.Find("sv_legacy_jump")?.SetValue("1");
});
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
Instance.RemoveListener<CheckTransmit>(CheckTransmit);
playersSkills.Clear();
staticSkills.Clear();
ctSkill = noneSkill;
tSkill = noneSkill;
allSkill = noneSkill;
PlayerManager.Clear();
}
}
private static HookResult RoundEnd(EventRoundEnd @event, GameEventInfo info)
{
Illiterate.Disable();
lock (setLock)
{
foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid))
@ -717,7 +760,7 @@ namespace src.player
string skillsText = "";
foreach (var _player in _players)
{
var _playerSkill = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == _player.SteamID);
var _playerSkill = PlayerManager.GetPlayerByIndex(_player.Index);
if (_playerSkill != null)
{
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, string.Empty, border: "b");
}
});
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
}
if (Config.LoadedConfig.DisableSkillsOnRoundEnd)
{
isTransmitRegistered = false;
Instance.AddTimer(1f, () => DisableAll());
Instance.AddTimer(1f, () => DisableAll(), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
Instance.RemoveListener<CheckTransmit>(CheckTransmit);
}
return HookResult.Continue;
@ -760,18 +803,18 @@ namespace src.player
foreach (string skillName in activeSkills)
Instance.SkillAction(skillName, "PlayerDeath", [@event]);
var victim = @event.Userid;
var attacker = @event.Attacker;
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
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;
Instance.SkillAction(playerInfo.Skill.ToString(), "DisableSkill", [victim]);
if (victim == attacker) return HookResult.Continue;
if (Config.LoadedConfig.KillerSkillChatInfo)
{
var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID);
var attackerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
if (attackerInfo != null)
{
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)
{
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
lock (setLock)
{
@ -802,7 +845,7 @@ namespace src.player
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 (SkillsInfo.GetValue<bool>(playerInfo.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
@ -872,14 +915,16 @@ namespace src.player
setSkillTimer = null;
lock (setLock)
{
if (Instance?.GameRules != null && Instance.GameRules.WarmupPeriod == true)
if (Instance == null) return;
if (Instance.GameRules != null && Instance.GameRules.WarmupPeriod == true)
{
setSkillTimer?.Kill();
return;
}
var validPlayers = Utilities.GetPlayers()
.Where(p => p != null && p.IsValid && !p.IsBot && !p.IsHLTV)
.Where(p => p != null && p.IsValid && !p.IsHLTV)
.Where(p => {
try { return p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist; }
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();
string teammateSkills = "";
var skillPlayer = Instance?.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
var skillPlayer = PlayerManager.GetPlayerByIndex(player!.Index);
if (skillPlayer == null) continue;
skillPlayer.IsDrawing = false;
@ -935,7 +980,8 @@ namespace src.player
{
List<jSkill_SkillInfo> skillList = [.. SkillData.Skills];
skillList.RemoveAll(s => s?.Skill == Skills.None);
skillList.RemoveAll(s => !string.IsNullOrEmpty(SkillsInfo.GetValue<string>(s.Skill, "requiredPermission")) && !AdminManager.PlayerHasPermissions(player, SkillsInfo.GetValue<string>(s.Skill, "requiredPermission")));
if (!player.IsBot)
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)
skillList.RemoveAll(s => s?.Skill == skillPlayer?.Skill || s?.Skill == skillPlayer?.SpecialSkill);
@ -951,7 +997,7 @@ namespace src.player
else
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));
if (skillList.Count == 0) skills.Clear();
@ -961,10 +1007,10 @@ namespace src.player
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);
else
playersSkills.TryAdd(player.SteamID, [randomSkill]);
playersSkills.TryAdd(player.Index, [randomSkill]);
}
}
else if (gameMode == Config.GameModes.TeamSkills)
@ -984,7 +1030,7 @@ namespace src.player
skillPlayer.Skill = randomSkill.Skill;
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;
else assignmentCounts[randomSkill.Skill] = 1;
@ -999,17 +1045,19 @@ namespace src.player
if (randomSkill.Display)
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(randomSkill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(randomSkill.Skill)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
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())
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]);
});
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
else
{
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)}\".");
@ -1027,7 +1075,7 @@ namespace src.player
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)
{
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, 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)
{
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)
{
@ -1067,7 +1115,7 @@ namespace src.player
}
if (player == null) return;
var skillPlayer = Instance?.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
var skillPlayer = PlayerManager.GetPlayerByIndex(player!.Index);
if (skillPlayer == null) return;
skillPlayer.IsDrawing = false;
@ -1081,13 +1129,14 @@ namespace src.player
if (Instance?.GameRules != null && Instance?.GameRules.WarmupPeriod == false)
{
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;
else if (gameMode == Config.GameModes.Normal || gameMode == Config.GameModes.FullRandom || gameMode == Config.GameModes.NoRepeat)
{
List<jSkill_SkillInfo> skillList = [.. SkillData.Skills];
skillList.RemoveAll(s => s?.Skill == Skills.None);
skillList.RemoveAll(s => !string.IsNullOrEmpty(SkillsInfo.GetValue<string>(s.Skill, "requiredPermission")) && !AdminManager.PlayerHasPermissions(player, SkillsInfo.GetValue<string>(s.Skill, "requiredPermission")));
if (!player.IsBot)
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)
skillList.RemoveAll(s => s?.Skill == skillPlayer?.Skill || s?.Skill == skillPlayer?.SpecialSkill);
@ -1103,7 +1152,7 @@ namespace src.player
else
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));
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.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)
Illiterate.Enable();
@ -1148,12 +1197,12 @@ namespace src.player
if (SkillsInfo.GetValue<bool>(randomSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
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]);
});
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
else
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)}\".");
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.Utils;
using src.utils;
using System.Linq;
using static CounterStrikeSharp.API.Core.Listeners;
using static src.jRandomSkills;
@ -16,49 +15,62 @@ namespace src.player
Instance.RegisterListener<OnTick>(() =>
{
UpdateGameRules();
var players = Utilities.GetPlayers().ToArray();
foreach (var player in players)
foreach (var player in Utilities.GetPlayers())
{
if (player != null && player.IsValid)
UpdatePlayerHud(player);
}
});
Instance.RegisterListener<OnMapStart>(OnMapStart);
Instance.RegisterListener<OnMapEnd>(OnMapEnd);
}
private static void OnMapStart(string mapName)
{
Instance.GameRules = null;
Event.OnMapChange();
BotManager.Initialize();
}
private static void OnMapEnd()
{
BotManager.Stop();
}
private static void InitializeGameRules()
{
if (Instance.GameRules != null) return;
var gameRulesProxy = Utilities.FindAllEntitiesByDesignerName<CCSGameRulesProxy>("cs_gamerules").FirstOrDefault();
if (gameRulesProxy != null)
Instance.GameRules = gameRulesProxy?.GameRules;
Instance.GameRules = gameRulesProxy.GameRules;
}
private static void UpdateGameRules()
{
if (Instance?.GameRules == null || Instance?.GameRules?.Handle == IntPtr.Zero)
if (Instance?.GameRules == null || Instance.GameRules.Handle == IntPtr.Zero)
InitializeGameRules();
else if (Instance != null && Config.LoadedConfig.FlashingHtmlHudFix && !Instance.GameRules.WarmupPeriod)
Instance.GameRules.GameRestart = Instance.GameRules?.RestartRoundTime < Server.CurrentTime;
else if (Instance != null && Config.LoadedConfig.EnableFlashingHtmlHudFix && !Instance.GameRules.WarmupPeriod)
Instance.GameRules.GameRestart = Instance.GameRules.RestartRoundTime < Server.CurrentTime;
}
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 skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (skillPlayer == null || !skillPlayer.DisplayHUD) return;
if (player.PawnIsAlive && skillPlayer.SkillHudExpired < now) return;
string infoLine = string.Empty;
string skillLine = string.Empty;
string remainingLine = string.Empty;
bool showDescriptionHUD = skillPlayer.SkillDescriptionHudExpired >= now;
bool isDescription = true;
@ -72,10 +84,12 @@ namespace src.player
else if (skillPlayer.IsDrawing && player.PawnIsAlive)
{
int skillCount = skills.Count;
if (skillCount > 0)
{
var skillsArray = skills.ToArray();
var randomSkill = skillsArray[Instance.Random.Next(skillCount)];
infoLine = player.GetTranslation("drawing_skill");
skillLine = $"<font color='{randomSkill.Color}'>{player.GetSkillName(randomSkill.Skill)}</font>";
}
@ -85,61 +99,70 @@ namespace src.player
if (player.PawnIsAlive)
{
var skillInfo = skills.FirstOrDefault(s => s.Skill == skillPlayer.Skill);
if (skillInfo != null)
{
infoLine = player.GetTranslation("your_skill");
skillLine = $"<font color='{skillInfo.Color}'>{player.GetSkillName(skillInfo.Skill, skillPlayer.SkillChance)}</font>";
if (skillInfo.Skill != Skills.None)
{
remainingLine = string.IsNullOrEmpty(skillPlayer.PrintHTML)
? (showDescriptionHUD ? player.GetSkillDescription(skillInfo.Skill, skillPlayer.SkillChance) : "")
: skillPlayer.PrintHTML;
isDescription = string.IsNullOrEmpty(skillPlayer.PrintHTML);
}
}
}
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;
var pawn = player.Pawn.Value;
if (pawn == null || pawn.ObserverServices == null) return;
if (pawn?.ObserverServices == null) return;
var observerTarget = pawn.ObserverServices.ObserverTarget?.Value;
if (observerTarget == null || !observerTarget.IsValid) return;
var players = Utilities.GetPlayers();
var targetHandle = observerTarget.Handle;
var observedPlayer = players.FirstOrDefault(p => p?.IsValid == true && p?.Pawn?.Value?.Handle == targetHandle);
var observedPlayer = Utilities.GetPlayers().FirstOrDefault(p =>
p != null && p.IsValid && p.Pawn?.Value?.Handle == observerTarget.Handle);
if (observedPlayer == null) return;
var observeredPlayerSkill = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == observedPlayer.SteamID);
if (observeredPlayerSkill == null) return;
var observedEvent = PlayerManager.GetPlayerEvent(observedPlayer);
if (observedEvent == null || !observedEvent.IsValid) return;
var observeredPlayerSkillInfo = skills.FirstOrDefault(s => s.Skill == observeredPlayerSkill.Skill);
var observeredPlayerSpecialSkillInfo = observeredPlayerSkill.SpecialSkill != Skills.None ? skills.FirstOrDefault(s => s.Skill == observeredPlayerSkill.SpecialSkill) : null;
var observedSkill = PlayerManager.GetPlayerByIndex(observedEvent.Index);
if (observedSkill == null) return;
string primaryName = player.GetSkillName(observeredPlayerSkill.Skill, observeredPlayerSkill.SkillChance);
string primaryColor = observeredPlayerSkillInfo?.Color ?? SkillsInfo.GetValue<string>(Skills.None, "color");
var observedSkillInfo = skills.FirstOrDefault(s => s.Skill == observedSkill.Skill);
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)
pName = $"{pName[..17]}...";
var observerSkill = player.GetTranslation("observer_skill");
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>";
else
{
string specialName = player.GetSkillName(observeredPlayerSpecialSkillInfo.Skill);
skillLine = $"<font color='{observeredPlayerSpecialSkillInfo.Color}'>{specialName}({primaryName})</font>";
string specialName = player.GetSkillName(observedSpecialInfo.Skill);
skillLine = $"<font color='{observedSpecialInfo.Color}'>{specialName}({primaryName})</font>";
}
if (showDescriptionHUD)
remainingLine = player.GetSkillDescription(observeredPlayerSkill.Skill, observeredPlayerSkill.SkillChance);
remainingLine = player.GetSkillDescription(observedSkill.Skill, observedSkill.SkillChance);
}
}
@ -149,4 +172,4 @@ namespace src.player
Event.UpdateSkillHUD(player, infoLine, skillLine, remainingLine, isDescription);
}
}
}
}

View file

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

View file

@ -2,9 +2,9 @@
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils;
using System.Runtime.InteropServices;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
using CounterStrikeSharp.API;
namespace src.player.skills
{
@ -23,61 +23,35 @@ namespace src.player.skills
CEntityInstance param = h.GetParam<CEntityInstance>(0);
CTakeDamageInfo param2 = h.GetParam<CTakeDamageInfo>(1);
if (param == null || !param.IsValid || param.Entity == null)
return;
if (param == null || !param.IsValid || param2 == null || param2.Handle == nint.Zero) 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)
return;
var attackerEnt = param2.Attacker.Value;
if (attackerEnt == null || !attackerEnt.IsValid) return;
var attackerHandle = param2.Attacker;
if (attackerHandle.Value == null || !attackerHandle.IsValid)
return;
var attackerPawn = attackerEnt.As<CCSPlayerPawn>();
if (attackerPawn == null || !attackerPawn.IsValid) return;
var attackerEnt = attackerHandle.Value;
var victimEnt = param;
var attackerController = attackerPawn.Controller.Value;
if (attackerController == null || !attackerController.IsValid) return;
if (attackerEnt == null || victimEnt == null || !victimEnt.IsValid || !attackerEnt.IsValid)
return;
var attacker = PlayerManager.GetPlayerEvent(attackerController.As<CCSPlayerController>())!;
CCSPlayerPawn attackerPawn = new(attackerEnt.Handle);
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);
var playerInfo = PlayerManager.GetPlayerByIndex(attacker.Index);
if (playerInfo == null) return;
if (!attacker.CheckPlayer())
return;
int offset = GameData.GetOffset("CTakeDamageInfo_HitGroup");
if (offset <= 0)
return;
if (offset <= 0) return;
nint hitGroupPointer = Marshal.ReadIntPtr(param2.Handle, offset);
if (hitGroupPointer == nint.Zero)
return;
if (hitGroupPointer == nint.Zero) return;
nint hitGroupOffset = Marshal.ReadIntPtr(hitGroupPointer, 16);
if (hitGroupOffset == nint.Zero)
return;
if (hitGroupOffset == nint.Zero) return;
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);
}
else if (hitGroups.TryGetValue(hitGroupOffset, out var hitGroup))
@ -87,10 +61,13 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController _)
{
foreach (var hit in hitGroups)
Marshal.WriteInt32(hit.Key, 56, hit.Value);
{
if (hit.Key != nint.Zero)
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 src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills
{
@ -11,7 +10,8 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Anomaly;
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();
public static void LoadSkill()
@ -29,18 +29,24 @@ namespace src.player.skills
{
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 (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
{
if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
{
UpdateHUD(player, skillInfo);
if (Server.TickCount % tickRate != 0) return;
if (Server.TickCount % tickRate != 0) continue;
var pawn = player.PlayerPawn.Value;
if (pawn != null && pawn.IsValid && pawn.AbsOrigin != null)
{
if (skillInfo.LastRotations == null || skillInfo.LastPositions == null) continue;
skillInfo.LastPositions.Enqueue(new Vector(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z));
skillInfo.LastRotations.Enqueue(new QAngle(pawn.V_angle.X, pawn.V_angle.Y, 0));
if (skillInfo.LastRotations.Count > SkillsInfo.GetValue<int>(skillName, "secondsInBack"))
{
skillInfo.LastPositions.TryDequeue(out _);
@ -48,40 +54,42 @@ namespace src.player.skills
}
}
}
}
}
}
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,
Cooldown = DateTime.MinValue,
LastPositions = [],
LastRotations = [],
LastPositions = new ConcurrentQueue<Vector>(),
LastRotations = new ConcurrentQueue<QAngle>()
});
}
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);
}
private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo)
{
if (player == null || !player.IsValid || skillInfo == null) return;
float cooldown = 0;
if (skillInfo != null)
{
float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue<float>(skillName, "cooldown")) - DateTime.Now).TotalSeconds);
cooldown = Math.Max(time, 0);
float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue<float>(skillName, "cooldown")) - DateTime.Now).TotalSeconds);
cooldown = Math.Max(time, 0);
if (cooldown == 0 && skillInfo?.CanUse == false)
skillInfo.CanUse = true;
}
if (cooldown == 0 && !skillInfo.CanUse)
skillInfo.CanUse = true;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return;
if (cooldown == 0)
@ -92,19 +100,27 @@ namespace src.player.skills
public static void UseSkill(CCSPlayerController player)
{
var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return;
if (player == null || !player.IsValid) 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)
if (!skillInfo.CanUse) return;
skillInfo.Cooldown = DateTime.Now;
skillInfo.CanUse = false;
var playerPawn = player.PlayerPawn.Value;
if (playerPawn != null && playerPawn.IsValid)
{
skillInfo.CanUse = false;
skillInfo.Cooldown = DateTime.Now;
if (skillInfo.LastRotations == null || skillInfo.LastRotations.IsEmpty || skillInfo.LastPositions == null || skillInfo.LastPositions.IsEmpty) return;
if (skillInfo.LastPositions == null || skillInfo.LastPositions.IsEmpty) return;
if (skillInfo.LastRotations == null || skillInfo.LastRotations.IsEmpty) return;
Vector? lastPosition = skillInfo.LastPositions.FirstOrDefault();
QAngle? lastRotation = skillInfo.LastRotations.FirstOrDefault();
if (lastPosition != null && lastRotation != null)
{
playerPawn.Teleport(lastPosition, null, null);
@ -116,7 +132,7 @@ namespace src.player.skills
public class PlayerSkillInfo
{
public ulong SteamID { get; set; }
public uint PlayerIndex { get; set; }
public bool CanUse { get; set; }
public DateTime Cooldown { 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.Utils;
using src.utils;
using static src.jRandomSkills;
namespace src.player.skills
{
@ -17,25 +16,31 @@ namespace src.player.skills
public static void PlayerBlind(EventPlayerBlind @event)
{
var player = @event.Userid;
var attacker = @event.Attacker;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
if (attacker == null || !attacker.IsValid) return;
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null || !playerPawn.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName)
{
playerPawn.FlashDuration = 0.0f;
else if (attackerInfo?.Skill == skillName)
playerPawn.FlashDuration = SkillsInfo.GetValue<float>(skillName, "flashDuration");
}
else if (attacker != null && attacker.IsValid)
{
var attackerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
if (attackerInfo?.Skill == skillName)
playerPawn.FlashDuration = SkillsInfo.GetValue<float>(skillName, "flashDuration");
}
}
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
SkillUtils.TryGiveWeapon(player, CsItem.FlashbangGrenade);
}

View file

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

View file

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

View file

@ -1,7 +1,6 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using static src.jRandomSkills;
namespace src.player.skills
{
@ -18,29 +17,34 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event)
{
var damage = @event.DmgHealth;
var victim = @event.Userid;
var attacker = @event.Attacker;
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var weapon = @event.Weapon;
HitGroup_t hitgroup = (HitGroup_t)@event.Hitgroup;
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return;
if (nades.Contains(weapon)) return;
if (victim == null || !victim.IsValid || attacker == null || !attacker.IsValid || attacker == victim) 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 (IsBehind(attacker!, victim!))
SkillUtils.TakeHealth(victim!.PlayerPawn.Value, (int)(damage * (SkillsInfo.GetValue<float>(skillName, "damageMultiplier") - 1f)));
if (IsBehind(attacker, victim))
{
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)
{
var attackerPawn = attacker.PlayerPawn.Value;
var victimPawn = victim.PlayerPawn.Value;
if (attackerPawn == null || !attackerPawn.IsValid || victimPawn == null || !victimPawn.IsValid) return false;
if (victimPawn.AbsRotation == null || attackerPawn.AbsRotation == null) return false;
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)
@ -55,7 +59,7 @@ namespace src.player.skills
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)
return (target >= a && target <= b);

View file

@ -23,29 +23,40 @@ namespace src.player.skills
public static void NewRound()
{
foreach (var player in Utilities.GetPlayers())
DisableSkill(player);
{
if (player != null && player.IsValid)
DisableSkill(player);
}
}
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (player == null || !player.IsValid) return;
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return;
player.PlayerPawn.Value.ActualGravityScale = 1;
pawn.ActualGravityScale = 1.0f;
}
private static void ApplyGravityModifier(CCSPlayerController player)
{
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (player == null || !player.IsValid) return;
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
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);
playerInfo.SkillChance = 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");
player.PlayerPawn.Value.ActualGravityScale = gravityModifier;
border: !Utilities.GetPlayers().Any(p => p.IsValid && p.Team == player.Team && p != player) ? "tb" : "t");
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)

View file

@ -1,9 +1,8 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
using System.Collections.Concurrent;
namespace src.player.skills
{
@ -19,66 +18,88 @@ namespace src.player.skills
public static void NewRound()
{
foreach (var player in Utilities.GetPlayers())
SkillUtils.CloseMenu(player);
{
if (player != null && player.IsValid)
SkillUtils.CloseMenu(player);
}
}
public static void OnTick()
{
if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers())
{
if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (player == null || !player.IsValid || !SkillUtils.HasMenu(player)) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
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())));
SkillUtils.UpdateMenu(player, menuItems);
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);
}
}
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)
{
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (player == null || !player.IsValid || commands.Length < 1) return;
string option = commands[0];
if (string.IsNullOrEmpty(option)) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed)
{
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("areareaper_used_info")}");
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("selectplayerskill_used_info")}");
return;
}
string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Team != player.Team && p.Index.ToString() == enemyId);
if (enemy == null)
if (uint.TryParse(option, out uint enemyIndex))
{
player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("selectplayerskill_incorrect_enemy_index"));
return;
var enemy = Utilities.GetEntityFromIndex<CCSPlayerController>((int)enemyIndex);
if (enemy != null && enemy.IsValid && enemy.PawnIsAlive && enemy.Team != player.Team)
{
ResetMoney(enemy);
playerInfo.SkillUsed = true;
SkillUtils.CloseMenu(player);
player.PrintToChat($" {ChatColors.Lime}{player.GetTranslation("bankrupt_player_info", enemy.PlayerName)}");
enemy.PrintToChat($" {ChatColors.Red}{enemy.GetTranslation("bankrupt_enemy_info")}");
return;
}
}
ResetMoney(enemy);
playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("bankrupt_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("bankrupt_enemy_info"));
}
public static void EnableSkill(CCSPlayerController player)
{
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo == null) return;
playerInfo.SkillUsed = false;
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0)
{
ConcurrentBag<(string, string)> menuItems = 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")}");
}
private static void ResetMoney(CCSPlayerController enemy)
@ -93,7 +114,8 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
SkillUtils.CloseMenu(player);
if (player != null && player.IsValid)
SkillUtils.CloseMenu(player);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#abab33", 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

@ -1,10 +1,10 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills
{
@ -20,14 +20,14 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event)
{
var victim = @event.Userid;
var attacker = @event.Attacker;
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var weapon = @event.Weapon;
if (weapon != "decoy") 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;
SkillUtils.TakeHealth(victim!.PlayerPawn.Value, SkillsInfo.GetValue<int>(skillName, "damageDeal"));
@ -41,27 +41,27 @@ namespace src.player.skills
var decoy = entity.As<CDecoyProjectile>();
if (decoy == null || !decoy.IsValid || decoy.OwnerEntity == null || decoy.OwnerEntity.Value == null || !decoy.OwnerEntity.Value.IsValid) return;
var pawn = decoy.OwnerEntity.Value.As<CCSPlayerPawn>();
if (pawn == null || !pawn.IsValid || pawn.Controller == null || pawn.Controller.Value == null || !pawn.Controller.Value.IsValid) return;
var player = pawn.Controller.Value.As<CCSPlayerController>();
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;
decoys.TryAdd(decoy.Index, 0);
decoy.Collision.CollisionAttribute.InteractsWith = pawn.Collision.CollisionAttribute.InteractsWith;
decoy.Collision.CollisionGroup = pawn.Collision.CollisionGroup;
}
public static void DecoyStarted(EventDecoyStarted @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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;
uint key = (uint)@event.Entityid;
@ -69,7 +69,7 @@ namespace src.player.skills
{
var decoy = Utilities.GetEntityFromIndex<CDecoyProjectile>(@event.Entityid);
if (decoy != null && decoy.IsValid)
decoy.AcceptInput("Kill");
decoy.AddEntityIOEvent("Kill", decoy, delay: 0.1f);
decoys.TryRemove(key, out _);
}
}

View file

@ -17,11 +17,11 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event)
{
var attacker = @event!.Attacker;
var victim = @event!.Userid;
var attacker = PlayerManager.GetPlayerEvent(@event!.Attacker);
var victim = PlayerManager.GetPlayerEvent(@event!.Userid);
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 (Instance.Random.NextDouble() <= playerInfo.SkillChance)
@ -30,12 +30,12 @@ namespace src.player.skills
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;
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
}
private static void RotateEnemy(CCSPlayerController player)

View file

@ -18,58 +18,71 @@ namespace src.player.skills
public static void OnTick()
{
var modifier = SkillsInfo.GetValue<float>(skillName, "velocityModifier");
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;
var playerPawn = player.PlayerPawn?.Value;
if (playerPawn == null || !playerPawn.IsValid || playerPawn.VelocityModifier == 0) continue;
var weaponServices = playerPawn.WeaponServices;
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"))
return;
if (weaponServices == null) continue;
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)
{
var victim = @event.Userid;
int damage = @event.DmgHealth;
HitGroup_t hitGroup = (HitGroup_t)@event.Hitgroup;
string weapon = @event.Weapon;
var damage = @event.DmgHealth;
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Weapon;
int hitgroup = @event.Hitgroup;
if (noReflectionWeapon.Contains(weapon) || !Instance.IsPlayerValid(victim)) return;
var victimInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == victim?.SteamID);
if (victimInfo == null || victimInfo.Skill != skillName) return;
if (victim == null || !victim.IsValid || attacker == null || !attacker.IsValid || attacker == victim) return;
int chance = Instance.Random.Next(0, 101);
if (hitGroup == HitGroup_t.HITGROUP_LEFTLEG || hitGroup == HitGroup_t.HITGROUP_RIGHTLEG)
{
if (chance > SkillsInfo.GetValue<float>(skillName, "legReflectionChance") * 100)
return;
}
else
if (chance > SkillsInfo.GetValue<float>(skillName, "torseReflectionChance") * 100)
return;
var playerInfo = PlayerManager.GetPlayerByIndex(victim.Index);
if (playerInfo?.Skill != skillName) return;
var pawn = victim!.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return;
if (string.IsNullOrEmpty(weapon) || noReflectionWeapon.Contains(weapon)) return;
var weaponServices = pawn.WeaponServices;
float chance = (hitgroup == (int)HitGroup_t.HITGROUP_LEFTLEG || hitgroup == (int)HitGroup_t.HITGROUP_RIGHTLEG)
? SkillsInfo.GetValue<float>(skillName, "legReflectionChance")
: SkillsInfo.GetValue<float>(skillName, "torseReflectionChance");
var victimPawn = victim.PlayerPawn?.Value;
if (victimPawn == null || !victimPawn.IsValid || Instance.Random.NextDouble() > chance)
return;
var weaponServices = victimPawn.WeaponServices;
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;
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 LegReflectionChance { get; set; } = legReflectionChance;

View file

@ -3,14 +3,13 @@ using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills
{
public class BunnyHop : ISkill
{
private const Skills skillName = Skills.BunnyHop;
private static readonly ConcurrentDictionary<ulong, int> playersLastJump = [];
private static readonly ConcurrentDictionary<uint, int> playersLastJump = [];
public static void LoadSkill()
{
@ -21,7 +20,9 @@ namespace src.player.skills
{
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)
GiveBunnyHop(player);
}
@ -29,26 +30,31 @@ namespace src.player.skills
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;
if (playerPawn == null || !playerPawn.IsValid) return;
if (JumpBan.bannedPlayers.ContainsKey(player.Index)) return;
var flags = (PlayerFlags)playerPawn.Flags;
var flags = (PlayerFlags)eventPlayerPawn.Flags;
var buttons = player.Buttons;
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)
|| (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 vX = playerPawn.AbsVelocity.X;
var vY = playerPawn.AbsVelocity.Y;
var vX = eventPlayerPawn.AbsVelocity.X;
var vY = eventPlayerPawn.AbsVelocity.Y;
var speed2D = Math.Sqrt(vX * vX + vY * vY);
var scale = 1d;
@ -60,8 +66,8 @@ namespace src.player.skills
else if (speed2D > maxSpeed)
scale = maxSpeed / speed2D;
playerPawn.AbsVelocity.X = (float)(vX * scale);
playerPawn.AbsVelocity.Y = (float)(vY * scale);
eventPlayerPawn.AbsVelocity.X = (float)(vX * scale);
eventPlayerPawn.AbsVelocity.Y = (float)(vY * scale);
}
}

View file

@ -4,6 +4,7 @@ using CounterStrikeSharp.API.Core.Attributes;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using System.Drawing;
using static src.jRandomSkills;
namespace src.player.skills
@ -13,11 +14,13 @@ namespace src.player.skills
private const Skills skillName = Skills.C4Camouflage;
private static readonly ConcurrentDictionary<uint, byte> invisiblePlayers = [];
private const string bloodParticle = "particles/blood_impact/blood_impact_high.vpcf";
private const string cameraViewModel = "models/sprays/spray_plane.vmdl";
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
Instance.AddToManifest(bloodParticle);
Instance.AddToManifest(cameraViewModel);
}
public static void NewRound()
@ -27,40 +30,74 @@ namespace src.player.skills
public static void WeaponPickup(EventItemPickup @event)
{
var player = @event.Userid;
if (!Instance.IsPlayerValid(player)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
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)
{
var player = @event.Userid!;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item;
if (!Instance.IsPlayerValid(player)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
if (player == null || !player.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (weapon == "c4")
{
invisiblePlayers.TryAdd(player.Index, 0);
SkillUtils.SetPlayerInvisibility(player, .5f);
}
else
{
invisiblePlayers.TryRemove(player.Index, out _);
SkillUtils.SetPlayerInvisibility(player, 0);
}
}
public static void OnTick()
{
if (Server.TickCount % 2 != 0) return;
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 _);
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)
{
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;
bool isObservingC4Camouflage = false;
@ -68,14 +105,17 @@ namespace src.player.skills
if (targetHandle != nint.Zero)
{
var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle);
var targetInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == target?.SteamID);
var targetInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(target)?.Index);
if (targetInfo?.Skill == skillName) isObservingC4Camouflage = true;
}
foreach (var playerIndex in invisiblePlayers.Keys)
{
var playerController = Utilities.GetPlayerFromIndex((int)playerIndex);
if (playerController == null || !playerController.IsValid || playerController.SteamID == player.SteamID)
var playerController = PlayerManager.GetPlayerEvent(Utilities.GetPlayerFromIndex((int)playerIndex));
if (playerController == null || !playerController.IsValid || playerController.Index == player.Index)
continue;
if (player.Team == playerController.Team)
continue;
if (!isObservingC4Camouflage)
@ -105,6 +145,10 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value;
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.ActiveWeapon.Value == null || !playerPawn.WeaponServices.ActiveWeapon.Value.IsValid) return;
@ -112,32 +156,55 @@ namespace src.player.skills
if (activeWeapon.DesignerName != "weapon_c4") return;
invisiblePlayers.TryAdd(player.Index, 0);
SkillUtils.SetPlayerInvisibility(player, .5f);
}
public static void DisableSkill(CCSPlayerController player)
{
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)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
if (!invisiblePlayers.ContainsKey(player.Index)) return;
var playerPawn = player.PlayerPawn.Value;
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;
particle.EffectName = bloodParticle;
particle.StartActive = true;
Vector pos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 50);
particle.Teleport(pos);
particle.DispatchSpawn();
particle.AcceptInput("Start");
}

View file

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

View file

@ -17,11 +17,11 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event)
{
var attacker = @event.Attacker;
var victim = @event.Userid;
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
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 (Instance.Random.NextDouble() <= attackerInfo.SkillChance)
@ -34,12 +34,12 @@ namespace src.player.skills
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;
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "chanceTo") - SkillsInfo.GetValue<float>(skillName, "chanceFrom")) + SkillsInfo.GetValue<float>(skillName, "chanceFrom");
playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
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)

View file

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

View file

@ -1,6 +1,7 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using Microsoft.Extensions.Logging;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
@ -10,7 +11,7 @@ namespace src.player.skills
public class ChillOut : ISkill
{
private const Skills skillName = Skills.ChillOut;
private static readonly ConcurrentDictionary<ulong, float> plantingPlayers = [];
private static readonly ConcurrentDictionary<uint, float> plantingPlayers = [];
public static void LoadSkill()
{
@ -25,25 +26,27 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
plantingPlayers.TryRemove(player.SteamID, out _);
plantingPlayers.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player);
}
public static void BombAbortplant(EventBombAbortplant @event)
{
var user = @event.Userid;
if (user == null || !user.IsValid || !user.PawnIsAlive) return;
plantingPlayers.TryRemove(user.SteamID, out _);
var user = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(user)) return;
plantingPlayers.TryRemove(user.Index, out _);
SkillUtils.ResetPrintHTML(user);
}
public static void BombBeginplant(EventBombBeginplant @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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)
{
var bombEntities = Utilities.FindAllEntitiesByDesignerName<CC4>("weapon_c4").ToList();
@ -58,9 +61,10 @@ namespace src.player.skills
public static void BombPlanted(EventBombPlanted @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(player)) return;
plantingPlayers.TryRemove(player!.SteamID, out _);
plantingPlayers.TryRemove(player!.Index, out _);
SkillUtils.ResetPrintHTML(player);
}
@ -71,9 +75,9 @@ namespace src.player.skills
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;
var pawn = player.PlayerPawn.Value;
@ -83,7 +87,7 @@ namespace src.player.skills
var activeWeapon = pawn.WeaponServices.ActiveWeapon.Value;
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;
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 src.utils;
using static src.jRandomSkills;
@ -17,12 +17,12 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event)
{
var damage = @event.DmgHealth;
var attacker = @event.Attacker;
var victim = @event.Userid;
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Weapon;
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 (weapon == "knife" || weapon == "bayonet")

View file

@ -1,5 +1,6 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Commands.Targeting;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Timers;
using CounterStrikeSharp.API.Modules.Utils;
@ -178,15 +179,18 @@ namespace src.player.skills
if (cameraView == null || !cameraView.IsValid) return;
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;
cameraTimer = jRandomSkills.Instance.AddTimer(2f, () =>
{
var target = Utilities.GetPlayers().FirstOrDefault(p => p.IsValid && p.SteamID == playerSteamID);
if (target == null || !target.IsValid || !target.PawnIsAlive)
var target = Utilities.GetPlayers().FirstOrDefault(p => p.IsValid && p.Index == playerIndex);
if (target == null || !target.IsValid || target.LifeState != (byte)LifeState_t.LIFE_ALIVE)
{
cameraTimer?.Kill();
return;
@ -198,7 +202,14 @@ namespace src.player.skills
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);
}
else
@ -222,12 +233,12 @@ namespace src.player.skills
if (!CheckCameraPosition(finalPos, player))
return null;
var camera = Utilities.CreateEntityByName<CDynamicProp>("prop_dynamic_override");
var camera = EntityManager.CreateTrackedPropOverride(player.Index);
if (camera == null || !camera.IsValid) return null;
camera.Collision.SolidType = SolidType_t.SOLID_VPHYSICS;
camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(camera.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
camera.Entity!.Name = camera.Globalname = $"CypherCamera_{Server.TickCount}_{player.SteamID}";
camera.Entity!.Name = camera.Globalname = $"CypherCamera_{Server.TickCount}_{player.Index}";
camera.SetModel(cameraPropModel);
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 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;
Server.NextFrame(() =>
{
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.Render = Color.FromArgb(1, 255, 255, 255);
camera.Teleport(finalPos, cameraProp.AbsRotation);
camera.DispatchSpawn();
EntityManager.RegisterExisting(camera, ownerIndex, "prop_dynamic");
});
return camera;
@ -272,10 +293,10 @@ namespace src.player.skills
if (!param.Entity.Name.StartsWith("CypherCamera_")) return;
var nameParams = param.Entity.Name.Split('_')[2];
_ = ulong.TryParse(nameParams, out ulong steamID);
if (steamID == 0) return;
_ = uint.TryParse(nameParams, out uint userIndex);
if (userIndex == 0) return;
var player = Utilities.GetPlayerFromSteamId(steamID);
var player = Utilities.GetPlayerFromIndex((int)userIndex);
if (player == null) return;
if (playersInfo.TryGetValue(player.Index, out var playerSkill))
@ -355,7 +376,7 @@ namespace src.player.skills
var player = Utilities.GetPlayerFromIndex((int)playerSkill.Player);
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;
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.Modules.Timers;
using CounterStrikeSharp.API.Modules.Utils;
@ -12,7 +12,8 @@ namespace src.player.skills
public class Darkness : ISkill
{
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();
public static void LoadSkill()
@ -26,31 +27,25 @@ namespace src.player.skills
{
foreach (var player in Utilities.GetPlayers())
{
if (playersInDark.ContainsKey(player.SteamID))
if (playersInDark.ContainsKey(player.Index))
DisableSkill(player);
SkillUtils.CloseMenu(player);
}
playersInDark.Clear();
playersToTarget.Clear();
}
}
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null) return;
DisableSkill(player);
}
public static void OnTick()
{
if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers())
{
if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
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()))];
SkillUtils.UpdateMenu(player, menuItems);
@ -59,8 +54,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands)
{
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed)
@ -70,7 +65,8 @@ namespace src.player.skills
}
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)
{
@ -79,18 +75,20 @@ namespace src.player.skills
}
SetUpPostProcessing(enemy);
playersToTarget[player.Index] = enemy.Index;
playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("darkness_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("darkness_enemy_info"));
}
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;
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)
{
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => (e.PlayerName, e.Index.ToString()))];
@ -104,34 +102,50 @@ namespace src.player.skills
{
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);
}
}
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)
{
if (player == null || !player.IsValid) return;
ulong? playerSteamID = player?.SteamID;
if (playerSteamID == null) return;
uint playerIndex = player.Index;
lock (setLock)
{
if (!turnOff)
{
playersInDark.TryAdd((ulong)playerSteamID, 0);
playersInDark.TryAdd(playerIndex, 0);
ApplyColor(player);
Timer? darkTimer = null;
darkTimer = Instance.AddTimer(5f, () => {
if (!playersInDark.ContainsKey((ulong)playerSteamID))
if (!playersInDark.ContainsKey(playerIndex))
{
darkTimer?.Kill();
return;
}
var target = Utilities.GetPlayers().FirstOrDefault(p => p.IsValid && p.SteamID == playerSteamID);
var target = Utilities.GetPlayerFromIndex((int)playerIndex);
if (target == null || !target.IsValid)
{
darkTimer?.Kill();
@ -145,7 +159,7 @@ namespace src.player.skills
else
{
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);
}
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 G { get; set; } = g;

View file

@ -1,16 +1,15 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills
{
public class Dash : ISkill
{
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();
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)
{
SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo
SkillPlayerInfo.TryAdd(player.Index, new PlayerSkillInfo
{
SteamID = player.SteamID,
Username = player.PlayerName,
CanUse = true,
Cooldown = DateTime.MinValue,
LastFlags = 0,
Jumps = 0,
LastButtons = 0
WasOnGround = true,
JumpReleasedTicks = 10
});
}
public static void DisableSkill(CCSPlayerController player)
{
SkillPlayerInfo.TryRemove(player.SteamID, out _);
SkillPlayerInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player);
}
@ -72,7 +56,7 @@ namespace src.player.skills
skillInfo.CanUse = true;
}
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return;
if (cooldown == 0)
@ -81,31 +65,49 @@ namespace src.player.skills
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)
{
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;
var flags = (PlayerFlags)playerPawn.Flags;
var buttons = player.Buttons;
bool jumpPressed = (buttons & PlayerButtons.Jump) != 0
|| (playerPawn.MovementServices?.QueuedButtonChangeMask & (ulong)PlayerButtons.Jump) != 0;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerPawn == null || playerInfo == null) return;
bool isOnGround =
eventPlayerPawn.GroundEntity != null
&& eventPlayerPawn.GroundEntity.IsValid;
bool wasOnGround = (skillInfo.LastFlags & PlayerFlags.FL_ONGROUND) != 0;
bool isOnGround = (flags & PlayerFlags.FL_ONGROUND) != 0;
if (wasOnGround && !isOnGround && jumpPressed)
if (skillInfo.WasOnGround && !isOnGround && jumpPressed)
skillInfo.Jumps = 0;
else if (isOnGround)
skillInfo.Jumps = 0;
else if (!isOnGround && jumpPressed && skillInfo.Jumps < 1)
{
bool lastJumpPressed = (skillInfo.LastButtons & PlayerButtons.Jump) != 0;
if (!lastJumpPressed && skillInfo.CanUse)
if (skillInfo.JumpReleasedTicks >= 3 && skillInfo.CanUse)
{
skillInfo.Jumps++;
skillInfo.CanUse = false;
@ -133,29 +135,33 @@ namespace src.player.skills
moveY = 1;
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");
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;
playerPawn.AbsVelocity.Y = newVelocity.Y;
playerPawn.AbsVelocity.Z = newVelocity.Z;
eventPlayerPawn.AbsVelocity.X = newVelocity.X;
eventPlayerPawn.AbsVelocity.Y = newVelocity.Y;
eventPlayerPawn.AbsVelocity.Z = newVelocity.Z;
}
}
skillInfo.LastFlags = flags;
skillInfo.LastButtons = buttons;
skillInfo.WasOnGround = isOnGround;
if (!jumpPressed)
skillInfo.JumpReleasedTicks++;
else
skillInfo.JumpReleasedTicks = 0;
}
public class PlayerSkillInfo
{
public ulong SteamID { get; set; }
public string? Username { get; set; }
public bool CanUse { get; set; }
public DateTime Cooldown { get; set; }
public PlayerFlags LastFlags { get; set; }
public int Jumps { get; set; }
public PlayerButtons LastButtons { get; set; }
public 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)

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
@ -28,15 +28,15 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers())
{
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;
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 = [];
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;
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill);
if (skillData == null) continue;
@ -50,15 +50,16 @@ namespace src.player.skills
{
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;
var playerPawn = player.PlayerPawn.Value;
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];
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)
{
@ -71,13 +72,13 @@ namespace src.player.skills
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)
{
ConcurrentBag<(string, string)> menuItems = [];
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;
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill);
if (skillData == null) continue;
@ -91,7 +92,7 @@ namespace src.player.skills
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;
playerInfo.SpecialSkill = Skills.None;
SkillUtils.CloseMenu(player);
@ -99,8 +100,8 @@ namespace src.player.skills
private static void DeacitvateSkill(CCSPlayerController player, CCSPlayerController enemy)
{
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
var enemyInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == enemy.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
var enemyInfo = PlayerManager.GetPlayerByIndex(enemy.Index);
if (playerInfo != null)
{

View file

@ -1,8 +1,7 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.UserMessages;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
@ -12,6 +11,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Deaf;
private static readonly ConcurrentDictionary<uint, byte> deafPlayers = [];
private static readonly ConcurrentDictionary<uint, uint> playersToTarget = [];
public static void LoadSkill()
{
@ -28,6 +28,8 @@ namespace src.player.skills
}
deafPlayers.Clear();
playersToTarget.Clear();
foreach (var player in Utilities.GetPlayers())
SkillUtils.CloseMenu(player);
}
@ -48,10 +50,10 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers())
{
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;
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()))];
SkillUtils.UpdateMenu(player, menuItems);
@ -60,8 +62,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands)
{
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed)
@ -71,7 +73,8 @@ namespace src.player.skills
}
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)
{
@ -80,18 +83,20 @@ namespace src.player.skills
}
deafPlayers.TryAdd(enemy.Index, 0);
playersToTarget[player.Index] = enemy.Index;
playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("deaf_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("deaf_enemy_info"));
}
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;
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)
{
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)
{
if (playersToTarget.TryRemove(player.Index, out uint targetIndex))
deafPlayers.TryRemove(targetIndex, out _);
SkillUtils.CloseMenu(player);
}
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null || !player.IsValid) return;
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)

View file

@ -17,11 +17,11 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event)
{
var attacker = @event.Attacker;
var victim = @event.Userid;
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
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)
{
@ -39,12 +39,12 @@ namespace src.player.skills
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;
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "chanceTo") - SkillsInfo.GetValue<float>(skillName, "chanceFrom")) + SkillsInfo.GetValue<float>(skillName, "chanceFrom");
playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
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)

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -31,7 +31,7 @@ namespace src.player.skills
var player = Utilities.GetPlayerFromIndex((int)playerIndex);
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;
var playerPawn = player.PlayerPawn.Value;

View file

@ -17,11 +17,11 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event)
{
var attacker = @event.Attacker;
var victim = @event.Userid;
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
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)
HealAttacker(attacker!, @event.DmgHealth);

View file

@ -1,6 +1,5 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
@ -29,18 +28,20 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers())
{
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;
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 = [];
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;
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill);
if (skillData == null) continue;
menuItems.Add(($"{enemy.PlayerName} : {player.GetSkillName(skillData.Skill)}", enemy.Index.ToString()));
}
SkillUtils.UpdateMenu(player, menuItems);
@ -51,12 +52,12 @@ namespace src.player.skills
{
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;
var playerPawn = player.PlayerPawn.Value;
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];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Index.ToString() == enemyId);
@ -72,14 +73,14 @@ namespace src.player.skills
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)
{
ConcurrentBag<string> skills = [];
ConcurrentBag<(string, string)> menuItems = [];
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;
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill);
if (skillData == null) continue;
@ -89,6 +90,7 @@ namespace src.player.skills
int ctSkills = Event.counterterroristSkills.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))
{
Event.SetRandomSkill(player);
@ -97,7 +99,7 @@ namespace src.player.skills
SkillUtils.CreateMenu(player, menuItems);
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
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("selectplayerskill_incorrect_enemy_index")}");
@ -105,7 +107,7 @@ namespace src.player.skills
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;
playerInfo.SpecialSkill = Skills.None;
SkillUtils.CloseMenu(player);
@ -113,27 +115,27 @@ namespace src.player.skills
private static void DuplicateSkill(CCSPlayerController player, CCSPlayerController enemy)
{
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
var enemyInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == enemy.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
var enemyInfo = PlayerManager.GetPlayerByIndex(enemy.Index);
if (playerInfo == null || enemyInfo == null) return;
var enemySkill = enemyInfo.Skill;
bool ctSkill = Event.counterterroristSkills.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;
if ((player.Team == CsTeam.Terrorist && ctSkill) || (player.Team == CsTeam.CounterTerrorist && ttSkill))
{
Instance.AddTimer(.1f, () =>
{
var player = Utilities.GetPlayerFromSteamId(steamID);
var player = Utilities.GetPlayerFromIndex((int)playerIndex);
if (player == null || !player.IsValid) return;
Instance.SkillAction(skillName.ToString(), "EnableSkill", [player]);
player.PrintToChat($" {ChatColors.Red}" + player.GetTranslation("thief_incorrect_skill", enemyName));
});
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
return;
}
@ -146,15 +148,16 @@ namespace src.player.skills
if (SkillsInfo.GetValue<bool>(enemySkill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
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 (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]);
});
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
else
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));
}

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -26,7 +26,7 @@ namespace src.player.skills
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;
var playerPawn = player.PlayerPawn?.Value;
@ -38,13 +38,13 @@ namespace src.player.skills
SkillUtils.ChangePlayerScale(player, 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)
{
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return;
var playerPawn = player.PlayerPawn?.Value;

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
@ -9,136 +9,133 @@ namespace src.player.skills
{
public class Earthquake : ISkill
{
private const Skills skillName = Skills.Earthquake;
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new();
//private const Skills skillName = Skills.Earthquake;
//private static readonly ConcurrentDictionary<uint, PlayerSkillInfo> SkillPlayerInfo = [];
//private static readonly object setLock = new();
public static void LoadSkill()
{
// SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
//public static void LoadSkill()
//{
// SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
//}
public static void NewRound()
{
lock (setLock)
SkillPlayerInfo.Clear();
}
//public static void NewRound()
//{
// lock (setLock)
// SkillPlayerInfo.Clear();
//}
public static void EnableSkill(CCSPlayerController player)
{
SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo
{
SteamID = player.SteamID,
CanUse = true,
Cooldown = DateTime.MinValue,
});
}
//public static void EnableSkill(CCSPlayerController player)
//{
// SkillPlayerInfo.TryAdd(player.Index, new PlayerSkillInfo
// {
// SteamID = player.Index,
// CanUse = true,
// Cooldown = DateTime.MinValue,
// });
//}
public static void DisableSkill(CCSPlayerController player)
{
SkillPlayerInfo.TryRemove(player.SteamID, out _);
SkillUtils.ResetPrintHTML(player);
}
//public static void DisableSkill(CCSPlayerController player)
//{
// SkillPlayerInfo.TryRemove(player.Index, out _);
// SkillUtils.ResetPrintHTML(player);
//}
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo?.Skill == skillName)
SkillPlayerInfo.TryRemove(player.SteamID, out _);
}
//public static void PlayerDeath(EventPlayerDeath @event)
//{
// var player = PlayerManager.GetPlayerEvent(@event.Userid);
// if (player == null || !player.IsValid) return;
// var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
// if (playerInfo?.Skill == skillName)
// SkillPlayerInfo.TryRemove(player.Index, out _);
//}
public static void OnTick()
{
foreach (var player in Utilities.GetPlayers())
{
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);
}
}
//public static void OnTick()
//{
// foreach (var player in Utilities.GetPlayers())
// {
// var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
// if (playerInfo?.Skill == skillName)
// if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
// UpdateHUD(player, skillInfo);
// }
//}
private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo)
{
float cooldown = 0;
if (skillInfo != null)
{
float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue<float>(skillName, "cooldown")) - DateTime.Now).TotalSeconds);
cooldown = Math.Max(time, 0);
//private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo)
//{
// float cooldown = 0;
// if (skillInfo != null)
// {
// float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue<float>(skillName, "cooldown")) - DateTime.Now).TotalSeconds);
// cooldown = Math.Max(time, 0);
if (cooldown == 0 && skillInfo?.CanUse == false)
skillInfo.CanUse = true;
}
// if (cooldown == 0 && skillInfo?.CanUse == false)
// skillInfo.CanUse = true;
// }
if (cooldown == 0)
return;
// if (cooldown == 0)
// return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
if (playerInfo == null) return;
// var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
// 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)
{
var playerPawn = player.PlayerPawn.Value;
if (playerPawn?.CBodyComponent == null) return;
//public static void UseSkill(CCSPlayerController player)
//{
// var playerPawn = player.PlayerPawn.Value;
// if (playerPawn?.CBodyComponent == null) return;
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
{
if (!player.IsValid || !player.PawnIsAlive) return;
if (skillInfo.CanUse)
{
skillInfo.CanUse = false;
skillInfo.Cooldown = DateTime.Now;
MakeShake(player);
}
}
}
// if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
// {
// if (!player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
// if (skillInfo.CanUse)
// {
// skillInfo.CanUse = false;
// skillInfo.Cooldown = DateTime.Now;
// MakeShake(player);
// }
// }
//}
private static void MakeShake(CCSPlayerController player)
{
foreach (var enemy in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.PawnIsAlive))
CreateShake(player);
}
//private static void MakeShake(CCSPlayerController player)
//{
// foreach (var enemy in Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.PawnIsAlive))
// CreateShake(player);
//}
private static void CreateShake(CCSPlayerController player)
{
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
//private static void CreateShake(CCSPlayerController player)
//{
// var pawn = player.PlayerPawn.Value;
// if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
var shake = Utilities.CreateEntityByName<CEnvShake>("env_shake");
if (shake == null) return;
// var shake = EntityManager.CreateTrackedEnvShake(player.Index);
// if (shake == null || !shake.IsValid) return;
shake.DispatchSpawn();
if (!shake.IsValid) return;
// shake.Amplitude = SkillsInfo.GetValue<float>(skillName, "amplitude");
// shake.Frequency = SkillsInfo.GetValue<float>(skillName, "frequency");
// shake.Duration = SkillsInfo.GetValue<float>(skillName, "duration");
// shake.Radius = SkillsInfo.GetValue<float>(skillName, "radius");
shake.Amplitude = SkillsInfo.GetValue<float>(skillName, "amplitude");
shake.Frequency = SkillsInfo.GetValue<float>(skillName, "frequency");
shake.Duration = SkillsInfo.GetValue<float>(skillName, "duration");
shake.Radius = SkillsInfo.GetValue<float>(skillName, "radius");
// 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");
//}
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 bool CanUse { get; set; }
// public DateTime Cooldown { get; set; }
//}
public class PlayerSkillInfo
{
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 float Amplitude { get; set; } = amplitude;
public float Frequency { get; set; } = frequency;
public float Duration { get; set; } = duration;
public float Radius { get; set; } = radius;
}
//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 float Amplitude { get; set; } = amplitude;
// 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.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
@ -10,7 +9,7 @@ namespace src.player.skills
public class EnemySpawn : ISkill
{
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();
public static void LoadSkill()
@ -29,9 +28,9 @@ namespace src.player.skills
if (SkillUtils.IsFreezeTime()) return;
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 (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
UpdateHUD(player, skillInfo);
}
}
@ -39,9 +38,9 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player)
{
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,
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)
{
SkillPlayerInfo.TryRemove(player.SteamID, out _);
SkillPlayerInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player);
}
@ -65,7 +64,7 @@ namespace src.player.skills
skillInfo.CanUse = true;
}
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return;
if (cooldown == 0)
@ -79,9 +78,9 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value;
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.CanUse = false;

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -21,14 +21,14 @@ namespace src.player.skills
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;
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
}
private static void SpawnExplosion(Vector vector)
@ -64,12 +64,12 @@ namespace src.player.skills
{
if (lastTick == Server.TickCount) return;
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
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 (Instance.Random.NextDouble() <= playerInfo.SkillChance)

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using System.Drawing;
@ -11,7 +11,7 @@ namespace src.player.skills
public class FalconEye : ISkill
{
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()
{
@ -21,28 +21,23 @@ namespace src.player.skills
public static void NewRound()
{
foreach (var cameraIndex in cameras.Values)
{
var camera = Utilities.GetEntityFromIndex<CDynamicProp>((int)cameraIndex.Item2);
if (camera == null || !camera.IsValid) continue;
camera.AcceptInput("Kill");
}
EntityManager.DestroyEntity(cameraIndex.Item2);
cameras.Clear();
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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 ;
var pawn = player!.PlayerPawn.Value;
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);
}
@ -55,13 +50,15 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
if (player == null) return;
ChangeCamera(player, true);
EntityManager.DestroyPlayerEntities(player.Index);
}
public static void OnTick()
{
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;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue;
@ -88,7 +85,7 @@ namespace src.player.skills
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.CameraServices == null) return;
if (cameras.TryGetValue(player.SteamID, out var cameraInfo) && cameraInfo.Item2 != 0)
if (cameras.TryGetValue(player.Index, out var cameraInfo) && cameraInfo.Item2 != 0)
{
orginalCameraRaw = cameraInfo.Item1;
@ -114,7 +111,7 @@ namespace src.player.skills
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;
var pawn = player.PlayerPawn.Value;
@ -124,13 +121,14 @@ namespace src.player.skills
Server.NextFrame(() =>
{
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.Render = Color.FromArgb(0, 255, 255, 255);
camera.Teleport(pos, new QAngle(90, 0, 0));
camera.DispatchSpawn();
});
cameras.AddOrUpdate(player.SteamID, (pawn.CameraServices!.ViewEntity.Raw, camera.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;
}

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -20,9 +20,9 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value;
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 (!player.IsValid || !player.PawnIsAlive) return;
if (!player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
InstaReload(playerPawn);
}

View file

@ -11,7 +11,7 @@ namespace src.player.skills
public class Flash : ISkill
{
private const Skills skillName = Skills.Flash;
public static readonly ConcurrentDictionary<ulong, int> jumpedPlayers = [];
public static readonly ConcurrentDictionary<uint, int> jumpedPlayers = [];
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);
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 (player!.Buttons.HasFlag(PlayerButtons.Speed) || player.Buttons.HasFlag(PlayerButtons.Duck))
@ -43,26 +43,26 @@ namespace src.player.skills
public static void PlayerJump(EventPlayerJump @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
if (!jumpedPlayers.TryGetValue(player.SteamID, out _)) return;
jumpedPlayers.AddOrUpdate(player.SteamID, Server.TickCount + 20, (k, v) => Server.TickCount + 20);
if (!jumpedPlayers.TryGetValue(player.Index, out _)) return;
jumpedPlayers.AddOrUpdate(player.Index, Server.TickCount + 20, (k, v) => Server.TickCount + 20);
}
public static void EnableSkill(CCSPlayerController player)
{
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;
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);
playerInfo.SkillChance = newSpeed;
jumpedPlayers.TryAdd(player.SteamID, 0);
jumpedPlayers.TryAdd(player.Index, 0);
playerPawn.VelocityModifier = 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)
@ -70,7 +70,7 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value;
if (playerPawn == null) return;
playerPawn.VelocityModifier = 1;
jumpedPlayers.TryRemove(player.SteamID, out _);
jumpedPlayers.TryRemove(player.Index, out _);
}
public static void OnTick()
@ -79,7 +79,7 @@ namespace src.player.skills
{
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;
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))
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;
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.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils;
@ -11,8 +11,9 @@ namespace src.player.skills
public class Fortnite : ISkill
{
private const Skills skillName = Skills.Fortnite;
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly ConcurrentDictionary<ulong, int> barricades = [];
private static readonly ConcurrentDictionary<uint, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly ConcurrentDictionary<uint, int> barricades = [];
public static bool skillInThisRound = false;
private static readonly object setLock = new();
public static void LoadSkill()
@ -23,6 +24,7 @@ namespace src.player.skills
public static void NewRound()
{
skillInThisRound = false;
lock (setLock)
{
SkillPlayerInfo.Clear();
@ -34,18 +36,19 @@ namespace src.player.skills
{
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 (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
UpdateHUD(player, skillInfo);
}
}
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,
Cooldown = DateTime.MinValue,
});
@ -53,7 +56,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
SkillPlayerInfo.TryRemove(player.SteamID, out _);
SkillPlayerInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player);
}
@ -69,7 +72,7 @@ namespace src.player.skills
skillInfo.CanUse = true;
}
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return;
if (cooldown == 0)
@ -83,9 +86,10 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value;
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.CanUse = false;
@ -98,7 +102,7 @@ namespace src.player.skills
private static void CreateBox(CCSPlayerController player)
{
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;
float distance = 50;
@ -140,12 +144,12 @@ namespace src.player.skills
if (newHealth <= 0)
{
barricades.TryRemove(box.Index, out _);
box.AcceptInput("Kill");
EntityManager.DestroyEntity(box.Index);
}
else
barricades.AddOrUpdate(box.Index, newHealth, (k, v) => newHealth);
}
else box.AcceptInput("Kill");
else EntityManager.DestroyEntity(box.Index);
}
public class PlayerSkillInfo

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -40,7 +40,7 @@ namespace src.player.skills
plantedC4 = null;
var plantedBomb = Utilities.FindAllEntitiesByDesignerName<CPlantedC4>("planted_c4").FirstOrDefault();
if (plantedBomb != null && plantedBomb.IsValid)
plantedBomb.AcceptInput("Kill");
plantedBomb.AddEntityIOEvent("Kill", plantedBomb, delay: 0.1f);
SkillUtils.TerminateRound(CsTeam.CounterTerrorist);
}
@ -48,12 +48,12 @@ namespace src.player.skills
{
if (lastTick == Server.TickCount) return;
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid || plantedC4 == null) return;
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 (SkillUtils.Distance(plantedC4, pos) >= 8)

View file

@ -1,6 +1,5 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Cvars;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using static src.jRandomSkills;
@ -20,15 +19,14 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event)
{
var damage = @event.DmgHealth;
var victim = @event.Userid;
var attacker = @event.Attacker;
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var weapon = @event.Weapon;
HitGroup_t hitgroup = (HitGroup_t)@event.Hitgroup;
if (nades.Contains(weapon)) 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;
Server.ExecuteCommand("mp_autokick 0");

View file

@ -1,10 +1,9 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills
{
@ -25,10 +24,10 @@ namespace src.player.skills
public static void DecoyStarted(EventDecoyStarted @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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;
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)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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;
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()
{
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 pawn = player.PlayerPawn.Value;
var pawn = eventPlayer.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue;
double distance = SkillUtils.GetDistance(decoyPos, pawn.AbsOrigin);
if (distance <= decoyRadius)
{

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
@ -24,11 +24,11 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands)
{
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
ulong steamID = player.SteamID;
uint playerIndex = player.Index;
if (playerInfo.SkillUsed)
{
@ -58,15 +58,16 @@ namespace src.player.skills
if (SkillsInfo.GetValue<bool>(skill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
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 (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]);
});
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
else
Instance?.SkillAction(skill.Skill.ToString(), "EnableSkill", [player]);
});
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
}
private static bool TakeMoney(CCSPlayerController player)
@ -86,7 +87,7 @@ namespace src.player.skills
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;
playerInfo.SkillUsed = false;
@ -107,13 +108,13 @@ namespace src.player.skills
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];
List<jSkill_SkillInfo> skillList = [.. SkillData.Skills];
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();
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 System.Collections.Concurrent;
using System.Collections.Immutable;
using System.Drawing;
using static src.jRandomSkills;
namespace src.player.skills
@ -26,11 +27,13 @@ namespace src.player.skills
];
private static readonly ConcurrentDictionary<uint, byte> invisiblePlayers = [];
private const string bloodParticle = "particles/blood_impact/blood_impact_high.vpcf";
private const string cameraViewModel = "models/sprays/spray_plane.vmdl";
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
Instance.AddToManifest(bloodParticle);
Instance.AddToManifest(cameraViewModel);
}
public static void NewRound()
@ -42,9 +45,9 @@ namespace src.player.skills
public static void WeaponPickup(EventItemPickup @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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;
SetWeaponAttack(player!, true);
@ -52,9 +55,9 @@ namespace src.player.skills
public static void WeaponEquip(EventItemEquip @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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;
SetWeaponAttack(player!, true);
@ -64,7 +67,7 @@ namespace src.player.skills
{
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;
bool isObservingGhost = false;
@ -72,14 +75,17 @@ namespace src.player.skills
if (targetHandle != nint.Zero)
{
var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle);
var targetInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == target?.SteamID);
var targetInfo = PlayerManager.GetPlayerByIndex(target?.Index);
if (targetInfo?.Skill == skillName) isObservingGhost = true;
}
foreach (var playerIndex in invisiblePlayers.Keys)
{
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;
if (!isObservingGhost)
@ -108,48 +114,92 @@ namespace src.player.skills
{
Event.EnableTransmit();
SetWeaponAttack(player, true);
SkillUtils.SetPlayerInvisibility(player, .5f);
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)
{
SkillUtils.ResetPrintHTML(player);
SetWeaponAttack(player, false);
SkillUtils.SetPlayerInvisibility(player, 0);
invisiblePlayers.TryRemove(player.Index, out _);
EntityManager.DestroyPlayerEntities(player.Index);
}
public static void OnTick()
{
if (Server.TickCount % 2 != 0) return;
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)
UpdateHUD(player);
if (!player.PawnIsAlive)
if (player.LifeState != (byte)LifeState_t.LIFE_ALIVE)
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)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
if (!invisiblePlayers.ContainsKey(player.Index)) return;
var playerPawn = player.PlayerPawn.Value;
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;
particle.EffectName = bloodParticle;
particle.StartActive = true;
Vector pos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 50);
particle.Teleport(pos);
particle.DispatchSpawn();
particle.AcceptInput("Start");
}
@ -177,7 +227,7 @@ namespace src.player.skills
var pawn = player.PlayerPawn.Value;
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;
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.Attributes;
using CounterStrikeSharp.API.Modules.Entities.Constants;
@ -41,10 +41,10 @@ namespace src.player.skills
foreach (var (info, player) in infoList)
{
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 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;
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.Modules.Commands.Targeting;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
using System.Collections.Concurrent;
namespace src.player.skills
{
public class Glitch : ISkill
{
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();
public static void LoadSkill()
@ -21,30 +22,28 @@ namespace src.player.skills
public static void NewRound()
{
lock (setLock)
glitchedPlayers.Clear();
foreach (var player in Utilities.GetPlayers())
{
DisableSkill(player);
SkillUtils.CloseMenu(player);
foreach (var player in Utilities.GetPlayers())
{
DisableSkill(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()
{
if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers())
{
if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
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())));
SkillUtils.UpdateMenu(player, menuItems);
@ -53,8 +52,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands)
{
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed)
@ -64,7 +63,8 @@ namespace src.player.skills
}
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)
{
@ -72,20 +72,23 @@ namespace src.player.skills
return;
}
glitchedPlayers.TryAdd(enemy, 0);
glitchedPlayers.TryAdd(enemy.Index, 0);
playersToTarget[player.Index] = enemy.Index;
enemy.ReplicateConVar("sv_disable_radar", "1");
playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("glitch_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("glitch_enemy_info"));
}
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;
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)
{
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)
{
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");
glitchedPlayers.TryRemove(player, out _);
glitchedPlayers.TryRemove(player.Index, out _);
SkillUtils.CloseMenu(player);
}

View file

@ -1,7 +1,6 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using static src.jRandomSkills;
namespace src.player.skills
{
@ -29,7 +28,7 @@ namespace src.player.skills
var player = pawn.Controller.Value.As<CCSPlayerController>();
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;
grenade.Bounces = 555;
}

View file

@ -1,6 +1,5 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
@ -11,7 +10,7 @@ namespace src.player.skills
public class GodMode : ISkill
{
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();
public static void LoadSkill()
@ -27,9 +26,9 @@ namespace src.player.skills
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,
Cooldown = DateTime.MinValue,
});
@ -39,16 +38,16 @@ namespace src.player.skills
{
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 (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
UpdateHUD(player, skillInfo);
}
}
public static void DisableSkill(CCSPlayerController player)
{
SkillPlayerInfo.TryRemove(player.SteamID, out _);
SkillPlayerInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player);
var playerPawn = player.PlayerPawn.Value;
@ -68,7 +67,7 @@ namespace src.player.skills
skillInfo.CanUse = true;
}
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return;
if (cooldown == 0)
@ -82,29 +81,29 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value;
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)
{
skillInfo.CanUse = false;
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;
Instance.AddTimer(SkillsInfo.GetValue<float>(skillName, "duration"), () => {
var player = Utilities.GetPlayerFromSteamId(steamID);
if (player != null && player.IsValid && player.PawnIsAlive)
var player = Utilities.GetPlayerFromIndex((int)playerIndex);
if (player != null && player.IsValid)
{
if (player.PlayerPawn == null || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return;
player.PlayerPawn.Value.TakesDamage = true;
player.PrintToChat($" {ChatColors.Red} {player.GetTranslation("godmode_off")}");
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)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Weapon;
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)
player!.GiveNamedItem($"weapon_{weapon}");
}

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Timers;
@ -13,72 +13,70 @@ namespace src.player.skills
{
public class HealingChicken : ISkill
{
private const Skills skillName = Skills.HealingChicken;
private readonly static ConcurrentDictionary<ulong, List<Timer>> playerSmokes = [];
private static readonly object setLock = new();
//private const Skills skillName = Skills.HealingChicken;
//private readonly static ConcurrentDictionary<uint, List<Timer>> playerSmokes = [];
//private static readonly object setLock = new();
public static void LoadSkill()
{
// SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
//public static void LoadSkill()
//{
// SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
//}
public static void NewRound()
{
//public static void NewRound()
//{
}
//}
public static void EnableSkill(CCSPlayerController player)
{
SpawnChicken(player);
}
//public static void EnableSkill(CCSPlayerController player)
//{
// SpawnChicken(player);
//}
public static void DisableSkill(CCSPlayerController player)
{
//public static void DisableSkill(CCSPlayerController player)
//{
}
//}
private static void SpawnChicken(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
//private static void SpawnChicken(CCSPlayerController player)
//{
// if (player == null || !player.IsValid) return;
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
// var pawn = player.PlayerPawn.Value;
// if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
int amount = SkillsInfo.GetValue<int>(skillName, "amount");
for (int i = 0; i < 1; i++)
{
CChicken? chicken = Utilities.CreateEntityByName<CChicken>("chicken");
if (chicken == null || !chicken.IsValid) continue;
// int amount = SkillsInfo.GetValue<int>(skillName, "amount");
// for (int i = 0; i < 1; i++)
// {
// CChicken? chicken = EntityManager.CreateTrackedChicken(player.Index);
// if (chicken == null || !chicken.IsValid) continue;
chicken.Render = Color.Green;
Vector offset = new (
(float)(100 * Math.Cos(2 * Math.PI * i / amount)),
(float)(100 * Math.Sin(2 * Math.PI * i / amount)),
0
);
// chicken.Render = Color.Green;
// Vector offset = new (
// (float)(100 * Math.Cos(2 * Math.PI * i / amount)),
// (float)(100 * Math.Sin(2 * Math.PI * i / amount)),
// 0
// );
chicken.DispatchSpawn();
chicken.Teleport(pawn.AbsOrigin + offset);
// chicken.Teleport(pawn.AbsOrigin + offset);
// Schema.SetSchemaValue(chicken.Handle, "CChicken", "m_leader", player.PlayerPawn.Raw);
Vector spawn = SkillUtils.GetSpawnPointVector(player);
Schema.SetSchemaValue(chicken.Handle, "CChicken", "m_vecPathGoal", spawn);
// // Schema.SetSchemaValue(chicken.Handle, "CChicken", "m_leader", player.PlayerPawn.Raw);
// Vector? spawn = SkillUtils.GetSpawnPointVector(player);
// Schema.SetSchemaValue(chicken.Handle, "CChicken", "m_vecPathGoal", spawn);
float speed = 50;
Instance.AddTickTimer(1, () =>
{
if (chicken == null || !chicken.IsValid) return;
// Instance.AddTickTimer(1, () =>
// {
// if (chicken == null || !chicken.IsValid) return;
Server.PrintToChatAll($"{chicken.PathGoal}, {chicken.UpdateTimer.Duration}, {chicken.UpdateTimer.Timescale}");
}, TimerFlags.REPEAT | TimerFlags.STOP_ON_MAPCHANGE);
}
}
// Server.PrintToChatAll($"{chicken.PathGoal}, {chicken.UpdateTimer.Duration}, {chicken.UpdateTimer.Timescale}");
// }, 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 int Amount { get; set; } = amount;
public int Heal { get; set; } = heal;
public int TickCooldown { get; set; } = tickCooldown;
}
//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 Heal { get; set; } = heal;
// 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.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills
{
@ -25,10 +24,10 @@ namespace src.player.skills
public static void SmokegrenadeDetonate(EventSmokegrenadeDetonate @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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;
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)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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;
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>();
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;
Server.NextFrame(() =>
@ -82,13 +81,17 @@ namespace src.player.skills
int smokeHeal = SkillsInfo.GetValue<int>(skillName, "smokeHeal");
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 (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);
}
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 int SmokeHeal { get; set; } = smokeHeal;

View file

@ -31,10 +31,10 @@ namespace src.player.skills
public static void PlayerDeath(EventPlayerDeath @event)
{
var attacker = @event.Attacker;
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
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;
var pawn = attacker!.PlayerPawn.Value;

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
@ -32,7 +32,7 @@ namespace src.player.skills
if (playerPawn == null || !playerPawn.IsValid) return;
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;
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.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills
{
@ -41,13 +40,13 @@ namespace src.player.skills
Vector currentPos = new(nade.AbsOrigin.X, nade.AbsOrigin.Y, nade.AbsOrigin.Z);
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");
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;
double minDistance = int.MaxValue;
@ -95,7 +94,7 @@ namespace src.player.skills
}
if (closetEnemyPos == null)
return Vector.Zero;
return null;
Vector direction = closetEnemyPos - nadePos;
float length = direction.Length();
@ -127,7 +126,7 @@ namespace src.player.skills
if (pawn.Controller.Value == null || !pawn.Controller.Value.IsValid) return;
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;
Vector pos = new(grenade.AbsOrigin?.X, grenade.AbsOrigin?.Y, grenade.AbsOrigin?.Z);
@ -136,7 +135,7 @@ namespace src.player.skills
Server.NextWorldUpdate(() =>
{
if (grenade == null || !grenade.IsValid) return;
grenade.DetonateTime += 100f;
grenade.DetonateTime += 30f;
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))
{
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;
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)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Item;
@ -66,7 +69,7 @@ namespace src.player.skills
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
players.TryRemove(player.Index, out _);
}

View file

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

View file

@ -10,6 +10,7 @@ namespace src.player.skills
private const Skills skillName = Skills.Illiterate;
private static bool isActive = false;
private static int offset = 5;
private static int lastChange = 0;
private static readonly object offsetLock = new();
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;
}
@ -48,24 +49,28 @@ namespace src.player.skills
if (!isActive || player == null || !player.IsValid) 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;
return Utilities.GetPlayers().Any(
p => p != null &&
p.IsValid &&
p.Pawn?.Value != null &&
p.PawnIsAlive &&
p.PlayerPawn?.Value != null &&
p.PlayerPawn.Value.Health > 0 &&
p.Team != player.Team &&
playersWithSkill.Contains(p.SteamID));
playersWithSkill.Contains(p.Index));
}
public static string? GetRandomText(string? input)
{
if (string.IsNullOrEmpty(input)) return null;
if (Server.TickCount % 64 == 0 || offset == 0)
if (Server.TickCount - lastChange > 64 || offset == 0)
{
EnsureOffset();
lastChange = Server.TickCount;
}
var chars = input.Select(c =>
{
@ -84,7 +89,6 @@ namespace src.player.skills
{
lock (offsetLock)
{
if (offset != 0) return;
try
{
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.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils;
@ -13,7 +13,7 @@ namespace src.player.skills
public class Illusionist : ISkill
{
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 object setLock = new();
@ -37,27 +37,27 @@ namespace src.player.skills
var entities = Utilities.FindAllEntitiesByDesignerName<CDynamicProp>("prop_dynamic_override");
foreach (var entity in entities)
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()
{
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 (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
UpdateHUD(player, skillInfo);
}
}
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,
Cooldown = DateTime.MinValue,
});
@ -65,7 +65,9 @@ namespace src.player.skills
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);
}
@ -81,7 +83,7 @@ namespace src.player.skills
skillInfo.CanUse = true;
}
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return;
if (cooldown == 0)
@ -92,9 +94,9 @@ namespace src.player.skills
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.Cooldown = DateTime.Now;
@ -108,7 +110,7 @@ namespace src.player.skills
if (playerPawn == null || !playerPawn.IsValid) 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;
replica.Collision.SolidType = SolidType_t.SOLID_VPHYSICS;
@ -166,10 +168,10 @@ namespace src.player.skills
{
if (replica != null && replica.IsValid)
{
replica.AcceptInput("Kill");
EntityManager.DestroyEntity(replica.Index);
if (ActiveTimers.TryRemove(replicaIndex, out var timer)) timer?.Kill();
}
});
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
}
public static void OnTakeDamage(DynamicHook h)
@ -188,7 +190,7 @@ namespace src.player.skills
replica.EmitSound("GlassBottle.BulletImpact", volume: 1f);
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);
if (attackerPawn.DesignerName != "player") return;

View file

@ -13,7 +13,7 @@ namespace src.player.skills
private const Skills skillName = Skills.Impostor;
private static readonly string defaultCTModel = "agents/models/ctm_sas/ctm_sas.vmdl";
private static readonly string defaultTModel = "agents/models/tm_phoenix/tm_phoenix.vmdl";
private static readonly ConcurrentDictionary<ulong, string> originalModels = [];
private static readonly ConcurrentDictionary<uint, string> originalModels = [];
public static void LoadSkill()
{
@ -29,16 +29,16 @@ namespace src.player.skills
{
string model = GetEnemyModel(player);
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);
}
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;
SetPlayerModel(player, model);
originalModels.TryRemove(player.SteamID, out _);
originalModels.TryRemove(player.Index, out _);
}
private static string GetEnemyModel(CCSPlayerController player)

View file

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

View file

@ -1,9 +1,9 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Commands.Targeting;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
using System.Collections.Concurrent;
namespace src.player.skills
{
@ -11,6 +11,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Jammer;
private static readonly ConcurrentDictionary<uint, byte> jammedPlayers = [];
private static readonly ConcurrentDictionary<uint, uint> jammerToTarget = [];
private static readonly object setLock = new();
public static void LoadSkill()
@ -29,7 +30,9 @@ namespace src.player.skills
SetCrosshair(player, true);
}
jammedPlayers.Clear();
jammerToTarget.Clear();
}
foreach (var player in Utilities.GetPlayers())
SkillUtils.CloseMenu(player);
}
@ -40,10 +43,10 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers())
{
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;
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())));
SkillUtils.UpdateMenu(player, menuItems);
@ -52,8 +55,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands)
{
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed)
@ -63,7 +66,8 @@ namespace src.player.skills
}
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)
{
@ -72,8 +76,11 @@ namespace src.player.skills
}
jammedPlayers.TryAdd(enemy.Index, 0);
jammerToTarget[player.Index] = enemy.Index;
SetCrosshair(enemy, false);
playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("jammer_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("jammer_enemy_info"));
}
@ -90,11 +97,11 @@ namespace src.player.skills
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;
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)
{
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)
{
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);
jammedPlayers.TryRemove(player.Index, out _);
SkillUtils.CloseMenu(player);

View file

@ -1,6 +1,5 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
@ -13,7 +12,7 @@ namespace src.player.skills
public class Jester : ISkill
{
private const Skills skillName = Skills.Jester;
private static readonly ConcurrentDictionary<ulong, JesterInfo> jesters = [];
private static readonly ConcurrentDictionary<uint, JesterInfo> jesters = [];
public static void LoadSkill()
{
@ -32,13 +31,13 @@ namespace src.player.skills
jester.Timer = null;
}
var player = Utilities.GetPlayerFromSteamId(jester.SteamId);
var player = Utilities.GetPlayerFromIndex((int)jester.PlayerIndex);
if (player != null && player.IsValid)
{
SkillUtils.ResetPrintHTML(player);
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);
pawn.Render = color;
@ -51,7 +50,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
var jester = GetJesterInfo(player.SteamID);
var jester = GetJesterInfo(player.Index);
if (jester == null) return;
Server.NextWorldUpdate(() =>
@ -69,11 +68,11 @@ namespace src.player.skills
public static void BombBegindefuse(EventBombBegindefuse @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
ulong steamId = player.SteamID;
var jester = GetJesterInfo(steamId);
uint playerIndex = player.Index;
var jester = GetJesterInfo(playerIndex);
if (jester == null) return;
if (jester.Timer != null)
@ -83,17 +82,17 @@ namespace src.player.skills
}
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)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
ulong steamId = player.SteamID;
var jester = GetJesterInfo(steamId);
uint playerIndex = player.Index;
var jester = GetJesterInfo(playerIndex);
if (jester == null) return;
if (jester.Timer != null)
@ -104,18 +103,17 @@ namespace src.player.skills
jester.Timer = Instance.AddTimer(1, () => {
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)
{
var attacker = @event.Attacker;
var victim = @event.Userid;
int hitgroup = @event.Hitgroup;
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
if (!Instance.IsPlayerValid(victim)) return;
var jesterVictim = GetJesterInfo(victim!.SteamID);
var jesterVictim = GetJesterInfo(victim!.Index);
if (!Instance.IsPlayerValid(attacker))
{
@ -124,7 +122,7 @@ namespace src.player.skills
return;
}
var jesterAttacker = GetJesterInfo(attacker!.SteamID);
var jesterAttacker = GetJesterInfo(attacker!.Index);
if ((jesterVictim != null && jesterVictim.Active) || (jesterAttacker != null && jesterAttacker.Active))
SkillUtils.RestoreHealth(victim);
}
@ -135,18 +133,18 @@ namespace src.player.skills
var maxTime = SkillsInfo.GetValue<float>(skillName, "maxTime");
float wait = (float)Instance.Random.NextDouble() * (maxTime - minTime) + minTime;
ulong steamId = player.SteamID;
uint playerIndex = player.Index;
jesters.TryAdd(steamId, new JesterInfo {
SteamId = steamId,
jesters.TryAdd(playerIndex, new JesterInfo {
PlayerIndex = playerIndex,
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)
{
@ -154,10 +152,10 @@ namespace src.player.skills
jester.Timer = null;
}
var player = Utilities.GetPlayerFromSteamId(steamId);
if (player == null || !player.IsValid || !player.PawnIsAlive)
var player = Utilities.GetPlayerFromIndex((int)playerIndex);
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE)
{
jesters.TryRemove(steamId, out _);
jesters.TryRemove(playerIndex, out _);
return;
}
@ -167,14 +165,17 @@ namespace src.player.skills
if (jester.Active != previousState)
{
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 maxTime = SkillsInfo.GetValue<float>(skillName, "maxTime");
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)
@ -184,7 +185,7 @@ namespace src.player.skills
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return;
var jester = GetJesterInfo(player.SteamID);
var jester = GetJesterInfo(player.Index);
if (jester == null) return;
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()
{
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 playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
var playeEvent = PlayerManager.GetPlayerEvent(player);
if (playeEvent == null || !playeEvent.IsValid || playeEvent.PlayerPawn.Value == null || !playeEvent.PlayerPawn.Value.IsValid) continue;
var playerInfo = PlayerManager.GetPlayerByIndex(playeEvent.Index);
if (playerInfo?.Skill == skillName)
UpdateHUD(player);
UpdateHUD(playeEvent);
}
}
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;
var jester = GetJesterInfo(player.SteamID);
var jester = GetJesterInfo(player.Index);
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>";
}
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 null;
}
public class JesterInfo()
{
public required ulong SteamId { get; set; }
public required uint PlayerIndex { get; set; }
public bool Active { get; set; } = false;
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.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
@ -11,6 +10,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.JumpBan;
public static readonly ConcurrentDictionary<uint, int> bannedPlayers = [];
private static readonly ConcurrentDictionary<uint, uint> playersToTarget = [];
public static void LoadSkill()
{
@ -20,13 +20,15 @@ namespace src.player.skills
public static void NewRound()
{
bannedPlayers.Clear();
playersToTarget.Clear();
foreach (var player in Utilities.GetPlayers())
SkillUtils.CloseMenu(player);
}
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 (!bannedPlayers.TryGetValue(player.Index, out _)) return;
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())
{
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;
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()))];
SkillUtils.UpdateMenu(player, menuItems);
@ -65,8 +67,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands)
{
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed)
@ -76,7 +78,8 @@ namespace src.player.skills
}
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)
{
@ -85,18 +88,20 @@ namespace src.player.skills
}
bannedPlayers.AddOrUpdate(enemy.Index, 0, (k, v) => 0);
playersToTarget[player.Index] = enemy.Index;
playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("jumpban_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("jumpban_enemy_info"));
}
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;
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)
{
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)
{
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 _);
SkillUtils.CloseMenu(player);
}

View file

@ -1,8 +1,6 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using static src.jRandomSkills;
namespace src.player.skills
{
@ -19,9 +17,14 @@ namespace src.player.skills
{
var player = @event.Userid;
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;
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)

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Commands.Targeting;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
@ -18,12 +18,12 @@ namespace src.player.skills
public static void PlayerBlind(EventPlayerBlind @event)
{
var player = @event.Userid;
var attacker = @event.Attacker;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
if (!Instance.IsPlayerValid(player) || !Instance.IsPlayerValid(attacker)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
var attackerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
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.Modules.Utils;
using static src.jRandomSkills;
@ -28,20 +28,20 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers())
{
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;
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);
}
}
public static void TypeSkill(CCSPlayerController player, string[] commands)
{
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed)
@ -51,7 +51,8 @@ namespace src.player.skills
}
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)
{
@ -67,11 +68,11 @@ namespace src.player.skills
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;
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)
{
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.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils;
@ -14,7 +14,7 @@ namespace src.player.skills
private static bool hooked = false;
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"));
public static void LoadSkill()
@ -34,12 +34,12 @@ namespace src.player.skills
if (hooked) return;
hooked = true;
Shoot_Secondary.Hook(ShootSecondary, HookMode.Pre);
playersInAction.TryAdd(player.SteamID, 0);
playersInAction.TryAdd(player.Index, 0);
}
public static void DisableSkill(CCSPlayerController player)
{
playersInAction.TryRemove(player.SteamID, out _);
playersInAction.TryRemove(player.Index, out _);
if (playersInAction.IsEmpty)
{
Shoot_Secondary.Unhook(ShootSecondary, HookMode.Pre);
@ -61,19 +61,22 @@ namespace src.player.skills
var player = pawn.Controller.Value.As<CCSPlayerController>();
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;
KnifeHit(player, true);
KnifeHit(eventPlayer, true);
return HookResult.Continue;
}
public static void WeaponFire(EventWeaponFire @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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;
var pawn = player!.PlayerPawn.Value;
@ -97,10 +100,10 @@ namespace src.player.skills
if (!result.Value.HitPlayer(out CCSPlayerController? target) || target == null)
return;
if (target.Handle == player.Handle || result.Value.Distance() <= 70)
return;
if (target.PlayerPawn.Value == null || !target.PlayerPawn.Value.IsValid)
return;

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -17,10 +17,10 @@ namespace src.player.skills
public unsafe static void WeaponFire(EventWeaponFire @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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;
var pawn = player!.PlayerPawn.Value;

View file

@ -1,10 +1,9 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills
{
@ -25,10 +24,10 @@ namespace src.player.skills
public static void DecoyStarted(EventDecoyStarted @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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;
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)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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;
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()
{
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 pawn = player.PlayerPawn.Value;
var pawn = eventPlayer.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue;
double distance = SkillUtils.GetDistance(decoyPos, pawn.AbsOrigin);

View file

@ -40,7 +40,7 @@ namespace src.player.skills
foreach (var playerIndex in players.Keys)
{
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 _);
continue;

View file

@ -1,9 +1,8 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
using System.Collections.Concurrent;
namespace src.player.skills
{
@ -11,6 +10,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Magnifier;
private static readonly ConcurrentDictionary<uint, uint> playersFOV = [];
private static readonly ConcurrentDictionary<uint, uint> playersToTarget = [];
public static void LoadSkill()
{
@ -27,27 +27,22 @@ namespace src.player.skills
}
playersFOV.Clear();
playersToTarget.Clear();
foreach (var player in Utilities.GetPlayers())
SkillUtils.CloseMenu(player);
}
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
if (player == null) return;
DisableSkill(player);
}
public static void OnTick()
{
if (Server.TickCount % 32 != 0) return;
foreach (var player in Utilities.GetPlayers())
{
if (!SkillUtils.HasMenu(player)) continue;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
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())));
SkillUtils.UpdateMenu(player, menuItems);
@ -56,18 +51,19 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands)
{
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed)
{
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("areareaper_used_info")}");
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("areareaper_used_info")}" );
return;
}
string enemyId = commands[0];
var enemy = Utilities.GetPlayers().FirstOrDefault(p => p.Team != player.Team && p.Index.ToString() == enemyId);
if (!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)
{
@ -75,23 +71,24 @@ namespace src.player.skills
return;
}
if (!playersFOV.ContainsKey(enemy.Index))
playersFOV.TryAdd(enemy.Index, enemy.DesiredFOV);
playersFOV.AddOrUpdate(enemy.Index, enemy.DesiredFOV, (k, v) => enemy.DesiredFOV);
playersToTarget[player.Index] = enemy.Index;
enemy.DesiredFOV = SkillsInfo.GetValue<uint>(skillName, "customFOV");
Utilities.SetStateChanged(enemy, "CBasePlayerController", "m_iDesiredFOV");
playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("magnifier_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("magnifier_enemy_info"));
}
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;
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)
{
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)
{
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;
Utilities.SetStateChanged(player, "CBasePlayerController", "m_iDesiredFOV");
var target = Utilities.GetPlayerFromIndex((int)targetIndex);
if (target != null && target.IsValid)
if (playersFOV.TryGetValue(targetIndex, out uint fov))
{
target.DesiredFOV = fov;
Utilities.SetStateChanged(target, "CBasePlayerController", "m_iDesiredFOV");
}
playersFOV.TryRemove(targetIndex, out _);
}
playersFOV.TryRemove(player.Index, 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)

View file

@ -10,7 +10,7 @@ namespace src.player.skills
public class Medic : ISkill
{
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();
public static void LoadSkill()
@ -29,18 +29,18 @@ namespace src.player.skills
if (SkillUtils.IsFreezeTime()) return;
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 (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
UpdateHUD(player, skillInfo);
}
}
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,
Cooldown = DateTime.MinValue,
Count = SkillsInfo.GetValue<int>(skillName, "healthShotLimit"),
@ -49,7 +49,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
SkillPlayerInfo.TryRemove(player.SteamID, out _);
SkillPlayerInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player);
}
@ -68,7 +68,7 @@ namespace src.player.skills
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName);
if (skillData == null) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return;
string remainingLine = cooldown != 0
@ -83,9 +83,9 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value;
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)
{
skillInfo.CanUse = false;

View file

@ -1,10 +1,9 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills
{
@ -87,7 +86,7 @@ namespace src.player.skills
if (pawn.Controller.Value == null || !pawn.Controller.Value.IsValid) return;
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;
nades.TryAdd(grenade.Index, 0);

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
@ -28,10 +28,10 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers())
{
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;
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()))];
SkillUtils.UpdateMenu(player, menuItems);
@ -40,8 +40,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands)
{
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed)
@ -51,7 +51,8 @@ namespace src.player.skills
}
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)
{
@ -67,11 +68,11 @@ namespace src.player.skills
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;
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)
{
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)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (!IsDeadPlayerValid(player)) return;
CsTeam lastTeam = player!.Team;
@ -40,7 +40,7 @@ namespace src.player.skills
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.Health == pawn.MaxHealth) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill == skillName)
SpawnExplosion(player!);
});
@ -56,9 +56,9 @@ namespace src.player.skills
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")}",
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 randomFile = fileNames[new Random().Next(fileNames.Length)];

View file

@ -1,4 +1,4 @@
/*using CounterStrikeSharp.API;
/*using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using static jRandomSkills.jRandomSkills;
@ -26,7 +26,7 @@ namespace src.player.skills
var pawn = grenade.OwnerEntity.Value.As<CCSPlayerPawn>();
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;
Server.NextFrame(() => {
@ -55,8 +55,8 @@ namespace src.player.skills
Instance.AddTimer(5f, () =>
{
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<uint, byte> invisiblePlayers = [];
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();
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
Instance.AddToManifest(bloodParticle);
Instance.AddToManifest(cameraViewModel);
}
public static void NewRound()
@ -35,8 +37,9 @@ namespace src.player.skills
public static void WeaponEquip(EventItemEquip @event)
{
var player = @event.Userid;
if (!Instance.IsPlayerValid(player)) return;
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?.Skill != skillName) return;
UpdateNinja(player);
@ -45,8 +48,9 @@ namespace src.player.skills
public static void WeaponPickup(EventItemPickup @event)
{
var player = @event.Userid;
if (!Instance.IsPlayerValid(player)) return;
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?.Skill != skillName) return;
UpdateNinja(player);
@ -56,7 +60,7 @@ namespace src.player.skills
{
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;
bool isObservingNinja = false;
@ -64,14 +68,17 @@ namespace src.player.skills
if (targetHandle != nint.Zero)
{
var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle);
var targetInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == target?.SteamID);
var targetInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(target)?.Index);
if (targetInfo?.Skill == skillName) isObservingNinja = true;
}
foreach (var playerIndex in invisiblePlayers.Keys)
{
var playerController = Utilities.GetPlayerFromIndex((int)playerIndex);
if (playerController == null || !playerController.IsValid || playerController.SteamID == player.SteamID)
var playerController = PlayerManager.GetPlayerEvent(Utilities.GetPlayerFromIndex((int)playerIndex));
if (playerController == null || !playerController.IsValid || playerController.Index == player.Index)
continue;
if (player.Team == playerController.Team)
continue;
if (!isObservingNinja)
@ -95,31 +102,81 @@ namespace src.player.skills
public static void OnTick()
{
if (Server.TickCount % 2 != 0) return;
foreach (var player in Utilities.GetPlayers())
{
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo?.Skill == skillName)
UpdateNinja(player);
if (!player.PawnIsAlive)
if (player.LifeState != (byte)LifeState_t.LIFE_ALIVE)
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();
if (EntityManager.GetPlayerEntities(player.Index, "empty_prop").Count == 0)
CreatePlayerPosProp(player);
}
public static void DisableSkill(CCSPlayerController player)
{
SetPlayerVisibility(player, 0);
SkillUtils.SetPlayerInvisibility(player, 0);
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)
{
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;
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))
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)
return;
invisibilityChanged.AddOrUpdate(player.Handle, percentInvisibility, (_, _) => percentInvisibility);
invisibilityChanged.AddOrUpdate(playerEvent.Handle, percentInvisibility, (_, _) => percentInvisibility);
if (percentInvisibility > .9)
invisiblePlayers.TryAdd(player.Index, 0);
invisiblePlayers.TryAdd(playerEvent.Index, 0);
else
{
SetPlayerVisibility(player, percentInvisibility);
invisiblePlayers.TryRemove(player.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");
SkillUtils.SetPlayerInvisibility(playerEvent, percentInvisibility);
invisiblePlayers.TryRemove(playerEvent.Index, out _);
}
}
public static void PlayerHurt(EventPlayerHurt @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
if (!invisiblePlayers.ContainsKey(player.Index)) return;
var playerPawn = player.PlayerPawn.Value;
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;
particle.EffectName = bloodParticle;
particle.StartActive = true;
Vector pos = new(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z + 50);
particle.Teleport(pos);
particle.DispatchSpawn();
particle.AcceptInput("Start");
}

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -18,11 +18,11 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event)
{
var damage = @event.DmgHealth;
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Weapon;
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 (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.Modules.Utils;
using src.utils;
@ -25,13 +25,13 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
player.ReplicateConVar("weapon_accuracy_nospread", "1");
Server.ExecuteCommand("weapon_accuracy_nospread 1");
}
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
player.ReplicateConVar("weapon_accuracy_nospread", "0");
Server.ExecuteCommand("weapon_accuracy_nospread 0");
}
public static void OnTick()
@ -39,7 +39,7 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers())
{
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)
{

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Memory;
@ -13,7 +13,7 @@ namespace src.player.skills
public class Noclip : ISkill
{
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();
public static void LoadSkill()
@ -31,18 +31,18 @@ namespace src.player.skills
{
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 (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
UpdateHUD(player, skillInfo);
}
}
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,
IsFlying = false,
Cooldown = DateTime.MinValue,
@ -52,7 +52,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
SkillPlayerInfo.TryRemove(player.SteamID, out _);
SkillPlayerInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player);
}
@ -72,7 +72,7 @@ namespace src.player.skills
skillInfo.CanUse = true;
}
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return;
if (cooldown == 0)
@ -92,9 +92,9 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value;
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)
{
@ -116,14 +116,14 @@ namespace src.player.skills
skillInfo.Timer = Instance.AddTimer(duration, () =>
{
var player = Utilities.GetPlayerFromSteamId(steamId);
var player = Utilities.GetPlayerFromIndex((int)playerIndex);
if (player == null || !player.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == steamId);
var playerInfo = PlayerManager.GetPlayerByIndex(playerIndex);
if (playerInfo == null) return;
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;
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;
Schema.SetSchemaValue(playerPawn.Handle, "CBaseEntity", "m_nActualMoveType", (int)playerPawn.MoveType);
@ -148,7 +148,7 @@ namespace src.player.skills
if (!skillInfo.IsFlying) return;
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);
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.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)
return;
CCSPlayerController attacker = attackerPawn.Controller.Value.As<CCSPlayerController>();
CCSPlayerController victim = victimPawn.Controller.Value.As<CCSPlayerController>();
CCSPlayerController attacker = PlayerManager.GetPlayerEvent(attackerPawn.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.Skill == skillName && attacker.PawnIsAlive)
if (playerInfo.Skill == skillName)
param2.Damage = 1000f;
}

View file

@ -1,4 +1,4 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -17,13 +17,13 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event)
{
var attacker = @event.Attacker;
var victim = @event.Userid;
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
int damage = @event.DmgHealth;
var hitgroup = (HitGroup_t)@event.Hitgroup;
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;
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())
{
if (!Instance.IsPlayerValid(player)) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (player == null || !player.IsValid) return;
var playerEvent = PlayerManager.GetPlayerEvent(player);
var playerInfo = PlayerManager.GetPlayerByIndex(playerEvent!.Index);
if (playerInfo?.Skill == skillName)
GiveAdditionalJump(player);
GiveAdditionalJump(player, playerEvent);
}
}
public static void EnableSkill(CCSPlayerController player)
{
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;
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);
playerInfo.SkillChance = 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;
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;
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)
|| (playerPawn.MovementServices?.QueuedButtonChangeMask & (ulong)PlayerButtons.Jump) != 0;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerPawn == null || playerInfo == null) return;
var playerInfo = PlayerManager.GetPlayerByIndex(playerEvent!.Index);
if (playerInfo == null) return;
bool isOnGround = (flags & PlayerFlags.FL_ONGROUND) != 0;
@ -67,7 +72,7 @@ namespace src.player.skills
else if (jumpPressed && J[player.Slot] < playerInfo.SkillChance + 1)
{
J[player.Slot]++;
playerPawn.AbsVelocity.Z = 300;
playerEventPawn.AbsVelocity.Z = 300;
}
LB[player.Slot] = buttons;

View file

@ -1,122 +1,60 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Timers;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
namespace src.player.skills
{
public class Phoenix : ISkill
{
private const Skills skillName = Skills.Phoenix;
private static readonly object setLock = new();
private static readonly ConcurrentDictionary<ulong, Timer> timers = [];
public static void LoadSkill()
{
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;
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return;
var user = @event.Userid;
if (user == null || !user.IsValid) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (playerInfo?.Skill == skillName)
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
if (victim == null || !victim.IsValid) return;
var pawn = victim.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(victim.Index);
if (playerInfo?.Skill != skillName || pawn.Health > 0) return;
if (Instance.Random.NextDouble() > playerInfo.SkillChance) return;
if (victim.TeamChanged) return;
SkillUtils.AddHealth(pawn, 100 - pawn.Health);
SkillUtils.PrintToChat(user, user.GetTranslation("phoenix_respawn"));
Server.NextFrame(() =>
{
if (Instance.Random.NextDouble() <= playerInfo.SkillChance)
{
lock (setLock)
{
ulong steamID = player.SteamID;
int team = player.TeamNum;
if (victim == null || !victim.IsValid) return;
if (pawn == null || !pawn.IsValid) return;
if (team != 2 && team != 3) return;
var spawnpoint = SkillUtils.GetSpawnPointVector(victim);
if (spawnpoint == null) return;
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;
bool isBlock = team != player.TeamNum || player.TeamChanged;
player.Respawn();
if (isBlock)
{
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(() =>
{
if (pawn == null || !pawn.IsValid) return;
pawn.CommitSuicide(false, true);
});
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"));
}
}
}
pawn.Teleport(spawnpoint);
});
}
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;
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
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)

View file

@ -10,7 +10,7 @@ namespace src.player.skills
public class Pilot : ISkill
{
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()
{
@ -26,7 +26,7 @@ namespace src.player.skills
{
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)
HandlePilot(player);
}
@ -34,12 +34,12 @@ namespace src.player.skills
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)
{
PlayerPilotInfo.TryRemove(player.SteamID, out _);
PlayerPilotInfo.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player);
}
@ -48,7 +48,7 @@ namespace src.player.skills
var playerPawn = player.PlayerPawn.Value;
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 buttons = player.Buttons;
@ -107,7 +107,7 @@ namespace src.player.skills
private static void UpdateHUD(CCSPlayerController player, Pilot_PlayerInfo pilotInfo)
{
if (pilotInfo == null) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return;
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.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils;
@ -11,7 +11,7 @@ namespace src.player.skills
public class Planter : ISkill
{
private const Skills skillName = Skills.Planter;
private static readonly ConcurrentDictionary<ulong, float> plantingPlayers = [];
private static readonly ConcurrentDictionary<uint, float> plantingPlayers = [];
public static void LoadSkill()
{
@ -20,26 +20,26 @@ namespace src.player.skills
public static void BombBeginplant(EventBombBeginplant @event)
{
var user = @event.Userid;
var user = PlayerManager.GetPlayerEvent(@event.Userid);
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)
{
var user = @event.Userid;
var user = PlayerManager.GetPlayerEvent(@event.Userid);
if (user == null || !user.IsValid || !user.PawnIsAlive) return;
plantingPlayers.TryRemove(user.SteamID, out _);
plantingPlayers.TryRemove(user.Index, out _);
SkillUtils.ResetPrintHTML(user);
}
public static void BombPlanted(EventBombPlanted @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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;
playerInfo.PrintHTML = null;
@ -64,7 +64,7 @@ namespace src.player.skills
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
plantingPlayers.TryRemove(player.SteamID, out _);
plantingPlayers.TryRemove(player.Index, out _);
SkillUtils.ResetPrintHTML(player);
var pawn = player.PlayerPawn.Value;
@ -80,7 +80,7 @@ namespace src.player.skills
{
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;
var pawn = player.PlayerPawn.Value;
@ -93,7 +93,7 @@ namespace src.player.skills
pawn.InBombZone = 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;
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.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
@ -11,6 +10,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Poison;
private static readonly ConcurrentDictionary<uint, byte> poisonedPlayers = [];
private static readonly ConcurrentDictionary<uint, uint> playersToTarget = [];
private static readonly object setLock = new();
public static void LoadSkill()
@ -21,7 +21,10 @@ namespace src.player.skills
public static void NewRound()
{
lock (setLock)
{
poisonedPlayers.Clear();
playersToTarget.Clear();
}
}
public static void OnTick()
@ -45,10 +48,10 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers())
{
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;
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())));
SkillUtils.UpdateMenu(player, menuItems);
@ -57,8 +60,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands)
{
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed)
@ -68,7 +71,8 @@ namespace src.player.skills
}
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)
{
@ -77,18 +81,20 @@ namespace src.player.skills
}
poisonedPlayers.TryAdd(enemy.Index, 0);
playersToTarget[player.Index] = enemy.Index;
playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("poison_player_info", enemy.PlayerName));
enemy.PrintToChat($" {ChatColors.Red}" + enemy.GetTranslation("poison_enemy_info"));
}
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;
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)
{
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)
{
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 _);
SkillUtils.CloseMenu(player);
}

View file

@ -1,7 +1,6 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
@ -10,7 +9,8 @@ namespace src.player.skills
public class PrimaryBan : ISkill
{
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 string[] disabledWeapons =
[
@ -28,6 +28,8 @@ namespace src.player.skills
lock (setLock)
{
bannedPlayers.Clear();
playersToTarget.Clear();
foreach (var player in Utilities.GetPlayers())
SkillUtils.CloseMenu(player);
}
@ -35,10 +37,10 @@ namespace src.player.skills
public static void WeaponEquip(EventItemEquip @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item;
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");
}
@ -48,10 +50,10 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers())
{
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;
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())));
SkillUtils.UpdateMenu(player, menuItems);
@ -60,8 +62,8 @@ namespace src.player.skills
public static void TypeSkill(CCSPlayerController player, string[] commands)
{
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playerInfo.SkillUsed)
@ -71,7 +73,8 @@ namespace src.player.skills
}
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)
{
@ -79,9 +82,11 @@ namespace src.player.skills
return;
}
bannedPlayers.TryAdd(enemy.SteamID, 0);
bannedPlayers.TryAdd(enemy.Index, 0);
playersToTarget[player.Index] = enemy.Index;
CheckWeapon(enemy);
playerInfo.SkillUsed = true;
player.PrintToChat($" {ChatColors.Green}" + player.GetTranslation("primaryban_player_info", enemy.PlayerName));
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.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");
}
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;
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)
{
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)
{
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);
}

View file

@ -1,4 +1,3 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -17,13 +16,12 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event)
{
var attacker = @event.Attacker;
var victim = @event.Userid;
int damage = @event.DmgHealth;
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
var hitgroup = (HitGroup_t)@event.Hitgroup;
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;
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.Modules.Utils;
using static src.jRandomSkills;
@ -31,10 +31,10 @@ namespace src.player.skills
public static void PlayerDeath(EventPlayerDeath @event)
{
var player = @event.Userid;
var player = PlayerManager.GetPlayerEvent(@event.Userid);
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)
SkillPlayerInfo.TryRemove(player.Index, out _);
}
@ -78,7 +78,7 @@ namespace src.player.skills
var plantedBomb = Utilities.FindAllEntitiesByDesignerName<CPlantedC4>("planted_c4").FirstOrDefault();
if (plantedBomb != null)
{
plantedBomb.AcceptInput("Kill");
plantedBomb.AddEntityIOEvent("Kill", plantedBomb, delay: 0.1f);
SkillUtils.TerminateRound(CsTeam.CounterTerrorist);
}
SkillUtils.ResetPrintHTML(player);
@ -96,7 +96,7 @@ namespace src.player.skills
SkillPlayerInfo.TryAdd(player.Index, new PlayerSkillInfo
{
SteamID = player.SteamID,
SteamID = player.Index,
Defusing = false,
DefusingTime = SkillsInfo.GetValue<float>(skillName, "defusingTime"),
});
@ -113,7 +113,7 @@ namespace src.player.skills
if (!skillInfo.Defusing) return;
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 (cooldown == 0)

View file

@ -17,13 +17,13 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event)
{
var attacker = @event.Attacker;
var victim = @event.Userid;
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
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)
{
@ -34,12 +34,12 @@ namespace src.player.skills
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;
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
}
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.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
@ -18,13 +18,14 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event)
{
var victim = @event.Userid;
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
int damage = @event.DmgHealth;
string weapon = @event.Weapon;
if (weapon != "inferno" || !Instance.IsPlayerValid(victim)) return;
var victimInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == victim?.SteamID);
if (victimInfo == null || victimInfo.Skill != skillName) return ;
var victimInfo = PlayerManager.GetPlayerByIndex(victim!.Index);
if (victimInfo == null || victimInfo.Skill != skillName) return;
var pawn = victim!.PlayerPawn.Value;
SkillUtils.AddHealth(pawn, (int)(damage * SkillsInfo.GetValue<float>(skillName, "regenerationMultiplier")));

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