Updates & Fixes
# Updates & Fixes - Vote system: Timer now resets after each vote - Automatic copying of gamedata files from source to server (Thanks to vinicius-trev for the help) - Improved power assignment at round start - Observers can now see invisible players. - Added geolocation support for Turkey and Czechia - New power: Illiterate - In development: Smoker skill - Baseball: Decoy now have the same collision as players (PlayerClip) - Noclip: Reworked - Pilot: Currently broken - Replicator: Added crouching animations for replicas - SoundMaker: Reworked (automatically play a sound every 2s (only for you)) - Wallhack: Glow disabled for dead players # TODO - Add/update descriptions for new/reworked skills - Fix Pilot, SniperElite
This commit is contained in:
parent
f76093ef6e
commit
09803748bc
28 changed files with 691 additions and 295 deletions
|
|
@ -100,6 +100,7 @@ public enum Skills
|
|||
Hermit,
|
||||
HolyHandGrenade,
|
||||
Iana,
|
||||
Illiterate,
|
||||
Impostor,
|
||||
InfiniteAmmo,
|
||||
Jackal,
|
||||
|
|
@ -150,6 +151,7 @@ public enum Skills
|
|||
Shade,
|
||||
ShortBomb,
|
||||
Silent,
|
||||
Smoker,
|
||||
SniperElite,
|
||||
Soldier,
|
||||
SoundMaker,
|
||||
|
|
|
|||
|
|
@ -8,15 +8,18 @@ using CounterStrikeSharp.API.Modules.Memory;
|
|||
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
|
||||
using CounterStrikeSharp.API.Modules.UserMessages;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.player.skills;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using static CounterStrikeSharp.API.Core.Listeners;
|
||||
using static src.jRandomSkills;
|
||||
using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
|
||||
|
||||
namespace src.player
|
||||
{
|
||||
public static partial class Event
|
||||
{
|
||||
private static Timer? setSkillTimer = null;
|
||||
private static DateTime freezeTimeEnd = DateTime.MinValue;
|
||||
private static bool isTransmitRegistered = false;
|
||||
public static readonly jSkill_SkillInfo noneSkill = new(Skills.None, SkillsInfo.GetValue<string>(Skills.None, "color"), false);
|
||||
|
|
@ -39,6 +42,7 @@ namespace src.player
|
|||
Instance.RegisterEventHandler<EventPlayerConnectFull>(PlayerConnectFull);
|
||||
Instance.RegisterEventHandler<EventPlayerDisconnect>(PlayerDisconnect);
|
||||
// Instance.RegisterEventHandler<EventPlayerChat>(PlayerChat);
|
||||
Instance.RegisterEventHandler<EventPlayerSpawned>(PlayerSpawned);
|
||||
Instance.RegisterEventHandler<EventRoundStart>(RoundStart);
|
||||
Instance.RegisterEventHandler<EventRoundEnd>(RoundEnd);
|
||||
|
||||
|
|
@ -384,6 +388,32 @@ namespace src.player
|
|||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
private static HookResult PlayerSpawned(EventPlayerSpawned @event, GameEventInfo info)
|
||||
{
|
||||
lock (setLock)
|
||||
{
|
||||
var player = @event.Userid;
|
||||
if (player == null || !player.IsValid) return HookResult.Continue;
|
||||
|
||||
var skillPlayer = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (skillPlayer == null) return HookResult.Continue;
|
||||
|
||||
if (setSkillTimer != null)
|
||||
{
|
||||
skillPlayer.IsDrawing = true;
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
skillPlayer.IsDrawing = false;
|
||||
if (Instance?.GameRules != null &&
|
||||
Instance?.GameRules.WarmupPeriod == false &&
|
||||
skillPlayer.Skill == Skills.None &&
|
||||
skillPlayer.SpecialSkill == Skills.None)
|
||||
SetRandomSkill(player);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
||||
private static HookResult RoundStart(EventRoundStart @event, GameEventInfo info)
|
||||
{
|
||||
lock (setLock)
|
||||
|
|
@ -401,7 +431,11 @@ namespace src.player
|
|||
Instance.RemoveListener<CheckTransmit>(CheckTransmit);
|
||||
int freezetime = ConVar.Find("mp_freezetime")?.GetPrimitiveValue<Int32>() ?? 0;
|
||||
freezeTimeEnd = DateTime.Now.AddSeconds(freezetime + (Instance?.GameRules?.TeamIntroPeriod == true ? 7 : 0));
|
||||
Instance?.AddTimer((Instance?.GameRules?.TeamIntroPeriod == true ? 7 : 0) + Math.Max(freezetime - Config.LoadedConfig.SkillTimeBeforeStart, 0) + .3f, SetSkill);
|
||||
|
||||
setSkillTimer?.Kill();
|
||||
|
||||
float timeToDraw = (Instance?.GameRules?.TeamIntroPeriod == true ? 7 : 0) + Math.Max(freezetime - Config.LoadedConfig.SkillTimeBeforeStart, 0) + .3f;
|
||||
setSkillTimer = Instance?.AddTimer(timeToDraw, SetSkill);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -447,6 +481,7 @@ namespace src.player
|
|||
|
||||
private static HookResult RoundEnd(EventRoundEnd @event, GameEventInfo info)
|
||||
{
|
||||
Illiterate.Disable();
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid))
|
||||
|
|
@ -567,6 +602,7 @@ namespace src.player
|
|||
|
||||
private static void SetSkill()
|
||||
{
|
||||
setSkillTimer = null;
|
||||
lock (setLock)
|
||||
{
|
||||
var validPlayers = Utilities.GetPlayers().Where(p => p.IsValid && !p.IsBot && !p.IsHLTV && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist).ToList();
|
||||
|
|
@ -670,14 +706,20 @@ namespace src.player
|
|||
skillPlayer.Skill = randomSkill.Skill;
|
||||
skillPlayer.SpecialSkill = Skills.None;
|
||||
|
||||
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 (randomSkill.Skill == Skills.Illiterate)
|
||||
Illiterate.Enable();
|
||||
|
||||
Instance?.AddTimer(.2f, () =>
|
||||
{
|
||||
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;
|
||||
Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]);
|
||||
});
|
||||
else
|
||||
Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]);
|
||||
});
|
||||
else
|
||||
Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]);
|
||||
});
|
||||
|
||||
Debug.WriteToDebug($"Player {skillPlayer.PlayerName} has got the skill \"{player.GetSkillName(randomSkill.Skill)}\".");
|
||||
skillPlayer.SkillHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillHudDuration);
|
||||
|
|
@ -685,7 +727,7 @@ namespace src.player
|
|||
|
||||
if (Config.LoadedConfig.TeamMateSkillChatInfo)
|
||||
{
|
||||
Instance?.AddTimer(.5f, () =>
|
||||
Instance?.AddTimer(.6f, () =>
|
||||
{
|
||||
foreach (var teammate in teammates)
|
||||
{
|
||||
|
|
@ -732,6 +774,7 @@ namespace src.player
|
|||
var skillPlayer = Instance?.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (skillPlayer == null) return;
|
||||
|
||||
skillPlayer.IsDrawing = false;
|
||||
if (player.PlayerPawn.Value == null || !player.PlayerPawn.IsValid)
|
||||
{
|
||||
skillPlayer.Skill = Skills.None;
|
||||
|
|
@ -792,13 +835,20 @@ namespace src.player
|
|||
skillPlayer.Skill = randomSkill.Skill;
|
||||
skillPlayer.SpecialSkill = Skills.None;
|
||||
|
||||
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 (randomSkill.Skill == Skills.Illiterate)
|
||||
Illiterate.Enable();
|
||||
|
||||
Instance?.AddTimer(.2f, () =>
|
||||
{
|
||||
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;
|
||||
Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]);
|
||||
});
|
||||
else
|
||||
Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]);
|
||||
});
|
||||
else
|
||||
Instance?.SkillAction(randomSkill.Skill.ToString(), "EnableSkill", [player]);
|
||||
});
|
||||
|
||||
Debug.WriteToDebug($"Player {skillPlayer.PlayerName} has got the skill \"{player.GetSkillName(randomSkill.Skill)}\".");
|
||||
skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration);
|
||||
|
|
@ -820,6 +870,14 @@ namespace src.player
|
|||
lock (setLock)
|
||||
{
|
||||
if (player == null || !player.IsValid) return;
|
||||
|
||||
if (Illiterate.CheckIlliterateSkill(player))
|
||||
{
|
||||
headerLine = Illiterate.GetRandomText(headerLine);
|
||||
centerLine = Illiterate.GetRandomText(centerLine);
|
||||
extraLine = Illiterate.GetRandomText(extraLine);
|
||||
}
|
||||
|
||||
var config = Config.LoadedConfig.HtmlHudCustomisation;
|
||||
var emptySymbol = $"<font class='fontSize-{(string.IsNullOrEmpty(headerLine) ? "l" : "ml")}'> </font>";
|
||||
var emptySymbol2 = $"<font class='fontSize-ml'> </font>";
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace src.player
|
|||
infoLine = player.GetTranslation("your_skill");
|
||||
skillLine = player.GetTranslation("none");
|
||||
}
|
||||
else if (skillPlayer.IsDrawing)
|
||||
else if (skillPlayer.IsDrawing && player.PawnIsAlive)
|
||||
{
|
||||
var randomSkill = SkillData.Skills.ToArray()[Instance.Random.Next(SkillData.Skills.Count)];
|
||||
infoLine = player.GetTranslation("drawing_skill");
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ namespace src.player.skills
|
|||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo?.Skill != skillName) return;
|
||||
decoys.TryAdd(decoy, 0);
|
||||
|
||||
decoy.Collision.CollisionAttribute.InteractsWith = pawn.Collision.CollisionAttribute.InteractsWith;
|
||||
decoy.Collision.CollisionGroup = pawn.Collision.CollisionGroup;
|
||||
}
|
||||
|
||||
public static void DecoyStarted(EventDecoyStarted @event)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
|
|
@ -62,8 +61,19 @@ namespace src.player.skills
|
|||
foreach (var (info, player) in infoList)
|
||||
{
|
||||
if (player == null || !player.IsValid) continue;
|
||||
|
||||
var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero;
|
||||
bool isObservingC4Camouflage = false;
|
||||
|
||||
if (targetHandle != nint.Zero)
|
||||
{
|
||||
var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle);
|
||||
var targetInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == target?.SteamID);
|
||||
if (targetInfo?.Skill == skillName) isObservingC4Camouflage = true;
|
||||
}
|
||||
|
||||
foreach (var _player in invisiblePlayers.Keys)
|
||||
if (player.SteamID != _player.SteamID)
|
||||
if (player.SteamID != _player.SteamID && !isObservingC4Camouflage)
|
||||
{
|
||||
var playerPawn = _player.PlayerPawn.Value;
|
||||
if (playerPawn == null || !playerPawn.IsValid) continue;
|
||||
|
|
|
|||
|
|
@ -151,12 +151,13 @@ namespace src.player.skills
|
|||
pawn!.CameraServices!.ViewEntity.Raw = player.CameraView.EntityHandle.Raw;
|
||||
SkillUtils.ApplyScreenColor(player.Player, 0, 0, 255, 20, 100, 1020);
|
||||
|
||||
Timer? cameraTimer = null;
|
||||
ulong playerSteamID = player.Player.SteamID;
|
||||
ulong? playerSteamID = player.Player?.SteamID;
|
||||
if (playerSteamID == null) return;
|
||||
|
||||
Timer? cameraTimer = null;
|
||||
cameraTimer = jRandomSkills.Instance.AddTimer(2f, () =>
|
||||
{
|
||||
var target = Utilities.GetPlayerFromSteamId(playerSteamID);
|
||||
var target = Utilities.GetPlayers().FirstOrDefault(p => p.IsValid && p.SteamID == playerSteamID);
|
||||
if (target == null || !target.IsValid || !target.PawnIsAlive)
|
||||
{
|
||||
cameraTimer?.Kill();
|
||||
|
|
|
|||
|
|
@ -112,24 +112,26 @@ namespace src.player.skills
|
|||
private static void SetUpPostProcessing(CCSPlayerController player, bool turnOff = false)
|
||||
{
|
||||
if (player == null || !player.IsValid) return;
|
||||
ulong playerSteamID = player.SteamID;
|
||||
|
||||
ulong? playerSteamID = player?.SteamID;
|
||||
if (playerSteamID == null) return;
|
||||
|
||||
lock (setLock)
|
||||
{
|
||||
if (!turnOff)
|
||||
{
|
||||
playersInDark.TryAdd(playerSteamID, 0);
|
||||
playersInDark.TryAdd((ulong)playerSteamID, 0);
|
||||
ApplyColor(player);
|
||||
|
||||
Timer? darkTimer = null;
|
||||
darkTimer = Instance.AddTimer(5f, () => {
|
||||
if (!playersInDark.ContainsKey(playerSteamID))
|
||||
if (!playersInDark.ContainsKey((ulong)playerSteamID))
|
||||
{
|
||||
darkTimer?.Kill();
|
||||
return;
|
||||
}
|
||||
|
||||
var target = Utilities.GetPlayerFromSteamId(playerSteamID);
|
||||
var target = Utilities.GetPlayers().FirstOrDefault(p => p.IsValid && p.SteamID == playerSteamID);
|
||||
if (target == null || !target.IsValid)
|
||||
{
|
||||
darkTimer?.Kill();
|
||||
|
|
@ -137,18 +139,18 @@ namespace src.player.skills
|
|||
}
|
||||
|
||||
if (target.PawnIsAlive)
|
||||
ApplyColor(player);
|
||||
ApplyColor(target);
|
||||
}, TimerFlags.STOP_ON_MAPCHANGE | TimerFlags.REPEAT);
|
||||
}
|
||||
else
|
||||
{
|
||||
SkillUtils.ApplyScreenColor(player, r: 0, g: 0, b: 0, a: 0, duration: 200, holdTime: 0);
|
||||
playersInDark.TryRemove(player.SteamID, out _);
|
||||
playersInDark.TryRemove((ulong)playerSteamID, out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ApplyColor(CCSPlayerController player)
|
||||
private static void ApplyColor(CCSPlayerController? player)
|
||||
{
|
||||
SkillUtils.ApplyScreenColor(player,
|
||||
r: SkillsInfo.GetValue<int>(skillName, "R"),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
|
|
@ -65,9 +64,20 @@ namespace src.player.skills
|
|||
{
|
||||
foreach (var (info, player) in infoList)
|
||||
{
|
||||
if (player == null) continue;
|
||||
if (player == null || !player.IsValid) continue;
|
||||
|
||||
var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero;
|
||||
bool isObservingGhost = false;
|
||||
|
||||
if (targetHandle != nint.Zero)
|
||||
{
|
||||
var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle);
|
||||
var targetInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == target?.SteamID);
|
||||
if (targetInfo?.Skill == skillName) isObservingGhost = true;
|
||||
}
|
||||
|
||||
foreach (var _player in invisiblePlayers.Keys)
|
||||
if (player.SteamID != _player.SteamID)
|
||||
if (player.SteamID != _player.SteamID && !isObservingGhost)
|
||||
{
|
||||
var playerPawn = _player.PlayerPawn.Value;
|
||||
if (playerPawn == null || !playerPawn.IsValid) continue;
|
||||
|
|
|
|||
|
|
@ -154,12 +154,13 @@ namespace src.player.skills
|
|||
KillClone(playerSkill);
|
||||
});
|
||||
|
||||
Timer? cloneTimer = null;
|
||||
ulong playerSteamID = player.SteamID;
|
||||
ulong? playerSteamID = player?.SteamID;
|
||||
if (playerSteamID == null) return;
|
||||
|
||||
Timer? cloneTimer = null;
|
||||
cloneTimer = jRandomSkills.Instance.AddTimer(2f, () =>
|
||||
{
|
||||
var target = Utilities.GetPlayerFromSteamId(playerSteamID);
|
||||
var target = Utilities.GetPlayers().FirstOrDefault(p => p.IsValid && p.SteamID == playerSteamID);
|
||||
if (target == null || !target.IsValid || !target.PawnIsAlive)
|
||||
{
|
||||
cloneTimer?.Kill();
|
||||
|
|
|
|||
77
jRandomSkills - SRC Files/src/player/skills/Illiterate.cs
Normal file
77
jRandomSkills - SRC Files/src/player/skills/Illiterate.cs
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.utils;
|
||||
|
||||
namespace src.player.skills
|
||||
{
|
||||
public class Illiterate : ISkill
|
||||
{
|
||||
private const Skills skillName = Skills.Illiterate;
|
||||
private static bool isActive = false;
|
||||
private static int offset = jRandomSkills.Instance.Random.Next(0, 26);
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
}
|
||||
|
||||
public static void NewRound()
|
||||
{
|
||||
isActive = false;
|
||||
}
|
||||
|
||||
public static void EnableSkill(CCSPlayerController player)
|
||||
{
|
||||
isActive = true;
|
||||
}
|
||||
|
||||
public static void Enable()
|
||||
{
|
||||
isActive = true;
|
||||
}
|
||||
|
||||
public static void Disable()
|
||||
{
|
||||
isActive = false;
|
||||
}
|
||||
|
||||
public static bool CheckIlliterateSkill(CCSPlayerController? player)
|
||||
{
|
||||
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);
|
||||
if (!playersWithSkill.Any()) return false;
|
||||
|
||||
return Utilities.GetPlayers().Any(
|
||||
p => p.IsValid &&
|
||||
p.PawnIsAlive &&
|
||||
p.Team != player.Team
|
||||
&& playersWithSkill.Contains(p.SteamID));
|
||||
}
|
||||
|
||||
public static string? GetRandomText(string? input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input)) return null;
|
||||
if (Server.TickCount % 64 == 0)
|
||||
offset = jRandomSkills.Instance.Random.Next(1, 26);
|
||||
|
||||
return new string([.. input.Select(c =>
|
||||
{
|
||||
if (char.IsDigit(c)) return '?';
|
||||
if (!char.IsLetter(c)) return c;
|
||||
|
||||
char baseChar = char.IsUpper(c) ? 'A' : 'a';
|
||||
return (char)(baseChar + (c - baseChar + offset) % 26);
|
||||
})]);
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1466F5", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float maximumFuel = 150f, float fuelConsumption = .64f, float refuelling = .1f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
{
|
||||
public float MaximumFuel { get; set; } = maximumFuel;
|
||||
public float FuelConsumption { get; set; } = fuelConsumption;
|
||||
public float Refuelling { get; set; } = refuelling;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -107,9 +107,9 @@ namespace src.player.skills
|
|||
|
||||
if (Config.LoadedConfig.CS2TraceRayDebug)
|
||||
{
|
||||
CreateLine(eyePos, endPos, Color.FromArgb(255, 255, 255, 0));
|
||||
CreateLine(new Vector(trace.StartPos.X, trace.StartPos.Y, trace.StartPos.Z), new Vector(trace.EndPos.X, trace.EndPos.Y, trace.EndPos.Z), Color.FromArgb(255, 255, 0, 0));
|
||||
CreateLine(new Vector(trace.StartPos.X, trace.StartPos.Y, trace.StartPos.Z), new Vector(trace.Position.X, trace.Position.Y, trace.Position.Z), Color.FromArgb(255, 0, 0, 255));
|
||||
SkillUtils.CreateLine(eyePos, endPos, Color.FromArgb(255, 255, 255, 0));
|
||||
SkillUtils.CreateLine(new Vector(trace.StartPos.X, trace.StartPos.Y, trace.StartPos.Z), new Vector(trace.EndPos.X, trace.EndPos.Y, trace.EndPos.Z), Color.FromArgb(255, 255, 0, 0));
|
||||
SkillUtils.CreateLine(new Vector(trace.StartPos.X, trace.StartPos.Y, trace.StartPos.Z), new Vector(trace.Position.X, trace.Position.Y, trace.Position.Z), Color.FromArgb(255, 0, 0, 255));
|
||||
|
||||
if (trace.DidHit())
|
||||
{
|
||||
|
|
@ -133,24 +133,6 @@ namespace src.player.skills
|
|||
SkillUtils.TakeHealth(target.PlayerPawn.Value, heavyHit ? Instance.Random.Next(45, 55) : Instance.Random.Next(21, 34));
|
||||
}
|
||||
|
||||
private static void CreateLine(Vector start, Vector end, Color color)
|
||||
{
|
||||
CBeam beam = Utilities.CreateEntityByName<CBeam>("beam")!;
|
||||
if (beam == null) return;
|
||||
|
||||
beam.Render = color;
|
||||
beam.Width = 2.0f;
|
||||
beam.EndWidth = 2.0f;
|
||||
beam.Teleport(start);
|
||||
|
||||
beam.EndPos.X = end.X;
|
||||
beam.EndPos.Y = end.Y;
|
||||
beam.EndPos.Z = end.Z;
|
||||
|
||||
beam.DispatchSpawn();
|
||||
beam.AcceptInput("FollowEntity", beam, null!, "");
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#c9f8ff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float maxDistance = 4096f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
{
|
||||
public float MaxDistance { get; set; } = maxDistance;
|
||||
|
|
|
|||
|
|
@ -45,9 +45,9 @@ namespace src.player.skills
|
|||
|
||||
if (Config.LoadedConfig.CS2TraceRayDebug)
|
||||
{
|
||||
CreateLine(eyePos, endPos, Color.FromArgb(255, 255, 255, 0));
|
||||
CreateLine(new Vector(trace.StartPos.X, trace.StartPos.Y, trace.StartPos.Z), new Vector(trace.EndPos.X, trace.EndPos.Y, trace.EndPos.Z), Color.FromArgb(255, 255, 0, 0));
|
||||
CreateLine(new Vector(trace.StartPos.X, trace.StartPos.Y, trace.StartPos.Z), new Vector(trace.Position.X, trace.Position.Y, trace.Position.Z), Color.FromArgb(255, 0, 0, 255));
|
||||
SkillUtils.CreateLine(eyePos, endPos, Color.FromArgb(255, 255, 255, 0));
|
||||
SkillUtils.CreateLine(new Vector(trace.StartPos.X, trace.StartPos.Y, trace.StartPos.Z), new Vector(trace.EndPos.X, trace.EndPos.Y, trace.EndPos.Z), Color.FromArgb(255, 255, 0, 0));
|
||||
SkillUtils.CreateLine(new Vector(trace.StartPos.X, trace.StartPos.Y, trace.StartPos.Z), new Vector(trace.Position.X, trace.Position.Y, trace.Position.Z), Color.FromArgb(255, 0, 0, 255));
|
||||
|
||||
if (trace.DidHit())
|
||||
{
|
||||
|
|
@ -70,24 +70,6 @@ namespace src.player.skills
|
|||
SkillUtils.TryGiveWeapon(player, CsItem.Zeus);
|
||||
}
|
||||
|
||||
private static void CreateLine(Vector start, Vector end, Color color)
|
||||
{
|
||||
CBeam beam = Utilities.CreateEntityByName<CBeam>("beam")!;
|
||||
if (beam == null) return;
|
||||
|
||||
beam.Render = color;
|
||||
beam.Width = 2.0f;
|
||||
beam.EndWidth = 2.0f;
|
||||
beam.Teleport(start);
|
||||
|
||||
beam.EndPos.X = end.X;
|
||||
beam.EndPos.Y = end.Y;
|
||||
beam.EndPos.Z = end.Z;
|
||||
|
||||
beam.DispatchSpawn();
|
||||
beam.AcceptInput("FollowEntity", beam, null!, "");
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#6effc7", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float maxDistance = 4096f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
{
|
||||
public float MaxDistance { get; set; } = maxDistance;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
|
|
@ -57,9 +56,20 @@ namespace src.player.skills
|
|||
{
|
||||
foreach (var (info, player) in infoList)
|
||||
{
|
||||
if (player == null) continue;
|
||||
if (player == null || !player.IsValid) continue;
|
||||
|
||||
var targetHandle = player.Pawn.Value?.ObserverServices?.ObserverTarget.Value?.Handle ?? nint.Zero;
|
||||
bool isObservingNinja = false;
|
||||
|
||||
if (targetHandle != nint.Zero)
|
||||
{
|
||||
var target = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == targetHandle);
|
||||
var targetInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == target?.SteamID);
|
||||
if (targetInfo?.Skill == skillName) isObservingNinja = true;
|
||||
}
|
||||
|
||||
foreach (var _player in invisiblePlayers.Keys)
|
||||
if (player.SteamID != _player.SteamID)
|
||||
if (player.SteamID != _player.SteamID && !isObservingNinja)
|
||||
{
|
||||
var playerPawn = _player.PlayerPawn.Value;
|
||||
if (playerPawn == null || !playerPawn.IsValid) continue;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using static src.jRandomSkills;
|
||||
using System.Collections.Concurrent;
|
||||
using CS2TraceRay.Class;
|
||||
using CS2TraceRay.Struct;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using static src.jRandomSkills;
|
||||
using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
|
||||
|
||||
namespace src.player.skills
|
||||
{
|
||||
|
|
@ -87,52 +91,139 @@ namespace src.player.skills
|
|||
public static void UseSkill(CCSPlayerController player)
|
||||
{
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
var duration = SkillsInfo.GetValue<float>(skillName, "duration");
|
||||
if (playerPawn?.CBodyComponent == null) return;
|
||||
|
||||
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
|
||||
{
|
||||
if (!player.IsValid || !player.PawnIsAlive) return;
|
||||
if (skillInfo.IsFlying)
|
||||
{
|
||||
StopFlying(player, skillInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (skillInfo.CanUse)
|
||||
{
|
||||
var duration = SkillsInfo.GetValue<float>(skillName, "duration");
|
||||
|
||||
skillInfo.CanUse = false;
|
||||
skillInfo.IsFlying = true;
|
||||
skillInfo.Cooldown = DateTime.Now;
|
||||
skillInfo.LastPosition = playerPawn.AbsOrigin == null ? null : new Vector(playerPawn.AbsOrigin.X, playerPawn.AbsOrigin.Y, playerPawn.AbsOrigin.Z);
|
||||
SetNoclip(player, true);
|
||||
skillInfo.Timer?.Kill();
|
||||
|
||||
playerPawn.ActualMoveType = MoveType_t.MOVETYPE_NOCLIP;
|
||||
Instance.AddTimer(duration, () => {
|
||||
if (playerPawn == null || !playerPawn.IsValid || !skillInfo.IsFlying) return;
|
||||
skillInfo.IsFlying = false;
|
||||
playerPawn.ActualMoveType = MoveType_t.MOVETYPE_WALK;
|
||||
});
|
||||
|
||||
Instance.AddTimer(duration + 4, () => {
|
||||
if (playerPawn == null || !playerPawn.IsValid || !player.PawnIsAlive || skillInfo.IsFlying) return;
|
||||
if (skillInfo.LastPosition == null || playerPawn.AbsOrigin == null) return;
|
||||
skillInfo.IsFlying = false;
|
||||
var diff = Math.Abs(playerPawn.AbsOrigin.Z - skillInfo.LastPosition.Z);
|
||||
if (diff > 3000 && playerPawn.AbsOrigin.Z < skillInfo.LastPosition.Z)
|
||||
playerPawn.Teleport(skillInfo.LastPosition, null, new Vector(0,0,0));
|
||||
});
|
||||
}
|
||||
else if (skillInfo.IsFlying)
|
||||
{
|
||||
skillInfo.IsFlying = false;
|
||||
playerPawn.ActualMoveType = MoveType_t.MOVETYPE_WALK;
|
||||
|
||||
Instance.AddTimer(4, () => {
|
||||
if (playerPawn == null || !playerPawn.IsValid || !player.PawnIsAlive || skillInfo.IsFlying) return;
|
||||
if (skillInfo.LastPosition == null || playerPawn.AbsOrigin == null) return;
|
||||
skillInfo.IsFlying = false;
|
||||
var diff = Math.Abs(playerPawn.AbsOrigin.Z - skillInfo.LastPosition.Z);
|
||||
if (diff > 3000 && playerPawn.AbsOrigin.Z < skillInfo.LastPosition.Z)
|
||||
playerPawn.Teleport(skillInfo.LastPosition, null, new Vector(0, 0, 0));
|
||||
skillInfo.Timer = Instance.AddTimer(duration, () =>
|
||||
{
|
||||
StopFlying(player, skillInfo);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetNoclip(CCSPlayerController player, bool noclip = true)
|
||||
{
|
||||
if (player == null || !player.IsValid) return;
|
||||
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
if (playerPawn == null || !playerPawn.IsValid || !player.PawnIsAlive) return;
|
||||
|
||||
playerPawn.MoveType = noclip ? MoveType_t.MOVETYPE_NOCLIP : MoveType_t.MOVETYPE_WALK;
|
||||
Schema.SetSchemaValue(playerPawn.Handle, "CBaseEntity", "m_nActualMoveType", (int)playerPawn.MoveType);
|
||||
Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_MoveType");
|
||||
}
|
||||
|
||||
private static void StopFlying(CCSPlayerController player, PlayerSkillInfo skillInfo)
|
||||
{
|
||||
skillInfo.Timer?.Kill();
|
||||
skillInfo.Timer = null;
|
||||
|
||||
if (!skillInfo.IsFlying) return;
|
||||
skillInfo.IsFlying = false;
|
||||
|
||||
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
|
||||
SetNoclip(player, false);
|
||||
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
if (playerPawn == null || !playerPawn.IsValid || skillInfo.IsFlying) return;
|
||||
|
||||
Vector? safePoint = GetCorrectPosition(player, skillInfo);
|
||||
playerPawn.Teleport(safePoint ?? skillInfo.LastPosition, null, new Vector(0, 0, 0));
|
||||
}
|
||||
|
||||
private static Vector? GetCorrectPosition(CCSPlayerController player, PlayerSkillInfo skillInfo)
|
||||
{
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return null;
|
||||
|
||||
Vector currentPos = playerPawn.AbsOrigin;
|
||||
float offset = 50;
|
||||
|
||||
Vector[] checkOffsets =
|
||||
{
|
||||
currentPos,
|
||||
currentPos + new Vector(offset, 0, 10),
|
||||
currentPos + new Vector(-offset, 0, 10),
|
||||
currentPos + new Vector(0, offset, 10),
|
||||
currentPos + new Vector(0, -offset, 10),
|
||||
|
||||
currentPos + new Vector(offset, 0, 60),
|
||||
currentPos + new Vector(-offset, 0, 60),
|
||||
currentPos + new Vector(0, offset, 60),
|
||||
currentPos + new Vector(0, -offset, 60),
|
||||
};
|
||||
|
||||
ulong mask = playerPawn.Collision.CollisionAttribute.InteractsWith;
|
||||
ulong contents = playerPawn.Collision.CollisionGroup;
|
||||
bool hasGround = false;
|
||||
|
||||
foreach (Vector targetPos in checkOffsets)
|
||||
{
|
||||
Vector start = new(targetPos.X, targetPos.Y, targetPos.Z + 70);
|
||||
Vector end = new(targetPos.X, targetPos.Y, targetPos.Z - 1000);
|
||||
|
||||
CGameTrace groundTrace = TraceRay.TraceShape(start, end, mask, contents, player);
|
||||
if (!groundTrace.DidHit()) continue;
|
||||
|
||||
hasGround = true;
|
||||
Vector newPos =
|
||||
groundTrace.EndPos.Z > targetPos.Z
|
||||
? new(groundTrace.EndPos.X, groundTrace.EndPos.Y, groundTrace.EndPos.Z)
|
||||
: targetPos;
|
||||
|
||||
if (IsPositionSafe(newPos, player))
|
||||
return newPos;
|
||||
}
|
||||
|
||||
if (hasGround)
|
||||
skillInfo.Cooldown = DateTime.Now.AddSeconds(-SkillsInfo.GetValue<float>(skillName, "cooldown") + SkillsInfo.GetValue<float>(skillName, "cooldownWhenStuck"));
|
||||
return hasGround ? currentPos : null;
|
||||
}
|
||||
|
||||
private static bool IsPositionSafe(Vector pos, CCSPlayerController player)
|
||||
{
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return false;
|
||||
|
||||
float footHeight = 0;
|
||||
float headHeight = 70;
|
||||
float innerDist = 12;
|
||||
|
||||
ulong mask = playerPawn.Collision.CollisionAttribute.InteractsWith;
|
||||
ulong contents = playerPawn.Collision.CollisionGroup;
|
||||
|
||||
Vector s1 = new(pos.X - innerDist, pos.Y - innerDist, pos.Z + footHeight);
|
||||
Vector e1 = new(pos.X + innerDist, pos.Y + innerDist, pos.Z + headHeight);
|
||||
CGameTrace t1 = TraceRay.TraceShape(s1, e1, mask, contents, player);
|
||||
if (t1.DidHit() || t1.AllSolid) return false;
|
||||
|
||||
Vector s2 = new(pos.X + innerDist, pos.Y - innerDist, pos.Z + footHeight);
|
||||
Vector e2 = new(pos.X - innerDist, pos.Y + innerDist, pos.Z + headHeight);
|
||||
CGameTrace t2 = TraceRay.TraceShape(s2, e2, mask, contents, player);
|
||||
if (t2.DidHit() || t2.AllSolid) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public class PlayerSkillInfo
|
||||
{
|
||||
public ulong SteamID { get; set; }
|
||||
|
|
@ -140,11 +231,13 @@ namespace src.player.skills
|
|||
public bool IsFlying { get; set; }
|
||||
public DateTime Cooldown { get; set; }
|
||||
public Vector? LastPosition { get; set; }
|
||||
public Timer? Timer { get; set; }
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#44ebd4", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 30f, float duration = 2f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#44ebd4", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 30f, float duration = 2f, float cooldownWhenStuck = 5f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
{
|
||||
public float Cooldown { get; set; } = cooldown;
|
||||
public float CooldownWhenStuck { get; set; } = cooldownWhenStuck;
|
||||
public float Duration { get; set; } = duration;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ namespace src.player.skills
|
|||
public class PawelJumper : ISkill
|
||||
{
|
||||
private const Skills skillName = Skills.PawelJumper;
|
||||
private static readonly PlayerFlags[] LF = new PlayerFlags[64];
|
||||
private static readonly int?[] J = new int?[64];
|
||||
private static readonly PlayerButtons[] LB = new PlayerButtons[64];
|
||||
|
||||
|
|
@ -71,7 +70,6 @@ namespace src.player.skills
|
|||
playerPawn.AbsVelocity.Z = 300;
|
||||
}
|
||||
|
||||
LF[player.Slot] = flags;
|
||||
LB[player.Slot] = buttons;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ namespace src.player.skills
|
|||
{
|
||||
SteamID = player.SteamID,
|
||||
Fuel = SkillsInfo.GetValue<float>(skillName, "maximumFuel"),
|
||||
LastButtons = 0
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -49,16 +50,37 @@ namespace src.player.skills
|
|||
|
||||
private static void HandlePilot(CCSPlayerController player)
|
||||
{
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
if (playerPawn == null || !playerPawn.IsValid) return;
|
||||
|
||||
if (!PlayerPilotInfo.TryGetValue(player.SteamID, out var pilotInfo)) return;
|
||||
|
||||
var flags = (PlayerFlags)playerPawn.Flags;
|
||||
var buttons = player.Buttons;
|
||||
|
||||
bool isJumpDown = (playerPawn.MovementServices?.Buttons?.ButtonStates[0] & (ulong)PlayerButtons.Jump) != 0 || (buttons & PlayerButtons.Jump) != 0;
|
||||
bool wasJumpDown = (pilotInfo.LastButtons & PlayerButtons.Jump) != 0;
|
||||
|
||||
bool jumpPressed = (isJumpDown && !wasJumpDown)
|
||||
|| (playerPawn.MovementServices?.QueuedButtonChangeMask & (ulong)PlayerButtons.Jump) != 0;
|
||||
|
||||
bool isOnGround = (flags & PlayerFlags.FL_ONGROUND) != 0;
|
||||
bool inUse = jumpPressed && !isOnGround;
|
||||
|
||||
var maximumFuel = SkillsInfo.GetValue<float>(skillName, "maximumFuel");
|
||||
if (PlayerPilotInfo.TryGetValue(player.SteamID, out var pilotInfo))
|
||||
{
|
||||
pilotInfo.Fuel = Math.Min(Math.Max(0, pilotInfo.Fuel - (buttons.HasFlag(PlayerButtons.Use) ? SkillsInfo.GetValue<float>(skillName, "fuelConsumption") : -SkillsInfo.GetValue<float>(skillName, "refuelling"))), maximumFuel);
|
||||
if (buttons.HasFlag(PlayerButtons.Use))
|
||||
if (pilotInfo.Fuel > 0 && player.PlayerPawn.Value != null && player.PlayerPawn.Value.IsValid && !player.PlayerPawn.Value.IsDefusing)
|
||||
ApplyPilotEffect(player);
|
||||
UpdateHUD(player, pilotInfo);
|
||||
}
|
||||
pilotInfo.Fuel = Math.Min(
|
||||
Math.Max(
|
||||
0,
|
||||
pilotInfo.Fuel - (inUse
|
||||
? SkillsInfo.GetValue<float>(skillName, "fuelConsumption")
|
||||
: -SkillsInfo.GetValue<float>(skillName, "refuelling"))),
|
||||
maximumFuel);
|
||||
pilotInfo.LastButtons = buttons;
|
||||
|
||||
if (inUse && pilotInfo.Fuel > 0)
|
||||
ApplyPilotEffect(player);
|
||||
|
||||
UpdateHUD(player, pilotInfo);
|
||||
}
|
||||
|
||||
private static void UpdateHUD(CCSPlayerController player, Pilot_PlayerInfo pilotInfo)
|
||||
|
|
@ -121,6 +143,7 @@ namespace src.player.skills
|
|||
{
|
||||
public ulong SteamID { get; set; }
|
||||
public float Fuel { get; set; }
|
||||
public PlayerButtons LastButtons { get; set; }
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1466F5", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float maximumFuel = 150f, float fuelConsumption = .64f, float refuelling = .1f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
|
|
|
|||
|
|
@ -99,9 +99,6 @@ namespace src.player.skills
|
|||
|
||||
float distance = 40;
|
||||
Vector pos = playerPawn.AbsOrigin + SkillUtils.GetForwardVector(playerPawn.AbsRotation) * distance;
|
||||
|
||||
if (((PlayerFlags)playerPawn.Flags).HasFlag(PlayerFlags.FL_DUCKING))
|
||||
pos.Z -= 19;
|
||||
|
||||
replica.Flags = playerPawn.Flags;
|
||||
replica.Flags |= (uint)Flags_t.FL_DUCKING;
|
||||
|
|
@ -109,6 +106,13 @@ namespace src.player.skills
|
|||
replica.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(replica.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
|
||||
replica.SetModel(playerPawn!.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.ModelName);
|
||||
replica.Entity!.Name = replica.Globalname = $"Replica_{Server.TickCount}_{(player.Team == CsTeam.CounterTerrorist ? "CT" : "TT")}";
|
||||
|
||||
replica.UseAnimGraph = false;
|
||||
string animName = "idle_for_turns_stand_pistol";
|
||||
if (((PlayerFlags)playerPawn.Flags).HasFlag(PlayerFlags.FL_DUCKING))
|
||||
animName = "idle_for_turns_crouch_pistol";
|
||||
|
||||
replica.AcceptInput("SetAnimation", value: animName);
|
||||
replica.Teleport(pos, playerPawn.AbsRotation, null);
|
||||
replica.DispatchSpawn();
|
||||
}
|
||||
|
|
|
|||
75
jRandomSkills - SRC Files/src/player/skills/Smoker.cs
Normal file
75
jRandomSkills - SRC Files/src/player/skills/Smoker.cs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using CounterStrikeSharp.API.Modules.Entities.Constants;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using static src.jRandomSkills;
|
||||
|
||||
namespace src.player.skills
|
||||
{
|
||||
public class Smoker : ISkill
|
||||
{
|
||||
private const Skills skillName = Skills.Smoker;
|
||||
private readonly static ConcurrentDictionary<uint, int> smokes = [];
|
||||
private static readonly object setLock = new();
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
}
|
||||
|
||||
public static void NewRound()
|
||||
{
|
||||
lock (setLock)
|
||||
smokes.Clear();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void EnableSkill(CCSPlayerController player)
|
||||
{
|
||||
SkillUtils.TryGiveWeapon(player, CsItem.SmokeGrenade);
|
||||
}
|
||||
|
||||
public static void SmokegrenadeDetonate(EventSmokegrenadeDetonate @event)
|
||||
{
|
||||
Server.PrintToChatAll("BOOM");
|
||||
var player = @event.Userid;
|
||||
if (player == null || !player.IsValid) return;
|
||||
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo?.Skill != skillName) return;
|
||||
|
||||
var smoke = Utilities.GetEntityFromIndex<CSmokeGrenadeProjectile>(@event.Entityid);
|
||||
if (smoke == null || !smoke.IsValid) return;
|
||||
|
||||
smokes.TryAdd(smoke.Index, Server.TickCount);
|
||||
|
||||
// smoke.SmokeEffectTickBegin = Server.TickCount - ((19 - 15) * 64);
|
||||
smoke.NextThinkTick = 0;
|
||||
|
||||
// Utilities.SetStateChanged(smoke, "CSmokeGrenadeProjectile", "m_nSmokeEffectTickBegin");
|
||||
Utilities.SetStateChanged(smoke, "CBaseEntity", "m_nNextThinkTick");
|
||||
}
|
||||
|
||||
public static void SmokegrenadeExpired(EventSmokegrenadeExpired @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) return;
|
||||
|
||||
Vector pos = new(@event.X, @event.Y, @event.Z);
|
||||
SkillUtils.CreateSmokeGrenadeProjectile(pos, new QAngle(0, 0, 0), new Vector(0, 0, 0), player.TeamNum);
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#b5ab8f", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,22 @@
|
|||
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;
|
||||
using System.Collections.Concurrent;
|
||||
using static src.jRandomSkills;
|
||||
|
||||
namespace src.player.skills
|
||||
{
|
||||
public class SoundMaker : ISkill
|
||||
{
|
||||
private const Skills skillName = Skills.SoundMaker;
|
||||
private static readonly ConcurrentDictionary<ulong, PlayerSkillInfo> SkillPlayerInfo = [];
|
||||
private static readonly ConcurrentDictionary<ulong, byte> SkillPlayerInfo = [];
|
||||
private static readonly object setLock = new();
|
||||
|
||||
private const string soundEventName = "Hostage.Pain";
|
||||
private const uint soundEventHash = 1876781570;
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
|
|
@ -26,12 +30,7 @@ namespace src.player.skills
|
|||
|
||||
public static void EnableSkill(CCSPlayerController player)
|
||||
{
|
||||
SkillPlayerInfo.TryAdd(player.SteamID, new PlayerSkillInfo
|
||||
{
|
||||
SteamID = player.SteamID,
|
||||
CanUse = true,
|
||||
Cooldown = DateTime.MinValue,
|
||||
});
|
||||
SkillPlayerInfo.TryAdd(player.SteamID, 0);
|
||||
}
|
||||
|
||||
public static void DisableSkill(CCSPlayerController player)
|
||||
|
|
@ -49,78 +48,40 @@ namespace src.player.skills
|
|||
SkillPlayerInfo.TryRemove(player.SteamID, out _);
|
||||
}
|
||||
|
||||
public static void PlayerMakeSound(UserMessage um)
|
||||
{
|
||||
var soundevent = um.ReadUInt("soundevent_hash");
|
||||
if (soundevent != soundEventHash) return;
|
||||
|
||||
var userIndex = um.ReadUInt("source_entity_index");
|
||||
if (userIndex == 0) return;
|
||||
|
||||
var sourcePlayer = Utilities.GetPlayers().FirstOrDefault(p => p.Pawn?.Value != null && p.Pawn.Value.IsValid && p.Pawn.Value.Index == userIndex);
|
||||
if (sourcePlayer == null || !sourcePlayer.IsValid) return;
|
||||
|
||||
var toRemove = um.Recipients.Where(r =>
|
||||
{
|
||||
if (r.Team == sourcePlayer.Team) return true;
|
||||
if (SkillPlayerInfo.ContainsKey(r.SteamID)) return false;
|
||||
return true;
|
||||
}).ToList();
|
||||
|
||||
foreach (var player in toRemove)
|
||||
um.Recipients.Remove(player);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
if (Server.TickCount % (60 * SkillsInfo.GetValue<int>(skillName, "cooldown")) != 0) return;
|
||||
|
||||
foreach (var player in Utilities.GetPlayers()
|
||||
.Where(p => p != null && p.IsValid && p.PawnIsAlive && p.PlayerPawn.Value != null && p.PlayerPawn.Value.IsValid))
|
||||
player.PlayerPawn.Value!.EmitSound(soundEventName, volume: 1f);
|
||||
}
|
||||
|
||||
private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo)
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#e3ed8c", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int cooldown = 2) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
{
|
||||
float cooldown = 0;
|
||||
if (skillInfo != null)
|
||||
{
|
||||
float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue<float>(skillName, "Cooldown")) - DateTime.Now).TotalSeconds);
|
||||
cooldown = Math.Max(time, 0);
|
||||
|
||||
if (cooldown == 0 && skillInfo?.CanUse == false)
|
||||
skillInfo.CanUse = true;
|
||||
}
|
||||
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(s => s.SteamID == player?.SteamID);
|
||||
if (playerInfo == null) return;
|
||||
|
||||
if (cooldown == 0)
|
||||
playerInfo.PrintHTML = null;
|
||||
else
|
||||
playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
|
||||
}
|
||||
|
||||
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;
|
||||
MakeSound(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void MakeSound(CCSPlayerController player)
|
||||
{
|
||||
foreach (var enemy in Utilities.GetPlayers().Where(p => p.Team != player.Team))
|
||||
if (enemy != null && enemy.IsValid && enemy.PawnIsAlive && enemy.PlayerPawn.Value != null && enemy.PlayerPawn.Value.IsValid)
|
||||
enemy.PlayerPawn.Value.EmitSound(
|
||||
enemy.Team == CsTeam.CounterTerrorist
|
||||
? SkillsInfo.GetValue<string>(skillName, "CTSoundEvent")
|
||||
: SkillsInfo.GetValue<string>(skillName, "TSoundEvent")
|
||||
, volume: 1f);
|
||||
}
|
||||
|
||||
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 = true, string color = "#e3ed8c", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float cooldown = 5f, string ctSoundEvent = "c4.disarmstart", string tSoundEvent = "C4.PlantSoundB") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
{
|
||||
public float Cooldown { get; set; } = cooldown;
|
||||
public string CTSoundEvent { get; set; } = ctSoundEvent;
|
||||
public string TSoundEvent { get; set; } = tSoundEvent;
|
||||
public int Cooldown { get; set; } = cooldown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -95,10 +95,6 @@ namespace src.player.skills
|
|||
var trigger = SkillUtils.CreateTrigger(triggerName, SkillsInfo.GetValue<float>(skillName, "smokeRadius"), new Vector(@event.X, @event.Y, @event.Z));
|
||||
if (trigger == null) return;
|
||||
triggers.TryAdd(trigger, 0);
|
||||
|
||||
new VirtualFunctionVoid<CBaseEntity>(trigger.Handle, 153);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void SmokegrenadeExpired(EventSmokegrenadeExpired @event)
|
||||
|
|
@ -138,7 +134,7 @@ namespace src.player.skills
|
|||
}
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = false, string color = "#507529", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int smokeDamage = 2, float smokeRadius = 180) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#507529", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int smokeDamage = 2, float smokeRadius = 180) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
{
|
||||
public int SmokeDamage { get; set; } = smokeDamage;
|
||||
public float SmokeRadius { get; set; } = smokeRadius;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace src.player.skills
|
|||
{
|
||||
private const Skills skillName = Skills.Wallhack;
|
||||
private static readonly ConcurrentDictionary<ulong, byte> playersInAction = [];
|
||||
private static readonly ConcurrentBag<(CDynamicProp, CDynamicProp, CsTeam)> glows = [];
|
||||
private static readonly ConcurrentBag<(CDynamicProp, CDynamicProp, CsTeam, uint)> glows = [];
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
|
|
@ -32,8 +32,11 @@ namespace src.player.skills
|
|||
|
||||
foreach (var glow in glows)
|
||||
{
|
||||
if (glow.Item3 != player.Team && (playerInfo?.Skill == skillName || (observerInfo != null && observerInfo?.Skill == skillName)))
|
||||
continue;
|
||||
var enemy = Utilities.GetPlayers().FirstOrDefault(e => e.IsValid && e.Index == glow.Item4);
|
||||
|
||||
if (enemy != null && enemy.PawnIsAlive)
|
||||
if (glow.Item3 != player.Team && (playerInfo?.Skill == skillName || (observerInfo != null && observerInfo?.Skill == skillName)))
|
||||
continue;
|
||||
|
||||
var glowEntity1 = Utilities.GetEntityFromIndex<CBaseEntity>((int)glow.Item1.Index);
|
||||
if (glowEntity1 == null || !glowEntity1.IsValid) continue;
|
||||
|
|
@ -110,7 +113,7 @@ namespace src.player.skills
|
|||
|
||||
modelRelay.AcceptInput("FollowEntity", enemyPawn, modelRelay, "!activator");
|
||||
modelGlow.AcceptInput("FollowEntity", modelRelay, modelGlow, "!activator");
|
||||
glows.Add((modelRelay, modelGlow, enemy.Team));
|
||||
glows.Add((modelRelay, modelGlow, enemy.Team, enemy.Index));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue