From 576cee8cfb8910a58a85c53d27a38e3e7ca01b8f Mon Sep 17 00:00:00 2001 From: Juzlus Date: Tue, 25 Feb 2025 01:49:34 +0100 Subject: [PATCH] v1.0.3 --- .../src/dRandomSkills.cs | 88 ---- .../src/player/PlayerEvents.cs | 130 ------ .../src/player/PlayerOnTick.cs | 54 --- .../src/player/skills/AntyFlash.cs | 37 -- .../src/player/skills/Astronauta.cs | 41 -- .../src/player/skills/Bogacz.cs | 47 -- .../src/player/skills/Eliminator.cs | 68 --- .../src/player/skills/Flash.cs | 47 -- .../src/player/skills/Impostor.cs | 184 -------- .../src/player/skills/Medyk.cs | 50 --- .../src/player/skills/MiniMajk.cs | 58 --- .../src/player/skills/ObrotWroga.cs | 79 ---- .../src/player/skills/Phoenix.cs | 63 --- .../src/player/skills/Rambo.cs | 50 --- .../src/player/skills/Saper.cs | 68 --- .../src/player/skills/ZamianaMiejsc.cs | 164 ------- .../src/utils/Config.cs | 81 ---- .../plugins/dRandomSkills/Config.json | 8 - .../plugins/dRandomSkills/dRandomSkills.dll | Bin 87552 -> 0 bytes .../Properties/Resources.Designer.cs | 4 +- .../Properties/Resources.resx | 0 .../Properties/launchSettings.json | 2 +- .../jRandomSkills.csproj | 4 + .../jRandomSkills.sln | 2 +- .../src/command/Command.cs | 90 +++- .../src/jRandomSkills.cs | 109 +++++ jRandomSkills - SRC Files/src/lang/en.json | 127 ++++++ jRandomSkills - SRC Files/src/lang/pl.json | 127 ++++++ .../src/menu/Menu.cs | 8 +- .../src/player/ISkill.cs | 66 +++ .../src/player/PlayerEvents.cs | 199 +++++++++ .../src/player/PlayerOnTick.cs | 82 ++++ .../src/player/skills/Aimbot.cs | 66 +++ .../src/player/skills/AntyFlash.cs | 39 ++ .../src/player/skills/AntyHead.cs | 24 +- .../src/player/skills/Armored.cs | 84 ++++ .../src/player/skills/Astronaut.cs | 60 +++ .../src/player/skills/Behind.cs | 88 ++++ .../src/player/skills/BunnyHop.cs | 18 +- .../src/player/skills/Catapult.cs | 43 +- .../src/player/skills/Chicken.cs | 72 ++-- .../src/player/skills/Disarmament.cs | 43 +- .../src/player/skills/Dracula.cs | 25 +- .../src/player/skills/Dwarf.cs | 82 ++++ .../src/player/skills/EnemySpawn.cs | 181 ++++++++ .../src/player/skills/Flash.cs | 112 +++++ .../src/player/skills/FrozenDecoy.cs | 144 +++++++ .../src/player/skills/Ghost.cs | 59 ++- .../src/player/skills/GodMode.cs | 163 +++++++ .../src/player/skills/Impostor.cs | 79 ++++ .../src/player/skills/InfiniteAmmo.cs | 34 +- .../src/player/skills/KillerFlash.cs | 35 ++ .../src/player/skills/Medic.cs | 60 +++ .../src/player/skills/Muhammed.cs | 26 +- .../src/player/skills/Mute.cs | 58 +++ .../src/player/skills/None.cs | 14 + .../src/player/skills/OneShot.cs | 19 +- .../src/player/skills/PawelJumper.cs | 24 +- .../src/player/skills/Phoenix.cs | 72 ++++ .../src/player/skills/Pilot.cs | 55 ++- .../src/player/skills/Planter.cs | 74 ++++ .../src/player/skills/QuickShot.cs | 41 ++ .../src/player/skills/RadarHack.cs | 58 +++ .../src/player/skills/Rambo.cs | 70 +++ .../src/player/skills/RandomWeapon.cs | 191 ++++++++ .../src/player/skills/Retreat.cs | 166 +++++++ .../src/player/skills/RichBoy.cs | 63 +++ .../src/player/skills/Saper.cs | 66 +++ .../src/player/skills/Shade.cs | 26 +- .../src/player/skills/Silent.cs | 41 ++ .../src/player/skills/Soldier.cs | 79 ++++ .../src/player/skills/SwapPosition.cs | 193 +++++++++ .../src/player/skills/Teleporter.cs | 26 +- .../src/player/skills/TimeManipulator.cs | 155 +++++++ .../src/player/skills/Wallhack.cs | 92 ++++ .../src/player/skills/WeaponsSwap.cs | 224 ++++++++++ .../src/player/skills/Zeus.cs | 44 ++ jRandomSkills - SRC Files/src/utils/Config.cs | 153 +++++++ .../src/utils/Findtarget.cs | 9 +- .../src/utils/Localization.cs | 57 +++ .../src/utils/Utils.cs | 12 +- .../plugins/dRandomSkills/Config.json | 408 ++++++++++++++++++ .../plugins/dRandomSkills/Newtonsoft.Json.dll | Bin .../plugins/dRandomSkills/jRandomSkills.dll | Bin 0 -> 150016 bytes .../plugins/dRandomSkills/lang/en.json | 127 ++++++ .../plugins/dRandomSkills/lang/pl.json | 127 ++++++ readme.md | 97 +++++ 87 files changed, 4957 insertions(+), 1558 deletions(-) delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/dRandomSkills.cs delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/player/PlayerEvents.cs delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/player/PlayerOnTick.cs delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/player/skills/AntyFlash.cs delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/player/skills/Astronauta.cs delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/player/skills/Bogacz.cs delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/player/skills/Eliminator.cs delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/player/skills/Flash.cs delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/player/skills/Impostor.cs delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/player/skills/Medyk.cs delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/player/skills/MiniMajk.cs delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/player/skills/ObrotWroga.cs delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/player/skills/Phoenix.cs delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/player/skills/Rambo.cs delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/player/skills/Saper.cs delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/player/skills/ZamianaMiejsc.cs delete mode 100644 [ D3X ] dRandomSkills - SRC Files/src/utils/Config.cs delete mode 100644 [ D3X ] dRandomSkills - Server Files/plugins/dRandomSkills/Config.json delete mode 100644 [ D3X ] dRandomSkills - Server Files/plugins/dRandomSkills/dRandomSkills.dll rename {[ D3X ] dRandomSkills - SRC Files => jRandomSkills - SRC Files}/Properties/Resources.Designer.cs (96%) rename {[ D3X ] dRandomSkills - SRC Files => jRandomSkills - SRC Files}/Properties/Resources.resx (100%) rename {[ D3X ] dRandomSkills - SRC Files => jRandomSkills - SRC Files}/Properties/launchSettings.json (79%) rename [ D3X ] dRandomSkills - SRC Files/dRandomSkills.csproj => jRandomSkills - SRC Files/jRandomSkills.csproj (89%) rename [ D3X ] dRandomSkills - SRC Files/dRandomSkills.sln => jRandomSkills - SRC Files/jRandomSkills.sln (88%) rename {[ D3X ] dRandomSkills - SRC Files => jRandomSkills - SRC Files}/src/command/Command.cs (53%) create mode 100644 jRandomSkills - SRC Files/src/jRandomSkills.cs create mode 100644 jRandomSkills - SRC Files/src/lang/en.json create mode 100644 jRandomSkills - SRC Files/src/lang/pl.json rename {[ D3X ] dRandomSkills - SRC Files => jRandomSkills - SRC Files}/src/menu/Menu.cs (87%) create mode 100644 jRandomSkills - SRC Files/src/player/ISkill.cs create mode 100644 jRandomSkills - SRC Files/src/player/PlayerEvents.cs create mode 100644 jRandomSkills - SRC Files/src/player/PlayerOnTick.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/Aimbot.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/AntyFlash.cs rename [ D3X ] dRandomSkills - SRC Files/src/player/skills/ZelaznaGlowa.cs => jRandomSkills - SRC Files/src/player/skills/AntyHead.cs (59%) create mode 100644 jRandomSkills - SRC Files/src/player/skills/Armored.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/Astronaut.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/Behind.cs rename {[ D3X ] dRandomSkills - SRC Files => jRandomSkills - SRC Files}/src/player/skills/BunnyHop.cs (81%) rename [ D3X ] dRandomSkills - SRC Files/src/player/skills/Katapulta.cs => jRandomSkills - SRC Files/src/player/skills/Catapult.cs (50%) rename [ D3X ] dRandomSkills - SRC Files/src/player/skills/Kurczak.cs => jRandomSkills - SRC Files/src/player/skills/Chicken.cs (50%) rename [ D3X ] dRandomSkills - SRC Files/src/player/skills/Rozbrojenie.cs => jRandomSkills - SRC Files/src/player/skills/Disarmament.cs (53%) rename [ D3X ] dRandomSkills - SRC Files/src/player/skills/Drakula.cs => jRandomSkills - SRC Files/src/player/skills/Dracula.cs (64%) create mode 100644 jRandomSkills - SRC Files/src/player/skills/Dwarf.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/EnemySpawn.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/Flash.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/FrozenDecoy.cs rename [ D3X ] dRandomSkills - SRC Files/src/player/skills/Duszek.cs => jRandomSkills - SRC Files/src/player/skills/Ghost.cs (70%) create mode 100644 jRandomSkills - SRC Files/src/player/skills/GodMode.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/Impostor.cs rename [ D3X ] dRandomSkills - SRC Files/src/player/skills/NieskonczoneAmmo.cs => jRandomSkills - SRC Files/src/player/skills/InfiniteAmmo.cs (63%) create mode 100644 jRandomSkills - SRC Files/src/player/skills/KillerFlash.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/Medic.cs rename {[ D3X ] dRandomSkills - SRC Files => jRandomSkills - SRC Files}/src/player/skills/Muhammed.cs (73%) create mode 100644 jRandomSkills - SRC Files/src/player/skills/Mute.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/None.cs rename {[ D3X ] dRandomSkills - SRC Files => jRandomSkills - SRC Files}/src/player/skills/OneShot.cs (74%) rename {[ D3X ] dRandomSkills - SRC Files => jRandomSkills - SRC Files}/src/player/skills/PawelJumper.cs (76%) create mode 100644 jRandomSkills - SRC Files/src/player/skills/Phoenix.cs rename {[ D3X ] dRandomSkills - SRC Files => jRandomSkills - SRC Files}/src/player/skills/Pilot.cs (79%) create mode 100644 jRandomSkills - SRC Files/src/player/skills/Planter.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/QuickShot.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/RadarHack.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/Rambo.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/RandomWeapon.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/Retreat.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/RichBoy.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/Saper.cs rename [ D3X ] dRandomSkills - SRC Files/src/player/skills/Cien.cs => jRandomSkills - SRC Files/src/player/skills/Shade.cs (74%) create mode 100644 jRandomSkills - SRC Files/src/player/skills/Silent.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/Soldier.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/SwapPosition.cs rename {[ D3X ] dRandomSkills - SRC Files => jRandomSkills - SRC Files}/src/player/skills/Teleporter.cs (73%) create mode 100644 jRandomSkills - SRC Files/src/player/skills/TimeManipulator.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/Wallhack.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/WeaponsSwap.cs create mode 100644 jRandomSkills - SRC Files/src/player/skills/Zeus.cs create mode 100644 jRandomSkills - SRC Files/src/utils/Config.cs rename {[ D3X ] dRandomSkills - SRC Files => jRandomSkills - SRC Files}/src/utils/Findtarget.cs (88%) create mode 100644 jRandomSkills - SRC Files/src/utils/Localization.cs rename {[ D3X ] dRandomSkills - SRC Files => jRandomSkills - SRC Files}/src/utils/Utils.cs (54%) create mode 100644 jRandomSkills - Server Files/plugins/dRandomSkills/Config.json rename {[ D3X ] dRandomSkills - Server Files => jRandomSkills - Server Files}/plugins/dRandomSkills/Newtonsoft.Json.dll (100%) create mode 100644 jRandomSkills - Server Files/plugins/dRandomSkills/jRandomSkills.dll create mode 100644 jRandomSkills - Server Files/plugins/dRandomSkills/lang/en.json create mode 100644 jRandomSkills - Server Files/plugins/dRandomSkills/lang/pl.json create mode 100644 readme.md diff --git a/[ D3X ] dRandomSkills - SRC Files/src/dRandomSkills.cs b/[ D3X ] dRandomSkills - SRC Files/src/dRandomSkills.cs deleted file mode 100644 index 1fb31c4..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/dRandomSkills.cs +++ /dev/null @@ -1,88 +0,0 @@ -using CounterStrikeSharp.API.Core; - -namespace dRandomSkills -{ - public partial class dRandomSkills : BasePlugin - { - public static dRandomSkills Instance { get; private set; } - - public List skillPlayer { get; } = new List(); - public Random Random { get; } = new Random(); - - public override string ModuleName => "[CS2] D3X - [ Random Skills ]"; - public override string ModuleAuthor => "D3X"; - public override string ModuleDescription => "Plugin dodaje na serwer losowe moce co runde na serwery CS2 by D3X"; - public override string ModuleVersion => "1.0.2"; - - public override void Load(bool hotReload) - { - Instance = this; - - Config.Initialize(); - Event.Load(); - PlayerOnTick.Load(); - Command.Load(); - - // ==== NOWE ==== - MiniMajk.LoadMiniMajk(); - ZamianaMiejsc.LoadZamianaMiejsc(); - - // ==== POPRAWIONE/NAPRAWIONE ==== - Flash.LoadFlash(); - PawelJumper.LoadPawelJumper(); - BunnyHop.LoadBunnyHop(); - Impostor.LoadImpostor(); - OneShot.LoadOneShot(); - Muhammed.LoadMuhammed(); - Bogacz.LoadBogacz(); - Rambo.LoadRambo(); - Medyk.LoadMedyk(); - Duszek.LoadDuszek(); - Kurczak.LoadKurczak(); - Astronauta.LoadAstronauta(); - Rozbrojenie.LoadRozbrojenie(); - AntyFlash.LoadAntyFlash(); - ObrotWroga.LoadObrotWroga(); - NieskonczoneAmmo.LoadNieskonczoneAmmo(); - Katapulta.LoadKatapulta(); - Drakula.LoadDrakula(); - Teleporter.LoadTeleporter(); - Saper.LoadEliminator(); - Phoenix.LoadPhoenix(); - Pilot.LoadPilot(); - Cien.LoadCien(); - ZelaznaGlowa.LoadZelaznaGlowa(); - } - } - - public class dSkill_PlayerInfo - { - public required ulong SteamID { get; set; } - public required string PlayerName { get; set; } - public string? Skill { get; set; } - public float? SkillChance { get; set; } - public bool IsDrawing { get; set; } - } - - public class dSkill_SkillInfo - { - public string Name { get; } - public string Description { get; } - public string Color { get; } - - public bool Display { get; } - - public dSkill_SkillInfo(string name, string description, string color, bool display) - { - Name = name; - Description = description; - Color = color; - Display = display; - } - } - - public static class SkillData - { - public static List Skills { get; } = new List(); - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/PlayerEvents.cs b/[ D3X ] dRandomSkills - SRC Files/src/player/PlayerEvents.cs deleted file mode 100644 index b4e2773..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/PlayerEvents.cs +++ /dev/null @@ -1,130 +0,0 @@ -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Modules.Utils; -using static dRandomSkills.dRandomSkills; - -namespace dRandomSkills -{ - public static class Event - { - public static void Load() - { - Instance.RegisterEventHandler((@event, info) => - { - var player = @event.Userid; - - if (player == null || !player.IsValid) return HookResult.Continue; - - Instance.skillPlayer.Add(new dSkill_PlayerInfo - { - SteamID = player.SteamID, - PlayerName = player.PlayerName, - Skill = "", - IsDrawing = false, - SkillChance = 1, - }); - - return HookResult.Continue; - }); - - Instance.RegisterEventHandler((@event, info) => - { - 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) - { - Instance.skillPlayer.Remove(skillPlayer); - } - - return HookResult.Continue; - }); - - Instance.RegisterEventHandler((@event, info) => - { - foreach (var player in Utilities.GetPlayers()) - { - var skillPlayer = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - - if (skillPlayer != null) - { - skillPlayer.IsDrawing = true; - } - } - - return HookResult.Continue; - }); - - Instance.RegisterEventHandler((@event, info) => - { - foreach (var player in Utilities.GetPlayers()) - { - var playerTeam = player.Team; - var teammates = Utilities.GetPlayers().Where(p => p.Team == playerTeam && p != player); - string teammateSkills = ""; - - var skillPlayer = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - - if (skillPlayer != null) - { - skillPlayer.IsDrawing = false; - - var randomSkill = SkillData.Skills[Instance.Random.Next(SkillData.Skills.Count)]; - skillPlayer.Skill = randomSkill.Name; - - if (randomSkill.Display) - Utils.PrintToChat(player, $"{ChatColors.DarkRed}{randomSkill.Name}{ChatColors.Lime}: {randomSkill.Description}", false); - - if(Config.config.Settings.TeamMateSkillInfo) - { - Instance.AddTimer(0.5f, () => - { - foreach (var teammate in teammates) - { - var teammateSkill = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == teammate.SteamID)?.Skill; - if (!string.IsNullOrEmpty(teammateSkill)) - { - teammateSkills += $" {ChatColors.DarkRed}{teammate.PlayerName}{ChatColors.Lime}: {teammateSkill}\n"; - } - } - - if (!string.IsNullOrEmpty(teammateSkills)) - { - Utils.PrintToChat(player, $" {ChatColors.Lime}Supermoce twoich sojuszników:", false); - Utils.PrintToChat(player, teammateSkills.TrimEnd('\n'), false); - } - }); - } - } - } - - return HookResult.Continue; - }); - - Instance.RegisterEventHandler((@event, info) => - { - var victim = @event.Userid; - var attacker = @event.Attacker; - - if (victim == null || attacker == null || victim == attacker) return HookResult.Continue; - - if(Config.config.Settings.KillerSkillInfo) - { - var attackerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); - if (attackerInfo != null) - { - var skillData = SkillData.Skills.FirstOrDefault(s => s.Name == attackerInfo.Skill); - string skillDesc = skillData?.Description ?? "Brak opisu"; - - Utils.PrintToChat(victim, $"Supermoc przeciwnika {ChatColors.DarkRed}{attacker.PlayerName}{ChatColors.Lime}:", false); - Utils.PrintToChat(victim, $"{ChatColors.DarkRed}{attackerInfo.Skill}{ChatColors.Lime} - {skillDesc}", false); - } - } - - return HookResult.Continue; - }); - } - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/PlayerOnTick.cs b/[ D3X ] dRandomSkills - SRC Files/src/player/PlayerOnTick.cs deleted file mode 100644 index e92133e..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/PlayerOnTick.cs +++ /dev/null @@ -1,54 +0,0 @@ -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; -using static CounterStrikeSharp.API.Core.Listeners; -using static dRandomSkills.dRandomSkills; - -namespace dRandomSkills -{ - public static class PlayerOnTick - { - public static void Load() - { - Instance.RegisterListener(() => - { - foreach (var player in Utilities.GetPlayers()) - { - if (player != null && player.IsValid) - { - UpdatePlayerHud(player); - } - } - }); - } - - private static void UpdatePlayerHud(CCSPlayerController player) - { - if (player == null) return; - - var skillPlayer = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (skillPlayer == null) return; - - string infoLine = ""; - string skillLine = ""; - - if (skillPlayer.IsDrawing) - { - var randomSkill = SkillData.Skills[Instance.Random.Next(SkillData.Skills.Count)]; - infoLine = $"Losowanie mocy:
"; - skillLine = $"{randomSkill.Name}
"; - } - else if (!skillPlayer.IsDrawing) - { - var skillInfo = SkillData.Skills.FirstOrDefault(s => s.Name == skillPlayer.Skill); - if (skillInfo != null) - { - infoLine = $"Twoja aktualna moc:
"; - skillLine = $"{skillPlayer.Skill}
"; - } - } - - var hudContent = infoLine + skillLine; - player.PrintToCenterHtml(hudContent); - } - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/AntyFlash.cs b/[ D3X ] dRandomSkills - SRC Files/src/player/skills/AntyFlash.cs deleted file mode 100644 index c4dfd0b..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/AntyFlash.cs +++ /dev/null @@ -1,37 +0,0 @@ -using CounterStrikeSharp.API.Core; -using static dRandomSkills.dRandomSkills; - -namespace dRandomSkills -{ - public static class AntyFlash - { - public static void LoadAntyFlash() - { - Utils.RegisterSkill("Anty Flash", "Posiadasz odporność na flashe i 7 sekund trwają twoje flash'e", "#D6E6FF"); - - Instance.RegisterEventHandler((@event, info) => - { - var player = @event.Userid; - var attacker = @event.Attacker; - - var playerPawn = player.PlayerPawn.Value; - - if (!IsPlayerValid(player)) return HookResult.Continue; - - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - - if (playerInfo?.Skill == "Anty Flash") - playerPawn.FlashDuration = 0.0f; - else if (Instance.skillPlayer.Any(s => s.Skill == "Anty Flash")) - playerPawn.FlashDuration = 7.0f; - - return HookResult.Continue; - }); - } - - private static bool IsPlayerValid(CCSPlayerController player) - { - return player != null && player.IsValid && player.PlayerPawn?.Value != null && player.PlayerPawn.Value.LifeState == (byte)LifeState_t.LIFE_ALIVE; - } - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Astronauta.cs b/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Astronauta.cs deleted file mode 100644 index b02c1ec..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Astronauta.cs +++ /dev/null @@ -1,41 +0,0 @@ -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Modules.Entities; -using CounterStrikeSharp.API.Modules.Utils; -using static dRandomSkills.dRandomSkills; - -namespace dRandomSkills -{ - public static class Astronauta - { - public static void LoadAstronauta() - { - Utils.RegisterSkill("Astronauta", "Otrzymujesz losową ilość grawitacji na start rundy", "#7E10AD", false); - - Instance.RegisterEventHandler((@event, info) => - { - Instance.AddTimer(0.1f, () => - { - foreach (var player in Utilities.GetPlayers()) - { - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - var playerPawn = player.PlayerPawn.Value; - - if (playerInfo?.Skill == "Astronauta" && playerPawn != null) - { - ApplyGravityModifier(player); - } - } - }); - return HookResult.Continue; - }); - } - - private static void ApplyGravityModifier(CCSPlayerController player) - { - float gravityModifier = (float)Math.Round(Instance.Random.NextDouble() * (0.7f - 0.1f) + 0.1f, 1); - Utils.PrintToChat(player, $"{ChatColors.DarkRed}\"Astronauta\"{ChatColors.Lime}: Twoja losowa grawitacja wynosi: {gravityModifier}x", false); - player.Pawn.Value.GravityScale = gravityModifier; - } - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Bogacz.cs b/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Bogacz.cs deleted file mode 100644 index ea58c4b..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Bogacz.cs +++ /dev/null @@ -1,47 +0,0 @@ -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; -using static dRandomSkills.dRandomSkills; - -namespace dRandomSkills -{ - public static class Bogacz - { - public static void LoadBogacz() - { - Utils.RegisterSkill("Bogacz", "Otrzymujesz losową ilość kasy na start rundy", "#D4AF37"); - - Instance.RegisterEventHandler((@event, info) => - { - Instance.AddTimer(0.1f, () => - { - foreach (var player in Utilities.GetPlayers()) - { - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - - if (playerInfo?.Skill == "Bogacz") - { - ApplyMoneyBonus(player); - } - } - }); - return HookResult.Continue; - }); - } - - private static void ApplyMoneyBonus(CCSPlayerController player) - { - int moneyBonus = Instance.Random.Next(5000, 15000); - AddMoney(player, moneyBonus); - } - - private static void AddMoney(CCSPlayerController player, int money) - { - var moneyServices = player?.InGameMoneyServices; - - if (moneyServices == null) return; - - moneyServices.Account += money; - Utilities.SetStateChanged(player, "CCSPlayerController", "m_pInGameMoneyServices"); - } - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Eliminator.cs b/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Eliminator.cs deleted file mode 100644 index e8e050b..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Eliminator.cs +++ /dev/null @@ -1,68 +0,0 @@ -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; -using static dRandomSkills.dRandomSkills; - -namespace dRandomSkills -{ - public static class Eliminator - { - public static void LoadEliminator() - { - Utils.RegisterSkill("Eliminator", "Możesz szybciej podłożyć bombę oraz ją zdefować", "#8A2BE2"); - - Instance.RegisterEventHandler((@event, info) => - { - foreach (var player in Utilities.GetPlayers()) - { - if (!IsPlayerValid(player)) return HookResult.Continue; - - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Eliminator") - { - var bombEntities = Utilities.FindAllEntitiesByDesignerName("weapon_c4").ToList(); - - if (bombEntities.Any()) - { - var bomb = bombEntities.FirstOrDefault(); - if (bomb != null) - { - bomb.BombPlacedAnimation = false; - bomb.ArmedTime = 0.0f; - } - } - } - } - - return HookResult.Continue; - }); - - Instance.RegisterEventHandler((@event, info) => - { - var player = @event.Userid; - - if (IsPlayerValid(player)) - { - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Eliminator") - { - var plantedBomb = Utilities.FindAllEntitiesByDesignerName("planted_c4").FirstOrDefault(); - if (plantedBomb != null) - { - Server.NextFrame(() => - { - plantedBomb.DefuseCountDown = 0; - }); - } - } - } - - return HookResult.Continue; - }); - } - - private static bool IsPlayerValid(CCSPlayerController player) - { - return player != null && player.IsValid && player.PlayerPawn?.Value != null; - } - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Flash.cs b/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Flash.cs deleted file mode 100644 index 9234ca9..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Flash.cs +++ /dev/null @@ -1,47 +0,0 @@ -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Modules.Utils; -using static dRandomSkills.dRandomSkills; - -namespace dRandomSkills -{ - public static class Flash - { - public static void LoadFlash() - { - Utils.RegisterSkill("Flash", "Losowa prędkośc postaci na początku rundy", "#A31912", false); - - Instance.RegisterEventHandler((@event, info) => - { - Instance.AddTimer(0.1f, () => - { - foreach (var player in Utilities.GetPlayers()) - { - if (!IsPlayerValid(player)) continue; - - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill != "Flash") continue; - - var playerPawn = player.PlayerPawn?.Value; - - if (playerPawn != null) - { - float newSpeed = (float)Instance.Random.NextDouble() * (3.0f - 1.2f) + 1.2f; - newSpeed = (float)Math.Round(newSpeed, 2); - playerPawn.VelocityModifier = newSpeed; - Utilities.SetStateChanged(playerPawn, "CCSPlayerPawn", "m_flVelocityModifier"); - Utils.PrintToChat(player, $"{ChatColors.DarkRed}\"Flash\"{ChatColors.Lime}: Twój mnożnik prędkości to {newSpeed}x", false); - } - } - }); - - return HookResult.Continue; - }); - } - - private static bool IsPlayerValid(CCSPlayerController player) - { - return player != null && player.IsValid && player.PlayerPawn?.Value != null; - } - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Impostor.cs b/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Impostor.cs deleted file mode 100644 index 07091a0..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Impostor.cs +++ /dev/null @@ -1,184 +0,0 @@ -using System.Drawing; -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Modules.Utils; -using static dRandomSkills.dRandomSkills; - -namespace dRandomSkills -{ - public static class Impostor - { - private static readonly List CTModels = new List - { - // SWAT - "characters/models/ctm_swat/ctm_swat_variante.vmdl", - "characters/models/ctm_swat/ctm_swat_variantf.vmdl", - "characters/models/ctm_swat/ctm_swat_varianth.vmdl", - "characters/models/ctm_swat/ctm_swat_varianti.vmdl", - "characters/models/ctm_swat/ctm_swat_variantj.vmdl", - "characters/models/ctm_swat/ctm_swat_variantk.vmdl", - - // ST6 - "characters/models/ctm_st6/ctm_st6_variante.vmdl", - "characters/models/ctm_st6/ctm_st6_variantg.vmdl", - "characters/models/ctm_st6/ctm_st6_varianti.vmdl", - "characters/models/ctm_st6/ctm_st6_variantj.vmdl", - "characters/models/ctm_st6/ctm_st6_variantk.vmdl", - "characters/models/ctm_st6/ctm_st6_variantl.vmdl", - "characters/models/ctm_st6/ctm_st6_variantm.vmdl", - "characters/models/ctm_st6/ctm_st6_variantn.vmdl", - - // SAS - "characters/models/ctm_sas/ctm_sas.vmdl", - "characters/models/ctm_sas/ctm_sas_variantf.vmdl", - "characters/models/ctm_sas/ctm_sas_variantg.vmdl", - - // CTM_HEAVY - "characters/models/ctm_heavy/ctm_heavy.vmdl", - - // GENDARMERIE - "characters/models/ctm_gendarmerie/ctm_gendarmerie_varianta.vmdl", - "characters/models/ctm_gendarmerie/ctm_gendarmerie_variantb.vmdl", - "characters/models/ctm_gendarmerie/ctm_gendarmerie_variantc.vmdl", - "characters/models/ctm_gendarmerie/ctm_gendarmerie_variantd.vmdl", - "characters/models/ctm_gendarmerie/ctm_gendarmerie_variante.vmdl", - - // FBI - "characters/models/ctm_fbi/ctm_fbi.vmdl", - "characters/models/ctm_fbi/ctm_fbi_varianta.vmdl", - "characters/models/ctm_fbi/ctm_fbi_variantb.vmdl", - "characters/models/ctm_fbi/ctm_fbi_variantc.vmdl", - "characters/models/ctm_fbi/ctm_fbi_variantd.vmdl", - "characters/models/ctm_fbi/ctm_fbi_variante.vmdl", - "characters/models/ctm_fbi/ctm_fbi_variantf.vmdl", - "characters/models/ctm_fbi/ctm_fbi_variantg.vmdl", - "characters/models/ctm_fbi/ctm_fbi_varianth.vmdl", - - // DIVER - "characters/models/ctm_diver/ctm_diver_varianta.vmdl", - "characters/models/ctm_diver/ctm_diver_variantb.vmdl", - "characters/models/ctm_diver/ctm_diver_variantc.vmdl", - }; - - - private static readonly List TModels = new List - { - // BALKAN - "characters/models/tm_balkan/tm_balkan_variantf.vmdl", - "characters/models/tm_balkan/tm_balkan_variantg.vmdl", - "characters/models/tm_balkan/tm_balkan_varianth.vmdl", - "characters/models/tm_balkan/tm_balkan_varianti.vmdl", - "characters/models/tm_balkan/tm_balkan_variantj.vmdl", - "characters/models/tm_balkan/tm_balkan_variantk.vmdl", - "characters/models/tm_balkan/tm_balkan_variantl.vmdl", - - // JUMPSUIT - "characters/models/tm_jumpsuit/tm_jumpsuit_varianta.vmdl", - "characters/models/tm_jumpsuit/tm_jumpsuit_variantb.vmdl", - "characters/models/tm_jumpsuit/tm_jumpsuit_variantc.vmdl", - - // JUNGLERAIDER - "characters/models/tm_jungle_raider/tm_jungle_raider_varianta.vmdl", - "characters/models/tm_jungle_raider/tm_jungle_raider_variantb.vmdl", - "characters/models/tm_jungle_raider/tm_jungle_raider_variantb2.vmdl", - "characters/models/tm_jungle_raider/tm_jungle_raider_variantc.vmdl", - "characters/models/tm_jungle_raider/tm_jungle_raider_variantd.vmdl", - "characters/models/tm_jungle_raider/tm_jungle_raider_variante.vmdl", - "characters/models/tm_jungle_raider/tm_jungle_raider_variantf.vmdl", - "characters/models/tm_jungle_raider/tm_jungle_raider_variantf2.vmdl", - - // LEET - "characters/models/tm_leet/tm_leet_varianta.vmdl", - "characters/models/tm_leet/tm_leet_variantb.vmdl", - "characters/models/tm_leet/tm_leet_variantc.vmdl", - "characters/models/tm_leet/tm_leet_variantd.vmdl", - "characters/models/tm_leet/tm_leet_variante.vmdl", - "characters/models/tm_leet/tm_leet_variantf.vmdl", - "characters/models/tm_leet/tm_leet_variantg.vmdl", - "characters/models/tm_leet/tm_leet_varianth.vmdl", - "characters/models/tm_leet/tm_leet_varianti.vmdl", - "characters/models/tm_leet/tm_leet_variantj.vmdl", - "characters/models/tm_leet/tm_leet_variantk.vmdl", - - // PHOENIX - "characters/models/tm_phoenix/tm_phoenix.vmdl", - "characters/models/tm_phoenix/tm_phoenix_varianta.vmdl", - "characters/models/tm_phoenix/tm_phoenix_variantb.vmdl", - "characters/models/tm_phoenix/tm_phoenix_variantc.vmdl", - "characters/models/tm_phoenix/tm_phoenix_variantd.vmdl", - "characters/models/tm_phoenix/tm_phoenix_variantf.vmdl", - "characters/models/tm_phoenix/tm_phoenix_variantg.vmdl", - "characters/models/tm_phoenix/tm_phoenix_varianth.vmdl", - "characters/models/tm_phoenix/tm_phoenix_varianti.vmdl", - - // PHOENIX HEAVY - "characters/models/tm_phoenix_heavy/tm_phoenix_heavy.vmdl", - - // PROFESSIONAL - "characters/models/tm_professional/tm_professional_varf.vmdl", - "characters/models/tm_professional/tm_professional_varf1.vmdl", - "characters/models/tm_professional/tm_professional_varf2.vmdl", - "characters/models/tm_professional/tm_professional_varf3.vmdl", - "characters/models/tm_professional/tm_professional_varf4.vmdl", - "characters/models/tm_professional/tm_professional_varf5.vmdl", - "characters/models/tm_professional/tm_professional_varg.vmdl", - "characters/models/tm_professional/tm_professional_varh.vmdl", - "characters/models/tm_professional/tm_professional_vari.vmdl", - "characters/models/tm_professional/tm_professional_varj.vmdl", - }; - - - public static void LoadImpostor() - { - Utils.RegisterSkill("Impostor", "Otrzymujesz na start rundy model postaci wroga", "#99140B"); - - Instance.RegisterEventHandler((@event, info) => - { - Instance.AddTimer(0.1f, () => - { - foreach (var player in Utilities.GetPlayers()) - { - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Impostor") - { - string model = player.Team == CsTeam.Terrorist - ? GetRandomModel(CTModels) - : player.Team == CsTeam.CounterTerrorist - ? GetRandomModel(TModels) - : null; - - if (model != null) - { - SetPlayerModel(player, model); - } - } - } - }); - - return HookResult.Continue; - }); - } - - private static string GetRandomModel(List models) - { - if (models == null || models.Count == 0) return null; - var random = new Random(); - int index = random.Next(models.Count); - return models[index]; - } - - private static void SetPlayerModel(CCSPlayerController player, string model) - { - var pawn = player.PlayerPawn?.Value; - if (pawn == null) return; - - Server.NextFrame(() => - { - pawn.SetModel(model); - - var originalRender = pawn.Render; - pawn.Render = Color.FromArgb(255, originalRender.R, originalRender.G, originalRender.B); - }); - } - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Medyk.cs b/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Medyk.cs deleted file mode 100644 index 8c037d3..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Medyk.cs +++ /dev/null @@ -1,50 +0,0 @@ -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; -using static dRandomSkills.dRandomSkills; - -namespace dRandomSkills -{ - public static class Medyk - { - public static void LoadMedyk() - { - Utils.RegisterSkill("Medyk", "Otrzymujesz losową ilość apteczek na start rundy", "#42FF5F"); - - Instance.RegisterEventHandler((@event, info) => - { - Instance.AddTimer(0.1f, () => - { - foreach (var player in Utilities.GetPlayers()) - { - if (!IsPlayerValid(player)) continue; - player.RemoveItemByDesignerName("weapon_healthshot"); - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill != "Medyk") continue; - - int healthshot = Instance.Random.Next(1, 10); - for (int i = 0; i < healthshot; i++) - player.GiveNamedItem("weapon_healthshot"); - } - }); - - return HookResult.Continue; - }); - - Instance.RegisterEventHandler((@event, info) => - { - foreach (var player in Utilities.GetPlayers()) - { - if (!IsPlayerValid(player)) return HookResult.Continue; - player.RemoveItemByDesignerName("weapon_healthshot"); - } - - return HookResult.Continue; - }); - } - - private static bool IsPlayerValid(CCSPlayerController player) - { - return player != null && player.IsValid && player.PlayerPawn?.Value != null; - } - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/MiniMajk.cs b/[ D3X ] dRandomSkills - SRC Files/src/player/skills/MiniMajk.cs deleted file mode 100644 index 3462b0e..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/MiniMajk.cs +++ /dev/null @@ -1,58 +0,0 @@ -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Modules.Utils; -using static dRandomSkills.dRandomSkills; - -namespace dRandomSkills -{ - public static class MiniMajk - { - public static void LoadMiniMajk() - { - string defaultCT = "characters/models/ctm_sas/ctm_sas.vmdl"; - string defaultTT = "characters/models/tm_phoenix/tm_phoenix.vmdl"; - Utils.RegisterSkill("MiniMajk", "Losowa wielkość postaci na początku rundy", "#ffff00", false); - - Instance.RegisterEventHandler((@event, info) => - { - Instance.AddTimer(0.1f, () => - { - foreach (var player in Utilities.GetPlayers()) - { - if (!IsPlayerValid(player)) continue; - - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill != "MiniMajk") continue; - - var playerPawn = player.PlayerPawn?.Value; - - if (playerPawn != null) - { - float newSize = (float)Instance.Random.NextDouble() * (.95f - .6f) + .6f; - newSize = (float)Math.Round(newSize, 2); - - playerPawn.CBodyComponent.SceneNode.GetSkeletonInstance().Scale = newSize; - playerPawn.SetModel(player.Team == CsTeam.CounterTerrorist ? defaultTT : defaultCT); - playerPawn.CBodyComponent.SceneNode.GetSkeletonInstance().Scale = newSize; - playerPawn.SetModel(player.Team == CsTeam.CounterTerrorist ? defaultCT : defaultTT); - - Utils.PrintToChat(player, $"{ChatColors.DarkRed}\"MiniMajk\"{ChatColors.Lime}: Twój mnożnik wielkości to {newSize}x", false); - - Instance.AddTimer(.2f, () => { - if (IsPlayerValid(player)) - playerPawn.CBodyComponent.SceneNode.GetSkeletonInstance().Scale = 1; - }); - } - } - }); - - return HookResult.Continue; - }); - } - - private static bool IsPlayerValid(CCSPlayerController player) - { - return player != null && player.IsValid && player.PlayerPawn?.Value != null; - } - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/ObrotWroga.cs b/[ D3X ] dRandomSkills - SRC Files/src/player/skills/ObrotWroga.cs deleted file mode 100644 index c43e3e0..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/ObrotWroga.cs +++ /dev/null @@ -1,79 +0,0 @@ -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Modules.Utils; -using static dRandomSkills.dRandomSkills; - -namespace dRandomSkills -{ - public static class ObrotWroga - { - public static void LoadObrotWroga() - { - Utils.RegisterSkill("Obrót Wroga", "Masz losową szanse na obrócenie wroga o 180 stopni po trafieniu", "#00FF00", false); - - Instance.RegisterEventHandler((@event, info) => - { - Instance.AddTimer(0.1f, () => - { - foreach (var player in Utilities.GetPlayers()) - { - if (!IsPlayerValid(player)) continue; - - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill != "Obrót Wroga") continue; - - float newChance = (float)Instance.Random.NextDouble() * (.40f - .20f) + .20f; - playerInfo.SkillChance = newChance; - newChance = (float)Math.Round(newChance, 2) * 100; - newChance = (float)Math.Round(newChance); - - Utils.PrintToChat(player, $"{ChatColors.DarkRed}\"Obrót Wroga\"{ChatColors.Lime}: Twoje szanse na obrucenie wroga po trafieniu to: {newChance}%", false); - } - }); - - return HookResult.Continue; - }); - - Instance.RegisterEventHandler((@event, info) => - { - var attacker = @event.Attacker; - var victim = @event.Userid; - - if (!IsPlayerValid(attacker) || !IsPlayerValid(victim) || attacker == victim) - return HookResult.Continue; - - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); - - if (playerInfo?.Skill == "Obrót Wroga" && victim.PawnIsAlive) - { - if (Instance.Random.NextDouble() <= playerInfo.SkillChance) - RotateEnemy(victim); - } - - return HookResult.Continue; - }); - } - - private static bool IsPlayerValid(CCSPlayerController player) - { - return player != null && player.IsValid && player.PlayerPawn?.Value != null; - } - - private static void RotateEnemy(CCSPlayerController player) - { - if (player.PlayerPawn.Value.LifeState != (int)LifeState_t.LIFE_ALIVE) - return; - - var currentPosition = player.PlayerPawn.Value.AbsOrigin; - var currentAngles = player.PlayerPawn.Value.EyeAngles; - - QAngle newAngles = new QAngle( - currentAngles.X, - currentAngles.Y + 180, - currentAngles.Z - ); - - player.PlayerPawn.Value.Teleport(currentPosition, newAngles, new Vector(0, 0, 0)); - } - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Phoenix.cs b/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Phoenix.cs deleted file mode 100644 index 4dc7893..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Phoenix.cs +++ /dev/null @@ -1,63 +0,0 @@ -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Modules.Utils; -using static dRandomSkills.dRandomSkills; - -namespace dRandomSkills -{ - public static class Phoenix - { - public static void LoadPhoenix() - { - Utils.RegisterSkill("Phoenix", "Masz losową szans na odrodzenie się po śmierci", "#ff5C0A", false); - - Instance.RegisterEventHandler((@event, info) => - { - Instance.AddTimer(0.1f, () => - { - foreach (var player in Utilities.GetPlayers()) - { - if (!IsPlayerValid(player)) continue; - - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill != "Phoenix") continue; - - float newChance = (float)Instance.Random.NextDouble() * (.40f - .20f) + .20f; - playerInfo.SkillChance = newChance; - newChance = (float)Math.Round(newChance, 2) * 100; - newChance = (float)Math.Round(newChance); - - Utils.PrintToChat(player, $"{ChatColors.DarkRed}\"Phoenix\"{ChatColors.Lime}: Twoje szanse na odrodzenie się po śmierci: {newChance}%", false); - } - }); - - return HookResult.Continue; - }); - - Instance.RegisterEventHandler((@event, info) => - { - var player = @event.Userid; - - if (!IsPlayerValid(player)) return HookResult.Continue; - - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Phoenix") - { - if (Instance.Random.NextDouble() <= playerInfo.SkillChance) - { - player.Respawn(); - Instance.AddTimer(.2f, () => player.Respawn()); - Utils.PrintToChat(player, $"Zostałeś odrodzony z popiołów dzięki mocy: {ChatColors.DarkRed}Phoenix", false); - } - } - - return HookResult.Continue; - }); - } - - private static bool IsPlayerValid(CCSPlayerController player) - { - return player != null && player.IsValid; - } - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Rambo.cs b/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Rambo.cs deleted file mode 100644 index a812d84..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Rambo.cs +++ /dev/null @@ -1,50 +0,0 @@ -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Modules.Utils; -using static dRandomSkills.dRandomSkills; - -namespace dRandomSkills -{ - public static class Rambo - { - public static void LoadRambo() - { - Utils.RegisterSkill("Rambo", "Otrzymujesz losową ilość zdrowia na start rundy", "#009905"); - - Instance.RegisterEventHandler((@event, info) => - { - Instance.AddTimer(0.1f, () => - { - foreach (var player in Utilities.GetPlayers()) - { - if (!IsValidPlayer(player)) continue; - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Rambo") - { - int healthBonus = Instance.Random.Next(50, 501); - AddHealth(player, healthBonus); - } - } - }); - return HookResult.Continue; - }); - } - - private static bool IsValidPlayer(CCSPlayerController player) - { - return player != null && player.IsValid; - } - - public static void AddHealth(CCSPlayerController player, int health) - { - var pawn = player.PlayerPawn?.Value; - if (pawn == null) return; - - pawn.MaxHealth = Math.Min(pawn.Health + health, 1000); - Utilities.SetStateChanged(pawn, "CBaseEntity", "m_iMaxHealth"); - - pawn.Health = pawn.MaxHealth; - Utilities.SetStateChanged(pawn, "CBaseEntity", "m_iHealth"); - } - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Saper.cs b/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Saper.cs deleted file mode 100644 index eb62e59..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Saper.cs +++ /dev/null @@ -1,68 +0,0 @@ -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; -using static dRandomSkills.dRandomSkills; - -namespace dRandomSkills -{ - public static class Saper - { - public static void LoadEliminator() - { - Utils.RegisterSkill("Saper", "Możesz szybciej podłożyć bombę oraz ją zdefować", "#8A2BE2"); - - Instance.RegisterEventHandler((@event, info) => - { - foreach (var player in Utilities.GetPlayers()) - { - if (!IsPlayerValid(player)) return HookResult.Continue; - - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Saper") - { - var bombEntities = Utilities.FindAllEntitiesByDesignerName("weapon_c4").ToList(); - - if (bombEntities.Any()) - { - var bomb = bombEntities.FirstOrDefault(); - if (bomb != null) - { - bomb.BombPlacedAnimation = false; - bomb.ArmedTime = 0.0f; - } - } - } - } - - return HookResult.Continue; - }); - - Instance.RegisterEventHandler((@event, info) => - { - var player = @event.Userid; - - if (IsPlayerValid(player)) - { - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Saper") - { - var plantedBomb = Utilities.FindAllEntitiesByDesignerName("planted_c4").FirstOrDefault(); - if (plantedBomb != null) - { - Server.NextFrame(() => - { - plantedBomb.DefuseCountDown = 0; - }); - } - } - } - - return HookResult.Continue; - }); - } - - private static bool IsPlayerValid(CCSPlayerController player) - { - return player != null && player.IsValid && player.PlayerPawn?.Value != null; - } - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/ZamianaMiejsc.cs b/[ D3X ] dRandomSkills - SRC Files/src/player/skills/ZamianaMiejsc.cs deleted file mode 100644 index 79a4b8b..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/ZamianaMiejsc.cs +++ /dev/null @@ -1,164 +0,0 @@ -using CounterStrikeSharp.API; -using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Modules.Utils; -using static CounterStrikeSharp.API.Core.Listeners; -using static dRandomSkills.dRandomSkills; - -namespace dRandomSkills -{ - public static class ZamianaMiejsc - { - private static float timerCooldown = 30f; - private static readonly Dictionary SkillPlayerInfo = new Dictionary(); - public static void LoadZamianaMiejsc() - { - Utils.RegisterSkill("ZamianaMiejsc", "Zamiana miejscami z losowym wrogiem. Kliknij [USE - E], cooldown 30s!", "#1466F5"); - - Instance.RegisterEventHandler((@event, info) => - { - Instance.RegisterListener(CheckHandle); - Instance.AddTimer(0.1f, () => - { - foreach (var player in Utilities.GetPlayers()) - { - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "ZamianaMiejsc") - { - SkillPlayerInfo[player.SteamID] = new ZamianaMiejsc_PlayerInfo - { - SteamID = player.SteamID, - CanUse = true, - Cooldown = DateTime.MinValue - }; - } - } - }); - - return HookResult.Continue; - }); - - Instance.RegisterEventHandler((@event, info) => - { - Instance.RemoveListener(CheckHandle); - SkillPlayerInfo.Clear(); - return HookResult.Continue; - }); - - Instance.RegisterEventHandler((@event, info) => - { - var player = @event.Userid; - - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "ZamianaMiejsc") - if (SkillPlayerInfo.ContainsKey(player.SteamID)) - SkillPlayerInfo.Remove(player.SteamID); - - return HookResult.Continue; - }); - } - - private static void CheckHandle() - { - foreach (var player in Utilities.GetPlayers()) - { - var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "ZamianaMiejsc") - { - Handle(player); - } - } - } - - private static void Handle(CCSPlayerController player) - { - var buttons = player.Buttons; - if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) - { - if (buttons.HasFlag(PlayerButtons.Use)) - { - if (skillInfo.CanUse) - UseSkill(player, skillInfo); - else - UpdateHUD(player, skillInfo); - } - } - } - - private static void UpdateHUD(CCSPlayerController player, ZamianaMiejsc_PlayerInfo skillInfo = null) - { - float cooldown = 0; - if (skillInfo != null) - { - float time = (float)((skillInfo.Cooldown.Second + timerCooldown) - DateTime.Now.Second); - cooldown = time > 0 ? time : 0; - } - - string infoLine = $"ZamianaMiejsc:
"; - string remainingLine = skillInfo == null ? "Nie znaleziono przeciwnika
" : $"Musisz poczekać jeszcze {cooldown} sekund
"; - - var hudContent = infoLine + remainingLine; - player.PrintToCenterHtml(hudContent); - } - - private static void ActiveUse(CCSPlayerController player) - { - if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) - { - skillInfo.CanUse = true; - } - } - - private static void UseSkill(CCSPlayerController player, ZamianaMiejsc_PlayerInfo skillInfo) - { - var playerPawn = player.PlayerPawn.Value; - if (playerPawn?.CBodyComponent == null) return; - - List enemy = Utilities.GetPlayers().FindAll(p => IsPlayerValid(p) && p.Team != player.Team && p.PawnIsAlive); - if (enemy.Count == 0) - { - UpdateHUD(player); - return; - } - - CCSPlayerController randomEnemy = enemy[Instance.Random.Next(0, enemy.Count)]; - if (player.IsValid && player.PawnIsAlive && randomEnemy.IsValid && randomEnemy.PawnIsAlive) - { - skillInfo.CanUse = false; - skillInfo.Cooldown = DateTime.Now; - Instance.AddTimer(timerCooldown, () => ActiveUse(player)); - TeleportPlayers(player, randomEnemy); - } - else - UpdateHUD(player); - } - - private static void TeleportPlayers(CCSPlayerController attacker, CCSPlayerController victim) - { - var attackerPawn = attacker.PlayerPawn.Value; - var victimPawn = victim.PlayerPawn.Value; - - Vector attackerPosition = new Vector(attackerPawn.AbsOrigin.X, attackerPawn.AbsOrigin.Y, attackerPawn.AbsOrigin.Z); - QAngle attackerAngles = new QAngle(attackerPawn.AbsRotation.X, attackerPawn.AbsRotation.Y, attackerPawn.AbsRotation.Z); - Vector attackerVelocity = new Vector(attackerPawn.AbsVelocity.X, attackerPawn.AbsVelocity.Y, attackerPawn.AbsVelocity.Z); - - Vector victimPosition = new Vector(victimPawn.AbsOrigin.X, victimPawn.AbsOrigin.Y, victimPawn.AbsOrigin.Z); - QAngle victimAngles = new QAngle(victimPawn.AbsRotation.X, victimPawn.AbsRotation.Y, victimPawn.AbsRotation.Z); - Vector victimVelocity = new Vector(victimPawn.AbsVelocity.X, victimPawn.AbsVelocity.Y, victimPawn.AbsVelocity.Z); - - victimPawn.Teleport(attackerPosition, attackerAngles, attackerVelocity); - attackerPawn.Teleport(victimPosition, victimAngles, victimVelocity); - } - - private static bool IsPlayerValid(CCSPlayerController player) - { - return player != null && player.IsValid && player.PlayerPawn?.Value != null; - } - - public class ZamianaMiejsc_PlayerInfo - { - public ulong SteamID { get; set; } - public bool CanUse { get; set; } - public DateTime Cooldown { get; set; } - } - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/utils/Config.cs b/[ D3X ] dRandomSkills - SRC Files/src/utils/Config.cs deleted file mode 100644 index 33a5b7d..0000000 --- a/[ D3X ] dRandomSkills - SRC Files/src/utils/Config.cs +++ /dev/null @@ -1,81 +0,0 @@ -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using static dRandomSkills.dRandomSkills; - -namespace dRandomSkills -{ - public static class Config - { - private static readonly string configPath = Path.Combine(Instance.ModuleDirectory, "Config.json"); - public static ConfigModel config; - private static FileSystemWatcher fileWatcher; - - public static ConfigModel LoadedConfig => config; - - public static void Initialize() - { - config = LoadConfig(); - SetupFileWatcher(); - } - - private static ConfigModel LoadConfig() - { - if (!File.Exists(configPath)) - { - Instance.Logger.LogInformation("Plik konfiguracyjny nie istnieje. Tworzenie nowego pliku konfiguracyjnego..."); - var defaultConfig = new ConfigModel(); - SaveConfig(defaultConfig); - return defaultConfig; - } - - try - { - string json = File.ReadAllText(configPath); - return JsonConvert.DeserializeObject(json) ?? new ConfigModel(); - } - catch (Exception ex) - { - Instance.Logger.LogError($"Błąd podczas wczytywania pliku konfiguracyjnego."); - return new ConfigModel(); - } - } - - public static void SaveConfig(ConfigModel config) - { - try - { - string json = JsonConvert.SerializeObject(config, Formatting.Indented); - File.WriteAllText(configPath, json); - } - catch (Exception ex) - { - Instance.Logger.LogError($"Błąd podczas zapisywania pliku konfiguracyjnego: {ex.Message}"); - } - } - - private static void SetupFileWatcher() - { - fileWatcher = new FileSystemWatcher(Path.GetDirectoryName(configPath)) - { - Filter = Path.GetFileName(configPath), - NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size - }; - - fileWatcher.Changed += (sender, e) => config = LoadConfig(); - fileWatcher.EnableRaisingEvents = true; - } - - public class ConfigModel - { - public Settings Settings { get; set; } = new Settings(); - } - - public class Settings - { - public string Set_Skill { get; set; } = "ustawskill, setskill"; - public string SkillsList_Menu { get; set; } = "supermoc, skille, listamocy, supermoce, losowemoce"; - public bool KillerSkillInfo { get; set; } = true; - public bool TeamMateSkillInfo { get; set; } = true; - } - } -} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - Server Files/plugins/dRandomSkills/Config.json b/[ D3X ] dRandomSkills - Server Files/plugins/dRandomSkills/Config.json deleted file mode 100644 index 52841ab..0000000 --- a/[ D3X ] dRandomSkills - Server Files/plugins/dRandomSkills/Config.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Settings": { - "Set_Skill": "ustawskill, setskill", - "SkillsList_Menu": "supermoc, skille, listamocy, supermoce, losowemoce", - "KillerSkillInfo": true, - "TeamMateSkillInfo": true - } -} diff --git a/[ D3X ] dRandomSkills - Server Files/plugins/dRandomSkills/dRandomSkills.dll b/[ D3X ] dRandomSkills - Server Files/plugins/dRandomSkills/dRandomSkills.dll deleted file mode 100644 index 7e98c3f7d1aebf403d0a6537515ed4c78f911225..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87552 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�Iz(mt+Z+O| z6mfhNbYz(Sfw}MS@+VRq6tP4iMH2Wf3%<|G4|w?@FaIkj?KsGGcJMM7!uEx!{VaGt zFHhjI{ti>ec{#(&$9XC7QsL!V*zBP&budgl&MLpoP%8|t2>C5ueutMY^YTSrzQqd% z)%nw~`9zqSWC1ze`Ab}G7+&`BlIKM_`!a;Wfpa6TvWRQ22#{3nd3b1={3(b`Za{p~ zK;Uc#d*PebKMNb#4?S`EWerHl*@>LWP&&T@__E=OWiK$mq`|NOX-06bzcXNIROwwM z#?tIn$!54|?}x>v4)2nI=N{dHuq!0yje3n7cS^?wtj-;AZ-ilyI< zrN54}Agl(hz8jTdVHINQVAcc7o&B-&L$UP1So(3KF&{9Fy3l#r66j3CDotu7%)G={ zH}Yu=>;7EF-I2lUW**aJV+pmwv+j zI?K~njt?WgpU>_+&0m4zPjA`x>+&`08MeryM$R$2lP@YayByOizX)c`0EmnZkMN%{ zhaEF4nGYU0GEzFUR4Td0o;op7^o}1ra_q2IbQg~wJw7txp70JAM-Lx4dI)WRo}JwJ z(PFdtp@xrlEt}oaYZ_7h?ci6hV^Vm9qGRyxVEkla1HY8zH=22WDc`~`$u;v=%dM4s zL*I5@%2(yryqbBp;pJ<7E8lF_>wW{j%aAYE@~xF}GmrN!^9|`lu!bL@$QSMJEDVF# zUdP;%{9Q2I-#`aYge(5QSpDmF40IbE1pquj52e#%jyc@@%KYJZAMbV_#*55-yfk}_ zKYCZfi>~DdFiy40m6F%Uj2;UZc|eh+`Lbj5beFzk8$Z$H3CGpNkSe;;PpV7^d1Jne z+`s+TKl(#<^0W9e4xOPgS^E4X6MG|KJ&T%wtn<) zePQ}v{MoM^{MtYK^^X%<;lr2sOL)yoGleUMF5wO6t1Z8N>B5ZHda{aF?_YW;KYsY* z`Iqwvxz9hDpPMb@`SSqHOa9_3XosKmyHxX9(2`4us>AitqM180cIfC+#?t>$Kp$hA zeC6KOuYINQo2~I5{-l$sMB{sy>3nPevE<%ZJwrWcj8`gC=q-Mc4D;uC@i{CnEpEX|1Sp|nb`Yqz92aUwW6@68{n*W2A_|wLzl!{5dz)n!3_{|!OY>d#|6Wa zrgL~j>a;nB{3NcYk>=l9JAU-PRr3Nl)$fl;sm8l;l_q!`9|u_Z#;en~{lRk^JP*sW zCH#B8M9K4VE10*p^+cRLbt4tb7kB&?kUHoSPh;?uF@Cmh1Ey0Iee@?-aqmrt?>c1OFGi;xMKF diff --git a/[ D3X ] dRandomSkills - SRC Files/Properties/Resources.Designer.cs b/jRandomSkills - SRC Files/Properties/Resources.Designer.cs similarity index 96% rename from [ D3X ] dRandomSkills - SRC Files/Properties/Resources.Designer.cs rename to jRandomSkills - SRC Files/Properties/Resources.Designer.cs index 3631cab..90c5831 100644 --- a/[ D3X ] dRandomSkills - SRC Files/Properties/Resources.Designer.cs +++ b/jRandomSkills - SRC Files/Properties/Resources.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace dRandomSkills.Properties { +namespace jRandomSkills.Properties { using System; @@ -39,7 +39,7 @@ namespace dRandomSkills.Properties { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("dRandomSkills.Properties.Resources", typeof(Resources).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("jRandomSkills.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; diff --git a/[ D3X ] dRandomSkills - SRC Files/Properties/Resources.resx b/jRandomSkills - SRC Files/Properties/Resources.resx similarity index 100% rename from [ D3X ] dRandomSkills - SRC Files/Properties/Resources.resx rename to jRandomSkills - SRC Files/Properties/Resources.resx diff --git a/[ D3X ] dRandomSkills - SRC Files/Properties/launchSettings.json b/jRandomSkills - SRC Files/Properties/launchSettings.json similarity index 79% rename from [ D3X ] dRandomSkills - SRC Files/Properties/launchSettings.json rename to jRandomSkills - SRC Files/Properties/launchSettings.json index a7c25d0..36db3cc 100644 --- a/[ D3X ] dRandomSkills - SRC Files/Properties/launchSettings.json +++ b/jRandomSkills - SRC Files/Properties/launchSettings.json @@ -1,6 +1,6 @@ { "profiles": { - "dRandomSkills": { + "jRandomSkills": { "commandName": "Project", "nativeDebugging": true } diff --git a/[ D3X ] dRandomSkills - SRC Files/dRandomSkills.csproj b/jRandomSkills - SRC Files/jRandomSkills.csproj similarity index 89% rename from [ D3X ] dRandomSkills - SRC Files/dRandomSkills.csproj rename to jRandomSkills - SRC Files/jRandomSkills.csproj index 22d8ee0..58a46bd 100644 --- a/[ D3X ] dRandomSkills - SRC Files/dRandomSkills.csproj +++ b/jRandomSkills - SRC Files/jRandomSkills.csproj @@ -6,6 +6,10 @@ enable + + + + diff --git a/[ D3X ] dRandomSkills - SRC Files/dRandomSkills.sln b/jRandomSkills - SRC Files/jRandomSkills.sln similarity index 88% rename from [ D3X ] dRandomSkills - SRC Files/dRandomSkills.sln rename to jRandomSkills - SRC Files/jRandomSkills.sln index 92c07f8..ee66e2c 100644 --- a/[ D3X ] dRandomSkills - SRC Files/dRandomSkills.sln +++ b/jRandomSkills - SRC Files/jRandomSkills.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.9.34728.123 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dRandomSkills", "dRandomSkills.csproj", "{1412DD25-558C-425A-A7F6-347C970136E5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "jRandomSkills", "jRandomSkills.csproj", "{1412DD25-558C-425A-A7F6-347C970136E5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/[ D3X ] dRandomSkills - SRC Files/src/command/Command.cs b/jRandomSkills - SRC Files/src/command/Command.cs similarity index 53% rename from [ D3X ] dRandomSkills - SRC Files/src/command/Command.cs rename to jRandomSkills - SRC Files/src/command/Command.cs index 4aea72f..6b8757b 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/command/Command.cs +++ b/jRandomSkills - SRC Files/src/command/Command.cs @@ -1,10 +1,12 @@ +using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Admin; using CounterStrikeSharp.API.Modules.Commands; using CounterStrikeSharp.API.Modules.Utils; -using static dRandomSkills.dRandomSkills; +using jRandomSkills.src.utils; +using static jRandomSkills.jRandomSkills; -namespace dRandomSkills +namespace jRandomSkills { public static class Command { @@ -26,6 +28,10 @@ namespace dRandomSkills Instance.AddCommand($"css_{command}", commandPair.Value.description, commandPair.Value.handler); } } + + Instance.AddCommand($"css_map", "", Command_ChangeMap); + Instance.AddCommand($"css_console", "", Command_CustomCommand); + Instance.AddCommand($"css_start", "", Command_StartGame); } private static IEnumerable SplitCommands(string commands) @@ -49,29 +55,21 @@ namespace dRandomSkills (List players, string targetname) = FindTarget.Find(command, 2, false, true); - if (command.ArgCount < 1) - { - player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――"); - Utils.PrintToChat(player, $"Poprawne użycie: {ChatColors.DarkRed}!setskill ", true); - player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――"); - return; - } - if (command.ArgCount < 2) { player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――"); - Utils.PrintToChat(player, $"Poprawne użycie: {ChatColors.DarkRed}!setskill ", true); + Utils.PrintToChat(player, Localization.GetTranslation("correct_form_setskill"), true); player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――"); return; } - var skillName = command.GetArg(2); - var skill = SkillData.Skills.FirstOrDefault(s => s.Name.Equals(skillName, StringComparison.OrdinalIgnoreCase)); + var skillName = command.ArgCount > 3 ? $"{command.GetArg(2)} {command.GetArg(3)}" : command.GetArg(2); + var skill = SkillData.Skills.FirstOrDefault(s => s.Name.Equals(skillName, StringComparison.OrdinalIgnoreCase) || s.Skill.ToString().Equals(skillName, StringComparison.OrdinalIgnoreCase)); if (skill == null) { player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――"); - Utils.PrintToChat(player, $"Nie znaleziono takiej {ChatColors.DarkRed}supermocy", true); + Utils.PrintToChat(player, Localization.GetTranslation("skill_not_found_setskill"), true); player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――"); return; } @@ -81,19 +79,23 @@ namespace dRandomSkills var skillPlayer = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == target.SteamID); if (skillPlayer != null) { - skillPlayer.Skill = skill.Name; + + Instance.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", new object[] { target }); + skillPlayer.Skill = skill.Skill; + Instance.SkillAction(skill.Skill.ToString(), "EnableSkill", new object[] { target }); + player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――"); - Utils.PrintToChat(player, $"Ustawiono Supermoc: {ChatColors.LightRed}{skill.Name} {ChatColors.Lime}dla {ChatColors.LightRed}{target.PlayerName}", false); + Utils.PrintToChat(player, $"{Localization.GetTranslation("done_setskill")}: {ChatColors.LightRed}{skill.Name} {ChatColors.Lime}{Localization.GetTranslation("for_setskill")} {ChatColors.LightRed}{target.PlayerName}", false); player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――"); } else { player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――"); - Utils.PrintToChat(player, $"Nie udało się ustawić {ChatColors.DarkRed}supermocy", true); + Utils.PrintToChat(player, Localization.GetTranslation("error_setskill"), true); player.PrintToChat($" {ChatColors.Green}―――――――――――{ChatColors.DarkRed}◥◣◆◢◤{ChatColors.Green}―――――――――――"); } } - + } [CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)] @@ -102,5 +104,57 @@ namespace dRandomSkills if (player == null) return; Menu.DisplaySkillsList(player); } + + [RequiresPermissions("@css/root")] + [CommandHelper(minArgs: 1, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)] + public static void Command_ChangeMap(CCSPlayerController? player, CommandInfo command) + { + if (player == null) return; + string map = command.GetArg(1); + + if (string.IsNullOrEmpty(map)) + { + command.ReplyToCommand($" {ChatColors.Red}{Localization.GetTranslation("invalid_map")}"); + return; + } + + Server.PrintToChatAll($" {ChatColors.Yellow}{Localization.GetTranslation("loading_map")} ({ChatColors.Green}{map}{ChatColors.Yellow})..."); + + if (uint.TryParse(map, out _)) + Server.ExecuteCommand($"host_workshop_map {map}"); + else if (!Server.IsMapValid(map)) + command.ReplyToCommand($" {ChatColors.Red}{Localization.GetTranslation("invalid_map")}"); + else + Server.ExecuteCommand($"changelevel {map}"); + } + + [RequiresPermissions("@css/root")] + [CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)] + public static void Command_StartGame(CCSPlayerController? player, CommandInfo command) + { + if (player == null) return; + int cheats = command.GetArg(1) == "sv" ? 1 : 0; + + Server.ExecuteCommand($"mp_freezetime {(cheats == 1 ? 0 : 5)}"); + Server.ExecuteCommand("mp_warmup_end"); + Server.ExecuteCommand("mp_restartgame 1"); + + Instance.AddTimer(2.0f, () => { + Server.PrintToChatAll($" {ChatColors.Green}{Localization.GetTranslation("game_start")}"); + Server.ExecuteCommand("mp_forcecamera 0"); + Server.ExecuteCommand($"mp_freezetime {(cheats == 1 ? 0 : 5)}"); + Server.ExecuteCommand("mp_overtime_enable 1"); + Server.ExecuteCommand($"sv_cheats {cheats}"); + }); + } + + [RequiresPermissions("@css/root")] + [CommandHelper(minArgs: 1, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)] + public static void Command_CustomCommand(CCSPlayerController? player, CommandInfo command) + { + if (player == null) return; + string param = command.GetArg(1); + Server.ExecuteCommand(param); + } } } \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/jRandomSkills.cs b/jRandomSkills - SRC Files/src/jRandomSkills.cs new file mode 100644 index 0000000..d6f134e --- /dev/null +++ b/jRandomSkills - SRC Files/src/jRandomSkills.cs @@ -0,0 +1,109 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core.Commands; +using CounterStrikeSharp.API.Modules.Commands; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using System.Reflection; + +namespace jRandomSkills +{ + public partial class jRandomSkills : BasePlugin + { + public static jRandomSkills Instance { get; private set; } + + public List skillPlayer { get; } = new List(); + public Random Random { get; } = new Random(); + + public override string ModuleName => "[CS2] [ jRandomSkills ]"; + public override string ModuleAuthor => "D3X, Juzlus"; + public override string ModuleDescription => "Plugin adds random skills to the server every round for CS2 by D3X. Modified by Juzlus."; + public override string ModuleVersion => "1.0.3"; + + public override void Load(bool hotReload) + { + Instance = this; + + Config.Initialize(); + Localization.Load(); + Event.Load(); + PlayerOnTick.Load(); + Command.Load(); + + foreach (var skill in Enum.GetValues(typeof(Skills))) + SkillAction(skill.ToString(), "LoadSkill"); + } + + internal void SkillAction(string skill, string methodName, object[] param = null) + { + string className = $"jRandomSkills.{skill}"; + Type? type = Type.GetType(className); + + if (type != null && typeof(ISkill).IsAssignableFrom(type)) + { + MethodInfo? method = type.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public); + method?.Invoke(null, param); + } + else + Server.PrintToConsole($"Could not find or load {className}"); + } + + internal void RegisterListener(Action onTick, HookMode pre) + { + throw new NotImplementedException(); + } + + internal void RegisterListener(Action value) + { + throw new NotImplementedException(); + } + + internal void AddCommand(string name, string description, CommandInfo.CommandCallback handler) + { + var definition = new CommandDefinition(name, description, handler); + CommandDefinitions.Add(definition); + CommandManager.RegisterCommand(definition); + } + + internal bool IsPlayerValid(CCSPlayerController player) + { + return player != null && player.IsValid && player.PlayerPawn?.Value != null && player.PlayerPawn.Value.LifeState == (byte)LifeState_t.LIFE_ALIVE; + } + + public uint[] footstepSoundEvents = { 2026488395, 2745524735, 2684452812, 2265091453, 1269567645, 520432428, 3266483468, 1346129716, 2061955732, 2240518199, 2829617974, 1194677450, 1803111098, 3749333696, 29217150, 1692050905, 2207486967, 2633527058, 3342414459, 988265811, 540697918, 1763490157, 3755338324, 3161194970, 3753692454, 3166948458, 3997353267, 3161194970, 3753692454, 3166948458, 3997353267, 809738584, 3368720745, 3295206520, 3184465677, 123085364, 3123711576, 737696412, 1403457606, 1770765328, 892882552, 3023174225, 4163677892, 3952104171, 4082928848, 1019414932, 1485322532, 1161855519, 1557420499, 1163426340, 809738584, 3368720745, 2708661994, 2479376962, 3295206520, 1404198078, 1194093029, 1253503839, 2189706910, 1218015996, 96240187, 1116700262, 84876002, 1598540856, 2231399653 }; + public uint[] silentSoundEvents = { 740474905, 1661204257, 3009312615, 1506215040, 115843229, 3299941720, 1016523349, 2684452812, 2067683805, 2067683805, 1016523349, 4160462271, 1543118744, 585390608, 3802757032, 2302139631, 2546391140, 144629619, 4152012084, 4113422219, 1627020521, 2899365092, 819435812, 3218103073, 961838155, 1535891875, 1826799645, 3460445620, 1818046345, 3666896632, 3099536373, 1440734007, 1409986305, 1939055066, 782454593, 4074593561, 1540837791, 3257325156 }; + } + + public class dSkill_PlayerInfo + { + public required ulong SteamID { get; set; } + public required string PlayerName { get; set; } + public Skills Skill { get; set; } + public float? SkillChance { get; set; } + public bool IsDrawing { get; set; } + } + + public class dSkill_SkillInfo + { + public Skills Skill { get; } + public string Name { get; } + public string Description { get; } + public string Color { get; } + + public bool Display { get; } + + public dSkill_SkillInfo(Skills skill, string color, bool display) + { + Skill = skill; + Name = Localization.GetTranslation(skill.ToString().ToLower()); + Description = Localization.GetTranslation($"{skill.ToString().ToLower()}_desc"); + Color = color; + Display = display; + } + } + + public static class SkillData + { + public static List Skills { get; } = new List(); + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/lang/en.json b/jRandomSkills - SRC Files/src/lang/en.json new file mode 100644 index 0000000..2cebf3d --- /dev/null +++ b/jRandomSkills - SRC Files/src/lang/en.json @@ -0,0 +1,127 @@ +{ + "none_desc": "You have no skills", + "aimbot_desc": "Every bullet you hit counts as a headshot", + "antyflash_desc": "You are immune to flashes, and your flashes last 7 seconds", + "astronaut_desc": "You receive a random gravity value at the start of the round", + "astronaut_desc2": "Your random gravity is: {0}x", + "richboy_desc": "You receive a random amount of money at the start of the round", + "bunnyhop_desc": "You get auto BunnyHop", + "silent_desc": "Your footsteps and jumps are silent to OTHER players", + "shade_desc": "You teleport behind the back of a hit enemy", + "dracula_desc": "Hitting an enemy restores a percentage of the damage dealt as health", + "ghost_desc": "You are completely invisible", + "flash_desc": "Random player speed at the beginning of the round", + "flash_desc2": "Your speed multiplier is {0}x", + "godmode_desc": "You are immortal for 2 seconds. Press [css_useSkill], cooldown 30s", + "godmode_on": "Immortality enabled", + "godmode_off": "Immortality disabled", + "armored_desc": "You have a random damage taken multiplier", + "armored_desc2": "Your damage taken multiplier is: {0}x", + "muhammed_desc": "You explode upon death, killing nearby players", + "dwarf_desc": "Random character size at the start of the round", + "dwarf_desc2": "Your size multiplier is {0}x", + "medic_desc": "You receive a random number of medkits at the start of the round", + "randomweapon_desc": "You get a random weapon. Press [css_useSkill], cooldown 15s", + "chicken_desc": "You get a chicken model + 10% faster movement - 50 HP", + "impostor_desc": "You start the round with an enemy player model", + "catapult_desc": "You have a random chance to launch an enemy upwards", + "catapult_desc2": "Your chance to launch an enemy on hit is: {0}%", + "infiniteammo_desc": "You receive infinite ammo for all your weapons", + "behind_desc": "You have a random chance to turn an enemy 180 degrees on hit", + "behind_desc2": "Your chance to turn an enemy on hit is: {0}%", + "retreat_desc": "Return to spawn. Press [css_useSkill], cooldown 15s", + "oneshot_desc": "Hitting an enemy instantly kills them", + "paweljumper_desc": "You get an extra jump", + "phoenix_desc": "You have a random chance to respawn after death", + "phoenix_desc2": "Your chance to respawn after death: {0}%", + "phoenix_respawn": "You have been resurrected from the ashes thanks to the power of: CHATCOLORS.REDPhoenix", + "pilot_desc": "Fly for a limited time. Hold [USE - E] to fly", + "pilot_hud_info": "Recharging", + "radarhack_desc": "You can see enemies on the radar", + "rambo_desc": "You receive a random amount of health at the start of the round", + "enemyspawn_desc": "Teleport to enemy spawn. Press [css_useSkill], cooldown 15s", + "disarmament_desc": "You have a random chance to make an enemy drop their weapon on hit", + "disarmament_desc2": "Your chance to disarm an enemy is: {0}%", + "planter_desc": "You can plant the bomb anywhere; bomb detonation time is 60s", + "saper_desc": "You can plant and defuse bombs faster", + "timemanipulator_desc": "Slows down time for everyone for 6 seconds. Press [css_useSkill], cooldown 30s", + "quickshot_desc": "No cooldown when shooting", + "teleporter_desc": "You swap places with the hit enemy", + "wallhack_desc": "You can see enemies through walls", + "killer_flash_desc": "Every enemy fully blinded by your flashbang dies (including you)", + "weaponsswap_desc": "Swap weapons with a random enemy. Press [css_useSkill], cooldown 30s", + "weaponsswap_hud_info2": "You have no weapon to swap", + "hud_info_no_enemy": "No enemy found", + "zeus_desc": "Zeus x27 instantly recharges", + "frozendecoy_desc": "Your decoy grenade freezes all nearby players", + "antyhead_desc": "You receive no headshot damage", + "soldier_desc": "You have a random damage multiplier", + "soldier_desc2": "Your damage multiplier is: {0}x", + "swapposition_desc": "Swap places with a random enemy. Press [css_useSkill], cooldown 30s", + + "welcome_message": "Welcome {PLAYER} to {SERVER_NAME}!\nCurrent jRandomSkills version: {VERSION} ({SKILLS_COUNT} skills).\n\nOriginally created by:\n{AUTHOR1}\nModified and improved by:\n{AUTHOR2}", + "hud_info": "Wait {0} seconds", + "no_player": "No player found.", + "duplicate_player": "More than one player found with the same name.", + "drawing_skill": "Drawing a skill", + "your_skill": "Your current skill", + "summary_start": "======SUMMARY=OF=THE=LAST=ROUND======", + "summary_end": "=======================================", + "enemy_skill": "Enemy's skill", + "teammate_skills": "Your teammates' skills", + "observer_skill": "Player's power", + "game_start": "Game started!", + "invalid_map": "Invalid map name!", + "loading_map": "Loading a new map", + "skills_menu": "Skill List", + "correct_form_setskill": "Correct usage: CHATCOLORS.RED!setskill ", + "skill_not_found_setskill": "Skill CHATCOLORS.REDnot found", + "error_setskill": "Failed to set CHATCOLORS.REDskill", + "done_setskill": "Skill set", + "for_setskill": "for", + + "none": "None", + "dwarf": "Dwarf", + "swapposition": "Swapper", + "killerflash": "Deadly Flash", + "soldier": "Soldier", + "armored": "Tank", + "aimbot": "Aimbot", + "retreat": "Retreat", + "enemyspawn": "Enemy Spawn", + "zeus": "Zeus", + "radarhack": "Radar Hack", + "quickshot": "Quick-Shot", + "planter": "Planter", + "silent": "Silent Shadow", + "frozendecoy": "Freezing Decoy", + "timemanipulator": "Time Slow", + "godmode": "God Mode", + "randomweapon": "Random Weapon", + "weaponsswap": "Weapon Swap", + "wallhack": "Wallhack", + "flash": "Flash", + "paweljumper": "Paweł Jumper", + "bunnyhop": "Bunnyhop", + "impostor": "Spy", + "oneshot": "One-Shot", + "muhammed": "Muhammed", + "richboy": "Rich Boy", + "rambo": "Rambo", + "medic": "Medic", + "ghost": "Ghost", + "chicken": "Chicken", + "astronaut": "Astronaut", + "disarmament": "Disarmament", + "antyflash": "Anti-Flash", + "behind": "Enemy Rotation", + "infiniteammo": "Infinite Ammo", + "catapult": "Catapult", + "dracula": "Dracula", + "teleporter": "Teleporter", + "saper": "Saper", + "phoenix": "Phoenix", + "pilot": "Pilot", + "shade": "Shade", + "antyhead": "Anty Head" +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/lang/pl.json b/jRandomSkills - SRC Files/src/lang/pl.json new file mode 100644 index 0000000..ba0cf08 --- /dev/null +++ b/jRandomSkills - SRC Files/src/lang/pl.json @@ -0,0 +1,127 @@ +{ + "none_desc": "Nie posiadasz żadnej supermocy", + "aimbot_desc": "Każdy twój trafiony pocisk jest liczony jako głowa", + "antyflash_desc": "Posiadasz odporność na flashe i 7 sekund trwają twoje flash'e", + "astronaut_desc": "Otrzymujesz losową ilość grawitacji na start rundy", + "astronaut_desc2": "Twoja losowa grawitacja wynosi: {0}x", + "richboy_desc": "Otrzymujesz losową ilość kasy na start rundy", + "bunnyhop_desc": "Otrzymujesz auto BunnyHopa", + "silent_desc": "Twoje kroki i skoki są niesłyszalne dla INNYCH graczy", + "shade_desc": "Teleportujesz się za plecy trafionego wroga", + "dracula_desc": "Po trafieniu ofiary otrzymujesz zwrot zdrowia w postaci danego procentu zadanych obrażeń", + "ghost_desc": "Jesteś całkowicie niewidzialny", + "flash_desc": "Losowa prędkośc postaci na początku rundy", + "flash_desc2": "Twój mnożnik prędkości to {0}x", + "godmode_desc": "Jesteś nieśmiertelny przez 2 sekundy. Kliknij [css_useSkill], cooldown 30s", + "godmode_on": "Nieśmiertelność włączona", + "godmode_off": "Nieśmiertelność wyłączona", + "armored_desc": "Masz losowy mnożnik otrzymywanych obrażeń", + "armored_desc2": "Twój mnożnik otrzymywanych obrażeń wynosi: {0}x", + "muhammed_desc": "Po śmierci wybucha i zabija graczy w obrębie", + "dwarf_desc": "Losowa wielkość postaci na początku rundy", + "dwarf_desc2": "Twój mnożnik wielkości to {0}x", + "medic_desc": "Otrzymujesz losową ilość apteczek na start rundy", + "randomweapon_desc": "Dostajesz losową broń. Kliknij [css_useSkill], cooldown 15s", + "chicken_desc": "Otrzymujesz model kurczaka + jesteś o 10% szybszy - 50hp", + "impostor_desc": "Otrzymujesz na start rundy model postaci wroga", + "catapult_desc": "Masz losową szanse na podrzucenie wroga", + "catapult_desc2": "Twoje szanse na podrzucenie wroga po trafieniu to: {0}%", + "infiniteammo_desc": "Otrzymujesz nieskończoną ilość ammo do wszystkich swoich broni", + "behind_desc": "Masz losową szanse na obrócenie wroga o 180 stopni po trafieniu", + "behind_desc2": "Twoje szanse na obrócenie wroga po trafieniu to: {0}%", + "retreat_desc": "Powrót na spawna. Kliknij [css_useSkill], cooldown 15s", + "oneshot_desc": "Po trafieniu od razu zabija przeciwnika", + "paweljumper_desc": "Otrzymujesz dodatkowy skok", + "phoenix_desc": "Masz losową szans na odrodzenie się po śmierci", + "phoenix_desc2": "Twoje szanse na odrodzenie się po śmierci: {0}%", + "phoenix_respawn": "Zostałeś odrodzony z popiołów dzięki mocy: CHATCOLORS.REDPhoenix", + "pilot_desc": "Latanie przez określony czas. Przytrzymaj [USE - E], aby latać", + "pilot_hud_info": "W trakcie odnawiania", + "radarhack_desc": "Widzisz wrogów na radarze", + "rambo_desc": "Otrzymujesz losową ilość zdrowia na start rundy", + "enemyspawn_desc": "Teleportacja na spawn wroga. Kliknij [css_useSkill], cooldown 15s", + "disarmament_desc": "Masz losową szanse na wyrzucenie broni wroga po trafieniu", + "disarmament_desc2": "Twoje szanse na wyrzucenie broni wroga to: {0}%", + "planter_desc": "Możesz podłożyć bombę w dowolnym miejscu, czas detonacji bomby trwa 60s", + "saper_desc": "Możesz szybciej podłożyć bombę oraz ją zdefować", + "timemanipulator_desc": "Spowolnienie czasu dla wszystkich na 6 sekundy. Kliknij [css_useSkill], cooldown 30s", + "quickshot_desc": "Brak cooldown przy strzelaniu", + "teleporter_desc": "Zamieniasz się miejscami z trafionym wrogiem", + "wallhack_desc": "Widzisz wrogów przez ściany", + "killer_flash_desc": "Każdy całkowicie oślepiony twoim granatem umiera (również ty)", + "weaponsswap_desc": "Zamieniasz się bronią z losowym wrogiem. Kliknij [css_useSkill], cooldown 30s", + "weaponsswap_hud_info2": "Nie posiadasz broni na zamiane", + "hud_info_no_enemy": "Nie znaleziono przeciwnika", + "zeus_desc": "Zeus x27 natychmiastowo się odnawia", + "frozendecoy_desc": "Twój decoy zamraża wszystkich pobliskich graczy", + "antyhead_desc": "Nie otrzymujesz obrażeń w głowę", + "soldier_desc": "Masz losowy mnożnik obrażeń", + "soldier_desc2": "Twój mnożnik obrażeń wynosi: {0}x", + "swapposition_desc": "Zamiana miejscami z losowym wrogiem. Kliknij [css_useSkill], cooldown 30s", + + "welcome_message": "Witaj {PLAYER} na serwerze {SERVER_NAME}!\nAktualna wersja jRandomSkills: {VERSION} ({SKILLS_COUNT} supermocy).\n\nPierwotnie plugin stworzona przez:\n{AUTHOR1}\nZmodyfikowany i ulepszony przez:\n{AUTHOR2}", + "hud_info": "Poczekaj jeszcze {0} sekund", + "no_player": "Nie znaleziono pasującego gracza.", + "duplicate_player": "Znaleziono więcej niż jednego gracza o tej samej nazwie.", + "drawing_skill": "Losowanie mocy", + "your_skill": "Twoja aktualna moc", + "summary_start": "======PODSUMOWANIE=Z=OSTATNIEJ=RUNDY======", + "summary_end": "============================================", + "enemy_skill": "Supermoc przeciwnika", + "teammate_skills": "Supermoce twoich sojuszników", + "observer_skill": "Moc gracza", + "game_start": "Gra rozpoczęta!", + "invalid_map": "Niepoprawnie podano nazwę mapy!", + "loading_map": "Ładowanie nowej mapy", + "skills_menu": "Lista Super Mocy", + "correct_form_setskill": "Poprawne użycie: CHATCOLORS.RED!setskill ", + "skill_not_found_setskill": "Nie znaleziono takiej CHATCOLORS.REDsupermocy", + "error_setskill": "Nie udało się ustawić CHATCOLORS.REDsupermocy", + "done_setskill": "Ustawiono Supermoc", + "for_setskill": "dla", + + "none": "Brak", + "dwarf": "MiniMajk", + "swapoosition": "Zamiana Miejsc", + "killerflash": "Zabójczy Flash", + "soldier": "Żołnierz", + "armored": "Gruby", + "aimbot": "Aimbot", + "retreat": "Odwrót", + "enemyspawn": "Resp Wroga", + "zeus": "Zeus", + "radarhack": "Radarowiec", + "quickshot": "Szybkostrzelność", + "planter": "Samowolka", + "silent": "Cichociemny", + "frozendecoy": "Zamrażający Decoy", + "timemanipulator": "Spowlnienie Czasu", + "godmode": "Nieśmiertelność", + "randomweapon": "Losowa Broń", + "weaponsswap": "Zamiana Broni", + "wallhack": "Wallhack", + "flash": "Flash", + "paweljumper": "Pawel Jumper", + "bunnyhop": "Królik", + "impostor": "Szpieg", + "oneshot": "Jednostrzałowiec", + "muhammed": "Muhammed", + "richboy": "Bogacz", + "rambo": "Rambo", + "medic": "Medyk", + "ghost": "Duszek", + "chicken": "Kurczak", + "astronaut": "Astronauta", + "disarmament": "Rozbrojenie", + "antyflash": "Anty Flash", + "behind": "Obrót Wroga", + "infiniteammo": "Nieskończone Ammo", + "catapult": "Katapulta", + "dracula": "Drakula", + "teleporter": "Teleporter", + "saper": "Saper", + "phoenix": "Phoenix", + "pilot": "Pilot", + "shade": "Cień", + "antyhead": "Żelazna Głowa" +} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/menu/Menu.cs b/jRandomSkills - SRC Files/src/menu/Menu.cs similarity index 87% rename from [ D3X ] dRandomSkills - SRC Files/src/menu/Menu.cs rename to jRandomSkills - SRC Files/src/menu/Menu.cs index 9d4ca2a..31a4133 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/menu/Menu.cs +++ b/jRandomSkills - SRC Files/src/menu/Menu.cs @@ -1,17 +1,17 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Menu; using CounterStrikeSharp.API.Modules.Utils; -using static dRandomSkills.dRandomSkills; -using CounterStrikeSharp.API; +using static jRandomSkills.jRandomSkills; using System.Text.RegularExpressions; +using jRandomSkills.src.utils; -namespace dRandomSkills +namespace jRandomSkills { public static class Menu { public static void DisplaySkillsList(CCSPlayerController player) { - CenterHtmlMenu menu = new($"[ ★ Lista Super Mocy ★ ]"); + CenterHtmlMenu menu = new($"[ ★ {Localization.GetTranslation("skills_menu")} ★ ]"); for (int i = 0; i < SkillData.Skills.Count; i++) { diff --git a/jRandomSkills - SRC Files/src/player/ISkill.cs b/jRandomSkills - SRC Files/src/player/ISkill.cs new file mode 100644 index 0000000..245d8c2 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/ISkill.cs @@ -0,0 +1,66 @@ +using CounterStrikeSharp.API.Core; + +namespace jRandomSkills.src.player; + +public interface ISkill +{ + public static void LoadSkill() { } + public static void EnableSkill(CCSPlayerController player) + { + + } + + public static void DisableSkill(CCSPlayerController player) + { + + } +} + +public enum Skills +{ + None, + Dwarf, + SwapPosition, + FrozenDecoy, + Soldier, + Armored, + Aimbot, + Retreat, + EnemySpawn, + Zeus, + RadarHack, + QuickShot, + Planter, + Silent, + KillerFlash, + TimeManipulator, + GodMode, + RandomWeapon, + WeaponsSwap, + Wallhack, + + Flash, + PawelJumper, + BunnyHop, + Impostor, + OneShot, + Muhammed, + RichBoy, + Rambo, + Medic, + Ghost, + Chicken, + Astronaut, + Disarmament, + AntyFlash, + Behind, + InfiniteAmmo, + Catapult, + Dracula, + Teleporter, + Saper, + Phoenix, + Pilot, + Shade, + AntyHead, +} diff --git a/jRandomSkills - SRC Files/src/player/PlayerEvents.cs b/jRandomSkills - SRC Files/src/player/PlayerEvents.cs new file mode 100644 index 0000000..182cf39 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/PlayerEvents.cs @@ -0,0 +1,199 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Cvars; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using System.Text.RegularExpressions; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public static class Event + { + public static void Load() + { + Instance.RegisterEventHandler((@event, info) => + { + var player = @event.Userid; + + if (player == null || !player.IsValid) return HookResult.Continue; + + Instance.skillPlayer.Add(new dSkill_PlayerInfo + { + SteamID = player.SteamID, + PlayerName = player.PlayerName, + Skill = src.player.Skills.None, + IsDrawing = false, + SkillChance = 1, + }); + + const string defaultWelcomeMsg = "Welcome {PLAYER}, to the {SERVER_NAME} server!\n" + + "The current version of the jRandomSkills: {VERSION} ({SKILLS_COUNT} skills).\n\n" + + "Original plugin created by:\n{AUTHOR1}\n" + + "Modified and improved by:\n{AUTHOR2}"; + string langWelcomeMsg = Localization.GetTranslation("welcome_message", "welcome"); + string welcomeMsg = Regex.IsMatch(langWelcomeMsg, @"\{AUTHOR1\}", RegexOptions.IgnoreCase) && Regex.IsMatch(langWelcomeMsg, @"\{AUTHOR2\}", RegexOptions.IgnoreCase) ? langWelcomeMsg : defaultWelcomeMsg; + + foreach (string line in welcomeMsg.Split("\n")) + player.PrintToChat($" {ChatColors.Green}" + line.Replace("{PLAYER}", $" {ChatColors.Red}{player.PlayerName}{ChatColors.Green}", StringComparison.OrdinalIgnoreCase) + .Replace("{SERVER_NAME}", $" {ChatColors.Red}{ConVar.Find("hostname").StringValue ?? "Default Server"}{ChatColors.Green}", StringComparison.OrdinalIgnoreCase) + .Replace("{VERSION}", $" {ChatColors.Red}v{Instance.ModuleVersion}{ChatColors.Green}", StringComparison.OrdinalIgnoreCase) + .Replace("{SKILLS_COUNT}", $" {ChatColors.Red}{SkillData.Skills.Count - 1}{ChatColors.Green}", StringComparison.OrdinalIgnoreCase) + .Replace("{AUTHOR1}", $" {ChatColors.Red}Jakub Bartosik (D3X){ChatColors.Green} ({ChatColors.Red}https://github.com/jakubbartosik/dRandomSkills{ChatColors.Green})", StringComparison.OrdinalIgnoreCase) + .Replace("{AUTHOR2}", $" {ChatColors.Red}Juzlus{ChatColors.Green} ({ChatColors.Red}https://github.com/Juzlus/jRandomSkills{ChatColors.Green})", StringComparison.OrdinalIgnoreCase)); + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + 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) + { + Instance.skillPlayer.Remove(skillPlayer); + } + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + foreach (var player in Utilities.GetPlayers()) + { + var skillPlayer = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (skillPlayer != null) + skillPlayer.IsDrawing = true; + } + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + foreach (var player in Utilities.GetPlayers()) + { + Instance.AddTimer(0.5f, () => + { + var _players = Utilities.GetPlayers().Where(p => p.IsValid).OrderBy(p => p.Team); + + string skillsText = ""; + foreach (var _player in _players) + { + var _playerSkill = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == _player.SteamID)?.Skill; + if (_playerSkill != null) + { + var skillInfo = SkillData.Skills.FirstOrDefault(p => p.Skill == _playerSkill); + skillsText += $" {ChatColors.DarkRed}{_player.PlayerName}{ChatColors.Lime}: {skillInfo.Name}\n"; + } + } + + if (Config.config.Settings.SummaryAfterTheRound && !string.IsNullOrEmpty(skillsText)) + { + player.PrintToChat(" "); + player.PrintToChat($" {ChatColors.Lime}{Localization.GetTranslation("summary_start")}"); + foreach (string text in skillsText.Split("\n")) + if (!string.IsNullOrEmpty(text)) + player.PrintToChat(text); + player.PrintToChat($" {ChatColors.Lime}{Localization.GetTranslation("summary_end")}"); + player.PrintToChat(" \n"); + } + }); + } + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + foreach (var player in Utilities.GetPlayers()) + { + var playerTeam = player.Team; + var teammates = Utilities.GetPlayers().Where(p => p.Team == playerTeam && p != player); + string teammateSkills = ""; + + var skillPlayer = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + + if (skillPlayer != null) + { + skillPlayer.IsDrawing = false; + + List skillList = new List(SkillData.Skills); + skillList.RemoveAll(s => s?.Skill == skillPlayer?.Skill || s?.Skill == src.player.Skills.None); + + if (Utilities.GetPlayers().FindAll(p => p.Team == player.Team && p.IsValid && !p.IsBot).Count != 1) { + Config.SkillInfo[] skillsOnly1v1 = Config.config.SkillsInfo.Where(s => s.Only1v1).ToArray(); + skillList.RemoveAll(s => skillsOnly1v1.Any(s2 => s2.Name == s.Skill.ToString())); + } + + Config.SkillInfo[] terroristSkills = Config.config.SkillsInfo.Where(s => s.Team == 2).ToArray(); + Config.SkillInfo[] counterterroristSkills = Config.config.SkillsInfo.Where(s => s.Team == 3).ToArray(); + if (player.Team == CsTeam.Terrorist) + skillList.RemoveAll(s => counterterroristSkills.Any(s2 => s2.Name == s.Skill.ToString())); + else + skillList.RemoveAll(s => terroristSkills.Any(s2 => s2.Name == s.Skill.ToString())); + + var randomSkill = skillList.Count == 0 ? new dSkill_SkillInfo(Skills.None, "#ffffff", false) : skillList[Instance.Random.Next(skillList.Count)]; + skillPlayer.Skill = randomSkill.Skill; + + if (randomSkill.Display) + Utils.PrintToChat(player, $"{ChatColors.DarkRed}{randomSkill.Name}{ChatColors.Lime}: {randomSkill.Description}", false); + + if(Config.config.Settings.TeamMateSkillInfo) + { + Instance.AddTimer(0.5f, () => + { + foreach (var teammate in teammates) + { + var teammateSkill = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == teammate.SteamID)?.Skill; + if (teammateSkill != null) + { + var skillInfo = SkillData.Skills.FirstOrDefault(p => p.Skill == teammateSkill); + teammateSkills += $" {ChatColors.DarkRed}{teammate.PlayerName}{ChatColors.Lime}: {skillInfo.Name}\n"; + } + } + + if (!string.IsNullOrEmpty(teammateSkills)) + { + Utils.PrintToChat(player, $" {ChatColors.Lime}{Localization.GetTranslation("teammate_skills")}:", false); + foreach (string text in teammateSkills.Split("\n")) + if (!string.IsNullOrEmpty(text)) + player.PrintToChat(text); + } + }); + } + } + } + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + var victim = @event.Userid; + var attacker = @event.Attacker; + + if (victim == null || attacker == null || victim == attacker) return HookResult.Continue; + + if(Config.config.Settings.KillerSkillInfo) + { + var attackerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); + if (attackerInfo != null) + { + var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == attackerInfo.Skill); + string skillDesc = skillData?.Description; + + Utils.PrintToChat(victim, $"{Localization.GetTranslation("enemy_skill")} {ChatColors.DarkRed}{attacker.PlayerName}{ChatColors.Lime}:", false); + Utils.PrintToChat(victim, $"{ChatColors.DarkRed}{skillData.Name}{ChatColors.Lime} - {skillDesc}", false); + } + } + + return HookResult.Continue; + }); + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs b/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs new file mode 100644 index 0000000..c55a4a7 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/PlayerOnTick.cs @@ -0,0 +1,82 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using jRandomSkills.src.utils; +using static CounterStrikeSharp.API.Core.Listeners; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public static class PlayerOnTick + { + public static void Load() + { + Instance.RegisterListener(() => + { + foreach (var player in Utilities.GetPlayers()) + { + if (player != null && player.IsValid) + { + UpdatePlayerHud(player); + } + } + }); + } + + private static void UpdatePlayerHud(CCSPlayerController player) + { + if (player == null) return; + + var skillPlayer = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (skillPlayer == null) return; + + string infoLine = ""; + string skillLine = ""; + + if (SkillData.Skills.Count == 0) + { + infoLine = $"{Localization.GetTranslation("your_skill")}:
"; + skillLine = $"{Localization.GetTranslation("none")}
"; + } + else if (skillPlayer.IsDrawing) + { + var randomSkill = SkillData.Skills[Instance.Random.Next(SkillData.Skills.Count)]; + infoLine = $"{Localization.GetTranslation("drawing_skill")}:
"; + skillLine = $"{randomSkill.Name}
"; + } + else if (!skillPlayer.IsDrawing) + { + if (player?.IsValid == true && player?.PawnIsAlive == true) + { + var skillInfo = SkillData.Skills.FirstOrDefault(s => s.Skill == skillPlayer.Skill); + if (skillInfo != null) + { + infoLine = $"{Localization.GetTranslation("your_skill")}:
"; + skillLine = $"{skillInfo.Name}
"; + } + } else if (player?.IsValid == true) + { + var pawn = player.Pawn.Value; + if (pawn == null) return; + + var observedPlayer = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == pawn?.ObserverServices?.ObserverTarget?.Value?.Handle); + if (observedPlayer == null) return; + + var observeredPlayerSkill = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == observedPlayer.SteamID); + if (observeredPlayerSkill == null) return; + + var observeredPlayerSkillInfo = SkillData.Skills.FirstOrDefault(s => s.Skill == observeredPlayerSkill.Skill); + if (observeredPlayerSkillInfo == null) return; + + infoLine = $"{Localization.GetTranslation("observer_skill")} {observeredPlayerSkill.PlayerName}:
"; + skillLine = $"{observeredPlayerSkillInfo.Name}
"; + } + } + + if (string.IsNullOrEmpty(infoLine) && string.IsNullOrEmpty(skillLine)) + return; + + var hudContent = infoLine + skillLine; + player.PrintToCenterHtml(hudContent); + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Aimbot.cs b/jRandomSkills - SRC Files/src/player/skills/Aimbot.cs new file mode 100644 index 0000000..ea96d24 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Aimbot.cs @@ -0,0 +1,66 @@ +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Memory; +using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; +using jRandomSkills.src.player; +using System.Runtime.InteropServices; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Aimbot : ISkill + { + private static Skills skillName = Skills.Aimbot; + private static Dictionary hitGroups = new Dictionary(); + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#ff0000"); + VirtualFunctions.CBaseEntity_TakeDamageOldFunc.Hook(OnTakeDamage, HookMode.Pre); + } + + private static HookResult OnTakeDamage(DynamicHook h) + { + CEntityInstance param = h.GetParam(0); + CTakeDamageInfo param2 = h.GetParam(1); + + if (param == null || param2 == null || param2.Attacker == null) + return HookResult.Continue; + + CCSPlayerPawn attackerPawn = new CCSPlayerPawn(param2.Attacker.Value.Handle); + CCSPlayerPawn victimPawn = new CCSPlayerPawn(param.Handle); + + if (attackerPawn == null || attackerPawn.Controller?.Value == null || victimPawn == null || victimPawn.Controller?.Value == null) + return HookResult.Continue; + + CCSPlayerController attacker = attackerPawn.Controller.Value.As(); + CCSPlayerController victim = victimPawn.Controller.Value.As(); + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); + if (playerInfo == null) return HookResult.Continue; + + if (attacker.PawnIsAlive) + { + IntPtr hitGroupPointer = Marshal.ReadIntPtr(param2.Handle, 0x78); + if (hitGroupPointer != nint.Zero) + { + IntPtr hitGroupOffset = Marshal.ReadIntPtr(hitGroupPointer, 16); + if (hitGroupOffset != nint.Zero) + { + if (playerInfo.Skill == skillName) + { + int oldValue = Marshal.ReadInt32(hitGroupOffset, 56); + hitGroups.TryAdd(hitGroupOffset, Marshal.ReadInt32(hitGroupOffset, 56)); + Marshal.WriteInt32(hitGroupOffset, 56, (int)HitGroup_t.HITGROUP_HEAD); + } else if (hitGroups.TryGetValue(hitGroupOffset, out var hitGroup)) + Marshal.WriteInt32(hitGroupOffset, 56, hitGroup); + } + } + } + + return HookResult.Continue; + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/AntyFlash.cs b/jRandomSkills - SRC Files/src/player/skills/AntyFlash.cs new file mode 100644 index 0000000..5b41500 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/AntyFlash.cs @@ -0,0 +1,39 @@ +using CounterStrikeSharp.API.Core; +using jRandomSkills.src.player; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class AntyFlash : ISkill + { + private static Skills skillName = Skills.AntyFlash; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#D6E6FF"); + + Instance.RegisterEventHandler((@event, info) => + { + var player = @event.Userid; + var attacker = @event.Attacker; + + var playerPawn = player.PlayerPawn.Value; + + if (!Instance.IsPlayerValid(player)) return HookResult.Continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + var attackerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); + + if (playerInfo?.Skill == skillName) + playerPawn.FlashDuration = 0.0f; + else if (attackerInfo?.Skill == skillName) + playerPawn.FlashDuration = 7.0f; + + return HookResult.Continue; + }); + } + } +} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/ZelaznaGlowa.cs b/jRandomSkills - SRC Files/src/player/skills/AntyHead.cs similarity index 59% rename from [ D3X ] dRandomSkills - SRC Files/src/player/skills/ZelaznaGlowa.cs rename to jRandomSkills - SRC Files/src/player/skills/AntyHead.cs index f31611e..6e8e13f 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/ZelaznaGlowa.cs +++ b/jRandomSkills - SRC Files/src/player/skills/AntyHead.cs @@ -1,14 +1,19 @@ using CounterStrikeSharp.API.Core; -using static dRandomSkills.dRandomSkills; +using jRandomSkills.src.player; +using static jRandomSkills.jRandomSkills; -namespace dRandomSkills +namespace jRandomSkills { - public static class ZelaznaGlowa + public class AntyHead : ISkill { + private static Skills skillName = Skills.AntyHead; - public static void LoadZelaznaGlowa() + public static void LoadSkill() { - Utils.RegisterSkill("Żelazna Głowa", "Nie otrzymujesz obrażeń w głowę", "#8B4513"); + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#8B4513"); Instance.RegisterEventHandler((@event, info) => { @@ -16,11 +21,11 @@ namespace dRandomSkills var victim = @event.Userid; int hitgroup = @event.Hitgroup; - if (!IsValidPlayer(attacker) || !IsValidPlayer(victim) || attacker == victim) return HookResult.Continue; + if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return HookResult.Continue; var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == victim.SteamID); - if (playerInfo?.Skill == "Żelazna Głowa" && hitgroup != 3) + if (playerInfo?.Skill == skillName && hitgroup == (int)HitGroup_t.HITGROUP_HEAD) { ApplyIronHeadEffect(victim, @event.DmgHealth); return HookResult.Stop; @@ -30,11 +35,6 @@ namespace dRandomSkills }); } - private static bool IsValidPlayer(CCSPlayerController player) - { - return player != null && player.IsValid && player.PlayerPawn != null && player.PlayerPawn.Value != null; - } - private static void ApplyIronHeadEffect(CCSPlayerController victim, float damage) { var playerPawn = victim.PlayerPawn.Value; diff --git a/jRandomSkills - SRC Files/src/player/skills/Armored.cs b/jRandomSkills - SRC Files/src/player/skills/Armored.cs new file mode 100644 index 0000000..35a3b93 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Armored.cs @@ -0,0 +1,84 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Memory; +using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Armored : ISkill + { + private static Skills skillName = Skills.Armored; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#d1430a", false); + + VirtualFunctions.CBaseEntity_TakeDamageOldFunc.Hook(OnTakeDamage, HookMode.Pre); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill != skillName) continue; + EnableSkill(player); + } + }); + + return HookResult.Continue; + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + + var skillConfig = Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString()); + if (skillConfig == null) return; + + float newScale = (float)Instance.Random.NextDouble() * (skillConfig.ChanceTo - skillConfig.ChanceFrom) + skillConfig.ChanceFrom; + playerInfo.SkillChance = newScale; + newScale = (float)Math.Round(newScale, 2); + Utils.PrintToChat(player, $"{ChatColors.DarkRed}{Localization.GetTranslation("armored")}{ChatColors.Lime}: " + Localization.GetTranslation("armored_desc2", newScale), false); + } + + private static HookResult OnTakeDamage(DynamicHook h) + { + CEntityInstance param = h.GetParam(0); + CTakeDamageInfo param2 = h.GetParam(1); + + if (param == null || param2 == null || param2.Attacker == null) + return HookResult.Continue; + + CCSPlayerPawn attackerPawn = new CCSPlayerPawn(param2.Attacker.Value.Handle); + CCSPlayerPawn victimPawn = new CCSPlayerPawn(param.Handle); + + if (attackerPawn == null || attackerPawn.Controller?.Value == null || victimPawn == null || victimPawn.Controller?.Value == null) + return HookResult.Continue; + + CCSPlayerController attacker = attackerPawn.Controller.Value.As(); + CCSPlayerController victim = victimPawn.Controller.Value.As(); + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); + if (playerInfo == null) return HookResult.Continue; + + if (playerInfo.Skill == skillName && attacker.PawnIsAlive) + { + param2.Damage *= (float)playerInfo.SkillChance; + } + + return HookResult.Continue; + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Astronaut.cs b/jRandomSkills - SRC Files/src/player/skills/Astronaut.cs new file mode 100644 index 0000000..634bb07 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Astronaut.cs @@ -0,0 +1,60 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Astronaut : ISkill + { + private static Skills skillName = Skills.Astronaut; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#7E10AD", false); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + var playerPawn = player.PlayerPawn.Value; + + if (playerInfo?.Skill == skillName && playerPawn != null) + { + EnableSkill(player); + } + } + }); + return HookResult.Continue; + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + ApplyGravityModifier(player); + } + + public static void DisableSkill(CCSPlayerController player) + { + player.Pawn.Value.GravityScale = 1; + } + + private static void ApplyGravityModifier(CCSPlayerController player) + { + var skillConfig = Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString()); + if (skillConfig == null) return; + + float gravityModifier = (float)Math.Round(Instance.Random.NextDouble() * (skillConfig.ChanceTo - skillConfig.ChanceFrom) + skillConfig.ChanceFrom, 1); + Utils.PrintToChat(player, $"{ChatColors.DarkRed}{Localization.GetTranslation("astronaut")}{ChatColors.Lime}: " + Localization.GetTranslation("astronaut_desc2", gravityModifier), false); + player.Pawn.Value.GravityScale = gravityModifier; + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Behind.cs b/jRandomSkills - SRC Files/src/player/skills/Behind.cs new file mode 100644 index 0000000..b7dc8b7 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Behind.cs @@ -0,0 +1,88 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Behind : ISkill + { + private static Skills skillName = Skills.Behind; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#00FF00", false); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill != skillName) continue; + EnableSkill(player); + } + }); + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + var attacker = @event!.Attacker; + var victim = @event!.Userid; + + if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) + return HookResult.Continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); + + if (playerInfo?.Skill == skillName && victim.PawnIsAlive) + { + if (Instance.Random.NextDouble() <= playerInfo.SkillChance) + RotateEnemy(victim); + } + + return HookResult.Continue; + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + var skillConfig = Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString()); + if (skillConfig == null) return; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + float newChance = (float)Instance.Random.NextDouble() * (skillConfig.ChanceTo - skillConfig.ChanceFrom) + skillConfig.ChanceFrom; + playerInfo.SkillChance = newChance; + newChance = (float)Math.Round(newChance, 2) * 100; + newChance = (float)Math.Round(newChance); + Utils.PrintToChat(player, $"{ChatColors.DarkRed}{Localization.GetTranslation("behind")}{ChatColors.Lime}: " + Localization.GetTranslation("behind_desc2", newChance), false); + } + + private static void RotateEnemy(CCSPlayerController player) + { + if (player.PlayerPawn.Value.LifeState != (int)LifeState_t.LIFE_ALIVE) + return; + + var currentPosition = player.PlayerPawn.Value.AbsOrigin; + var currentAngles = player.PlayerPawn.Value.EyeAngles; + + QAngle newAngles = new QAngle( + currentAngles.X, + currentAngles.Y + 180, + currentAngles.Z + ); + + player.PlayerPawn.Value.Teleport(currentPosition, newAngles, new Vector(0, 0, 0)); + } + } +} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/BunnyHop.cs b/jRandomSkills - SRC Files/src/player/skills/BunnyHop.cs similarity index 81% rename from [ D3X ] dRandomSkills - SRC Files/src/player/skills/BunnyHop.cs rename to jRandomSkills - SRC Files/src/player/skills/BunnyHop.cs index 7775a99..f7ba2a0 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/BunnyHop.cs +++ b/jRandomSkills - SRC Files/src/player/skills/BunnyHop.cs @@ -1,20 +1,24 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; using static CounterStrikeSharp.API.Core.Listeners; -using static dRandomSkills.dRandomSkills; +using static jRandomSkills.jRandomSkills; -namespace dRandomSkills +namespace jRandomSkills { - public static class BunnyHop + public class BunnyHop : ISkill { + private static Skills skillName = Skills.BunnyHop; private const float MaxSpeed = 500f; private const float BunnyHopVelocity = 300f; - public static void LoadBunnyHop() + public static void LoadSkill() { - Utils.RegisterSkill("BunnyHop", "Otrzymujesz auto BunnyHopa", "#EB4034"); - + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#EB4034"); Instance.RegisterListener(OnTick); } @@ -24,7 +28,7 @@ namespace dRandomSkills { var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "BunnyHop") + if (playerInfo?.Skill == skillName) { GiveBunnyHop(player); } diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Katapulta.cs b/jRandomSkills - SRC Files/src/player/skills/Catapult.cs similarity index 50% rename from [ D3X ] dRandomSkills - SRC Files/src/player/skills/Katapulta.cs rename to jRandomSkills - SRC Files/src/player/skills/Catapult.cs index c974ed1..6df12da 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Katapulta.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Catapult.cs @@ -1,16 +1,22 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; -using static dRandomSkills.dRandomSkills; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static jRandomSkills.jRandomSkills; -namespace dRandomSkills +namespace jRandomSkills { - public static class Katapulta + public class Catapult : ISkill { + private static Skills skillName = Skills.Catapult; - public static void LoadKatapulta() + public static void LoadSkill() { - Utils.RegisterSkill("Katapulta", "Masz losow¹ szanse na podrzucenie wroga", "#FF4500"); + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#FF4500", false); Instance.RegisterEventHandler((@event, info) => { @@ -18,17 +24,11 @@ namespace dRandomSkills { foreach (var player in Utilities.GetPlayers()) { - if (!IsPlayerValid(player)) continue; + if (!Instance.IsPlayerValid(player)) continue; var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill != "Katapulta") continue; - - float newChance = (float)Instance.Random.NextDouble() * (.40f - .20f) + .20f; - playerInfo.SkillChance = newChance; - newChance = (float)Math.Round(newChance, 2) * 100; - newChance = (float)Math.Round(newChance); - - Utils.PrintToChat(player, $"{ChatColors.DarkRed}\"Katapulta\"{ChatColors.Lime}: Twoje szanse na podrzucenie wroga po trafieniu to: {newChance}%", false); + if (playerInfo?.Skill != skillName) continue; + EnableSkill(player); } }); @@ -46,7 +46,7 @@ namespace dRandomSkills var attackerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); - if (attackerInfo?.Skill == "Katapulta" && victim.PawnIsAlive) + if (attackerInfo?.Skill == skillName && victim.PawnIsAlive) { if (Instance.Random.NextDouble() <= attackerInfo.SkillChance) { @@ -61,9 +61,18 @@ namespace dRandomSkills return HookResult.Continue; }); } - private static bool IsPlayerValid(CCSPlayerController player) + + public static void EnableSkill(CCSPlayerController player) { - return player != null && player.IsValid && player.PlayerPawn?.Value != null; + var skillConfig = Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString()); + if (skillConfig == null) return; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + float newChance = (float)Instance.Random.NextDouble() * (skillConfig.ChanceTo - skillConfig.ChanceFrom) + skillConfig.ChanceFrom; + playerInfo.SkillChance = newChance; + newChance = (float)Math.Round(newChance, 2) * 100; + newChance = (float)Math.Round(newChance); + Utils.PrintToChat(player, $"{ChatColors.DarkRed}{Localization.GetTranslation("catapult")}{ChatColors.Lime}: " + Localization.GetTranslation("catapult_desc2", newChance), false); } } } \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Kurczak.cs b/jRandomSkills - SRC Files/src/player/skills/Chicken.cs similarity index 50% rename from [ D3X ] dRandomSkills - SRC Files/src/player/skills/Kurczak.cs rename to jRandomSkills - SRC Files/src/player/skills/Chicken.cs index 771810f..d21a360 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Kurczak.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Chicken.cs @@ -1,13 +1,17 @@ using System.Drawing; using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; using static CounterStrikeSharp.API.Core.Listeners; -using static dRandomSkills.dRandomSkills; +using static jRandomSkills.jRandomSkills; -namespace dRandomSkills +namespace jRandomSkills { - public static class Kurczak + public class Chicken : ISkill { + private static Skills skillName = Skills.Chicken; private static string[] pistols = { "weapon_deagle", @@ -21,10 +25,15 @@ namespace dRandomSkills "weapon_elite", "weapon_hkp2000" }; + private static readonly string defaultCTModel = "characters/models/ctm_sas/ctm_sas.vmdl"; + private static readonly string defaultTModel = "characters/models/tm_phoenix_heavy/tm_phoenix_heavy.vmdl"; - public static void LoadKurczak() + public static void LoadSkill() { - Utils.RegisterSkill("Kurczak", "Otrzymujesz model kurczaka + jesteś o 10% szybszy - 50hp", "#FF8B42"); + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#FF8B42"); Instance.RegisterEventHandler((@event, info) => { @@ -32,22 +41,11 @@ namespace dRandomSkills { foreach (var player in Utilities.GetPlayers()) { - if (!IsPlayerValid(player)) continue; + if (!Instance.IsPlayerValid(player)) continue; var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill != "Kurczak") continue; - - var playerPawn = player.PlayerPawn?.Value; - if (playerPawn != null) - { - SetPlayerModel(player, "models/chicken/chicken.vmdl"); - playerPawn.CBodyComponent.SceneNode.GetSkeletonInstance().MaterialGroup.Value = (uint)Instance.Random.Next(1, 4); - playerPawn.VelocityModifier = 1.1f; - Utilities.SetStateChanged(player, "CCSPlayerPawn", "m_flVelocityModifier"); - - playerPawn.Health = 50; - Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_iHealth"); - } + if (playerInfo?.Skill != skillName) continue; + EnableSkill(player); } }); @@ -57,13 +55,42 @@ namespace dRandomSkills Instance.RegisterListener(OnTick); } + public static void EnableSkill(CCSPlayerController player) + { + var playerPawn = player.PlayerPawn?.Value; + if (playerPawn != null) + { + SetPlayerModel(player, "models/chicken/chicken.vmdl"); + playerPawn.CBodyComponent.SceneNode.GetSkeletonInstance().MaterialGroup.Value = (uint)Instance.Random.Next(1, 4); + playerPawn.VelocityModifier = 1.1f; + Utilities.SetStateChanged(player, "CCSPlayerPawn", "m_flVelocityModifier"); + + playerPawn.Health = 50; + Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_iHealth"); + } + } + + public static void DisableSkill(CCSPlayerController player) + { + var playerPawn = player.PlayerPawn?.Value; + if (playerPawn != null) + { + SetPlayerModel(player, player.Team == CsTeam.CounterTerrorist ? defaultCTModel : defaultTModel); + playerPawn.VelocityModifier = 1f; + Utilities.SetStateChanged(player, "CCSPlayerPawn", "m_flVelocityModifier"); + + playerPawn.Health += 50; + Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_iHealth"); + } + } + private static void OnTick() { foreach (var player in Utilities.GetPlayers()) { var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Kurczak") + if (playerInfo?.Skill == skillName) { var activeWeapon = player.Pawn.Value.WeaponServices?.ActiveWeapon.Value; if (activeWeapon != null && activeWeapon.IsValid && activeWeapon.Clip1 != 0 && !pistols.Contains(activeWeapon?.DesignerName)) @@ -88,10 +115,5 @@ namespace dRandomSkills pawn.Render = Color.FromArgb(255, originalRender.R, originalRender.G, originalRender.B); }); } - - private static bool IsPlayerValid(CCSPlayerController player) - { - return player != null && player.IsValid && player.PlayerPawn?.Value != null; - } } } \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Rozbrojenie.cs b/jRandomSkills - SRC Files/src/player/skills/Disarmament.cs similarity index 53% rename from [ D3X ] dRandomSkills - SRC Files/src/player/skills/Rozbrojenie.cs rename to jRandomSkills - SRC Files/src/player/skills/Disarmament.cs index ce8a882..dc5cf23 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Rozbrojenie.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Disarmament.cs @@ -1,16 +1,22 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; -using static dRandomSkills.dRandomSkills; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static jRandomSkills.jRandomSkills; -namespace dRandomSkills +namespace jRandomSkills { - public static class Rozbrojenie + public class Disarmament : ISkill { + private static Skills skillName = Skills.Disarmament; - public static void LoadRozbrojenie() + public static void LoadSkill() { - Utils.RegisterSkill("Rozbrojenie", "Masz losow¹ szanse na wyrzucenie broni wroga po trafieniu", "#FF4500", false); + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#FF4500", false); Instance.RegisterEventHandler((@event, info) => { @@ -18,17 +24,11 @@ namespace dRandomSkills { foreach (var player in Utilities.GetPlayers()) { - if (!IsPlayerValid(player)) continue; + if (!Instance.IsPlayerValid(player)) continue; var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill != "Rozbrojenie") continue; - - float newChance = (float)Instance.Random.NextDouble() * (.40f - .20f) + .20f; - playerInfo.SkillChance = newChance; - newChance = (float)Math.Round(newChance, 2) * 100; - newChance = (float)Math.Round(newChance); - - Utils.PrintToChat(player, $"{ChatColors.DarkRed}\"Rozbrojenie\"{ChatColors.Lime}: Twoje szanse na wyrzucenie broni wroga to: {newChance}%", false); + if (playerInfo?.Skill != skillName) continue; + EnableSkill(player); } }); @@ -46,7 +46,7 @@ namespace dRandomSkills var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); - if (playerInfo?.Skill == "Rozbrojenie" && victim.PawnIsAlive) + if (playerInfo?.Skill == skillName && victim.PawnIsAlive) { if (Instance.Random.NextDouble() <= playerInfo.SkillChance) { @@ -61,9 +61,18 @@ namespace dRandomSkills return HookResult.Continue; }); } - private static bool IsPlayerValid(CCSPlayerController player) + + public static void EnableSkill(CCSPlayerController player) { - return player != null && player.IsValid && player.PlayerPawn?.Value != null; + var skillConfig = Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString()); + if (skillConfig == null) return; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + float newChance = (float)Instance.Random.NextDouble() * (skillConfig.ChanceTo - skillConfig.ChanceFrom) + skillConfig.ChanceFrom; + playerInfo.SkillChance = newChance; + newChance = (float)Math.Round(newChance, 2) * 100; + newChance = (float)Math.Round(newChance); + Utils.PrintToChat(player, $"{ChatColors.DarkRed}{Localization.GetTranslation("disarmament")}{ChatColors.Lime}: " + Localization.GetTranslation("disarmament_desc2", newChance), false); } } } \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Drakula.cs b/jRandomSkills - SRC Files/src/player/skills/Dracula.cs similarity index 64% rename from [ D3X ] dRandomSkills - SRC Files/src/player/skills/Drakula.cs rename to jRandomSkills - SRC Files/src/player/skills/Dracula.cs index 793b07b..787b46d 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Drakula.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Dracula.cs @@ -1,25 +1,31 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; -using static dRandomSkills.dRandomSkills; +using jRandomSkills.src.player; +using static jRandomSkills.jRandomSkills; -namespace dRandomSkills +namespace jRandomSkills { - public static class Drakula + public class Dracula : ISkill { - public static void LoadDrakula() + private static Skills skillName = Skills.Dracula; + + public static void LoadSkill() { - Utils.RegisterSkill("Drakula", "Po trafieniu ofiary otrzymujesz zwrot zdrowia w postaci danego procentu zadanych obrażeń", "#FA050D"); + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#FA050D"); Instance.RegisterEventHandler((@event, info) => { var attacker = @event.Attacker; var victim = @event.Userid; - if (!IsPlayerValid(attacker) || attacker == victim) return HookResult.Continue; + if (!Instance.IsPlayerValid(attacker) || attacker == victim) return HookResult.Continue; var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); - if (playerInfo?.Skill == "Drakula" && victim.PawnIsAlive) + if (playerInfo?.Skill == skillName && victim.PawnIsAlive) { HealAttacker(attacker, @event.DmgHealth); } @@ -40,10 +46,5 @@ namespace dRandomSkills attackerPawn.Health = newHealth; Utilities.SetStateChanged(attackerPawn, "CBaseEntity", "m_iHealth"); } - - private static bool IsPlayerValid(CCSPlayerController player) - { - return player != null && player.IsValid && player.PlayerPawn?.Value != null; - } } } \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Dwarf.cs b/jRandomSkills - SRC Files/src/player/skills/Dwarf.cs new file mode 100644 index 0000000..2739ef3 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Dwarf.cs @@ -0,0 +1,82 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Dwarf : ISkill + { + private static Skills skillName = Skills.Dwarf; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#ffff00", false); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill != skillName) continue; + EnableSkill(player); + player.Respawn(); + } + }); + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + DisableSkill(player); + } + }); + + return HookResult.Continue; + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + var playerPawn = player.PlayerPawn?.Value; + if (playerPawn != null) + { + var skillConfig = Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString()); + if (skillConfig == null) return; + + float newSize = (float)Instance.Random.NextDouble() * (skillConfig.ChanceTo - skillConfig.ChanceFrom) + skillConfig.ChanceFrom; + newSize = (float)Math.Round(newSize, 2); + + playerPawn.CBodyComponent.SceneNode.GetSkeletonInstance().Scale = newSize; + Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_CBodyComponent"); + + Utils.PrintToChat(player, $"{ChatColors.DarkRed}{Localization.GetTranslation("dwarf")}{ChatColors.Lime}: " + Localization.GetTranslation("dwarf_desc2", newSize), false); + } + } + + public static void DisableSkill(CCSPlayerController player) + { + var playerPawn = player.PlayerPawn?.Value; + if (playerPawn != null && playerPawn?.CBodyComponent != null) + { + playerPawn.CBodyComponent.SceneNode.GetSkeletonInstance().Scale = 1; + Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_CBodyComponent"); + } + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/EnemySpawn.cs b/jRandomSkills - SRC Files/src/player/skills/EnemySpawn.cs new file mode 100644 index 0000000..edae024 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/EnemySpawn.cs @@ -0,0 +1,181 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static CounterStrikeSharp.API.Core.Listeners; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class EnemySpawn : ISkill + { + private static Skills skillName = Skills.EnemySpawn; + private static float timerCooldown = (float)(Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Cooldown); + private static readonly Dictionary SkillPlayerInfo = new Dictionary(); + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#ff8c92"); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) return; + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + { + EnableSkill(player); + } + } + }); + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + SkillPlayerInfo.Clear(); + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + var player = @event.Userid; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + if (SkillPlayerInfo.ContainsKey(player.SteamID)) + SkillPlayerInfo.Remove(player.SteamID); + + return HookResult.Continue; + }); + + Instance.RegisterListener(() => + { + 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); + } + }); + + Instance.AddCommand("css_useSkill", "Use Skill", (player, _) => + { + if (player == null) return; + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + UseSkill(player); + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + { + SteamID = player.SteamID, + CanUse = true, + Cooldown = DateTime.MinValue, + LastClick = DateTime.MinValue, + }; + } + + public static void DisableSkill(CCSPlayerController player) + { + if (SkillPlayerInfo.ContainsKey(player.SteamID)) + SkillPlayerInfo.Remove(player.SteamID); + } + + public static Vector GetEnemySpawn(CCSPlayerController player) + { + List enemy = Utilities.GetPlayers().FindAll(p => Instance.IsPlayerValid(p) && p.Team != player.Team && p.PawnIsAlive); + if (enemy.Count == 0) + { + var abs = player.PlayerPawn.Value.AbsOrigin; + return new Vector(abs.X, abs.Y, abs.Z); + } + + CCSPlayerController randomEnemy = enemy[Instance.Random.Next(0, enemy.Count)]; + var eAbs = randomEnemy.PlayerPawn.Value.AbsOrigin; + return new Vector(eAbs.X, eAbs.Y, eAbs.Z); + } + + private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) + { + float cooldown = 0; + if (skillInfo != null) + { + float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + cooldown = Math.Max(time, 0); + + if (cooldown == 0 && skillInfo?.CanUse == false) + skillInfo.CanUse = true; + } + + var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); + if (skillData == null) return; + + string infoLine = $"{Localization.GetTranslation("your_skill")}:
"; + string skillLine = $"{skillData.Name}
"; + string remainingLine = cooldown != 0 ? $"{Localization.GetTranslation("hud_info", $"{cooldown}")}
" : ""; + + var hudContent = infoLine + skillLine + remainingLine; + player.PrintToCenterHtml(hudContent); + } + + private static void ActiveUse(CCSPlayerController player) + { + if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) + { + skillInfo.CanUse = true; + } + } + + private 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; + playerPawn.Teleport(GetEnemySpawnVector(player)); + } + else + skillInfo.LastClick = DateTime.Now; + } + } + + private static Vector GetEnemySpawnVector(CCSPlayerController player) + { + var abs = player.PlayerPawn.Value.AbsOrigin; + var spawns = Utilities.FindAllEntitiesByDesignerName(player.Team == CsTeam.CounterTerrorist ? "info_player_terrorist" : "info_player_counterterrorist").ToList(); + if (spawns.Any()) + { + var randomSpawn = spawns[Instance.Random.Next(spawns.Count)]; + return randomSpawn.AbsOrigin; + } + return new Vector(abs.X, abs.Y, abs.Z); + } + + public class PlayerSkillInfo + { + public ulong SteamID { get; set; } + public bool CanUse { get; set; } + public DateTime Cooldown { get; set; } + public DateTime LastClick { get; set; } + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Flash.cs b/jRandomSkills - SRC Files/src/player/skills/Flash.cs new file mode 100644 index 0000000..321a412 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Flash.cs @@ -0,0 +1,112 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static CounterStrikeSharp.API.Core.Listeners; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Flash : ISkill + { + private static Skills skillName = Skills.Flash; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#A31912", false); + Instance.RegisterListener(UpdateSpeed); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + var playerPawn = player.PlayerPawn?.Value; + + playerPawn.VelocityModifier = 1; + Utilities.SetStateChanged(playerPawn, "CCSPlayerPawn", "m_flVelocityModifier"); + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill != skillName) continue; + EnableSkill(player); + } + }); + + return HookResult.Continue; + }); + + Instance.HookUserMessage(208, um => + { + var soundevent = um.ReadUInt("soundevent_hash"); + var userIndex = um.ReadUInt("source_entity_index"); + + if (userIndex == 0) return HookResult.Continue; + if (!Instance.footstepSoundEvents.Contains(soundevent)) return HookResult.Continue; + + var player = Utilities.GetPlayers().FirstOrDefault(p => p.Pawn.Value.Index == userIndex); + if (!Instance.IsPlayerValid(player)) return HookResult.Continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill != skillName) return HookResult.Continue; + + if (player.Buttons.HasFlag(PlayerButtons.Speed) || player.Buttons.HasFlag(PlayerButtons.Duck)) + { + um.Recipients.Clear(); + return HookResult.Handled; + } + + return HookResult.Continue; + }, HookMode.Pre); + } + + public static void EnableSkill(CCSPlayerController player) + { + var playerPawn = player.PlayerPawn.Value; + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerPawn == null) return; + + var skillConfig = Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString()); + if (skillConfig == null) return; + + float newSpeed = (float)Instance.Random.NextDouble() * (skillConfig.ChanceTo - skillConfig.ChanceFrom) + skillConfig.ChanceFrom; + newSpeed = (float)Math.Round(newSpeed, 2); + playerInfo.SkillChance = newSpeed; + + playerPawn.VelocityModifier = newSpeed; + Utilities.SetStateChanged(playerPawn, "CCSPlayerPawn", "m_flVelocityModifier"); + Utils.PrintToChat(player, $"{ChatColors.DarkRed}{Localization.GetTranslation("flash")}{ChatColors.Lime}: " + Localization.GetTranslation("flash_desc2", newSpeed), false); + } + + public static void DisableSkill(CCSPlayerController player) + { + var playerPawn = player.PlayerPawn.Value; + if (playerPawn == null) return; + playerPawn.VelocityModifier = 1; + Utilities.SetStateChanged(playerPawn, "CCSPlayerPawn", "m_flVelocityModifier"); + } + + private static void UpdateSpeed() + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill != skillName) continue; + + var playerPawn = player.PlayerPawn?.Value; + if (playerPawn != null && playerPawn.VelocityModifier != 0) + { + playerPawn.VelocityModifier = Math.Max((float)playerInfo?.SkillChance, 1); + Utilities.SetStateChanged(playerPawn, "CCSPlayerPawn", "m_flVelocityModifier"); + } + } + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/FrozenDecoy.cs b/jRandomSkills - SRC Files/src/player/skills/FrozenDecoy.cs new file mode 100644 index 0000000..0cd73b6 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/FrozenDecoy.cs @@ -0,0 +1,144 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Entities.Constants; +using CounterStrikeSharp.API.Modules.Memory; +using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static CounterStrikeSharp.API.Core.Listeners; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class FrozenDecoy : ISkill + { + private static Skills skillName = Skills.FrozenDecoy; + private static Dictionary gravities = new Dictionary(); + private static List players = new List(); + private static Dictionary triggers = new Dictionary(); + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#00eaff"); + + Instance.RegisterEventHandler((@event, info) => + { + gravities.Clear(); + players.Clear(); + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, @info) => + { + var player = @event.Userid; + if (!Instance.IsPlayerValid(player)) return HookResult.Continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill != skillName) return HookResult.Continue; + + var trigger = Utilities.CreateEntityByName("trigger_multiple"); + if (trigger == null) return HookResult.Continue; + + trigger.Collision.SolidType = SolidType_t.SOLID_CAPSULE; + trigger.Collision.SolidFlags = 0; + trigger.Spawnflags = 1; + trigger.Globalname = $"frozen_decoy_{trigger.Index}"; + trigger.Collision.SolidFlags = 1; + + trigger.AbsOrigin.X = @event.X; + trigger.AbsOrigin.Y = @event.Y; + trigger.AbsOrigin.Z = @event.Z; + + trigger.Collision.CapsuleRadius = 150; + trigger.Collision.BoundingRadius = 150; + + trigger.Collision.CollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_TRIGGER; + trigger.Collision.EnablePhysics = 1; + trigger.Collision.TriggerBloat = 0; + + trigger.Collision.SurroundType = SurroundingBoundsType_t.USE_OBB_COLLISION_BOUNDS; + trigger.Collision.CollisionAttribute.CollisionFunctionMask = 39; + trigger.Collision.CollisionAttribute.CollisionGroup = 2; + + trigger.DispatchSpawn(); + triggers.Add(@event.Entityid, trigger); + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, @info) => + { + var player = @event.Userid; + if (!Instance.IsPlayerValid(player)) return HookResult.Continue; + + if (triggers.TryGetValue(@event.Entityid, out var existingTrigger)) + { + existingTrigger.AcceptInput("Kill"); + triggers.Remove(@event.Entityid); + } + + return HookResult.Continue; + }); + + Instance.RegisterListener(() => + { + foreach (CCSPlayerPawn player in players) + { + player.VelocityModifier = 0; + Utilities.SetStateChanged(player, "CCSPlayerPawn", "m_flVelocityModifier"); + + if ((player.Flags & (uint)PlayerFlags.FL_ONGROUND) != 0) + player.GravityScale = float.MaxValue; + } + }); + + VirtualFunctions.CBaseTrigger_StartTouchFunc.Hook(StartTouchFun, HookMode.Post); + VirtualFunctions.CBaseTrigger_EndTouchFunc.Hook(EndTouchFunc, HookMode.Post); + } + + private static HookResult StartTouchFun(DynamicHook h) + { + CBaseTrigger trigger = h.GetParam(0); + CBaseEntity entity = h.GetParam(1); + + if (trigger == null || entity == null) + return HookResult.Continue; +; + CCSPlayerPawn player = new CCSPlayerPawn(entity.Handle); + if (player == null) return HookResult.Continue; + + if (string.IsNullOrEmpty(trigger?.Globalname) || trigger?.Globalname?.StartsWith("frozen_decoy_") == false) + return HookResult.Continue; + + if (!players.Contains(player)) + players.Add(player); + + gravities.TryAdd(player.Index, player.GravityScale); + return HookResult.Continue; + } + + private static HookResult EndTouchFunc(DynamicHook h) + { + var trigger = h.GetParam(0); + var entity = h.GetParam(1); + + if (trigger == null || entity == null) return HookResult.Continue; + + CCSPlayerPawn player = new CCSPlayerPawn(entity.Handle); + if (player == null) return HookResult.Continue; + + if (string.IsNullOrEmpty(trigger?.Globalname) || trigger?.Globalname?.StartsWith("frozen_decoy_") == false) + return HookResult.Continue; + + if (players.Contains(player)) + players.Remove(player); + + float grav = gravities.GetValueOrDefault(player.Index); + player.GravityScale = Math.Min(grav, 1); + return HookResult.Continue; + } + } +} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Duszek.cs b/jRandomSkills - SRC Files/src/player/skills/Ghost.cs similarity index 70% rename from [ D3X ] dRandomSkills - SRC Files/src/player/skills/Duszek.cs rename to jRandomSkills - SRC Files/src/player/skills/Ghost.cs index af9e2ee..9ac1c01 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Duszek.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Ghost.cs @@ -1,16 +1,22 @@ using System.Drawing; using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; +using jRandomSkills.src.player; using static CounterStrikeSharp.API.Core.Listeners; -using static dRandomSkills.dRandomSkills; +using static jRandomSkills.jRandomSkills; -namespace dRandomSkills +namespace jRandomSkills { - public static class Duszek + public class Ghost : ISkill { - public static void LoadDuszek() + private static Skills skillName = Skills.Ghost; + + public static void LoadSkill() { - Utils.RegisterSkill("Duszek", "Jesteś całkowicie niewidzialny", "#FFFFFF"); + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#FFFFFF"); Instance.RegisterEventHandler((@event, info) => { @@ -18,9 +24,10 @@ namespace dRandomSkills { foreach (var player in Utilities.GetPlayers()) { - if (!IsValidPlayer(player)) continue; + if (!Instance.IsPlayerValid(player)) continue; + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Duszek") + if (playerInfo?.Skill == skillName) { SetPlayerVisibility(player, false); } @@ -34,11 +41,22 @@ namespace dRandomSkills { foreach (var player in Utilities.GetPlayers()) { - if (!IsValidPlayer(player)) continue; + if (!Instance.IsPlayerValid(player)) continue; var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Duszek") + if (playerInfo?.Skill == skillName) SetPlayerVisibility(player, true); } + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + var player = @event.Userid; + if (!player.IsValid || player.PlayerPawn.Value == null) return HookResult.Continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + SetPlayerVisibility(player, true); return HookResult.Continue; }); @@ -46,10 +64,10 @@ namespace dRandomSkills Instance.RegisterEventHandler((@event, info) => { var player = @event.Userid; - if (!IsValidPlayer(player)) return HookResult.Continue; + if (!Instance.IsPlayerValid(player)) return HookResult.Continue; var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill != "Duszek") return HookResult.Continue; + if (playerInfo?.Skill != skillName) return HookResult.Continue; SetWeaponVisibility(player, false); return HookResult.Continue; }); @@ -57,13 +75,23 @@ namespace dRandomSkills Instance.RegisterListener(OnTick); } + public static void EnableSkill(CCSPlayerController player) + { + SetPlayerVisibility(player, false); + } + + public static void DisableSkill(CCSPlayerController player) + { + SetPlayerVisibility(player, true); + } + private static void OnTick() { foreach (var player in Utilities.GetPlayers()) { var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Duszek") + if (playerInfo?.Skill == skillName) { var activeWeapon = player.Pawn.Value.WeaponServices?.ActiveWeapon.Value; if (activeWeapon != null && activeWeapon.IsValid && activeWeapon.Clip1 != 0) @@ -75,11 +103,6 @@ namespace dRandomSkills } } - private static bool IsValidPlayer(CCSPlayerController player) - { - return player != null && player.IsValid; - } - private static void SetPlayerVisibility(CCSPlayerController player, bool visible) { var playerPawn = player.PlayerPawn.Value; @@ -98,7 +121,7 @@ namespace dRandomSkills private static void SetWeaponVisibility(CCSPlayerController player, bool visible) { - if (!IsValidPlayer(player)) return; + if (!Instance.IsPlayerValid(player)) return; var playerPawn = player.PlayerPawn.Value; var color = visible ? Color.FromArgb(255, 255, 255, 255) : Color.FromArgb(0, 255, 255, 255); diff --git a/jRandomSkills - SRC Files/src/player/skills/GodMode.cs b/jRandomSkills - SRC Files/src/player/skills/GodMode.cs new file mode 100644 index 0000000..c78c892 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/GodMode.cs @@ -0,0 +1,163 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static CounterStrikeSharp.API.Core.Listeners; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class GodMode : ISkill + { + private static Skills skillName = Skills.GodMode; + private static float timerCooldown = (float)(Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Cooldown); + private static readonly Dictionary SkillPlayerInfo = new Dictionary(); + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#e0d83a"); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + { + EnableSkill(player); + } + } + }); + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + SkillPlayerInfo.Clear(); + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + var player = @event.Userid; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + if (SkillPlayerInfo.ContainsKey(player.SteamID)) + SkillPlayerInfo.Remove(player.SteamID); + + return HookResult.Continue; + }); + + Instance.RegisterListener(() => + { + 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); + } + }); + + Instance.AddCommand("css_useSkill", "Use Skill", (player, _) => + { + if (player == null) return; + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + UseSkill(player); + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + { + SteamID = player.SteamID, + CanUse = true, + Cooldown = DateTime.MinValue, + LastClick = DateTime.MinValue, + }; + } + + public static void DisableSkill(CCSPlayerController player) + { + if (SkillPlayerInfo.ContainsKey(player.SteamID)) + SkillPlayerInfo.Remove(player.SteamID); + } + + private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) + { + float cooldown = 0; + if (skillInfo != null) + { + float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + cooldown = Math.Max(time, 0); + + if (cooldown == 0 && skillInfo?.CanUse == false) + skillInfo.CanUse = true; + } + + var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); + if (skillData == null) return; + + string infoLine = $"{Localization.GetTranslation("your_skill")}:
"; + string skillLine = $"{skillData.Name}
"; + string remainingLine = cooldown != 0 ? $"{Localization.GetTranslation("hud_info", $"{cooldown}")}
" : ""; + + var hudContent = infoLine + skillLine + remainingLine; + player.PrintToCenterHtml(hudContent); + } + + private static void ActiveUse(CCSPlayerController player) + { + if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) + { + skillInfo.CanUse = true; + } + } + + private 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; + + player.PrintToChat($" {ChatColors.Green} {Localization.GetTranslation("godmode_on")}"); + player.PlayerPawn.Value.TakesDamage = false; + Instance.AddTimer(2, () => { + if (player.IsValid && player.PawnIsAlive) + { + player.PlayerPawn.Value.TakesDamage = true; + player.PrintToChat($" {ChatColors.Red} {Localization.GetTranslation("godmode_off")}"); + } + }); + } + else + skillInfo.LastClick = DateTime.Now; + } + } + + public class PlayerSkillInfo + { + public ulong SteamID { get; set; } + public bool CanUse { get; set; } + public DateTime Cooldown { get; set; } + public DateTime LastClick { get; set; } + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Impostor.cs b/jRandomSkills - SRC Files/src/player/skills/Impostor.cs new file mode 100644 index 0000000..9ccad3c --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Impostor.cs @@ -0,0 +1,79 @@ +using System.Drawing; +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Impostor : ISkill + { + private static Skills skillName = Skills.Impostor; + private static readonly string defaultCTModel = "characters/models/ctm_sas/ctm_sas.vmdl"; + private static readonly string defaultTModel = "characters/models/tm_phoenix_heavy/tm_phoenix_heavy.vmdl"; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#99140B"); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + { + string model = GetEnemyModel(player); + SetPlayerModel(player, model); + } + } + }); + + return HookResult.Continue; + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + string model = GetEnemyModel(player); + SetPlayerModel(player, model); + } + + public static void DisableSkill(CCSPlayerController player) + { + SetPlayerModel(player, player.Team == CsTeam.Terrorist ? defaultTModel : defaultCTModel); + } + + private static string GetEnemyModel(CCSPlayerController player) + { + CCSPlayerController[] models = Utilities.GetPlayers().FindAll(p => p.IsValid && p.PawnIsAlive && p.Team != player.Team).ToArray(); + if (models.Length > 0) + { + string modelName = models[Instance.Random.Next(models.Length)].PlayerPawn.Value.CBodyComponent.SceneNode.GetSkeletonInstance().ModelState.ModelName; + if (modelName != null) return modelName; + } + return player.Team == CsTeam.CounterTerrorist ? defaultTModel : defaultCTModel; + } + + private static void SetPlayerModel(CCSPlayerController player, string model) + { + var pawn = player.PlayerPawn?.Value; + if (pawn == null) return; + + Server.NextFrame(() => + { + pawn.SetModel(model); + + var originalRender = pawn.Render; + pawn.Render = Color.FromArgb(255, originalRender.R, originalRender.G, originalRender.B); + }); + } + } +} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/NieskonczoneAmmo.cs b/jRandomSkills - SRC Files/src/player/skills/InfiniteAmmo.cs similarity index 63% rename from [ D3X ] dRandomSkills - SRC Files/src/player/skills/NieskonczoneAmmo.cs rename to jRandomSkills - SRC Files/src/player/skills/InfiniteAmmo.cs index 24a5b5e..0a1616f 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/NieskonczoneAmmo.cs +++ b/jRandomSkills - SRC Files/src/player/skills/InfiniteAmmo.cs @@ -1,24 +1,29 @@ using CounterStrikeSharp.API.Core; -using CounterStrikeSharp.API.Modules.Utils; -using static dRandomSkills.dRandomSkills; +using jRandomSkills.src.player; +using static jRandomSkills.jRandomSkills; -namespace dRandomSkills +namespace jRandomSkills { - public static class NieskonczoneAmmo + public class InfiniteAmmo : ISkill { - public static void LoadNieskonczoneAmmo() + private static Skills skillName = Skills.InfiniteAmmo; + + public static void LoadSkill() { - Utils.RegisterSkill("Nieskończone Ammo", "Otrzymujesz nieskończoną ilość ammo do wszystkich swoich broni", "#0000FF"); + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#0000FF"); Instance.RegisterEventHandler((@event, info) => { var player = @event.Userid; - if (!IsValidPlayer(player)) return HookResult.Continue; + if (!Instance.IsPlayerValid(player)) return HookResult.Continue; var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Nieskończone Ammo") + if (playerInfo?.Skill == skillName) { ApplyInfiniteAmmo(player); } @@ -30,11 +35,11 @@ namespace dRandomSkills { var player = @event.Userid; - if (!IsValidPlayer(player)) return HookResult.Continue; + if (!Instance.IsPlayerValid(player)) return HookResult.Continue; var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Nieskończone Ammo") + if (playerInfo?.Skill == skillName) player.GiveNamedItem($"weapon_{@event.Weapon}"); return HookResult.Continue; @@ -44,11 +49,11 @@ namespace dRandomSkills { var player = @event.Userid; - if (!IsValidPlayer(player)) return HookResult.Continue; + if (!Instance.IsPlayerValid(player)) return HookResult.Continue; var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Nieskończone Ammo") + if (playerInfo?.Skill == skillName) { ApplyInfiniteAmmo(player); } @@ -57,11 +62,6 @@ namespace dRandomSkills }); } - private static bool IsValidPlayer(CCSPlayerController player) - { - return player != null && player.IsValid; - } - private static void ApplyInfiniteAmmo(CCSPlayerController player) { var activeWeaponHandle = player.PlayerPawn.Value?.WeaponServices?.ActiveWeapon; diff --git a/jRandomSkills - SRC Files/src/player/skills/KillerFlash.cs b/jRandomSkills - SRC Files/src/player/skills/KillerFlash.cs new file mode 100644 index 0000000..0bc8412 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/KillerFlash.cs @@ -0,0 +1,35 @@ +using CounterStrikeSharp.API.Core; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class KillerFlash : ISkill + { + private static Skills skillName = Skills.KillerFlash; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#57bcff"); + + Instance.RegisterEventHandler((@event, info) => + { + var player = @event.Userid; + var attacker = @event.Attacker; + if (!Instance.IsPlayerValid(player)) return HookResult.Continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + var attackerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); + + if (attackerInfo?.Skill == skillName && playerInfo?.Skill != Skills.AntyFlash && player?.PlayerPawn.Value.FlashDuration >= 1) + player?.PlayerPawn?.Value?.CommitSuicide(false, true); + + return HookResult.Continue; + }); + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Medic.cs b/jRandomSkills - SRC Files/src/player/skills/Medic.cs new file mode 100644 index 0000000..43253b8 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Medic.cs @@ -0,0 +1,60 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using jRandomSkills.src.player; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Medic : ISkill + { + private static Skills skillName = Skills.Medic; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#42FF5F"); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + player.RemoveItemByDesignerName("weapon_healthshot"); + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill != skillName) continue; + EnableSkill(player); + } + }); + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) return HookResult.Continue; + DisableSkill(player); + } + + return HookResult.Continue; + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + int healthshot = Instance.Random.Next(1, 10); + for (int i = 0; i < healthshot; i++) + player.GiveNamedItem("weapon_healthshot"); + } + + public static void DisableSkill(CCSPlayerController player) + { + player.RemoveItemByDesignerName("weapon_healthshot"); + } + } +} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Muhammed.cs b/jRandomSkills - SRC Files/src/player/skills/Muhammed.cs similarity index 73% rename from [ D3X ] dRandomSkills - SRC Files/src/player/skills/Muhammed.cs rename to jRandomSkills - SRC Files/src/player/skills/Muhammed.cs index 9700b2f..5257f79 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Muhammed.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Muhammed.cs @@ -1,27 +1,32 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; -using static dRandomSkills.dRandomSkills; +using jRandomSkills.src.player; +using static jRandomSkills.jRandomSkills; -namespace dRandomSkills +namespace jRandomSkills { - public static class Muhammed + public class Muhammed : ISkill { + private static Skills skillName = Skills.Muhammed; private const float ExplosionRadius = 500.0f; private const int ExplosionDamage = 999; - public static void LoadMuhammed() + public static void LoadSkill() { - Utils.RegisterSkill("Muhammed", "Po śmierci wybucha i zabija graczy w obrębie", "#F5CB42"); + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#F5CB42"); Instance.RegisterEventHandler((@event, info) => { CCSPlayerController player = @event.Userid; - if (!IsPlayerValid(player)) return HookResult.Continue; + if (!Instance.IsPlayerValid(player)) return HookResult.Continue; var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Muhammed") + if (playerInfo?.Skill == skillName) { SpawnExplosion(player); } @@ -47,7 +52,7 @@ namespace dRandomSkills heProjectile.AcceptInput("InitializeSpawnFromWorld", player.PlayerPawn.Value, player.PlayerPawn.Value, ""); heProjectile.DetonateTime = 0; - Server.PrintToChatAll($" {ChatColors.DarkRed}► {ChatColors.Green}[{ChatColors.DarkRed} SUPERMOCE {ChatColors.Green}] {ChatColors.DarkRed}{player.PlayerName}: {ChatColors.Lime}ALLAHU AKBAR!!!"); + Server.PrintToChatAll($" {ChatColors.DarkRed}► {ChatColors.Green}[{ChatColors.DarkRed} qRandomSkills {ChatColors.Green}] {ChatColors.DarkRed}{player.PlayerName}: {ChatColors.Lime}ALLAHU AKBAR!!!"); var fileNames = new[] { "radiobotfallback01", "radiobotfallback02", "radiobotfallback04" }; Instance.AddTimer(0.1f, () => @@ -56,10 +61,5 @@ namespace dRandomSkills player.ExecuteClientCommand($"play vo/agents/balkan/{randomFile}.vsnd"); }); } - - private static bool IsPlayerValid(CCSPlayerController player) - { - return player != null && player.IsValid && player.PlayerPawn?.Value != null; - } } } \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Mute.cs b/jRandomSkills - SRC Files/src/player/skills/Mute.cs new file mode 100644 index 0000000..1dd6b2a --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Mute.cs @@ -0,0 +1,58 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Memory; +using jRandomSkills.src.player; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Mute : ISkill + { + private static Skills skillName = Skills.None; + private const float ExplosionRadius = 500.0f; + private const int ExplosionDamage = 999; + + public static void LoadSkill() + { + return; + + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#F5CB42"); + + Instance.RegisterListener(@event => + { + var name = @event.DesignerName; + if (!name.EndsWith("_projectile")) + return; + + // mp_freezetime 0; mp_warmup_end + Server.PrintToChatAll("-> " + name); + + switch (name) + { + case "flashbang_projectile": + var flash = @event.As(); + break; + case "smokegrenade_projectile": + var smoke = @event.As(); + Schema.SetSchemaValue(smoke.Handle, "CSmokeGrenadeProjectile", "m_nSmokeEffectTickBegin", int.MaxValue); + Schema.SetSchemaValue(smoke.Handle, "CSmokeGrenadeProjectile", "m_bDidSmokeEffect", true); + break; + case "hegrenade_projectile": + var hegrenade = @event.As(); + hegrenade.DetonateTime = 0; + break; + case "molotov_projectile": + var molotov = @event.As(); + molotov.StillTimer.Timestamp = 0; + break; + case "decoy_projectile": + var decoy = @event.As(); + break; + } + }); + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/None.cs b/jRandomSkills - SRC Files/src/player/skills/None.cs new file mode 100644 index 0000000..c62f785 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/None.cs @@ -0,0 +1,14 @@ +using jRandomSkills.src.player; + +namespace jRandomSkills +{ + public class None : ISkill + { + private static Skills skillName = Skills.None; + + public static void LoadSkill() + { + Utils.RegisterSkill(skillName, "#FFFFFF", false); + } + } +} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/OneShot.cs b/jRandomSkills - SRC Files/src/player/skills/OneShot.cs similarity index 74% rename from [ D3X ] dRandomSkills - SRC Files/src/player/skills/OneShot.cs rename to jRandomSkills - SRC Files/src/player/skills/OneShot.cs index 3a11c27..d1e8375 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/OneShot.cs +++ b/jRandomSkills - SRC Files/src/player/skills/OneShot.cs @@ -1,16 +1,21 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Memory; using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; -using static dRandomSkills.dRandomSkills; +using jRandomSkills.src.player; +using static jRandomSkills.jRandomSkills; -namespace dRandomSkills +namespace jRandomSkills { - public static class OneShot + public class OneShot : ISkill { - public static void LoadOneShot() + private static Skills skillName = Skills.OneShot; + + public static void LoadSkill() { - Utils.RegisterSkill("One Shot", "Po trafieniu od razu zabija przeciwnika", "#ff5CD9"); - + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#ff5CD9"); VirtualFunctions.CBaseEntity_TakeDamageOldFunc.Hook(OnTakeDamage, HookMode.Pre); } @@ -34,7 +39,7 @@ namespace dRandomSkills var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); if (playerInfo == null) return HookResult.Continue; - if (playerInfo.Skill == "One Shot" && attacker.PawnIsAlive) + if (playerInfo.Skill == skillName && attacker.PawnIsAlive) { param2.Damage = 1000f; } diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/PawelJumper.cs b/jRandomSkills - SRC Files/src/player/skills/PawelJumper.cs similarity index 76% rename from [ D3X ] dRandomSkills - SRC Files/src/player/skills/PawelJumper.cs rename to jRandomSkills - SRC Files/src/player/skills/PawelJumper.cs index a440127..9fd5c74 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/PawelJumper.cs +++ b/jRandomSkills - SRC Files/src/player/skills/PawelJumper.cs @@ -1,28 +1,33 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; using static CounterStrikeSharp.API.Core.Listeners; -using static dRandomSkills.dRandomSkills; +using static jRandomSkills.jRandomSkills; -namespace dRandomSkills +namespace jRandomSkills { - public static class PawelJumper + public class PawelJumper : ISkill { + private static 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]; - public static void LoadPawelJumper() + public static void LoadSkill() { - Utils.RegisterSkill("Paweł Jumper", "Otrzymujesz dodatkowy Skok", "#FFA500"); + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#FFA500"); Instance.RegisterListener(() => { foreach (var player in Utilities.GetPlayers()) { - if (!IsPlayerValid(player)) return; + if (!Instance.IsPlayerValid(player)) return; var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Paweł Jumper") + if (playerInfo?.Skill == skillName) { GiveAdditionalJump(player); } @@ -53,10 +58,5 @@ namespace dRandomSkills LF[player.Slot] = flags; LB[player.Slot] = buttons; } - - private static bool IsPlayerValid(CCSPlayerController player) - { - return player != null && player.IsValid && player.PlayerPawn?.Value != null; - } } } \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Phoenix.cs b/jRandomSkills - SRC Files/src/player/skills/Phoenix.cs new file mode 100644 index 0000000..ea8d2bd --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Phoenix.cs @@ -0,0 +1,72 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Phoenix : ISkill + { + private static Skills skillName = Skills.Phoenix; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#ff5C0A", false); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill != skillName) continue; + EnableSkill(player); + } + }); + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + var player = @event.Userid; + + if (!Instance.IsPlayerValid(player)) return HookResult.Continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + { + if (Instance.Random.NextDouble() <= playerInfo.SkillChance) + { + player.Respawn(); + Instance.AddTimer(.2f, () => player.Respawn()); + Utils.PrintToChat(player, Localization.GetTranslation("phoenix_respawn"), false); ; + } + } + + return HookResult.Continue; + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + var skillConfig = Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString()); + if (skillConfig == null) return; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + float newChance = (float)Instance.Random.NextDouble() * (skillConfig.ChanceTo - skillConfig.ChanceFrom) + skillConfig.ChanceFrom; + playerInfo.SkillChance = newChance; + newChance = (float)Math.Round(newChance, 2) * 100; + newChance = (float)Math.Round(newChance); + Utils.PrintToChat(player, $"{ChatColors.DarkRed}{Localization.GetTranslation("phoenix")}{ChatColors.Lime}: " + Localization.GetTranslation("phoenix_desc2", newChance), false); + } + } +} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Pilot.cs b/jRandomSkills - SRC Files/src/player/skills/Pilot.cs similarity index 79% rename from [ D3X ] dRandomSkills - SRC Files/src/player/skills/Pilot.cs rename to jRandomSkills - SRC Files/src/player/skills/Pilot.cs index bb1ad83..a9a6df0 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Pilot.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Pilot.cs @@ -1,18 +1,24 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; using static CounterStrikeSharp.API.Core.Listeners; -using static dRandomSkills.dRandomSkills; +using static jRandomSkills.jRandomSkills; -namespace dRandomSkills +namespace jRandomSkills { - public static class Pilot + public class Pilot : ISkill { + private static Skills skillName = Skills.Pilot; private static readonly Dictionary PlayerPilotInfo = new Dictionary(); - public static void LoadPilot() + public static void LoadSkill() { - Utils.RegisterSkill("Pilot", "Latanie przez okreœlony czas. Przytrzymaj [USE - E], aby lataæ!", "#1466F5"); + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#1466F5"); Instance.RegisterEventHandler((@event, info) => { @@ -21,15 +27,9 @@ namespace dRandomSkills foreach (var player in Utilities.GetPlayers()) { var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Pilot") + if (playerInfo?.Skill == skillName) { - PlayerPilotInfo[player.SteamID] = new Pilot_PlayerInfo - { - SteamID = player.SteamID, - PressedUse = false, - CanUsePilot = true, - PilotStartTime = DateTime.MinValue - }; + EnableSkill(player); } } }); @@ -42,12 +42,10 @@ namespace dRandomSkills var player = @event.Userid; var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Pilot") + if (playerInfo?.Skill == skillName) { if (PlayerPilotInfo.ContainsKey(player.SteamID)) - { PlayerPilotInfo.Remove(player.SteamID); - } } return HookResult.Continue; @@ -58,14 +56,29 @@ namespace dRandomSkills foreach (var player in Utilities.GetPlayers()) { var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); - if (playerInfo?.Skill == "Pilot") - { + if (playerInfo?.Skill == skillName) HandlePilot(player); - } } }); } + public static void EnableSkill(CCSPlayerController player) + { + PlayerPilotInfo[player.SteamID] = new Pilot_PlayerInfo + { + SteamID = player.SteamID, + PressedUse = false, + CanUsePilot = true, + PilotStartTime = DateTime.MinValue + }; + } + + public static void DisableSkill(CCSPlayerController player) + { + if (PlayerPilotInfo.ContainsKey(player.SteamID)) + PlayerPilotInfo.Remove(player.SteamID); + } + private static void HandlePilot(CCSPlayerController player) { var buttons = player.Buttons; @@ -103,9 +116,9 @@ namespace dRandomSkills } string fuelColor = GetFuelColor(fuelPercentage); - string infoLine = buttons.HasFlag(PlayerButtons.Use) ? $"Pilot:
" : ""; + string infoLine = buttons.HasFlag(PlayerButtons.Use) ? $"{Localization.GetTranslation("pilot")}:
" : ""; string remainingLine = buttons.HasFlag(PlayerButtons.Use) ? - (pilotInfo.CanUsePilot ? $"{fuelPercentage:F0}%
" : "W trakcie odnawiania
") : ""; + (pilotInfo.CanUsePilot ? $"{fuelPercentage:F0}%
" : $"{Localization.GetTranslation("pilot_hud_info")}
") : ""; if (buttons.HasFlag(PlayerButtons.Use)) { diff --git a/jRandomSkills - SRC Files/src/player/skills/Planter.cs b/jRandomSkills - SRC Files/src/player/skills/Planter.cs new file mode 100644 index 0000000..820db06 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Planter.cs @@ -0,0 +1,74 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Memory; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static CounterStrikeSharp.API.Core.Listeners; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Planter : ISkill + { + private static Skills skillName = Skills.Planter; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#7d7d7d"); + + Instance.RegisterEventHandler((@event, @info) => + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + Schema.SetSchemaValue(player.Pawn.Value.Handle, "CCSPlayerPawn", "m_bInBombZone", false); + } + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill != skillName) continue; + + var plantedBomb = Utilities.FindAllEntitiesByDesignerName("planted_c4").FirstOrDefault(); + if (plantedBomb != null) + { + Server.NextFrame(() => + { + plantedBomb.C4Blow = (float)Server.EngineTime + 60; + }); + } + } + + return HookResult.Continue; + }); + + Instance.RegisterListener(OnTick); + } + + public static void DisableSkill(CCSPlayerController player) + { + Schema.SetSchemaValue(player.Pawn.Value.Handle, "CCSPlayerPawn", "m_bInBombZone", false); + } + + private static void OnTick() + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + + if (playerInfo?.Skill == skillName) + Schema.SetSchemaValue(player.Pawn.Value.Handle, "CCSPlayerPawn", "m_bInBombZone", true); + } + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/QuickShot.cs b/jRandomSkills - SRC Files/src/player/skills/QuickShot.cs new file mode 100644 index 0000000..37d6328 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/QuickShot.cs @@ -0,0 +1,41 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Modules.Memory; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static CounterStrikeSharp.API.Core.Listeners; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class QuickShot : ISkill + { + private static Skills skillName = Skills.QuickShot; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#8a42f5"); + Instance.RegisterListener(OnTick); + } + + private static void OnTick() + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + + if (playerInfo?.Skill == skillName) + { + var weapon = player.Pawn.Value.WeaponServices?.ActiveWeapon.Value; + if (weapon == null) continue; + + Schema.SetSchemaValue(weapon.Handle, "CBasePlayerWeapon", "m_nNextPrimaryAttackTick", Server.TickCount); + Schema.SetSchemaValue(weapon.Handle, "CBasePlayerWeapon", "m_nNextSecondaryAttackTick", Server.TickCount); + } + } + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/RadarHack.cs b/jRandomSkills - SRC Files/src/player/skills/RadarHack.cs new file mode 100644 index 0000000..b460569 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/RadarHack.cs @@ -0,0 +1,58 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using jRandomSkills.src.player; +using static CounterStrikeSharp.API.Core.Listeners; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class RadarHack : ISkill + { + private static Skills skillName = Skills.RadarHack; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#2effcb"); + Instance.RegisterListener(CheckRadarowiec); + } + + private static void CheckRadarowiec() + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + { + SetEnemiesVisibleOnRadar(player); + } + } + } + + private static void SetEnemiesVisibleOnRadar(CCSPlayerController player) + { + if (player == null || !player.IsValid || player.PlayerPawn?.Value == null) return; + int playerIndex = (int)player.Index - 1; + + foreach (var enemy in Utilities.GetPlayers().FindAll(p => p.Team != player.Team && p.PawnIsAlive)) + { + var enemyPawn = enemy.PlayerPawn.Value; + if (enemyPawn == null) continue; + enemyPawn.EntitySpottedState.SpottedByMask[0] |= (1u << (int)(playerIndex % 32)); + + } + + var bombEntities = Utilities.FindAllEntitiesByDesignerName("weapon_c4").ToList(); + if (bombEntities.Any()) + { + var bomb = bombEntities.FirstOrDefault(); + if (bomb != null) + bomb.EntitySpottedState.SpottedByMask[0] |= (1u << (int)(playerIndex % 32)); + } + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Rambo.cs b/jRandomSkills - SRC Files/src/player/skills/Rambo.cs new file mode 100644 index 0000000..1dba9bf --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Rambo.cs @@ -0,0 +1,70 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using jRandomSkills.src.player; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Rambo : ISkill + { + private static Skills skillName = Skills.Rambo; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#009905"); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + EnableSkill(player); + } + }); + return HookResult.Continue; + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + int healthBonus = Instance.Random.Next(50, 501); + AddHealth(player, healthBonus); + } + + public static void DisableSkill(CCSPlayerController player) + { + ResetHealth(player); + } + + public static void AddHealth(CCSPlayerController player, int health) + { + var pawn = player.PlayerPawn?.Value; + if (pawn == null) return; + + pawn.MaxHealth = Math.Min(pawn.Health + health, 1000); + Utilities.SetStateChanged(pawn, "CBaseEntity", "m_iMaxHealth"); + + pawn.Health = pawn.MaxHealth; + Utilities.SetStateChanged(pawn, "CBaseEntity", "m_iHealth"); + } + + public static void ResetHealth(CCSPlayerController player) + { + var pawn = player.PlayerPawn?.Value; + if (pawn == null) return; + + pawn.MaxHealth = 100; + Utilities.SetStateChanged(pawn, "CBaseEntity", "m_iMaxHealth"); + + pawn.Health = Math.Min(pawn.Health, 100); + Utilities.SetStateChanged(pawn, "CBaseEntity", "m_iHealth"); + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/RandomWeapon.cs b/jRandomSkills - SRC Files/src/player/skills/RandomWeapon.cs new file mode 100644 index 0000000..6cd9d40 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/RandomWeapon.cs @@ -0,0 +1,191 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using System.Collections.Immutable; +using static CounterStrikeSharp.API.Core.Listeners; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class RandomWeapon : ISkill + { + private static Skills skillName = Skills.RandomWeapon; + private static float timerCooldown = (float)(Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Cooldown); + private static readonly Dictionary SkillPlayerInfo = new Dictionary(); + + private static string[] pistols = { "weapon_deagle", "weapon_revolver", "weapon_glock", "weapon_usp_silencer", + "weapon_cz75a", "weapon_fiveseven", "weapon_p250", "weapon_tec9", "weapon_elite", "weapon_hkp2000" }; + + private static string[] rifles = { "weapon_mp9", "weapon_mac10", "weapon_bizon", "weapon_mp7", "weapon_ump45", "weapon_p90", + "weapon_mp5sd", "weapon_famas", "weapon_galilar", "weapon_m4a1", "weapon_m4a1_silencer", "weapon_ak47", + "weapon_aug", "weapon_sg553", "weapon_ssg08", "weapon_awp", "weapon_scar20", "weapon_g3sg1", + "weapon_nova", "weapon_xm1014", "weapon_mag7", "weapon_sawedoff", "weapon_m249", "weapon_negev" }; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#e0873a"); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + { + EnableSkill(player); + } + } + }); + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + SkillPlayerInfo.Clear(); + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + var player = @event.Userid; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + if (SkillPlayerInfo.ContainsKey(player.SteamID)) + SkillPlayerInfo.Remove(player.SteamID); + + return HookResult.Continue; + }); + + Instance.RegisterListener(() => + { + 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); + } + }); + + Instance.AddCommand("css_useSkill", "Use Skill", (player, _) => + { + if (player == null) return; + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + UseSkill(player); + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + { + SteamID = player.SteamID, + CanUse = true, + Cooldown = DateTime.MinValue, + LastClick = DateTime.MinValue, + }; + } + + public static void DisableSkill(CCSPlayerController player) + { + if (SkillPlayerInfo.ContainsKey(player.SteamID)) + SkillPlayerInfo.Remove(player.SteamID); + } + + private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) + { + float cooldown = 0; + if (skillInfo != null) + { + float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + cooldown = Math.Max(time, 0); + + if (cooldown == 0 && skillInfo?.CanUse == false) + skillInfo.CanUse = true; + } + + var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); + if (skillData == null) return; + + string infoLine = $"{Localization.GetTranslation("your_skill")}:
"; + string skillLine = $"{skillData.Name}
"; + string remainingLine = cooldown != 0 ? $"{Localization.GetTranslation("hud_info", $"{cooldown}")}
" : ""; + + var hudContent = infoLine + skillLine + remainingLine; + player.PrintToCenterHtml(hudContent); + } + + private 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; + RemoveAndGiveWeapon(player); + } + else + skillInfo.LastClick = DateTime.Now; + } + } + + private static void RemoveAndGiveWeapon(CCSPlayerController player) + { + List playerWeapons = new List(); + foreach (var item in player?.PlayerPawn?.Value?.WeaponServices?.MyWeapons) + if (!string.IsNullOrEmpty(item?.Value?.DesignerName)) + playerWeapons.Add(item?.Value?.DesignerName); + + if (playerWeapons.Count == 0) + return; + + List weaponList = new List(pistols.Concat(rifles)); + weaponList.RemoveAll(w => playerWeapons.Contains(w)); + + if (weaponList.Count == 0) + return; + + string weapon = weaponList[Instance.Random.Next(weaponList.Count)]; + bool isPistol = pistols.Contains(weapon); + + string? weaponToRemove = playerWeapons.FirstOrDefault(itemName => + (isPistol && pistols.Contains(itemName)) || (!isPistol && rifles.Contains(itemName))); + + if (!string.IsNullOrEmpty(weaponToRemove)) + { + foreach (var item in player.PlayerPawn.Value.WeaponServices.MyWeapons) + { + if (item != null && item.Value != null && item.Value.DesignerName == weaponToRemove) + item.Value.Remove(); + } + } + + Instance.AddTimer(.1f, () => + { + player.GiveNamedItem(weapon); + }); + } + + public class PlayerSkillInfo + { + public ulong SteamID { get; set; } + public bool CanUse { get; set; } + public DateTime Cooldown { get; set; } + public DateTime LastClick { get; set; } + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Retreat.cs b/jRandomSkills - SRC Files/src/player/skills/Retreat.cs new file mode 100644 index 0000000..087703e --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Retreat.cs @@ -0,0 +1,166 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static CounterStrikeSharp.API.Core.Listeners; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Retreat : ISkill + { + private static Skills skillName = Skills.Retreat; + private static float timerCooldown = (float)(Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Cooldown); + private static readonly Dictionary SkillPlayerInfo = new Dictionary(); + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#a86eff"); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + { + EnableSkill(player); + } + } + }); + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + SkillPlayerInfo.Clear(); + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + var player = @event.Userid; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + if (SkillPlayerInfo.ContainsKey(player.SteamID)) + SkillPlayerInfo.Remove(player.SteamID); + + return HookResult.Continue; + }); + + Instance.RegisterListener(() => + { + 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); + } + }); + + Instance.AddCommand("css_useSkill", "Use Skill", (player, _) => + { + if (player == null) return; + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + UseSkill(player); + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + { + SteamID = player.SteamID, + CanUse = true, + Cooldown = DateTime.MinValue, + LastClick = DateTime.MinValue, + }; + } + + public static void DisableSkill(CCSPlayerController player) + { + if (SkillPlayerInfo.ContainsKey(player.SteamID)) + SkillPlayerInfo.Remove(player.SteamID); + } + + private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) + { + float cooldown = 0; + if (skillInfo != null) + { + float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + cooldown = Math.Max(time, 0); + + if (cooldown == 0 && skillInfo?.CanUse == false) + skillInfo.CanUse = true; + } + + var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); + if (skillData == null) return; + + string infoLine = $"{Localization.GetTranslation("your_skill")}:
"; + string skillLine = $"{skillData.Name}
"; + string remainingLine = cooldown != 0 ? $"{Localization.GetTranslation("hud_info", $"{cooldown}")}
" : ""; + + var hudContent = infoLine + skillLine + remainingLine; + player.PrintToCenterHtml(hudContent); + } + + private static void ActiveUse(CCSPlayerController player) + { + if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) + { + skillInfo.CanUse = true; + } + } + + private 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; + playerPawn.Teleport(GetSpawnVector(player)); + } + else + skillInfo.LastClick = DateTime.Now; + } + } + + private static Vector GetSpawnVector(CCSPlayerController player) + { + var abs = player.PlayerPawn.Value.AbsOrigin; + var spawns = Utilities.FindAllEntitiesByDesignerName(player.Team == CsTeam.Terrorist ? "info_player_terrorist" : "info_player_counterterrorist").ToList(); + if (spawns.Any()) + { + var randomSpawn = spawns[Instance.Random.Next(spawns.Count)]; + return randomSpawn.AbsOrigin; + } + return new Vector(abs.X, abs.Y, abs.Z); + } + + public class PlayerSkillInfo + { + public ulong SteamID { get; set; } + public bool CanUse { get; set; } + public DateTime Cooldown { get; set; } + public DateTime LastClick { get; set; } + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/RichBoy.cs b/jRandomSkills - SRC Files/src/player/skills/RichBoy.cs new file mode 100644 index 0000000..215d3ba --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/RichBoy.cs @@ -0,0 +1,63 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using jRandomSkills.src.player; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class RichBoy : ISkill + { + private static Skills skillName = Skills.RichBoy; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#D4AF37"); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + + if (playerInfo?.Skill == skillName) + { + int moneyBonus = Instance.Random.Next(5000, 15000); + playerInfo.SkillChance = moneyBonus; + AddMoney(player, moneyBonus); + } + } + }); + return HookResult.Continue; + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + int moneyBonus = Instance.Random.Next(5000, 15000); + playerInfo.SkillChance = moneyBonus; + AddMoney(player, moneyBonus); + } + + public static void DisableSkill(CCSPlayerController player) + { + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + AddMoney(player, -(int)playerInfo.SkillChance); + } + + private static void AddMoney(CCSPlayerController player, int money) + { + var moneyServices = player?.InGameMoneyServices; + + if (moneyServices == null) return; + + moneyServices.Account = Math.Max(moneyServices.Account + money, 0); + Utilities.SetStateChanged(player, "CCSPlayerController", "m_pInGameMoneyServices"); + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Saper.cs b/jRandomSkills - SRC Files/src/player/skills/Saper.cs new file mode 100644 index 0000000..7847c7b --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Saper.cs @@ -0,0 +1,66 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Saper : ISkill + { + private static Skills skillName = Skills.Saper; + + public static void LoadSkill() + { + Utils.RegisterSkill(skillName, "#8A2BE2"); + + Instance.RegisterEventHandler((@event, info) => + { + var player = @event.Userid; + + if (!Instance.IsPlayerValid(player)) return HookResult.Continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + { + var bombEntities = Utilities.FindAllEntitiesByDesignerName("weapon_c4").ToList(); + + if (bombEntities.Any()) + { + var bomb = bombEntities.FirstOrDefault(); + if (bomb != null) + { + bomb.BombPlacedAnimation = false; + bomb.ArmedTime = 0.0f; + } + } + } + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + var player = @event.Userid; + + if (Instance.IsPlayerValid(player)) + { + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + { + var plantedBomb = Utilities.FindAllEntitiesByDesignerName("planted_c4").FirstOrDefault(); + if (plantedBomb != null) + { + Server.NextFrame(() => + { + plantedBomb.DefuseCountDown = 0; + }); + } + } + } + + return HookResult.Continue; + }); + } + } +} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Cien.cs b/jRandomSkills - SRC Files/src/player/skills/Shade.cs similarity index 74% rename from [ D3X ] dRandomSkills - SRC Files/src/player/skills/Cien.cs rename to jRandomSkills - SRC Files/src/player/skills/Shade.cs index 6cdd898..8b9433b 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Cien.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Shade.cs @@ -1,41 +1,39 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; -using static dRandomSkills.dRandomSkills; +using jRandomSkills.src.player; +using static jRandomSkills.jRandomSkills; -namespace dRandomSkills +namespace jRandomSkills { - public static class Cien + public class Shade : ISkill { + private static Skills skillName = Skills.Shade; private const float TeleportDistance = 100.0f; - public static void LoadCien() + public static void LoadSkill() { - Utils.RegisterSkill("Cień", "Teleportujesz się za plecy trafionego wroga", "#18171A"); + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#18171A"); Instance.RegisterEventHandler((@event, info) => { var attacker = @event.Attacker; var victim = @event.Userid; - if (!IsPlayerValid(attacker) || !IsPlayerValid(victim)) return HookResult.Continue; + if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim)) return HookResult.Continue; var victimInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == victim.SteamID); var attackerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); - if (attackerInfo?.Skill == "Cień") - { + if (attackerInfo?.Skill == skillName) TeleportAttackerBehindVictim(attacker, victim); - } return HookResult.Continue; }); } - private static bool IsPlayerValid(CCSPlayerController player) - { - return player != null && player.IsValid && player.PlayerPawn?.Value != null; - } - private static void TeleportAttackerBehindVictim(CCSPlayerController attacker, CCSPlayerController victim) { var victimPawn = victim.PlayerPawn.Value; diff --git a/jRandomSkills - SRC Files/src/player/skills/Silent.cs b/jRandomSkills - SRC Files/src/player/skills/Silent.cs new file mode 100644 index 0000000..5796991 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Silent.cs @@ -0,0 +1,41 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Silent : ISkill + { + private static Skills skillName = Skills.Silent; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#333333"); + + Instance.HookUserMessage(208, um => + { + var soundevent = um.ReadUInt("soundevent_hash"); + var userIndex = um.ReadUInt("source_entity_index"); + + if (userIndex == 0) return HookResult.Continue; + + if (!Instance.footstepSoundEvents.Contains(soundevent) && !Instance.silentSoundEvents.Contains(soundevent)) + return HookResult.Continue; + + var player = Utilities.GetPlayers().FirstOrDefault(p => p.Pawn.Value.Index == userIndex); + if (!Instance.IsPlayerValid(player)) return HookResult.Continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill != skillName) return HookResult.Continue; + + um.Recipients.Clear(); + return HookResult.Handled; + }, HookMode.Pre); + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Soldier.cs b/jRandomSkills - SRC Files/src/player/skills/Soldier.cs new file mode 100644 index 0000000..708feeb --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Soldier.cs @@ -0,0 +1,79 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Memory; +using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Soldier : ISkill + { + private static Skills skillName = Skills.Soldier; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#09ba00", false); + VirtualFunctions.CBaseEntity_TakeDamageOldFunc.Hook(OnTakeDamage, HookMode.Pre); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill != skillName) continue; + EnableSkill(player); + } + }); + + return HookResult.Continue; + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + float newScale = (float)Instance.Random.NextDouble() * (1.35f - 1.15f) + 1.15f; + playerInfo.SkillChance = newScale; + newScale = (float)Math.Round(newScale, 2); + Utils.PrintToChat(player, $"{ChatColors.DarkRed}{Localization.GetTranslation("soldier")}{ChatColors.Lime}: " + Localization.GetTranslation("soldier_desc2", newScale), false); + } + + private static HookResult OnTakeDamage(DynamicHook h) + { + CEntityInstance param = h.GetParam(0); + CTakeDamageInfo param2 = h.GetParam(1); + + if (param == null || param2 == null || param2.Attacker == null) + return HookResult.Continue; + + CCSPlayerPawn attackerPawn = new CCSPlayerPawn(param2.Attacker.Value.Handle); + CCSPlayerPawn victimPawn = new CCSPlayerPawn(param.Handle); + + if (attackerPawn == null || attackerPawn.Controller?.Value == null || victimPawn == null || victimPawn.Controller?.Value == null) + return HookResult.Continue; + + CCSPlayerController attacker = attackerPawn.Controller.Value.As(); + CCSPlayerController victim = victimPawn.Controller.Value.As(); + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); + if (playerInfo == null) return HookResult.Continue; + + if (playerInfo.Skill == skillName && attacker.PawnIsAlive) + { + param2.Damage *= (float)playerInfo.SkillChance; + } + + return HookResult.Continue; + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/SwapPosition.cs b/jRandomSkills - SRC Files/src/player/skills/SwapPosition.cs new file mode 100644 index 0000000..57e3f4d --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/SwapPosition.cs @@ -0,0 +1,193 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static CounterStrikeSharp.API.Core.Listeners; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class SwapPosition : ISkill + { + private static Skills skillName = Skills.SwapPosition; + private static float timerCooldown = (float)(Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Cooldown); + private static readonly Dictionary SkillPlayerInfo = new Dictionary(); + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#1466F5"); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + { + EnableSkill(player); + } + } + }); + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + SkillPlayerInfo.Clear(); + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + var player = @event.Userid; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + if (SkillPlayerInfo.ContainsKey(player.SteamID)) + SkillPlayerInfo.Remove(player.SteamID); + + return HookResult.Continue; + }); + + Instance.RegisterListener(() => + { + 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)) + if (skillInfo.LastClick.AddSeconds(4) >= DateTime.Now) + UpdateHUD(player, skillInfo, true); + else + UpdateHUD(player, skillInfo, false); + } + }); + + Instance.AddCommand("css_useSkill", "Use Skill", (player, _) => + { + if (player == null) return; + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + UseSkill(player); + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + SkillPlayerInfo[player.SteamID] = new ZamianaMiejsc_PlayerInfo + { + SteamID = player.SteamID, + CanUse = true, + Cooldown = DateTime.MinValue, + LastClick = DateTime.MinValue, + FindedEnemy = false, + }; + } + + public static void DisableSkill(CCSPlayerController player) + { + if (SkillPlayerInfo.ContainsKey(player.SteamID)) + SkillPlayerInfo.Remove(player.SteamID); + } + + private static void UpdateHUD(CCSPlayerController player, ZamianaMiejsc_PlayerInfo skillInfo, bool showInfo) + { + float cooldown = 0; + if (skillInfo != null) + { + float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + cooldown = Math.Max(time, 0); + + if (cooldown == 0 && skillInfo?.CanUse == false) + skillInfo.CanUse = true; + } + + var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); + if (skillData == null) return; + + string infoLine = $"{Localization.GetTranslation("your_skill")}:
"; + string skillLine = $"{skillData.Name}
"; + string remainingLine = ""; + + if (showInfo) + remainingLine = cooldown != 0 ? $"{Localization.GetTranslation("hud_info", $"{cooldown}")}
" + : !skillInfo.FindedEnemy ? $"{Localization.GetTranslation("hud_info_no_enemy")}
" + : ""; + else + remainingLine = cooldown != 0 ? $"{Localization.GetTranslation("hud_info", $"{cooldown}")}
" : ""; + + var hudContent = infoLine + skillLine + remainingLine; + player.PrintToCenterHtml(hudContent); + } + + private static void ActiveUse(CCSPlayerController player) + { + if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) + { + skillInfo.CanUse = true; + } + } + + private static void UseSkill(CCSPlayerController player) + { + var playerPawn = player.PlayerPawn.Value; + if (playerPawn?.CBodyComponent == null) return; + + if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) + { + List enemy = Utilities.GetPlayers().FindAll(p => Instance.IsPlayerValid(p) && p.Team != player.Team && p.PawnIsAlive); + if (enemy.Count == 0) + { + skillInfo.FindedEnemy = false; + skillInfo.LastClick = DateTime.Now; + return; + } + + CCSPlayerController randomEnemy = enemy[Instance.Random.Next(0, enemy.Count)]; + if (!player.IsValid || !player.PawnIsAlive || !randomEnemy.IsValid || !randomEnemy.PawnIsAlive) return; + if (skillInfo.CanUse) + { + skillInfo.FindedEnemy = true; + skillInfo.CanUse = false; + skillInfo.Cooldown = DateTime.Now; + TeleportPlayers(player, randomEnemy); + } + else + skillInfo.LastClick = DateTime.Now; + } + } + + private static void TeleportPlayers(CCSPlayerController attacker, CCSPlayerController victim) + { + var attackerPawn = attacker.PlayerPawn.Value; + var victimPawn = victim.PlayerPawn.Value; + + Vector attackerPosition = new Vector(attackerPawn.AbsOrigin.X, attackerPawn.AbsOrigin.Y, attackerPawn.AbsOrigin.Z); + QAngle attackerAngles = new QAngle(attackerPawn.AbsRotation.X, attackerPawn.AbsRotation.Y, attackerPawn.AbsRotation.Z); + Vector attackerVelocity = new Vector(attackerPawn.AbsVelocity.X, attackerPawn.AbsVelocity.Y, attackerPawn.AbsVelocity.Z); + + Vector victimPosition = new Vector(victimPawn.AbsOrigin.X, victimPawn.AbsOrigin.Y, victimPawn.AbsOrigin.Z); + QAngle victimAngles = new QAngle(victimPawn.AbsRotation.X, victimPawn.AbsRotation.Y, victimPawn.AbsRotation.Z); + Vector victimVelocity = new Vector(victimPawn.AbsVelocity.X, victimPawn.AbsVelocity.Y, victimPawn.AbsVelocity.Z); + + victimPawn.Teleport(attackerPosition, attackerAngles, attackerVelocity); + attackerPawn.Teleport(victimPosition, victimAngles, victimVelocity); + } + + public class ZamianaMiejsc_PlayerInfo + { + public ulong SteamID { get; set; } + public bool CanUse { get; set; } + public DateTime Cooldown { get; set; } + public DateTime LastClick { get; set; } + public bool FindedEnemy { get; set; } + } + } +} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Teleporter.cs b/jRandomSkills - SRC Files/src/player/skills/Teleporter.cs similarity index 73% rename from [ D3X ] dRandomSkills - SRC Files/src/player/skills/Teleporter.cs rename to jRandomSkills - SRC Files/src/player/skills/Teleporter.cs index b8b5ff0..f6b019c 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/player/skills/Teleporter.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Teleporter.cs @@ -1,27 +1,32 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; -using System.Numerics; -using static dRandomSkills.dRandomSkills; +using jRandomSkills.src.player; +using static jRandomSkills.jRandomSkills; using Vector = CounterStrikeSharp.API.Modules.Utils.Vector; -namespace dRandomSkills +namespace jRandomSkills { - public static class Teleporter + public class Teleporter : ISkill { - public static void LoadTeleporter() + private static Skills skillName = Skills.Teleporter; + + public static void LoadSkill() { - Utils.RegisterSkill("Teleportator", "Zamieniasz się miejscami z trafionym wrogiem", "#8A2BE2"); + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#8A2BE2"); Instance.RegisterEventHandler((@event, info) => { var victim = @event.Userid; var attacker = @event.Attacker; - if (!IsValidPlayer(victim) || !IsValidPlayer(attacker)) return HookResult.Continue; + if (!Instance.IsPlayerValid(victim) || !Instance.IsPlayerValid(attacker)) return HookResult.Continue; var attackerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == attacker.SteamID); - if (attackerInfo?.Skill == "Teleportator") + if (attackerInfo?.Skill == skillName) { TeleportPlayers(attacker, victim); } @@ -30,11 +35,6 @@ namespace dRandomSkills }); } - private static bool IsValidPlayer(CCSPlayerController player) - { - return player != null && player.IsValid && player.PlayerPawn != null && player.PlayerPawn.Value != null; - } - private static void TeleportPlayers(CCSPlayerController attacker, CCSPlayerController victim) { var attackerPawn = attacker.PlayerPawn.Value; diff --git a/jRandomSkills - SRC Files/src/player/skills/TimeManipulator.cs b/jRandomSkills - SRC Files/src/player/skills/TimeManipulator.cs new file mode 100644 index 0000000..e3d81b3 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/TimeManipulator.cs @@ -0,0 +1,155 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static CounterStrikeSharp.API.Core.Listeners; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class TimeManipulator : ISkill + { + private static Skills skillName = Skills.TimeManipulator; + private static float timerCooldown = (float)(Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Cooldown); + private static readonly Dictionary SkillPlayerInfo = new Dictionary(); + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#2ec761"); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + { + EnableSkill(player); + } + } + }); + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + SkillPlayerInfo.Clear(); + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + var player = @event.Userid; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + if (SkillPlayerInfo.ContainsKey(player.SteamID)) + SkillPlayerInfo.Remove(player.SteamID); + + return HookResult.Continue; + }); + + Instance.RegisterListener(() => + { + 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); + } + }); + + Instance.AddCommand("css_useSkill", "Use Skill", (player, _) => + { + if (player == null) return; + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + UseSkill(player); + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + { + SteamID = player.SteamID, + CanUse = true, + Cooldown = DateTime.MinValue, + LastClick = DateTime.MinValue, + }; + } + + public static void DisableSkill(CCSPlayerController player) + { + if (SkillPlayerInfo.ContainsKey(player.SteamID)) + SkillPlayerInfo.Remove(player.SteamID); + } + + private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo) + { + float cooldown = 0; + if (skillInfo != null) + { + float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + cooldown = Math.Max(time, 0); + + if (cooldown == 0 && skillInfo?.CanUse == false) + skillInfo.CanUse = true; + } + + var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); + if (skillData == null) return; + + string infoLine = $"{Localization.GetTranslation("your_skill")}:
"; + string skillLine = $"{skillData.Name}
"; + string remainingLine = cooldown != 0 ? $"{Localization.GetTranslation("hud_info", $"{cooldown}")}
" : ""; + + var hudContent = infoLine + skillLine + remainingLine; + player.PrintToCenterHtml(hudContent); + } + + private static void ActiveUse(CCSPlayerController player) + { + if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) + { + skillInfo.CanUse = true; + } + } + + private 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; + + Server.ExecuteCommand("host_timescale 0.1"); + Instance.AddTimer(.6f, () => Server.ExecuteCommand("host_timescale 1")); + } + else + skillInfo.LastClick = DateTime.Now; + } + } + + public class PlayerSkillInfo + { + public ulong SteamID { get; set; } + public bool CanUse { get; set; } + public DateTime Cooldown { get; set; } + public DateTime LastClick { get; set; } + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Wallhack.cs b/jRandomSkills - SRC Files/src/player/skills/Wallhack.cs new file mode 100644 index 0000000..675cec9 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Wallhack.cs @@ -0,0 +1,92 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Utils; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using System.Drawing; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Wallhack : ISkill + { + private static Skills skillName = Skills.Wallhack; + private static List glows = new List(); + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#5d00ff"); + + Instance.RegisterEventHandler((@event, @info) => + { + glows.Clear(); + Instance.AddTimer(.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + if (!Instance.IsPlayerValid(player)) continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + { + EnableSkill(player); + } + } + }); + return HookResult.Continue; + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + SetGlowEffectForEnemies(player); + } + + public static void DisableSkill(CCSPlayerController player) + { + foreach (var glow in glows) + { + glows.Remove(glow); + glow.Remove(); + } + } + + private static void SetGlowEffectForEnemies(CCSPlayerController player) + { + foreach (var enemy in Utilities.GetPlayers().FindAll(p => p.Team != player.Team && p.PawnIsAlive)) + { + var enemyPawn = enemy.PlayerPawn.Value; + var modelGlow = Utilities.CreateEntityByName("prop_dynamic"); + var modelRelay = Utilities.CreateEntityByName("prop_dynamic"); + + if (modelGlow == null || modelRelay == null) + return; + + modelRelay.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(modelRelay.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2)); + modelRelay.SetModel(enemyPawn!.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.ModelName); + modelRelay.Spawnflags = 256u; + modelRelay.RenderMode = RenderMode_t.kRenderNone; + modelRelay.DispatchSpawn(); + + modelGlow.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(modelGlow.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2)); + modelGlow.SetModel(enemyPawn!.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.ModelName); + modelGlow.Spawnflags = 256u; + modelGlow.Render = Color.FromArgb(1, 255, 255, 255); + modelGlow.DispatchSpawn(); + + modelGlow.Glow.GlowColorOverride = enemy.Team == CsTeam.Terrorist ? Color.FromArgb(255, 255, 165, 0) : Color.FromArgb(255, 173, 216, 230); + modelGlow.Glow.GlowRange = 5000; + modelGlow.Glow.GlowTeam = (int)player.Team; + modelGlow.Glow.GlowType = 3; + modelGlow.Glow.GlowRangeMin = 100; + + modelRelay.AcceptInput("FollowEntity", enemyPawn, modelRelay, "!activator"); + modelGlow.AcceptInput("FollowEntity", modelRelay, modelGlow, "!activator"); + glows.Add(modelRelay); + } + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/WeaponsSwap.cs b/jRandomSkills - SRC Files/src/player/skills/WeaponsSwap.cs new file mode 100644 index 0000000..1333101 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/WeaponsSwap.cs @@ -0,0 +1,224 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using jRandomSkills.src.player; +using jRandomSkills.src.utils; +using static CounterStrikeSharp.API.Core.Listeners; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class WeaponsSwap : ISkill + { + private static Skills skillName = Skills.WeaponsSwap; + private static float timerCooldown = (float)(Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Cooldown); + private static readonly Dictionary SkillPlayerInfo = new Dictionary(); + + private static string[] weapons = { "weapon_deagle", "weapon_revolver", "weapon_glock", "weapon_usp_silencer", + "weapon_cz75a", "weapon_fiveseven", "weapon_p250", "weapon_tec9", "weapon_elite", "weapon_hkp2000", + "weapon_mp9", "weapon_mac10", "weapon_bizon", "weapon_mp7", "weapon_ump45", "weapon_p90", + "weapon_mp5sd", "weapon_famas", "weapon_galilar", "weapon_m4a4", "weapon_m4a1_silencer", "weapon_ak47", + "weapon_aug", "weapon_sg553", "weapon_ssg08", "weapon_awp", "weapon_scar20", "weapon_g3sg1", + "weapon_nova", "weapon_xm1014", "weapon_mag7", "weapon_sawedoff", "weapon_m249", "weapon_negev" }; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#c7e03a"); + + Instance.RegisterEventHandler((@event, info) => + { + Instance.AddTimer(0.1f, () => + { + foreach (var player in Utilities.GetPlayers()) + { + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + { + EnableSkill(player); + } + } + }); + + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + SkillPlayerInfo.Clear(); + return HookResult.Continue; + }); + + Instance.RegisterEventHandler((@event, info) => + { + var player = @event.Userid; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + if (SkillPlayerInfo.ContainsKey(player.SteamID)) + SkillPlayerInfo.Remove(player.SteamID); + + return HookResult.Continue; + }); + + Instance.RegisterListener(() => + { + 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)) + if (skillInfo.LastClick.AddSeconds(4) >= DateTime.Now) + UpdateHUD(player, skillInfo, true); + else + UpdateHUD(player, skillInfo, false); + } + }); + + Instance.AddCommand("css_useSkill", "Use Skill", (player, _) => + { + if (player == null) return; + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + if (playerInfo?.Skill == skillName) + UseSkill(player); + }); + } + + public static void EnableSkill(CCSPlayerController player) + { + SkillPlayerInfo[player.SteamID] = new PlayerSkillInfo + { + SteamID = player.SteamID, + CanUse = true, + Cooldown = DateTime.MinValue, + LastClick = DateTime.MinValue, + FindedEnemy = true, + HaveWeapon = true, + }; + } + + public static void DisableSkill(CCSPlayerController player) + { + if (SkillPlayerInfo.ContainsKey(player.SteamID)) + SkillPlayerInfo.Remove(player.SteamID); + } + + private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo, bool showInfo) + { + float cooldown = 0; + if (skillInfo != null) + { + float time = (int)(skillInfo.Cooldown.AddSeconds(timerCooldown) - DateTime.Now).TotalSeconds; + cooldown = Math.Max(time, 0); + + if (cooldown == 0 && skillInfo?.CanUse == false) + skillInfo.CanUse = true; + } + + var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == skillName); + if (skillData == null) return; + + string infoLine = $"{Localization.GetTranslation("your_skill")}:
"; + string skillLine = $"{skillData.Name}
"; + string remainingLine = ""; + + if (showInfo) + remainingLine = cooldown != 0 ? $"{Localization.GetTranslation("hud_info", $"{cooldown}")}
" + : !skillInfo.FindedEnemy ? $"{Localization.GetTranslation("hud_info_no_enemy")}
" + : !skillInfo.HaveWeapon ? $"{Localization.GetTranslation("weaponsswap_hud_info")}
" + : ""; + else + remainingLine = cooldown != 0 ? $"{Localization.GetTranslation("hud_info", $"{cooldown}")}
" : ""; + + var hudContent = infoLine + skillLine + remainingLine; + player.PrintToCenterHtml(hudContent); + } + + private static void ActiveUse(CCSPlayerController player) + { + if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo)) + { + skillInfo.CanUse = true; + } + } + + private 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) + { + CCSPlayerController enemy = GetRandomEnemy(player); + if (enemy == null) + { + skillInfo.FindedEnemy = false; + skillInfo.LastClick = DateTime.Now; + return; + } + + string[]? playerWeapon = GetWeapons(player); + string[]? enemyWeapon = GetWeapons(enemy); + + if (playerWeapon.FirstOrDefault(w => weapons.Contains(w)) == null) + { + skillInfo.FindedEnemy = true; + skillInfo.HaveWeapon = false; + skillInfo.LastClick = DateTime.Now; + return; + } + + skillInfo.HaveWeapon = true; + skillInfo.FindedEnemy = true; + skillInfo.CanUse = false; + skillInfo.Cooldown = DateTime.Now; + + player.RemoveWeapons(); + enemy.RemoveWeapons(); + GiveWeapons(player, enemyWeapon, playerWeapon.Contains("weapon_c4")); + GiveWeapons(enemy, playerWeapon, enemyWeapon.Contains("weapon_c4")); + } + else + skillInfo.LastClick = DateTime.Now; + } + } + + private static string[]? GetWeapons(CCSPlayerController player) + { + List playerWeapons = new List(); + foreach (var weapon in player.PlayerPawn.Value.WeaponServices.MyWeapons) + playerWeapons.Add(weapon?.Value?.DesignerName); + return playerWeapons.Count == 0 ? null : playerWeapons.ToArray(); + } + + private static void GiveWeapons(CCSPlayerController player, string[] weapons, bool addC4) + { + foreach (var weapon in weapons) + if (weapon != "weapon_c4") + player.GiveNamedItem(weapon); + if (addC4) + player.GiveNamedItem("weapon_c4"); + } + + private static CCSPlayerController GetRandomEnemy(CCSPlayerController player) + { + CCSPlayerController[] enemies = Utilities.GetPlayers().FindAll(e => e.Team != player.Team).ToArray(); + if (enemies.Length == 0) return null; + return enemies[Instance.Random.Next(enemies.Length)]; + } + + public class PlayerSkillInfo + { + public ulong SteamID { get; set; } + public bool CanUse { get; set; } + public DateTime Cooldown { get; set; } + public DateTime LastClick { get; set; } + public bool FindedEnemy { get; set; } + public bool HaveWeapon { get; set; } + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/player/skills/Zeus.cs b/jRandomSkills - SRC Files/src/player/skills/Zeus.cs new file mode 100644 index 0000000..7d054e6 --- /dev/null +++ b/jRandomSkills - SRC Files/src/player/skills/Zeus.cs @@ -0,0 +1,44 @@ +using CounterStrikeSharp.API.Core; +using jRandomSkills.src.player; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public class Zeus : ISkill + { + private static Skills skillName = Skills.Zeus; + + public static void LoadSkill() + { + if (Config.config.SkillsInfo.FirstOrDefault(s => s.Name == skillName.ToString())?.Active != true) + return; + + Utils.RegisterSkill(skillName, "#fbff00"); + + Instance.RegisterEventHandler((@event, info) => + { + var player = @event.Userid; + if (!Instance.IsPlayerValid(player)) return HookResult.Continue; + + var playerInfo = Instance.skillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID); + + if (playerInfo?.Skill == skillName) + { + var activeWeapon = player.Pawn.Value.WeaponServices.ActiveWeapon.Value; + if (activeWeapon?.DesignerName != "weapon_taser") return HookResult.Continue; + var taser = activeWeapon.As(); + Instance.AddTimer(.1f, () => + { + if (taser.IsValid) + { + taser.LastAttackTick = 0; + taser.FireTime = 0; + } + }); + } + + return HookResult.Continue; + }); + } + } +} \ No newline at end of file diff --git a/jRandomSkills - SRC Files/src/utils/Config.cs b/jRandomSkills - SRC Files/src/utils/Config.cs new file mode 100644 index 0000000..c2a39e2 --- /dev/null +++ b/jRandomSkills - SRC Files/src/utils/Config.cs @@ -0,0 +1,153 @@ +using jRandomSkills.src.player; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using System.Diagnostics.Metrics; +using static jRandomSkills.jRandomSkills; + +namespace jRandomSkills +{ + public static class Config + { + private static readonly string configPath = Path.Combine(Instance.ModuleDirectory, "Config.json"); + public static ConfigModel config; + private static FileSystemWatcher fileWatcher; + + public static ConfigModel LoadedConfig => config; + + public static void Initialize() + { + config = LoadConfig(); + SetupFileWatcher(); + } + + private static ConfigModel LoadConfig() + { + if (!File.Exists(configPath)) + { + Instance.Logger.LogInformation("Config file does not exist. Create a new config file..."); + var defaultConfig = new ConfigModel(); + SaveConfig(defaultConfig); + return defaultConfig; + } + + try + { + string json = File.ReadAllText(configPath); + return JsonConvert.DeserializeObject(json) ?? new ConfigModel(); + } + catch (Exception ex) + { + Instance.Logger.LogError($"Error when loading the config file."); + return new ConfigModel(); + } + } + + public static void SaveConfig(ConfigModel config) + { + try + { + string json = JsonConvert.SerializeObject(config, Formatting.Indented); + File.WriteAllText(configPath, json); + } + catch (Exception ex) + { + Instance.Logger.LogError($"Error when saving the config file: {ex.Message}"); + } + } + + private static void SetupFileWatcher() + { + fileWatcher = new FileSystemWatcher(Path.GetDirectoryName(configPath)) + { + Filter = Path.GetFileName(configPath), + NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size + }; + + fileWatcher.Changed += (sender, e) => config = LoadConfig(); + fileWatcher.EnableRaisingEvents = true; + } + + public class ConfigModel + { + public Settings Settings { get; set; } = new Settings(); + public SkillInfo[] SkillsInfo = { + new SkillInfo(Skills.None), + new SkillInfo(Skills.Dwarf, chanceFrom : .6f, chanceTo : .95f), + new SkillInfo(Skills.SwapPosition, cooldown: 30), + new SkillInfo(Skills.FrozenDecoy), + new SkillInfo(Skills.Soldier), + new SkillInfo(Skills.Armored, chanceFrom : .65f, chanceTo : .85f), + new SkillInfo(Skills.Aimbot, only1v1: true), + new SkillInfo(Skills.Retreat, cooldown: 15), + new SkillInfo(Skills.EnemySpawn, cooldown: 15), + new SkillInfo(Skills.Zeus), + new SkillInfo(Skills.RadarHack), + new SkillInfo(Skills.QuickShot), + new SkillInfo(Skills.Planter, team: 2), + new SkillInfo(Skills.Silent), + new SkillInfo(Skills.KillerFlash), + new SkillInfo(Skills.TimeManipulator, cooldown: 30), + new SkillInfo(Skills.GodMode, cooldown: 30), + new SkillInfo(Skills.RandomWeapon, cooldown: 15), + new SkillInfo(Skills.WeaponsSwap, cooldown: 30), + new SkillInfo(Skills.Wallhack), + new SkillInfo(Skills.Flash, chanceFrom : 1.2f, chanceTo : 3.0f), + new SkillInfo(Skills.PawelJumper), + new SkillInfo(Skills.BunnyHop), + new SkillInfo(Skills.Impostor), + new SkillInfo(Skills.OneShot), + new SkillInfo(Skills.Muhammed), + new SkillInfo(Skills.RichBoy), + new SkillInfo(Skills.Rambo), + new SkillInfo(Skills.Medic), + new SkillInfo(Skills.Ghost), + new SkillInfo(Skills.Chicken), + new SkillInfo(Skills.Astronaut, chanceFrom : .1f, chanceTo : .7f), + new SkillInfo(Skills.Disarmament, chanceFrom: .2f, chanceTo: .4f), + new SkillInfo(Skills.AntyFlash), + new SkillInfo(Skills.Behind, chanceFrom: .2f, chanceTo: .4f), + new SkillInfo(Skills.InfiniteAmmo), + new SkillInfo(Skills.Catapult, chanceFrom : .2f, chanceTo : .4f), + new SkillInfo(Skills.Dracula), + new SkillInfo(Skills.Teleporter), + new SkillInfo(Skills.Saper), + new SkillInfo(Skills.Phoenix, chanceFrom: .2f, chanceTo: .4f), + new SkillInfo(Skills.Pilot), + new SkillInfo(Skills.Shade), + new SkillInfo(Skills.AntyHead), + }; + } + + public class Settings + { + public string LangCode { get; set; } = "en"; + public string Set_Skill { get; set; } = "ustawskill, setskill"; + public string SkillsList_Menu { get; set; } = "supermoc, skille, listamocy, supermoce, losowemoce"; + public bool KillerSkillInfo { get; set; } = true; + public bool TeamMateSkillInfo { get; set; } = true; + public bool SummaryAfterTheRound { get; set; } = true; + } + + public class SkillInfo + { + public string Name { get; set; } + public bool Active { get; set; } + public float Cooldown { get; set; } + public float ChanceFrom { get; set; } + public float ChanceTo { get; set; } + public int Team { get; set; } + public bool Only1v1 { get; set; } + + public SkillInfo(Skills skill, bool active = true, float cooldown = 15f, float chanceFrom = 1, float chanceTo = 1, int team = 1, bool only1v1 = false) + { + Name = skill.ToString(); + Active = active; + Cooldown = cooldown; + ChanceFrom = chanceFrom; + ChanceTo = chanceTo; + Team = team; + Only1v1 = only1v1; + } + } + } +} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - SRC Files/src/utils/Findtarget.cs b/jRandomSkills - SRC Files/src/utils/Findtarget.cs similarity index 88% rename from [ D3X ] dRandomSkills - SRC Files/src/utils/Findtarget.cs rename to jRandomSkills - SRC Files/src/utils/Findtarget.cs index 1861201..443560a 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/utils/Findtarget.cs +++ b/jRandomSkills - SRC Files/src/utils/Findtarget.cs @@ -1,9 +1,10 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Commands; using CounterStrikeSharp.API.Modules.Commands.Targeting; -using static dRandomSkills.dRandomSkills; +using jRandomSkills.src.utils; +using static jRandomSkills.jRandomSkills; -namespace dRandomSkills; +namespace jRandomSkills; public class FindTarget { @@ -26,14 +27,14 @@ public class FindTarget { if (!ignoreMessage) { - command.ReplyToCommand("Nie znaleziono pasującego gracza."); + command.ReplyToCommand(Localization.GetTranslation("no_player")); } return (new List(), string.Empty); } else if (singletarget && targetresult.Players.Count > 1) { - command.ReplyToCommand("Znaleziono więcej niż jednego gracza o tej samej nazwie."); + command.ReplyToCommand(Localization.GetTranslation("duplicate_player")); return (new List(), string.Empty); } diff --git a/jRandomSkills - SRC Files/src/utils/Localization.cs b/jRandomSkills - SRC Files/src/utils/Localization.cs new file mode 100644 index 0000000..6189611 --- /dev/null +++ b/jRandomSkills - SRC Files/src/utils/Localization.cs @@ -0,0 +1,57 @@ +using CounterStrikeSharp.API.Modules.Utils; +using System.Text.Json; + +namespace jRandomSkills.src.utils +{ + public static class Localization + { + private static readonly string path = Path.Combine(jRandomSkills.Instance.ModuleDirectory, "lang"); + private static readonly Dictionary> _translations = new Dictionary>(); + private static string langCode = "pl"; + + public static void Load() + { + _translations.Clear(); + SetLangCode(); + LoadAllLanguages(); + } + + private static void SetLangCode() + { + langCode = Config.config.Settings.LangCode; + } + + private static void LoadAllLanguages() + { + if (!Directory.Exists(path)) + return; + + foreach (var file in Directory.GetFiles(path, "*.json")) + LoadLanguage(file); + } + + private static void LoadLanguage(string langPath) + { + if (!File.Exists(langPath)) + return; + + var code = Path.GetFileNameWithoutExtension(langPath); + var jsonText = File.ReadAllText(langPath); + var translations = JsonSerializer.Deserialize>(jsonText); + + if (translations != null) + _translations[code] = translations; + } + + public static string GetTranslation(string key, params object[] args) + { + if (_translations.TryGetValue(langCode, out var langDict) && langDict.TryGetValue(key, out var translation)) + if (args.Length != 0 && args[0] == "welcome") + return translation; + else + return string.Format(translation, args).Replace("CHATCOLORS.RED", ChatColors.Red.ToString()); + + return key; + } + } +} diff --git a/[ D3X ] dRandomSkills - SRC Files/src/utils/Utils.cs b/jRandomSkills - SRC Files/src/utils/Utils.cs similarity index 54% rename from [ D3X ] dRandomSkills - SRC Files/src/utils/Utils.cs rename to jRandomSkills - SRC Files/src/utils/Utils.cs index 1f5a407..008c7a0 100644 --- a/[ D3X ] dRandomSkills - SRC Files/src/utils/Utils.cs +++ b/jRandomSkills - SRC Files/src/utils/Utils.cs @@ -1,22 +1,22 @@ using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.Utils; -using System.Diagnostics; +using jRandomSkills.src.player; -namespace dRandomSkills +namespace jRandomSkills { public static class Utils { public static void PrintToChat(CCSPlayerController player, string msg, bool isError) { string checkIcon = isError ? $"{ChatColors.DarkRed}✖{ChatColors.LightRed}" : $"{ChatColors.Green}✔{ChatColors.Lime}"; - player.PrintToChat($" {ChatColors.DarkRed}► {ChatColors.Green}[{ChatColors.DarkRed} LOSOWE MOCE {ChatColors.Green}] {checkIcon} {msg}"); + player.PrintToChat($" {ChatColors.DarkRed}► {ChatColors.Green}[{ChatColors.DarkRed} jRadnomSkills {ChatColors.Green}] {checkIcon} {msg}"); } - public static void RegisterSkill(string name, string description, string color, bool display = true) + public static void RegisterSkill(Skills skill, string color, bool display = true) { - if (!SkillData.Skills.Any(skill => skill.Name == name)) + if (!SkillData.Skills.Any(s => s.Skill == skill)) { - SkillData.Skills.Add(new dSkill_SkillInfo(name, description, color, display)); + SkillData.Skills.Add(new dSkill_SkillInfo(skill, color, display)); } } } diff --git a/jRandomSkills - Server Files/plugins/dRandomSkills/Config.json b/jRandomSkills - Server Files/plugins/dRandomSkills/Config.json new file mode 100644 index 0000000..b96ecc0 --- /dev/null +++ b/jRandomSkills - Server Files/plugins/dRandomSkills/Config.json @@ -0,0 +1,408 @@ +{ + "SkillsInfo": [ + { + "Name": "None", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Dwarf", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 0.6, + "ChanceTo": 0.95, + "Team": 1, + "Only1v1": false + }, + { + "Name": "SwapPosition", + "Active": true, + "Cooldown": 30.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "FrozenDecoy", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Soldier", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Armored", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 0.65, + "ChanceTo": 0.85, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Aimbot", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": true + }, + { + "Name": "Retreat", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "EnemySpawn", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Zeus", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "RadarHack", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "QuickShot", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Planter", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 2, + "Only1v1": false + }, + { + "Name": "Silent", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "KillerFlash", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "TimeManipulator", + "Active": true, + "Cooldown": 30.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "GodMode", + "Active": true, + "Cooldown": 30.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "RandomWeapon", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "WeaponsSwap", + "Active": true, + "Cooldown": 30.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Wallhack", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Flash", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.2, + "ChanceTo": 3.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "PawelJumper", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "BunnyHop", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Impostor", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "OneShot", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Muhammed", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "RichBoy", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Rambo", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Medic", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Ghost", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Chicken", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Astronaut", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 0.1, + "ChanceTo": 0.7, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Disarmament", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 0.2, + "ChanceTo": 0.4, + "Team": 1, + "Only1v1": false + }, + { + "Name": "AntyFlash", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Behind", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 0.2, + "ChanceTo": 0.4, + "Team": 1, + "Only1v1": false + }, + { + "Name": "InfiniteAmmo", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Catapult", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 0.2, + "ChanceTo": 0.4, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Dracula", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Teleporter", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Saper", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Phoenix", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 0.2, + "ChanceTo": 0.4, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Pilot", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "Shade", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + }, + { + "Name": "AntyHead", + "Active": true, + "Cooldown": 15.0, + "ChanceFrom": 1.0, + "ChanceTo": 1.0, + "Team": 1, + "Only1v1": false + } + ], + "Settings": { + "LangCode": "en", + "Set_Skill": "ustawskill, setskill", + "SkillsList_Menu": "supermoc, skille, listamocy, supermoce, losowemoce", + "KillerSkillInfo": true, + "TeamMateSkillInfo": true, + "SummaryAfterTheRound": true + } +} \ No newline at end of file diff --git a/[ D3X ] dRandomSkills - Server Files/plugins/dRandomSkills/Newtonsoft.Json.dll b/jRandomSkills - Server Files/plugins/dRandomSkills/Newtonsoft.Json.dll similarity index 100% rename from [ D3X ] dRandomSkills - Server Files/plugins/dRandomSkills/Newtonsoft.Json.dll rename to jRandomSkills - Server Files/plugins/dRandomSkills/Newtonsoft.Json.dll diff --git a/jRandomSkills - Server Files/plugins/dRandomSkills/jRandomSkills.dll b/jRandomSkills - Server Files/plugins/dRandomSkills/jRandomSkills.dll new file mode 100644 index 0000000000000000000000000000000000000000..96952e646cccd4a95b6164919284e23c03322d9e GIT binary patch literal 150016 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 S-?SC(mpAkOpXuKK2mUX!r-Q@* literal 0 HcmV?d00001 diff --git a/jRandomSkills - Server Files/plugins/dRandomSkills/lang/en.json b/jRandomSkills - Server Files/plugins/dRandomSkills/lang/en.json new file mode 100644 index 0000000..2cebf3d --- /dev/null +++ b/jRandomSkills - Server Files/plugins/dRandomSkills/lang/en.json @@ -0,0 +1,127 @@ +{ + "none_desc": "You have no skills", + "aimbot_desc": "Every bullet you hit counts as a headshot", + "antyflash_desc": "You are immune to flashes, and your flashes last 7 seconds", + "astronaut_desc": "You receive a random gravity value at the start of the round", + "astronaut_desc2": "Your random gravity is: {0}x", + "richboy_desc": "You receive a random amount of money at the start of the round", + "bunnyhop_desc": "You get auto BunnyHop", + "silent_desc": "Your footsteps and jumps are silent to OTHER players", + "shade_desc": "You teleport behind the back of a hit enemy", + "dracula_desc": "Hitting an enemy restores a percentage of the damage dealt as health", + "ghost_desc": "You are completely invisible", + "flash_desc": "Random player speed at the beginning of the round", + "flash_desc2": "Your speed multiplier is {0}x", + "godmode_desc": "You are immortal for 2 seconds. Press [css_useSkill], cooldown 30s", + "godmode_on": "Immortality enabled", + "godmode_off": "Immortality disabled", + "armored_desc": "You have a random damage taken multiplier", + "armored_desc2": "Your damage taken multiplier is: {0}x", + "muhammed_desc": "You explode upon death, killing nearby players", + "dwarf_desc": "Random character size at the start of the round", + "dwarf_desc2": "Your size multiplier is {0}x", + "medic_desc": "You receive a random number of medkits at the start of the round", + "randomweapon_desc": "You get a random weapon. Press [css_useSkill], cooldown 15s", + "chicken_desc": "You get a chicken model + 10% faster movement - 50 HP", + "impostor_desc": "You start the round with an enemy player model", + "catapult_desc": "You have a random chance to launch an enemy upwards", + "catapult_desc2": "Your chance to launch an enemy on hit is: {0}%", + "infiniteammo_desc": "You receive infinite ammo for all your weapons", + "behind_desc": "You have a random chance to turn an enemy 180 degrees on hit", + "behind_desc2": "Your chance to turn an enemy on hit is: {0}%", + "retreat_desc": "Return to spawn. Press [css_useSkill], cooldown 15s", + "oneshot_desc": "Hitting an enemy instantly kills them", + "paweljumper_desc": "You get an extra jump", + "phoenix_desc": "You have a random chance to respawn after death", + "phoenix_desc2": "Your chance to respawn after death: {0}%", + "phoenix_respawn": "You have been resurrected from the ashes thanks to the power of: CHATCOLORS.REDPhoenix", + "pilot_desc": "Fly for a limited time. Hold [USE - E] to fly", + "pilot_hud_info": "Recharging", + "radarhack_desc": "You can see enemies on the radar", + "rambo_desc": "You receive a random amount of health at the start of the round", + "enemyspawn_desc": "Teleport to enemy spawn. Press [css_useSkill], cooldown 15s", + "disarmament_desc": "You have a random chance to make an enemy drop their weapon on hit", + "disarmament_desc2": "Your chance to disarm an enemy is: {0}%", + "planter_desc": "You can plant the bomb anywhere; bomb detonation time is 60s", + "saper_desc": "You can plant and defuse bombs faster", + "timemanipulator_desc": "Slows down time for everyone for 6 seconds. Press [css_useSkill], cooldown 30s", + "quickshot_desc": "No cooldown when shooting", + "teleporter_desc": "You swap places with the hit enemy", + "wallhack_desc": "You can see enemies through walls", + "killer_flash_desc": "Every enemy fully blinded by your flashbang dies (including you)", + "weaponsswap_desc": "Swap weapons with a random enemy. Press [css_useSkill], cooldown 30s", + "weaponsswap_hud_info2": "You have no weapon to swap", + "hud_info_no_enemy": "No enemy found", + "zeus_desc": "Zeus x27 instantly recharges", + "frozendecoy_desc": "Your decoy grenade freezes all nearby players", + "antyhead_desc": "You receive no headshot damage", + "soldier_desc": "You have a random damage multiplier", + "soldier_desc2": "Your damage multiplier is: {0}x", + "swapposition_desc": "Swap places with a random enemy. Press [css_useSkill], cooldown 30s", + + "welcome_message": "Welcome {PLAYER} to {SERVER_NAME}!\nCurrent jRandomSkills version: {VERSION} ({SKILLS_COUNT} skills).\n\nOriginally created by:\n{AUTHOR1}\nModified and improved by:\n{AUTHOR2}", + "hud_info": "Wait {0} seconds", + "no_player": "No player found.", + "duplicate_player": "More than one player found with the same name.", + "drawing_skill": "Drawing a skill", + "your_skill": "Your current skill", + "summary_start": "======SUMMARY=OF=THE=LAST=ROUND======", + "summary_end": "=======================================", + "enemy_skill": "Enemy's skill", + "teammate_skills": "Your teammates' skills", + "observer_skill": "Player's power", + "game_start": "Game started!", + "invalid_map": "Invalid map name!", + "loading_map": "Loading a new map", + "skills_menu": "Skill List", + "correct_form_setskill": "Correct usage: CHATCOLORS.RED!setskill ", + "skill_not_found_setskill": "Skill CHATCOLORS.REDnot found", + "error_setskill": "Failed to set CHATCOLORS.REDskill", + "done_setskill": "Skill set", + "for_setskill": "for", + + "none": "None", + "dwarf": "Dwarf", + "swapposition": "Swapper", + "killerflash": "Deadly Flash", + "soldier": "Soldier", + "armored": "Tank", + "aimbot": "Aimbot", + "retreat": "Retreat", + "enemyspawn": "Enemy Spawn", + "zeus": "Zeus", + "radarhack": "Radar Hack", + "quickshot": "Quick-Shot", + "planter": "Planter", + "silent": "Silent Shadow", + "frozendecoy": "Freezing Decoy", + "timemanipulator": "Time Slow", + "godmode": "God Mode", + "randomweapon": "Random Weapon", + "weaponsswap": "Weapon Swap", + "wallhack": "Wallhack", + "flash": "Flash", + "paweljumper": "Paweł Jumper", + "bunnyhop": "Bunnyhop", + "impostor": "Spy", + "oneshot": "One-Shot", + "muhammed": "Muhammed", + "richboy": "Rich Boy", + "rambo": "Rambo", + "medic": "Medic", + "ghost": "Ghost", + "chicken": "Chicken", + "astronaut": "Astronaut", + "disarmament": "Disarmament", + "antyflash": "Anti-Flash", + "behind": "Enemy Rotation", + "infiniteammo": "Infinite Ammo", + "catapult": "Catapult", + "dracula": "Dracula", + "teleporter": "Teleporter", + "saper": "Saper", + "phoenix": "Phoenix", + "pilot": "Pilot", + "shade": "Shade", + "antyhead": "Anty Head" +} \ No newline at end of file diff --git a/jRandomSkills - Server Files/plugins/dRandomSkills/lang/pl.json b/jRandomSkills - Server Files/plugins/dRandomSkills/lang/pl.json new file mode 100644 index 0000000..ba0cf08 --- /dev/null +++ b/jRandomSkills - Server Files/plugins/dRandomSkills/lang/pl.json @@ -0,0 +1,127 @@ +{ + "none_desc": "Nie posiadasz żadnej supermocy", + "aimbot_desc": "Każdy twój trafiony pocisk jest liczony jako głowa", + "antyflash_desc": "Posiadasz odporność na flashe i 7 sekund trwają twoje flash'e", + "astronaut_desc": "Otrzymujesz losową ilość grawitacji na start rundy", + "astronaut_desc2": "Twoja losowa grawitacja wynosi: {0}x", + "richboy_desc": "Otrzymujesz losową ilość kasy na start rundy", + "bunnyhop_desc": "Otrzymujesz auto BunnyHopa", + "silent_desc": "Twoje kroki i skoki są niesłyszalne dla INNYCH graczy", + "shade_desc": "Teleportujesz się za plecy trafionego wroga", + "dracula_desc": "Po trafieniu ofiary otrzymujesz zwrot zdrowia w postaci danego procentu zadanych obrażeń", + "ghost_desc": "Jesteś całkowicie niewidzialny", + "flash_desc": "Losowa prędkośc postaci na początku rundy", + "flash_desc2": "Twój mnożnik prędkości to {0}x", + "godmode_desc": "Jesteś nieśmiertelny przez 2 sekundy. Kliknij [css_useSkill], cooldown 30s", + "godmode_on": "Nieśmiertelność włączona", + "godmode_off": "Nieśmiertelność wyłączona", + "armored_desc": "Masz losowy mnożnik otrzymywanych obrażeń", + "armored_desc2": "Twój mnożnik otrzymywanych obrażeń wynosi: {0}x", + "muhammed_desc": "Po śmierci wybucha i zabija graczy w obrębie", + "dwarf_desc": "Losowa wielkość postaci na początku rundy", + "dwarf_desc2": "Twój mnożnik wielkości to {0}x", + "medic_desc": "Otrzymujesz losową ilość apteczek na start rundy", + "randomweapon_desc": "Dostajesz losową broń. Kliknij [css_useSkill], cooldown 15s", + "chicken_desc": "Otrzymujesz model kurczaka + jesteś o 10% szybszy - 50hp", + "impostor_desc": "Otrzymujesz na start rundy model postaci wroga", + "catapult_desc": "Masz losową szanse na podrzucenie wroga", + "catapult_desc2": "Twoje szanse na podrzucenie wroga po trafieniu to: {0}%", + "infiniteammo_desc": "Otrzymujesz nieskończoną ilość ammo do wszystkich swoich broni", + "behind_desc": "Masz losową szanse na obrócenie wroga o 180 stopni po trafieniu", + "behind_desc2": "Twoje szanse na obrócenie wroga po trafieniu to: {0}%", + "retreat_desc": "Powrót na spawna. Kliknij [css_useSkill], cooldown 15s", + "oneshot_desc": "Po trafieniu od razu zabija przeciwnika", + "paweljumper_desc": "Otrzymujesz dodatkowy skok", + "phoenix_desc": "Masz losową szans na odrodzenie się po śmierci", + "phoenix_desc2": "Twoje szanse na odrodzenie się po śmierci: {0}%", + "phoenix_respawn": "Zostałeś odrodzony z popiołów dzięki mocy: CHATCOLORS.REDPhoenix", + "pilot_desc": "Latanie przez określony czas. Przytrzymaj [USE - E], aby latać", + "pilot_hud_info": "W trakcie odnawiania", + "radarhack_desc": "Widzisz wrogów na radarze", + "rambo_desc": "Otrzymujesz losową ilość zdrowia na start rundy", + "enemyspawn_desc": "Teleportacja na spawn wroga. Kliknij [css_useSkill], cooldown 15s", + "disarmament_desc": "Masz losową szanse na wyrzucenie broni wroga po trafieniu", + "disarmament_desc2": "Twoje szanse na wyrzucenie broni wroga to: {0}%", + "planter_desc": "Możesz podłożyć bombę w dowolnym miejscu, czas detonacji bomby trwa 60s", + "saper_desc": "Możesz szybciej podłożyć bombę oraz ją zdefować", + "timemanipulator_desc": "Spowolnienie czasu dla wszystkich na 6 sekundy. Kliknij [css_useSkill], cooldown 30s", + "quickshot_desc": "Brak cooldown przy strzelaniu", + "teleporter_desc": "Zamieniasz się miejscami z trafionym wrogiem", + "wallhack_desc": "Widzisz wrogów przez ściany", + "killer_flash_desc": "Każdy całkowicie oślepiony twoim granatem umiera (również ty)", + "weaponsswap_desc": "Zamieniasz się bronią z losowym wrogiem. Kliknij [css_useSkill], cooldown 30s", + "weaponsswap_hud_info2": "Nie posiadasz broni na zamiane", + "hud_info_no_enemy": "Nie znaleziono przeciwnika", + "zeus_desc": "Zeus x27 natychmiastowo się odnawia", + "frozendecoy_desc": "Twój decoy zamraża wszystkich pobliskich graczy", + "antyhead_desc": "Nie otrzymujesz obrażeń w głowę", + "soldier_desc": "Masz losowy mnożnik obrażeń", + "soldier_desc2": "Twój mnożnik obrażeń wynosi: {0}x", + "swapposition_desc": "Zamiana miejscami z losowym wrogiem. Kliknij [css_useSkill], cooldown 30s", + + "welcome_message": "Witaj {PLAYER} na serwerze {SERVER_NAME}!\nAktualna wersja jRandomSkills: {VERSION} ({SKILLS_COUNT} supermocy).\n\nPierwotnie plugin stworzona przez:\n{AUTHOR1}\nZmodyfikowany i ulepszony przez:\n{AUTHOR2}", + "hud_info": "Poczekaj jeszcze {0} sekund", + "no_player": "Nie znaleziono pasującego gracza.", + "duplicate_player": "Znaleziono więcej niż jednego gracza o tej samej nazwie.", + "drawing_skill": "Losowanie mocy", + "your_skill": "Twoja aktualna moc", + "summary_start": "======PODSUMOWANIE=Z=OSTATNIEJ=RUNDY======", + "summary_end": "============================================", + "enemy_skill": "Supermoc przeciwnika", + "teammate_skills": "Supermoce twoich sojuszników", + "observer_skill": "Moc gracza", + "game_start": "Gra rozpoczęta!", + "invalid_map": "Niepoprawnie podano nazwę mapy!", + "loading_map": "Ładowanie nowej mapy", + "skills_menu": "Lista Super Mocy", + "correct_form_setskill": "Poprawne użycie: CHATCOLORS.RED!setskill ", + "skill_not_found_setskill": "Nie znaleziono takiej CHATCOLORS.REDsupermocy", + "error_setskill": "Nie udało się ustawić CHATCOLORS.REDsupermocy", + "done_setskill": "Ustawiono Supermoc", + "for_setskill": "dla", + + "none": "Brak", + "dwarf": "MiniMajk", + "swapoosition": "Zamiana Miejsc", + "killerflash": "Zabójczy Flash", + "soldier": "Żołnierz", + "armored": "Gruby", + "aimbot": "Aimbot", + "retreat": "Odwrót", + "enemyspawn": "Resp Wroga", + "zeus": "Zeus", + "radarhack": "Radarowiec", + "quickshot": "Szybkostrzelność", + "planter": "Samowolka", + "silent": "Cichociemny", + "frozendecoy": "Zamrażający Decoy", + "timemanipulator": "Spowlnienie Czasu", + "godmode": "Nieśmiertelność", + "randomweapon": "Losowa Broń", + "weaponsswap": "Zamiana Broni", + "wallhack": "Wallhack", + "flash": "Flash", + "paweljumper": "Pawel Jumper", + "bunnyhop": "Królik", + "impostor": "Szpieg", + "oneshot": "Jednostrzałowiec", + "muhammed": "Muhammed", + "richboy": "Bogacz", + "rambo": "Rambo", + "medic": "Medyk", + "ghost": "Duszek", + "chicken": "Kurczak", + "astronaut": "Astronauta", + "disarmament": "Rozbrojenie", + "antyflash": "Anty Flash", + "behind": "Obrót Wroga", + "infiniteammo": "Nieskończone Ammo", + "catapult": "Katapulta", + "dracula": "Drakula", + "teleporter": "Teleporter", + "saper": "Saper", + "phoenix": "Phoenix", + "pilot": "Pilot", + "shade": "Cień", + "antyhead": "Żelazna Głowa" +} \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..e3d2bd7 --- /dev/null +++ b/readme.md @@ -0,0 +1,97 @@ +# 🤔 Opis +##### Link do [orginalnego projektu](https://github.com/Juzlus/dRandomSkills) stworzonego przez [jakubbartosik](https://github.com/jakubbartosik). + +## ✨ Aktualne moce (26) +- **MiniMajk:** Losowa wielkość postaci na początku rundy (0.6 - 0.95) +- **ZamianaMiejsc:** Zamiana miejscami z losowym wrogiem. Kliknij [USE - E], cooldown 30s +- **Flash:** Losowa prędkośc postaci na początku rundy (1.2 - 3.0) +- **PawelJumper:** Otrzymujesz dodatkowy skok +- **BunnyHop:** Otrzymujesz auto "BunnyHopa" +- **Impostor:** Otrzymujesz na start rundy model postaci wroga +- **OneShot:** Po trafieniu od razu zabija przeciwnika +- **Muhammed:** Po śmierci wybucha i zabija graczy w obrębie +- **Bogacz:** Otrzymujesz losową ilość kasy na start rundy (+5000 - +14999) +- **Rambo:** Otrzymujesz losową ilość zdrowia na start rundy (+50 - +500) +- **Medyk:** Otrzymujesz losową ilość apteczek na start rundy (1 - 4) +- **Duszek:** Jesteś całkowicie niewidzialny +- **Kurczak:** Otrzymujesz model kurczaka + jesteś o 10% szybszy - 50hp +- **Astronauta:** Otrzymujesz losową ilość grawitacji na start rundy (0.1 - 0.7)x +- **Rozbrojenie:** Masz losową szanse na wyrzucenie broni wroga po trafieniu (20% - 40%) +- **AntyFlash:** Posiadasz odporność na flashe i 7 sekund trwają twoje flash'e +- **ObrotWroga:** Masz losową szanse na obrócenie wroga o 180 stopni po trafieniu (20% - 40%) +- **NieskonczoneAmmo:** Otrzymujesz nieskończoną ilość ammo do wszystkich swoich broni +- **Katapulta:** Masz losową szanse na podrzucenie wroga (20% - 40%) +- **Drakula:** Po trafieniu ofiary otrzymujesz zwrot zdrowia w postaci danego procentu zadanych obrażeń (0.3x) +- **Teleporter:** Zamieniasz się miejscami z trafionym wrogiem +- **Saper:** Możesz szybciej podłożyć bombę oraz ją zdefować +- **Phoenix:** Masz losową szans na odrodzenie się po śmierci +- **Pilot:** Latanie przez określony czas. Przytrzymaj [USE - E], aby latać +- **Cien:** Teleportujesz się za plecy trafionego wroga +- **ZelaznaGlowa:** Nie otrzymujesz obrażeń w głowę + +## 💻 Instalacja + + +## 📋 Lista zmian + +### v1.0.3 (by Juzlus) +- #### Poprawki mocy: + - ##### Saper: + - ###### Naprawiono bład z natychmiastowym podkładaniem bomby jak ktokolwiek na serwerze miał moc 'Saper'. + +### v1.0.2 (by Juzlus) +- #### Nowe moce: + - ##### MiniMajk: + - ###### Losowa wielkość postaci w przedziale (60% - 95%). + - ##### ZamianaMiejsc: + - ###### Zamiana miejscami z losowym wrogiem, po kliknięciu przyciska akcji (E). Cooldown to 30s. +- #### Poprawki mocy: + - ##### AntyFlash: + - ###### Dodano: Twoje flash'e trwają dłużej (7s). + - ##### Astronauta: + - ###### Zmieniono: Mnożnik grawitacji z (0.2 - 0.7) na (0.1 - 0.7). + - ###### Dodano: Gracz widzi teraz mnożnik swojej grawitacji na czacie. + - ##### Drakula: + - ###### Zmieniono: Drakula od teraz może mieć nadwyżkę zdrowia. + - ##### Duszek: + - ###### Dodano: Zabklokowanie korzystania z broni innej niż nóż. + - ###### Dodano: Każda podniesiona broń przez duszka staje się niewidzialna. + - ##### Flash: + - ###### Naprawiono nie dostawanie prędkości. + - ###### Zmieniono: Mnożnik prędkości z (1.2 - 2.5) na (1.2 - 3.0). + - ###### Dodano: Gracz widzi teraz mnożnik swojej prędkości na czacie. + - ##### Katapulta: + - ###### Dodano: Losowe szanse na podrzucenie (20% - 40%). + - ###### Dodano: Gracz widzi teraz swoje szanse na czacie. + - ##### Kurczak: + - ###### Naprawiono nie dostawanie modelu kurczaka. + - ###### Dodano: Zabklokowanie korzystania z broni innej niż nóż lub pistolet. + - ###### Dodano: Kurczak może posiadać tylko 50 hp. + - ##### Medyk: + - ###### Naprawiono nie dostawanie apteczek. + - ###### Zmieniono: Od teraz wszyscy tracą apteczki na końcu rundy. + - ##### NieskonczoneAmmo: + - ###### Dodano: Od teraz granaty również są nieskończone. + - ##### ObrotWroga: + - ###### Dodano: Losowe szanse na obrót wroga (20% - 40%). + - ###### Dodano: Gracz widzi teraz swoje szanse na czacie. + - ##### Phoenix: + - ###### Naprawiono nie odradzanie się po śmierci. + - ###### Dodano: Losowe szanse na odrodzenie (20% - 40%). + - ###### Dodano: Gracz widzi teraz swoje szanse na czacie. + - ##### Pilot: + - ###### Zmieniono: Poprawiono opis supermocy. + - ##### Rambo: + - ###### Naprawiono nie dostawanie dodatkowego życia. + - ##### Rozbrojenie: + - ###### Dodano: Losowe szanse na wyrzucenie broni wroga (20% - 40%). + - ###### Dodano: Gracz widzi teraz swoje szanse na czacie. + - ###### Zmieniono: Wyrzuca teraz tylko aktywną broń wroga (naprawiono błąd wyrzucenia kosy). + - ##### Eliminator -> Saper: + - ###### Zmieniono: Zmineiono nazwę mocy z 'Eliminator' na 'Saper'. + - ##### Teleporter: + - ###### Naprawiono błąd, gdzie tylko gracz z supermocą był przeteleportowywany. + +## 📝 Kontakt + +Jeśli masz jakieś pytanie, napisz na juzlus.biznes@gmail.com lub [Discord](https://discordapp.com/users/284780352042434570). \ No newline at end of file