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
|
|
@ -5,6 +5,7 @@
|
|||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -16,7 +17,8 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.362" />
|
||||
<PackageReference Include="CS2TraceRay" Version="1.0.9" />
|
||||
<PackageReference Include="MaxMind.Db" Version="4.3.4" />
|
||||
<PackageReference Include="MaxMind.Db" Version="4.3.4">
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
@ -45,6 +47,8 @@
|
|||
<ServerLangDir>$(MSBuildProjectDirectory)\..\jRandomSkills - Server Files\plugins\jRandomSkills\languages</ServerLangDir>
|
||||
<SourceDLL>$(MSBuildProjectDirectory)\bin\Debug\net8.0</SourceDLL>
|
||||
<ServerDLL>$(MSBuildProjectDirectory)\..\jRandomSkills - Server Files\plugins\jRandomSkills</ServerDLL>
|
||||
<SourceGamedataDir>$(MSBuildProjectDirectory)\src\gamedata</SourceGamedataDir>
|
||||
<ServerGamedataDir>$(MSBuildProjectDirectory)\..\jRandomSkills - Server Files\gamedata</ServerGamedataDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Copy language files to server directory -->
|
||||
|
|
@ -63,8 +67,20 @@
|
|||
<ItemGroup>
|
||||
<CompiledDLL Include="$(SourceDLL)\jRandomSkills.dll" />
|
||||
<CompiledDLL Include="$(SourceDLL)\WASDMenuAPI.dll" />
|
||||
<CompiledDLL Include="$(SourceDLL)\MaxMind.Db.dll" />
|
||||
<CompiledDLL Include="$(SourceDLL)\Newtonsoft.Json.dll" />
|
||||
</ItemGroup>
|
||||
<MakeDir Directories="$(ServerDLL)" Condition="!Exists('$(ServerDLL)')" />
|
||||
<Copy SourceFiles="@(CompiledDLL)" DestinationFiles="@(CompiledDLL->'$(ServerDLL)\\%(Filename)%(Extension)')" SkipUnchangedFiles="false" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy gamedata files to server directory -->
|
||||
<Target Name="CopyGamedataFilesToServer" AfterTargets="Build">
|
||||
<Message Text="Copying gamedata files from $(SourceGamedataDir) to $(ServerGamedataDir)" Importance="High" />
|
||||
<ItemGroup>
|
||||
<GamedataFiles Include="$(SourceGamedataDir)\**\*.*" />
|
||||
</ItemGroup>
|
||||
<MakeDir Directories="$(ServerGamedataDir)" Condition="!Exists('$(ServerGamedataDir)')" />
|
||||
<Copy SourceFiles="@(GamedataFiles)" DestinationFiles="@(GamedataFiles->'$(ServerGamedataDir)\\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="false" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using CounterStrikeSharp.API.Core;
|
|||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
|
||||
|
||||
namespace src.command
|
||||
{
|
||||
|
|
@ -10,6 +11,20 @@ namespace src.command
|
|||
{
|
||||
private static readonly ConcurrentDictionary<VoteData, byte> votes = [];
|
||||
|
||||
private static void StartVoteTimer(VoteData vote, string commandName)
|
||||
{
|
||||
vote.ActiveTimer?.Kill();
|
||||
|
||||
vote.ActiveTimer = jRandomSkills.Instance.AddTimer(vote.TimeToVote, () =>
|
||||
{
|
||||
if (!votes.ContainsKey(vote) || !vote.GetActive()) return;
|
||||
|
||||
vote.SetActive(false);
|
||||
vote.TimeToNextSameVoting = vote.TimeToNextVoting;
|
||||
Localization.PrintTranslationToChatAll($" {ChatColors.Red}{{0}}", ["vote_timeout"], [commandName]);
|
||||
});
|
||||
}
|
||||
|
||||
private static VoteData? CreateVote(VoteType voteType, string? args = null)
|
||||
{
|
||||
var vote = new VoteData(10,
|
||||
|
|
@ -27,21 +42,15 @@ namespace src.command
|
|||
foreach (var player in Utilities.GetPlayers())
|
||||
player.EmitSound("UIPanorama.tab_mainmenu_news");
|
||||
|
||||
if (vote == null) return vote;
|
||||
jRandomSkills.Instance.AddTimer(vote.TimeToVote, () =>
|
||||
{
|
||||
if (!votes.ContainsKey(vote) || !vote.GetActive()) return;
|
||||
vote.SetActive(false);
|
||||
vote.TimeToNextSameVoting = vote.TimeToNextVoting;
|
||||
Localization.PrintTranslationToChatAll($" {ChatColors.Red}{{0}}", ["vote_timeout"], [commandName]);
|
||||
});
|
||||
StartVoteTimer(vote!, commandName);
|
||||
|
||||
float[] times = [vote.TimeToVote, vote.TimeToVote + vote.TimeToNextVoting, vote.TimeToVote + vote.TimeToNextSameVoting];
|
||||
float[] times = [vote!.TimeToVote, vote.TimeToVote + vote.TimeToNextVoting, vote.TimeToVote + vote.TimeToNextSameVoting];
|
||||
jRandomSkills.Instance.AddTimer(times.Max(), () =>
|
||||
{
|
||||
if (!votes.ContainsKey(vote)) return;
|
||||
votes.TryRemove(vote, out _);
|
||||
});
|
||||
|
||||
return vote;
|
||||
}
|
||||
|
||||
|
|
@ -78,16 +87,21 @@ namespace src.command
|
|||
private static void CheckVote(VoteData vote)
|
||||
{
|
||||
int voted = vote.PlayersVoted.Count;
|
||||
int playerCount = Utilities.GetPlayers().Where(p => !p.IsBot).ToArray().Length;
|
||||
int playerCount = Utilities.GetPlayers().Count(p => !p.IsBot);
|
||||
int playersNeeded = (int)Math.Ceiling(playerCount * (vote.PercentagesToSuccess / 100f));
|
||||
string commandName = $"!{VoteTypeCommands.GetCommand(vote.Type)?.Replace("css_", "")}{(!string.IsNullOrEmpty(vote?.Args) ? $" {vote?.Args}" : "")}";
|
||||
|
||||
if (voted >= playersNeeded)
|
||||
{
|
||||
vote!.ActiveTimer?.Kill();
|
||||
vote.SuccessAction.Invoke();
|
||||
vote.SetActive(false);
|
||||
}
|
||||
else
|
||||
Localization.PrintTranslationToChatAll($" {ChatColors.Yellow}{{0}} '!{VoteTypeCommands.GetCommand(vote.Type)?.Replace("css_", "")}{(!string.IsNullOrEmpty(vote?.Args) ? $" {vote?.Args}" : "")}': {ChatColors.Green}{voted}/{playersNeeded}", ["vote_vote"]);
|
||||
{
|
||||
StartVoteTimer(vote!, commandName);
|
||||
Localization.PrintTranslationToChatAll($" {ChatColors.Yellow}{{0}} '': {ChatColors.Green}{voted}/{playersNeeded}", ["vote_vote"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +117,7 @@ namespace src.command
|
|||
public VoteType Type { get; set; } = type;
|
||||
public string? Args { get; set; } = args;
|
||||
public ConcurrentDictionary<ulong, byte> PlayersVoted { get; set; } = [];
|
||||
|
||||
public Timer? ActiveTimer { get; set; }
|
||||
private DateTime CreatedTime { get; set; } = DateTime.Now;
|
||||
|
||||
public void SetActive(bool active)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"SmokeGrenadeProjectile_CreateFunc": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "48 8B C4 48 89 58 ? 48 89 68 ? 48 89 70 ? 57 41 56 41 57 48 81 EC ? ? ? ? 48 8B B4 24 ? ? ? ? 4D 8B F8",
|
||||
"linux": "55 4C 89 C1 48 89 E5 41 57 49 89 FF 41 56 45 89 CE"
|
||||
}
|
||||
},
|
||||
"HEGrenadeProjectile_CreateFunc": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC ? 48 8B AC 24 ? ? ? ? 49 8B F8",
|
||||
"linux": "55 4C 89 C1 48 89 E5 41 57 49 89 D7"
|
||||
}
|
||||
},
|
||||
"Shoot_Secondary": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "48 89 5C 24 ? 57 48 83 EC 20 44 0F BF C2",
|
||||
"linux": "55 48 89 E5 41 54 53 48 89 FB 66 83 FE 65"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,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.10.0";
|
||||
public override string ModuleVersion => "1.2.1";
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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,6 +706,11 @@ namespace src.player
|
|||
skillPlayer.Skill = randomSkill.Skill;
|
||||
skillPlayer.SpecialSkill = Skills.None;
|
||||
|
||||
if (randomSkill.Skill == Skills.Illiterate)
|
||||
Illiterate.Enable();
|
||||
|
||||
Instance?.AddTimer(.2f, () =>
|
||||
{
|
||||
if (SkillsInfo.GetValue<bool>(randomSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
|
||||
Instance?.AddTimer(Config.LoadedConfig.SkillTimeBeforeStart, () =>
|
||||
{
|
||||
|
|
@ -678,6 +719,7 @@ namespace src.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 (randomSkill.Skill == Skills.Illiterate)
|
||||
Illiterate.Enable();
|
||||
|
||||
Instance?.AddTimer(.2f, () =>
|
||||
{
|
||||
if (SkillsInfo.GetValue<bool>(randomSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
|
||||
Instance?.AddTimer(Config.LoadedConfig.SkillTimeBeforeStart, () => {
|
||||
Instance?.AddTimer(Config.LoadedConfig.SkillTimeBeforeStart, () =>
|
||||
{
|
||||
if (Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID && p.Skill == randomSkill.Skill) == null) return;
|
||||
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.Timer = Instance.AddTimer(duration, () =>
|
||||
{
|
||||
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));
|
||||
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,17 +50,38 @@ 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)
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -100,15 +100,19 @@ 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;
|
||||
replica.Collision.SolidType = SolidType_t.SOLID_VPHYSICS;
|
||||
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,6 +32,9 @@ namespace src.player.skills
|
|||
|
||||
foreach (var glow in glows)
|
||||
{
|
||||
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;
|
||||
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using static src.jRandomSkills;
|
||||
|
||||
namespace src.utils
|
||||
|
|
@ -69,6 +71,9 @@ namespace src.utils
|
|||
|
||||
public class SettingsModel
|
||||
{
|
||||
[DisplayName("Game Mode")]
|
||||
[Description("TESTfafw..")]
|
||||
[Range(0, 5)]
|
||||
public int GameMode { get; set; }
|
||||
public bool YourSkillChatInfo { get; set; }
|
||||
public bool KillerSkillChatInfo { get; set; }
|
||||
|
|
@ -120,6 +125,8 @@ namespace src.utils
|
|||
new LanguageInfo("PT-BR, PT, BR, AO, CV, GW, MZ, ST, TL", "pt-br"),
|
||||
new LanguageInfo("FR, MC, HT", "fr"),
|
||||
new LanguageInfo("DE, AT, CH, LI, LU, BE", "de"),
|
||||
new LanguageInfo("TR", "tr"),
|
||||
new LanguageInfo("CZ", "cs"),
|
||||
new LanguageInfo("PL", "pl"),
|
||||
new LanguageInfo("EN, GB, US", "en")
|
||||
]
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using Newtonsoft.Json;
|
|||
using System.Net;
|
||||
using System.Collections.Concurrent;
|
||||
using src.player;
|
||||
using src.player.skills;
|
||||
|
||||
namespace src.utils
|
||||
{
|
||||
|
|
@ -80,7 +81,7 @@ namespace src.utils
|
|||
}
|
||||
|
||||
var value = Math.Round((double)(chance ?? 1), 2);
|
||||
var skillNameText = GetTranslation(skill.ToString().ToLower(), langCode, value);
|
||||
var skillNameText = GetTranslation(skill.ToString().ToLower(), langCode, player, value);
|
||||
if (skillNameText.Contains('%')) skillNameText = skillNameText.Replace(value.ToString(), Math.Round(value * 100, 0).ToString());
|
||||
return skillNameText;
|
||||
}
|
||||
|
|
@ -104,7 +105,7 @@ namespace src.utils
|
|||
|
||||
var skillName = $"{skill.ToString().ToLower()}_desc2";
|
||||
var value = Math.Round((double)(chance ?? 1), 2);
|
||||
var desc2 = GetTranslation(skillName, langCode, value);
|
||||
var desc2 = GetTranslation(skillName, langCode, player, value);
|
||||
|
||||
var skilLDescription = desc2 == skillName
|
||||
? player.GetTranslation($"{skill.ToString().ToLower()}_desc")
|
||||
|
|
@ -127,7 +128,7 @@ namespace src.utils
|
|||
for (int i = 0; i < key.Length; i++)
|
||||
{
|
||||
object[] currentArgs = args != null && i < args.Length ? args[i] : [];
|
||||
string translation = GetTranslation(key[i], langCode, currentArgs);
|
||||
string translation = GetTranslation(key[i], langCode, null, currentArgs);
|
||||
translations.Add(translation);
|
||||
}
|
||||
player.PrintToChat(string.Format(message, [.. translations]));
|
||||
|
|
@ -137,10 +138,10 @@ namespace src.utils
|
|||
public static string GetTranslation(this CCSPlayerController player, string key, params object[] args)
|
||||
{
|
||||
string langCode = GetLangCode(player);
|
||||
return GetTranslation(key, langCode, args);
|
||||
return GetTranslation(key, langCode, player, args);
|
||||
}
|
||||
|
||||
public static string GetTranslation(string key, string? langCode = null, params object[] args)
|
||||
public static string GetTranslation(string key, string? langCode = null, CCSPlayerController? player = null, params object[] args)
|
||||
{
|
||||
langCode ??= defaultLangCode;
|
||||
if (_translations.TryGetValue(langCode, out var langDict) && langDict.TryGetValue(key, out var translation))
|
||||
|
|
@ -152,9 +153,14 @@ namespace src.utils
|
|||
output = output.Replace("CHATCOLORS.RED", ChatColors.Red.ToString());
|
||||
if (Config.LoadedConfig.AlternativeSkillButton != null)
|
||||
output = output.Replace("css_useSkill", $"css_useSkill/{Config.LoadedConfig.AlternativeSkillButton}");
|
||||
|
||||
if (Illiterate.CheckIlliterateSkill(player))
|
||||
return Illiterate.GetRandomText(output);
|
||||
return output;
|
||||
}
|
||||
|
||||
if (langCode != defaultLangCode)
|
||||
return GetTranslation(key, null, player, args);
|
||||
return key;
|
||||
}
|
||||
|
||||
|
|
@ -188,7 +194,10 @@ namespace src.utils
|
|||
if (string.IsNullOrEmpty(playerIP)) return null;
|
||||
if (!File.Exists(geoliteFilePath)) return null;
|
||||
using var reader = new Reader(geoliteFilePath);
|
||||
var ip = IPAddress.Parse(playerIP);
|
||||
|
||||
if (!IPAddress.TryParse(playerIP, out var ip))
|
||||
return null;
|
||||
|
||||
var data = reader.Find<ConcurrentDictionary<string, object>>(ip);
|
||||
if (data == null || data.IsEmpty) return null;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using CounterStrikeSharp.API.Modules.Utils;
|
|||
using src.player;
|
||||
using src.player.skills;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using WASDMenuAPI.Classes;
|
||||
|
|
@ -19,15 +20,21 @@ namespace src.utils
|
|||
public static class SkillUtils
|
||||
{
|
||||
private static readonly MemoryFunctionWithReturn<IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, int> HEGrenadeProjectile_CreateFunc = new(GameData.GetSignature("HEGrenadeProjectile_CreateFunc"));
|
||||
private static readonly MemoryFunctionWithReturn<IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, int> SmokeGrenadeProjectile_CreateFunc = new(GameData.GetSignature("SmokeGrenadeProjectile_CreateFunc"));
|
||||
private static readonly MemoryFunctionVoid<nint, float, RoundEndReason, nint, nint> TerminateRoundFunc = new(GameData.GetSignature("CCSGameRules_TerminateRound"));
|
||||
|
||||
public static void PrintToChat(CCSPlayerController player, string msg, string border = "tb", string? title = null)
|
||||
{
|
||||
if (!player.IsValid) return;
|
||||
|
||||
var config = Config.LoadedConfig.ChatMessage;
|
||||
float maxWidth = config.MaxWidth;
|
||||
char symbol = config.LineSymbol;
|
||||
if (string.IsNullOrEmpty(title)) title = player.GetTranslation("jRandomSkills");
|
||||
|
||||
if (Illiterate.CheckIlliterateSkill(player))
|
||||
msg = Illiterate.GetRandomText(msg);
|
||||
|
||||
if (border.Contains('t') && config.LineShow)
|
||||
player.PrintToChat($" {MeansureString.GetTextDashed($"{(config.TagFormat.Contains("{TAG}") ? config.TagFormat.Replace("{TAG}", title) : $"\u0002◢◆◤ {title} ◥◆◣")}", maxWidth, symbol, config.LineColor)}");
|
||||
if (!string.IsNullOrEmpty(msg) && config.InfoMessageShow)
|
||||
|
|
@ -86,9 +93,29 @@ namespace src.utils
|
|||
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
|
||||
public static void ApplyScreenColor(CCSPlayerController player, int r, int g, int b, int a, int duration, int holdTime, int flags = 1)
|
||||
public static CBeam? CreateLine(Vector start, Vector end, Color color)
|
||||
{
|
||||
CBeam beam = Utilities.CreateEntityByName<CBeam>("beam")!;
|
||||
if (beam == null) return null;
|
||||
|
||||
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();
|
||||
|
||||
return beam;
|
||||
}
|
||||
|
||||
public static void ApplyScreenColor(CCSPlayerController? player, int r, int g, int b, int a, int duration, int holdTime, int flags = 1)
|
||||
{
|
||||
if (player == null || !player.IsValid) return;
|
||||
|
||||
using var msg = UserMessage.FromPartialName("Fade");
|
||||
if (msg == null) return;
|
||||
int packageColor = (a << 24) | (b << 16) | (g << 8) | r;
|
||||
|
|
@ -142,6 +169,11 @@ namespace src.utils
|
|||
HEGrenadeProjectile_CreateFunc.Invoke(pos.Handle, angle.Handle, vel.Handle, vel.Handle, IntPtr.Zero, 44, teamNum);
|
||||
}
|
||||
|
||||
public static void CreateSmokeGrenadeProjectile(Vector pos, QAngle angle, Vector vel, int teamNum)
|
||||
{
|
||||
SmokeGrenadeProjectile_CreateFunc.Invoke(pos.Handle, angle.Handle, vel.Handle, vel.Handle, IntPtr.Zero, 45, teamNum);
|
||||
}
|
||||
|
||||
public static void TakeHealth(CCSPlayerPawn? pawn, int damage)
|
||||
{
|
||||
if (pawn == null || !pawn.IsValid || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
|
||||
|
|
@ -280,9 +312,11 @@ namespace src.utils
|
|||
var playerInfo = jRandomSkills.Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo == null) return;
|
||||
|
||||
bool isIlliterate = Illiterate.CheckIlliterateSkill(player);
|
||||
|
||||
Dictionary<string, Action<CCSPlayerController, IWasdMenuOption>> list = [];
|
||||
foreach (var item in items)
|
||||
list.TryAdd(item.Item1, (p, option) =>
|
||||
list.TryAdd(isIlliterate ? Illiterate.GetRandomText(item.Item1) : item.Item1, (p, option) =>
|
||||
{
|
||||
jRandomSkills.Instance.SkillAction(playerInfo.Skill.ToString(), "TypeSkill", [p, new[] { item.Item2 }]);
|
||||
manager.CloseMenu(p);
|
||||
|
|
@ -329,15 +363,17 @@ namespace src.utils
|
|||
string itemText = $"<font class='fontSize-{config.WSADMenuItemLineSize}' color='{config.WSADMenuItemLineColor}'>{{0}}</font><br>";
|
||||
string itemHoverText = $"<font class='fontSize-{config.WSADMenuItemLineSize}'><font color='purple'>[ </font><font color='{config.WSADMenuItemHoverLineColor}'>{{0}}</font><font color='purple'> ]</font></font><br>";
|
||||
|
||||
bool isIlliterate = Illiterate.CheckIlliterateSkill(player);
|
||||
|
||||
IWasdMenu menu = manager.CreateMenu(hudContent, itemText, itemHoverText, controllsLine);
|
||||
foreach (var enemy in enemies)
|
||||
menu.Add(enemy.Item1, (p, option) =>
|
||||
menu.Add(isIlliterate ? Illiterate.GetRandomText(enemy.Item1) : enemy.Item1, (p, option) =>
|
||||
{
|
||||
jRandomSkills.Instance.SkillAction(playerInfo.Skill.ToString(), "TypeSkill", [p, new[] { enemy.Item2 }]);
|
||||
manager.CloseMenu(p);
|
||||
});
|
||||
if (lastElement != null)
|
||||
menu.Add(lastElement.Value.Item1, (p, option) =>
|
||||
menu.Add(isIlliterate ? Illiterate.GetRandomText(lastElement.Value.Item1) : lastElement.Value.Item1, (p, option) =>
|
||||
{
|
||||
jRandomSkills.Instance.SkillAction(playerInfo.Skill.ToString(), "TypeSkill", [p, new[] { lastElement.Value.Item2 }]);
|
||||
if (lastElement.Value.Item3)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue