v1.2.2.b2

## GENERAL
- Updated CSS to version 1.0.369.
- Upgraded the project from .NET 8.0 to .NET 10.0.
- Updated Turkish language translation by @ByDexterTR.
- Added Russian language translation by @213sdfsdgf.
- Fixed an issue with incorrect display of Arabic nicknames.
- Used ForceFullUpdate to resolve the "FATAL ERROR: CopyExistingEntity" crash.
- Disabled stale HandleCommandDrop hook to avoid crashes when a player joins a team (thanks to @vladimir214sd).
- Added new signatures to gamedata.
- Added the ability to configure the number of grenades for every skill that uses grenades as part of its ability (e.g., Miner, AntyFlash, MagneticDecoy, etc.).

## SKILL IMPROVEMENTS
- Re-Zombie:
  -- Fixed weapon switching issues when a player is holding a Zeus and a knife.
  -- Weapons are now removed for bots in zombie mode.
- Ghost:
  -- Blocked the ability to use the Zeus.
- Thorns:
  -- Added a configurable maximum health limit (37 HP) for the damage that can be reflected.
- Second Life / Phoenix / Re-Zombie:
  -- Fixed an issue where players would occasionally fail to respawn if they took too much damage too quickly.
- Ghost / Chicken:
  -- Blocked the ability to use the SG556 (`weapon_sg556`).
- Wallhack:
  -- Fixed a bug that caused temporary enemy highlighting right after death.
- Cypher:
  -- Added camera position persistence.
- God Mode:
  -- Fixed an issue with permanent immortality triggering after reaching exactly 0 HP.
- Weapons Swap:
  -- The ammo count is now also transferred when weapons are swapped.
- Muhammed:
  -- Renamed the skill to "DeathBomb".
- Spectator:
  -- Fixed a bug where a player with the Chicken skill would still display as a ragdoll after death when spectated.
- Friendly Fire:
  -- The skill now works even when the server's mp_friendlyfire setting is set to 0.
- Baseball:
  -- Disabled teammate killing.
This commit is contained in:
Juzlus 2026-06-10 13:47:34 +02:00
parent cba834e8f0
commit 91761f7376
84 changed files with 6894 additions and 1689 deletions

View file

@ -158,7 +158,7 @@ namespace src.command
return;
}
SkillUtils.PrintToChat(player, $"{player.GetTranslation("done_setskill")}: {ChatColors.LightRed}{player.GetSkillName(skill.Skill)} {ChatColors.Lime}{player.GetTranslation("for_setskill")} {ChatColors.LightRed}{targetPlayer.PlayerName}");
SkillUtils.PrintToChat(player, $"{player.GetTranslation("done_setskill")}: {ChatColors.LightRed}{player.GetSkillName(skill.Skill)} {ChatColors.Lime}{player.GetTranslation("for_setskill")} {ChatColors.LightRed}\u202A{targetPlayer.PlayerName}\u202C");
if (skill.Display)
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(skill.Skill)}", border: "b");
@ -518,7 +518,7 @@ namespace src.command
return;
}
SkillUtils.PrintToChat(player, $"{player.GetTranslation("done_setskill")}: {ChatColors.LightRed}{player.GetSkillName(skill.Skill)} {ChatColors.Lime}{player.GetTranslation("for_setskill")} {ChatColors.LightRed}{targetPlayer.PlayerName}");
SkillUtils.PrintToChat(player, $"{player.GetTranslation("done_setskill")}: {ChatColors.LightRed}{player.GetSkillName(skill.Skill)} {ChatColors.Lime}{player.GetTranslation("for_setskill")} {ChatColors.LightRed}\u202A{targetPlayer.PlayerName}\u202C");
if (skill.Display)
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(skill.Skill)}", border: "b");

View file

@ -27,11 +27,22 @@
"linux": "55 48 89 E5 41 57 49 89 FF 48 89 F7 41 56 41 55 41 54 53 48 81 EC"
}
},
"CCSPlayerController_HandleCommandDrop": {
"signatures": {
"library": "server",
"windows": "48 89 5C 24 ? 57 48 83 EC ? 48 8B FA E8 ? ? ? ? 48 8B D8",
"linux": "55 48 89 E5 41 54 49 89 F4 53 E8 ? ? ? ? 48 85 C0 74 ? 48 89 C3"
"CServerSideClient_m_nDeltaTick": {
"offsets": {
"windows": 348,
"linux": 348
}
},
"INetworkGameServer_Slots": {
"offsets": {
"windows": 592,
"linux": 592
}
},
"INetworkServerService_GetIGameServer": {
"offsets": {
"windows": 23,
"linux": 24
}
}
}

View file

@ -28,7 +28,7 @@ namespace src
public override string ModuleName => "[CS2] [ jRandomSkills ]";
public override string ModuleAuthor => "D3X, Juzlus";
public override string ModuleDescription => "Plugin adds random skills every round for CS2 by D3X. Modified by Juzlus.";
public override string ModuleVersion => "1.2.2.b1";
public override string ModuleVersion => "1.2.2.b2";
public override void Load(bool hotReload)
{

View file

@ -1,519 +1,519 @@
{
"none": "Keine",
"none_desc": "Du hast keine Fertigkeit",
"none": "Keine",
"none_desc": "Du hast keine Fertigkeit",
"aimbot": "Aimbot",
"aimbot_desc": "Jede Kugel, die du triffst, zählt als Kopfschuss",
"aimbot": "Aimbot",
"aimbot_desc": "Jede Kugel, die du triffst, zählt als Kopfschuss",
"aimlock": "Aim-Lock",
"aimlock_desc": "Klicke [css_useSkill], um dein Visier auf den nächsten Gegner zu fixieren",
"aimlock": "Aim-Lock",
"aimlock_desc": "Klicke [css_useSkill], um dein Visier auf den nächsten Gegner zu fixieren",
"anomaly": "Anomalie",
"anomaly_desc": "Du spulst die Zeit um einige Sekunden zurück",
"anomaly": "Anomalie",
"anomaly_desc": "Du spulst die Zeit um einige Sekunden zurück",
"antyflash": "Anti-Flash",
"antyflash_desc": "Du bist immun gegen Blendgranaten und deine Blendgranaten halten 7 Sekunden lang",
"antyflash": "Anti-Flash",
"antyflash_desc": "Du bist immun gegen Blendgranaten und deine Blendgranaten halten 7 Sekunden lang",
"antyhead": "Eiserner Kopf",
"antyhead_desc": "Du erleidest keinen Schaden durch Kopfschüsse",
"antyhead": "Eiserner Kopf",
"antyhead_desc": "Du erleidest keinen Schaden durch Kopfschüsse",
"areareaper": "Zone Reaper",
"areareaper_desc": "Du kannst einen Bombenort auswählen, den du deaktivieren möchtest",
"areareaper_incorrect_site": "Kein solcher Bombenort gefunden",
"areareaper_no_site": "Keine Bombenstandorte gefunden.",
"areareaper_select_info": "Standort zum Deaktivieren auswählen:",
"areareaper_site_disabled": "Bombenstandort {0} wurde deaktiviert – dort können keine Bomben platziert werden!",
"areareaper_used_info": "Deine Fähigkeit wurde bereits eingesetzt.",
"areareaper_bombsite_disabled": "Dieser Bombenplatz wurde deaktiviert!",
"areareaper": "Zone Reaper",
"areareaper_desc": "Du kannst einen Bombenort auswählen, den du deaktivieren möchtest",
"areareaper_incorrect_site": "Kein solcher Bombenort gefunden",
"areareaper_no_site": "Keine Bombenstandorte gefunden.",
"areareaper_select_info": "Standort zum Deaktivieren auswählen:",
"areareaper_site_disabled": "Bombenstandort {0} wurde deaktiviert – dort können keine Bomben platziert werden!",
"areareaper_used_info": "Deine Fähigkeit wurde bereits eingesetzt.",
"areareaper_bombsite_disabled": "Dieser Bombenplatz wurde deaktiviert!",
"armored": "Gepanzert",
"armored_desc": "Du hast einen zufälligen Schadensmultiplikator",
"armored_desc2": "Dein Schadensmultiplikator beträgt: {0}x",
"armored": "Gepanzert",
"armored_desc": "Du hast einen zufälligen Schadensmultiplikator",
"armored_desc2": "Dein Schadensmultiplikator beträgt: {0}x",
"assassin": "Attentäter",
"assassin_desc": "Du fügst Gegnern von hinten erhöhten Schaden zu",
"assassin": "Attentäter",
"assassin_desc": "Du fügst Gegnern von hinten erhöhten Schaden zu",
"astronaut": "Astronaut",
"astronaut_desc": "Du erhältst zu Beginn der Runde einen zufälligen Schwerkraftwert",
"astronaut_desc2": "Deine zufällige Schwerkraft beträgt: {0}x",
"astronaut": "Astronaut",
"astronaut_desc": "Du erhältst zu Beginn der Runde einen zufälligen Schwerkraftwert",
"astronaut_desc2": "Deine zufällige Schwerkraft beträgt: {0}x",
"moneyswap": "Steuerbeamter",
"moneyswap_desc": "Wähle einen Spieler aus, mit dem du Geld tauschen möchtest",
"moneyswap_enemy_info": "Das Finanzamt hat dich erwischt.",
"moneyswap_player_info": "Du hast Geld mit dem Spieler \"{0}\" getauscht.",
"moneyswap_select_info": "Geld mit Spieler tauschen:",
"moneyswap": "Steuerbeamter",
"moneyswap_desc": "Wähle einen Spieler aus, mit dem du Geld tauschen möchtest",
"moneyswap_enemy_info": "Das Finanzamt hat dich erwischt.",
"moneyswap_player_info": "Du hast Geld mit dem Spieler \"{0}\" getauscht.",
"moneyswap_select_info": "Geld mit Spieler tauschen:",
"baseball": "Baseballspieler",
"baseball_desc": "Deine Attrappe prallt von Wänden ab und tötet einen Gegner sofort beim Aufprall.",
"baseball": "Baseballspieler",
"baseball_desc": "Deine Attrappe prallt von Wänden ab und tötet einen Gegner sofort beim Aufprall.",
"behind": "Feind drehen",
"behind_desc": "Du hast eine zufällige Chance, einen Feind um 180 Grad zu drehen, wenn du ihn triffst",
"behind_desc2": "Deine Chance, einen Feind bei einem Treffer zu drehen, beträgt: {0} %",
"behind": "Feind drehen",
"behind_desc": "Du hast eine zufällige Chance, einen Feind um 180 Grad zu drehen, wenn du ihn triffst",
"behind_desc2": "Deine Chance, einen Feind bei einem Treffer zu drehen, beträgt: {0} %",
"blademaster": "Schwertmeister",
"blademaster_desc": "Wenn du ein Messer hältst, hast du eine hohe Chance, einen Schuss abzuwehren",
"blademaster": "Schwertmeister",
"blademaster_desc": "Wenn du ein Messer hältst, hast du eine hohe Chance, einen Schuss abzuwehren",
"bunnyhop": "Hase",
"bunnyhop_desc": "Du erhältst automatisch bunnyhop",
"bunnyhop": "Hase",
"bunnyhop_desc": "Du erhältst automatisch bunnyhop",
"c4camouflage": "C4-Tarnung",
"c4camouflage_desc": "Du bist unsichtbar, während du die Bombe hältst",
"c4camouflage": "C4-Tarnung",
"c4camouflage_desc": "Du bist unsichtbar, während du die Bombe hältst",
"carefulbullets": "Vorsichtige Kugeln",
"carefulbullets_desc": "Wähle einen Spieler aus, der für jeden Fehlschuss Schaden nimmt",
"carefulbullets_enemy_info": "Von nun an wird Ungenauigkeit buchstäblich wehtun.",
"carefulbullets_player_info": "‚{0}‘ muss jetzt vorsichtiger sein.",
"carefulbullets_select_info": "Fehler schaden dem Spieler:",
"carefulbullets": "Vorsichtige Kugeln",
"carefulbullets_desc": "Wähle einen Spieler aus, der für jeden Fehlschuss Schaden nimmt",
"carefulbullets_enemy_info": "Von nun an wird Ungenauigkeit buchstäblich wehtun.",
"carefulbullets_player_info": "‚{0}‘ muss jetzt vorsichtiger sein.",
"carefulbullets_select_info": "Fehler schaden dem Spieler:",
"catapult": "Katapult",
"catapult_desc": "Du hast eine zufällige Chance, einen Gegner nach oben zu schleudern",
"catapult_desc2": "Deine Chance, einen Gegner bei einem Treffer zu schleudern, beträgt: {0} %",
"catapult": "Katapult",
"catapult_desc": "Du hast eine zufällige Chance, einen Gegner nach oben zu schleudern",
"catapult_desc2": "Deine Chance, einen Gegner bei einem Treffer zu schleudern, beträgt: {0} %",
"chicken": "Huhn",
"chicken_desc": "Du erhältst ein Huhn-Modell + 10 % schnellere Bewegung – 50 HP",
"chicken": "Huhn",
"chicken_desc": "Du erhältst ein Huhn-Modell + 10 % schnellere Bewegung – 50 HP",
"chillout": "Chillout",
"chillout_desc": "Das Platzieren der Bombe dauert deutlich länger",
"chillout": "Chillout",
"chillout_desc": "Das Platzieren der Bombe dauert deutlich länger",
"cutter": "Cutter",
"cutter_desc": "Sofortiger Tod mit einem Messer",
"cutter": "Cutter",
"cutter_desc": "Sofortiger Tod mit einem Messer",
"cypher": "Kamera",
"cypher_desc": "Klicken Sie auf [css_useSkill], um eine Kamera zu erstellen/zu wechseln",
"cypher_nospace": "Die Kamera muss im rechten Winkel zur Wand positioniert werden",
"cypher": "Kamera",
"cypher_desc": "Klicken Sie auf [css_useSkill], um eine Kamera zu erstellen/zu wechseln",
"cypher_nospace": "Die Kamera muss im rechten Winkel zur Wand positioniert werden",
"darkness": "Dunkelheit",
"darkness_desc": "Wendet einen Dunkelheitseffekt auf einen ausgewählten Gegner an",
"darkness_enemy_info": "Lass die Lichter ausgehen",
"darkness_player_info": "Die Dunkelheit hat den Spieler \"{0}\" überwältigt.",
"darkness_select_info": "Wähle einen Spieler für die Dunkelheit aus:",
"darkness": "Dunkelheit",
"darkness_desc": "Wendet einen Dunkelheitseffekt auf einen ausgewählten Gegner an",
"darkness_enemy_info": "Lass die Lichter ausgehen",
"darkness_player_info": "Die Dunkelheit hat den Spieler \"{0}\" überwältigt.",
"darkness_select_info": "Wähle einen Spieler für die Dunkelheit aus:",
"deactivator": "Deaktivator",
"deactivator_desc": "Wähle einen Spieler aus, dessen Fähigkeit du deaktivieren möchtest",
"deactivator_enemy_info": "Deine Fähigkeit wurde deaktiviert",
"deactivator_player_info": "Die Fähigkeit des Spielers ‚{0}‘ wurde deaktiviert",
"deactivator_select_info": "Fähigkeit eines Spielers deaktivieren:",
"deactivator": "Deaktivator",
"deactivator_desc": "Wähle einen Spieler aus, dessen Fähigkeit du deaktivieren möchtest",
"deactivator_enemy_info": "Deine Fähigkeit wurde deaktiviert",
"deactivator_player_info": "Die Fähigkeit des Spielers ‚{0}‘ wurde deaktiviert",
"deactivator_select_info": "Fähigkeit eines Spielers deaktivieren:",
"deaf": "Taub",
"deaf_desc": "Wähle einen Spieler aus, für den alle Sounds stummgeschaltet werden sollen",
"deaf_enemy_info": "Deine Kopfhörer haben das Spiel verlassen.",
"deaf_player_info": "Der Ton für den Spieler ‚{0}‘ wurde deaktiviert.",
"deaf_select_info": "Alle Töne für den Spieler stummschalten:",
"deaf": "Taub",
"deaf_desc": "Wähle einen Spieler aus, für den alle Sounds stummgeschaltet werden sollen",
"deaf_enemy_info": "Deine Kopfhörer haben das Spiel verlassen.",
"deaf_player_info": "Der Ton für den Spieler ‚{0}‘ wurde deaktiviert.",
"deaf_select_info": "Alle Töne für den Spieler stummschalten:",
"disarmament": "Entwaffnung",
"disarmament_desc": "Du hast eine zufällige Chance, einen Gegner bei einem Treffer seine Waffe fallen zu lassen.",
"disarmament_desc2": "Ihre Chance, einen Gegner zu entwaffnen, beträgt: {0} %",
"disarmament": "Entwaffnung",
"disarmament_desc": "Du hast eine zufällige Chance, einen Gegner bei einem Treffer seine Waffe fallen zu lassen.",
"disarmament_desc2": "Ihre Chance, einen Gegner zu entwaffnen, beträgt: {0} %",
"distancer": "Entfernungsmesser",
"distancer_desc": "Sie können die Entfernung zum nächsten Gegner sehen",
"distancer": "Entfernungsmesser",
"distancer_desc": "Sie können die Entfernung zum nächsten Gegner sehen",
"dash": "Sprinten",
"dash_desc": "Führe einen zweiten Sprung aus, um zu sprinten",
"dash": "Sprinten",
"dash_desc": "Führe einen zweiten Sprung aus, um zu sprinten",
"dracula": "Dracula",
"dracula_desc": "Wenn du einen Gegner triffst, wird deine Gesundheit um einen Prozentsatz des verursachten Schadens wiederhergestellt",
"dracula": "Dracula",
"dracula_desc": "Wenn du einen Gegner triffst, wird deine Gesundheit um einen Prozentsatz des verursachten Schadens wiederhergestellt",
"duplicator": "Duplikator",
"duplicator_desc": "Wähle einen Spieler aus, dessen Fertigkeit du kopieren möchtest",
"duplicator_player_info": "Die Fertigkeit des Spielers ‚{0}‘ wurde kopiert.",
"duplicator_select_info": "Kopiere die Fertigkeit eines Spielers:",
"duplicator": "Duplikator",
"duplicator_desc": "Wähle einen Spieler aus, dessen Fertigkeit du kopieren möchtest",
"duplicator_player_info": "Die Fertigkeit des Spielers ‚{0}‘ wurde kopiert.",
"duplicator_select_info": "Kopiere die Fertigkeit eines Spielers:",
"dwarf": "Zwerg",
"dwarf_desc": "Zufällige Charaktergröße zu Beginn der Runde",
"dwarf_desc2": "Dein Größenmultiplikator beträgt: {0}x",
"dwarf": "Zwerg",
"dwarf_desc": "Zufällige Charaktergröße zu Beginn der Runde",
"dwarf_desc2": "Dein Größenmultiplikator beträgt: {0}x",
"enemyspawn": "Feindes-Spawn",
"enemyspawn_desc": "Klicke auf [css_useSkill], um zum Feindes-Spawn zu teleportieren",
"enemyspawn": "Feindes-Spawn",
"enemyspawn_desc": "Klicke auf [css_useSkill], um zum Feindes-Spawn zu teleportieren",
"explosiveshot": "Explosiver Schuss",
"explosiveshot_desc": "Zufällige Chance, beim Schießen eine explosive Kugel abzufeuern",
"explosiveshot_desc2": "Deine Chance, eine explosive Kugel abzufeuern: {0} %",
"explosiveshot": "Explosiver Schuss",
"explosiveshot_desc": "Zufällige Chance, beim Schießen eine explosive Kugel abzufeuern",
"explosiveshot_desc2": "Deine Chance, eine explosive Kugel abzufeuern: {0} %",
"falconeye": "Falkenauge",
"falconeye_desc": "Klicke auf [css_useSkill], um eine Vogelperspektive zu aktivieren",
"falconeye": "Falkenauge",
"falconeye_desc": "Klicke auf [css_useSkill], um eine Vogelperspektive zu aktivieren",
"fastreload": "Schnellnachladen",
"fastreload_desc": "Klicke auf [css_useSkill], um die Waffe, die du gerade hältst, nachzuladen",
"fastreload": "Schnellnachladen",
"fastreload_desc": "Klicke auf [css_useSkill], um die Waffe, die du gerade hältst, nachzuladen",
"flash": "Blitz",
"flash_desc": "Zufällige Spielergeschwindigkeit zu Beginn der Runde",
"flash_desc2": "Dein Geschwindigkeitsmultiplikator beträgt: {0}x",
"flash": "Blitz",
"flash_desc": "Zufällige Spielergeschwindigkeit zu Beginn der Runde",
"flash_desc2": "Dein Geschwindigkeitsmultiplikator beträgt: {0}x",
"fortnite": "Fortnite",
"fortnite_desc": "Klicke auf [css_useSkill], um eine zerstörbare Barrikade zu erstellen",
"fortnite": "Fortnite",
"fortnite_desc": "Klicke auf [css_useSkill], um eine zerstörbare Barrikade zu erstellen",
"fragilebomb": "Fragile Bombe",
"fragilebomb_desc": "Das Schießen auf die Bombe beschädigt sie",
"fragilebomb_bomb_health": "Bombengesundheit",
"fragilebomb": "Fragile Bombe",
"fragilebomb_desc": "Das Schießen auf die Bombe beschädigt sie",
"fragilebomb_bomb_health": "Bombengesundheit",
"friendlyfire": "Friendly Fire",
"friendlyfire_desc": "Das Schießen auf Teamkameraden heilt sie",
"friendlyfire": "Friendly Fire",
"friendlyfire_desc": "Das Schießen auf Teamkameraden heilt sie",
"frozendecoy": "Eisige Attrappe",
"frozendecoy_desc": "Deine Attrappe friert alle Spieler in der Nähe ein",
"frozendecoy": "Eisige Attrappe",
"frozendecoy_desc": "Deine Attrappe friert alle Spieler in der Nähe ein",
"gambler": "Zocker",
"gambler_desc": "Wähle eine Fertigkeit aus der Liste aus.",
"gambler_select_info": "Wähle deine Fähigkeit aus:",
"gambler_more": "#00FF00|Aktualisieren für ${0}",
"gambler_no_money": "Nicht genug Geld.",
"gambler": "Zocker",
"gambler_desc": "Wähle eine Fertigkeit aus der Liste aus.",
"gambler_select_info": "Wähle deine Fähigkeit aus:",
"gambler_more": "#00FF00|Aktualisieren für ${0}",
"gambler_no_money": "Nicht genug Geld.",
"ghost": "Geist",
"ghost_desc": "Du bist vollständig unsichtbar",
"ghost": "Geist",
"ghost_desc": "Du bist vollständig unsichtbar",
"glaz": "Glaz",
"glaz_desc": "Du kannst durch Rauchgranaten hindurchsehen",
"glaz": "Glaz",
"glaz_desc": "Du kannst durch Rauchgranaten hindurchsehen",
"glitch": "Glitch",
"glitch_desc": "Deaktiviert das Radar für einen ausgewählten Gegner",
"glitch_enemy_info": "Dein Radar wurde deaktiviert",
"glitch_player_info": "Das Radar des Spielers ‚{0}‘ wurde deaktiviert.",
"glitch_select_info": "Radar des Spielers ausschalten:",
"glitch": "Glitch",
"glitch_desc": "Deaktiviert das Radar für einen ausgewählten Gegner",
"glitch_enemy_info": "Dein Radar wurde deaktiviert",
"glitch_player_info": "Das Radar des Spielers ‚{0}‘ wurde deaktiviert.",
"glitch_select_info": "Radar des Spielers ausschalten:",
"glue": "Glue",
"glue_desc": "Deine Granaten haften an Wänden",
"glue": "Glue",
"glue_desc": "Deine Granaten haften an Wänden",
"godmode": "Gott-Modus",
"godmode_desc": "Klicke auf [css_useSkill], um für kurze Zeit unsterblich zu werden",
"godmode_off": "Unsterblichkeit deaktiviert",
"godmode_on": "Unsterblichkeit aktiviert",
"godmode": "Gott-Modus",
"godmode_desc": "Klicke auf [css_useSkill], um für kurze Zeit unsterblich zu werden",
"godmode_off": "Unsterblichkeit deaktiviert",
"godmode_on": "Unsterblichkeit aktiviert",
"grenadier": "Grenadier",
"grenadier_desc": "Du hast unendlich viele Granaten",
"grenadier": "Grenadier",
"grenadier_desc": "Du hast unendlich viele Granaten",
"healingsmoke": "Heilender Rauch",
"healingsmoke_desc": "Deine Rauchgranaten heilen",
"healingsmoke": "Heilender Rauch",
"healingsmoke_desc": "Deine Rauchgranaten heilen",
"hermit": "Einsiedler",
"hermit_desc": "Durch das Töten von Gegnern werden Munition und ein Teil der Gesundheit wiederhergestellt",
"hermit": "Einsiedler",
"hermit_desc": "Durch das Töten von Gegnern werden Munition und ein Teil der Gesundheit wiederhergestellt",
"holyhandgrenade": "Heilige Handgranate",
"holyhandgrenade_desc": "Deine HE-Granaten verursachen doppelten Schaden und haben doppelte Reichweite",
"holyhandgrenade": "Heilige Handgranate",
"holyhandgrenade_desc": "Deine HE-Granaten verursachen doppelten Schaden und haben doppelte Reichweite",
"homingnades": "Zielsuchende Granaten",
"homingnades_desc": "Deine Granaten (außer Smokes) werden von Gegnern angezogen",
"homingnades": "Zielsuchende Granaten",
"homingnades_desc": "Deine Granaten (außer Smokes) werden von Gegnern angezogen",
"hotbomb": "Heiße Bombe",
"hotbomb_desc": "Solange du am Leben bist, fügt die Bombe ihrem Träger Schaden zu",
"hotbomb_hint": "Vorsicht, die Bombe ist heiß!",
"hotbomb": "Heiße Bombe",
"hotbomb_desc": "Solange du am Leben bist, fügt die Bombe ihrem Träger Schaden zu",
"hotbomb_hint": "Vorsicht, die Bombe ist heiß!",
"iana": "Hologramm",
"iana_desc": "Klicken Sie auf [css_useSkill], um Ihr Hologramm für einige Sekunden zu steuern",
"iana": "Hologramm",
"iana_desc": "Klicken Sie auf [css_useSkill], um Ihr Hologramm für einige Sekunden zu steuern",
"illiterate": "Analphabet",
"illiterate_desc": "Solange du am Leben bist, können deine Feinde nichts lesen",
"illiterate": "Analphabet",
"illiterate_desc": "Solange du am Leben bist, können deine Feinde nichts lesen",
"illusionist": "Illusionist",
"illusionist_desc": "Klicke [css_useSkill], um ein Abbild zu schicken, das geradeaus läuft",
"illusionist": "Illusionist",
"illusionist_desc": "Klicke [css_useSkill], um ein Abbild zu schicken, das geradeaus läuft",
"impostor": "Betrüger",
"impostor_desc": "Du beginnst die Runde mit einem feindlichen Spielermodell",
"impostor": "Betrüger",
"impostor_desc": "Du beginnst die Runde mit einem feindlichen Spielermodell",
"infiniteammo": "Unendliche Munition",
"infiniteammo_desc": "Du erhältst unendliche Munition für alle deine Waffen",
"infiniteammo": "Unendliche Munition",
"infiniteammo_desc": "Du erhältst unendliche Munition für alle deine Waffen",
"jackal": "Spürhund",
"jackal_desc": "Jeder Gegner hinterlässt eine Spur",
"jackal": "Spürhund",
"jackal_desc": "Jeder Gegner hinterlässt eine Spur",
"jammer": "Störsender",
"jammer_desc": "Wähle einen Spieler aus, um dessen Fadenkreuz zu deaktivieren",
"jammer_enemy_info": "Dein Fadenkreuz wurde deaktiviert.",
"jammer_player_info": "Das Fadenkreuz von Spieler ‚{0}‘ wurde deaktiviert.",
"jammer_select_info": "Fadenkreuz des Spielers deaktivieren:",
"jammer": "Störsender",
"jammer_desc": "Wähle einen Spieler aus, um dessen Fadenkreuz zu deaktivieren",
"jammer_enemy_info": "Dein Fadenkreuz wurde deaktiviert.",
"jammer_player_info": "Das Fadenkreuz von Spieler ‚{0}‘ wurde deaktiviert.",
"jammer_select_info": "Fadenkreuz des Spielers deaktivieren:",
"jester": "Narr",
"jester_desc": "Im Narrenmodus kannst du keinen Schaden erleiden oder verursachen. Dieser Modus ändert sich alle paar Sekunden.",
"jester_mode": "Jester-Modus",
"jester_on": "EIN",
"jester_off": "AUS",
"jester": "Narr",
"jester_desc": "Im Narrenmodus kannst du keinen Schaden erleiden oder verursachen. Dieser Modus ändert sich alle paar Sekunden.",
"jester_mode": "Jester-Modus",
"jester_on": "EIN",
"jester_off": "AUS",
"jumpban": "Beinlos",
"jumpban_desc": "Wähle einen Spieler, der nicht springen kann",
"jumpban_enemy_info": "Jemand hat dir die Beine abgeschnitten.",
"jumpban_player_info": "Der Spieler ‚{0}‘ kann nicht mehr springen.",
"jumpban_select_info": "Spieler vom Springen ausschließen:",
"jumpban": "Beinlos",
"jumpban_desc": "Wähle einen Spieler, der nicht springen kann",
"jumpban_enemy_info": "Jemand hat dir die Beine abgeschnitten.",
"jumpban_player_info": "Der Spieler ‚{0}‘ kann nicht mehr springen.",
"jumpban_select_info": "Spieler vom Springen ausschließen:",
"jumpingjack": "Jumping Jack",
"jumpingjack_desc": "Durch Springen wird die Gesundheit wiederhergestellt",
"jumpingjack": "Jumping Jack",
"jumpingjack_desc": "Durch Springen wird die Gesundheit wiederhergestellt",
"killerflash": "Killer Flash",
"killerflash_desc": "Jeder, der durch deine Blendgranate vollständig geblendet wird, stirbt (einschließlich dir selbst)",
"killerflash": "Killer Flash",
"killerflash_desc": "Jeder, der durch deine Blendgranate vollständig geblendet wird, stirbt (einschließlich dir selbst)",
"lifeswap": "Lebensaustausch",
"lifeswap_desc": "Wähle einen Spieler aus, mit dem du deine Gesundheit austauschen möchtest",
"lifeswap_enemy_info": "Jemand hat sich deine Gesundheit ausgeliehen",
"lifeswap_player_info": "Du hast deine Gesundheit mit dem Spieler \"{0}\" ausgetauscht",
"lifeswap_select_info": "Tausche Gesundheit mit Spieler:",
"lifeswap": "Lebensaustausch",
"lifeswap_desc": "Wähle einen Spieler aus, mit dem du deine Gesundheit austauschen möchtest",
"lifeswap_enemy_info": "Jemand hat sich deine Gesundheit ausgeliehen",
"lifeswap_player_info": "Du hast deine Gesundheit mit dem Spieler \"{0}\" ausgetauscht",
"lifeswap_select_info": "Tausche Gesundheit mit Spieler:",
"longknife": "Langes Messer",
"longknife_desc": "Ein Messerangriff verursacht unabhängig von der Entfernung Schaden",
"longknife": "Langes Messer",
"longknife_desc": "Ein Messerangriff verursacht unabhängig von der Entfernung Schaden",
"longzeus": "Langer Zeus",
"longzeus_desc": "Zeus verursacht unabhängig von der Entfernung Schaden",
"longzeus": "Langer Zeus",
"longzeus_desc": "Zeus verursacht unabhängig von der Entfernung Schaden",
"magneticdecoy": "Magnetischer Köder",
"magneticdecoy_desc": "Dein Köder zieht Spieler in der Nähe zu sich heran",
"magneticdecoy": "Magnetischer Köder",
"magneticdecoy_desc": "Dein Köder zieht Spieler in der Nähe zu sich heran",
"magneto": "Magneto",
"magneto_desc": "Alle feindlichen Granaten werden von dir weggestoßen",
"magneto": "Magneto",
"magneto_desc": "Alle feindlichen Granaten werden von dir weggestoßen",
"magnifier": "Lupe",
"magnifier_desc": "Vergrößert den Bildschirm des Gegners und verringert dessen Sichtfeld",
"magnifier_enemy_info": "Dein Sichtfeld wurde verzerrt!",
"magnifier_player_info": "Der Spieler ‚{0}‘ wurde in den Zoom-Modus versetzt.",
"magnifier_select_info": "Bildschirm des Spielers vergrößern:",
"magnifier": "Lupe",
"magnifier_desc": "Vergrößert den Bildschirm des Gegners und verringert dessen Sichtfeld",
"magnifier_enemy_info": "Dein Sichtfeld wurde verzerrt!",
"magnifier_player_info": "Der Spieler ‚{0}‘ wurde in den Zoom-Modus versetzt.",
"magnifier_select_info": "Bildschirm des Spielers vergrößern:",
"medic": "Sanitäter",
"medic_desc": "Klicke auf [css_useSkill], um eine Heilungsladung zu verwenden, die 50 Gesundheitspunkte wiederherstellt",
"medic": "Sanitäter",
"medic_desc": "Klicke auf [css_useSkill], um eine Heilungsladung zu verwenden, die 50 Gesundheitspunkte wiederherstellt",
"miner": "Bomben-Miner",
"miner_desc": "Deine HE-Granate explodiert nur, wenn ein Gegner in der Nähe ist",
"miner": "Bomben-Miner",
"miner_desc": "Deine HE-Granate explodiert nur, wenn ein Gegner in der Nähe ist",
"bankrupt": "Bankrott",
"bankrupt_desc": "Wähle den Spieler aus, der sein gesamtes Geld verlieren wird",
"bankrupt_enemy_info": "Du bist bankrott.",
"bankrupt_player_info": "Der Spieler ‚{0}‘ ist bankrott.",
"bankrupt_select_info": "Wähle einen Spieler aus, der bankrott gehen soll:",
"bankrupt": "Bankrott",
"bankrupt_desc": "Wähle den Spieler aus, der sein gesamtes Geld verlieren wird",
"bankrupt_enemy_info": "Du bist bankrott.",
"bankrupt_player_info": "Der Spieler ‚{0}‘ ist bankrott.",
"bankrupt_select_info": "Wähle einen Spieler aus, der bankrott gehen soll:",
"muhammed": "Muhammed",
"muhammed_desc": "Du explodierst beim Tod und tötest Spieler in deiner Nähe",
"muhammed_explosion": "ALLAHU AKBAR!!!",
"deathbomb": "Todesbombe",
"deathbomb_desc": "Du explodierst beim Tod und tötest Spieler in deiner Nähe",
"deathbomb_explosion": "Kaboom!",
"ninja": "Ninja",
"ninja_desc": "Wenn du stillstehst, erhöht sich deine Unsichtbarkeit um 33 %, wenn du dich duckst um 33 % und wenn du ein Messer hältst um 33 %",
"ninja": "Ninja",
"ninja_desc": "Wenn du stillstehst, erhöht sich deine Unsichtbarkeit um 33 %, wenn du dich duckst um 33 % und wenn du ein Messer hältst um 33 %",
"nonades": "No-Nades",
"nonades_desc": "Granaten fügen dir keinen Schaden zu",
"norecoil": "Fokus",
"norecoil_desc": "Kein Rückstoß beim Schießen",
"nonades": "No-Nades",
"nonades_desc": "Granaten fügen dir keinen Schaden zu",
"noclip": "NoClip",
"noclip_desc": "Klicke auf [css_useSkill], um NoClip für kurze Zeit zu aktivieren",
"norecoil": "Fokus",
"norecoil_desc": "Kein Rückstoß beim Schießen",
"oneshot": "One-Shot",
"oneshot_desc": "Ein Treffer tötet einen Gegner sofort",
"noclip": "NoClip",
"noclip_desc": "Klicke auf [css_useSkill], um NoClip für kurze Zeit zu aktivieren",
"onlyhead": "Nur Kopf",
"onlyhead_desc": "Du erleidest nur Schaden am Kopf",
"oneshot": "One-Shot",
"oneshot_desc": "Ein Treffer tötet einen Gegner sofort",
"paweljumper": "Pawel Jumper",
"paweljumper_desc": "Du erhältst eine zufällige Anzahl zusätzlicher Sprünge",
"paweljumper_desc2": "Du erhältst {0} zusätzliche Sprünge",
"onlyhead": "Nur Kopf",
"onlyhead_desc": "Du erleidest nur Schaden am Kopf",
"phoenix": "Phönix",
"phoenix_desc": "Du hast eine zufällige Chance, nach dem Tod wieder zu erscheinen",
"phoenix_desc2": "Deine Chance, nach dem Tod wieder zu erscheinen: {0} %",
"phoenix_respawn": "Du bist dank der Kraft von CHATCOLORS.REDPhoenix aus der Asche auferstanden",
"paweljumper": "Pawel Jumper",
"paweljumper_desc": "Du erhältst eine zufällige Anzahl zusätzlicher Sprünge",
"paweljumper_desc2": "Du erhältst {0} zusätzliche Sprünge",
"psychicdefusing": "Psychic Defusing",
"psychicdefusing_desc": "Wenn du dich in der Nähe der Bombe befindest, beginnst du, sie zu entschärfen",
"psychicdefusing_hud_info": "{0} Sekunden verbleibend bis zur Entschärfung",
"phoenix": "Phönix",
"phoenix_desc": "Du hast eine zufällige Chance, nach dem Tod wieder zu erscheinen",
"phoenix_desc2": "Deine Chance, nach dem Tod wieder zu erscheinen: {0} %",
"phoenix_respawn": "Du bist dank der Kraft von CHATCOLORS.REDPhoenix aus der Asche auferstanden",
"pilot": "Pilot",
"pilot_desc": "Fliege für begrenzte Zeit. Doppelklick auf Sprung zum Fliegen",
"pilot_hud_info": "Treibstoff",
"psychicdefusing": "Psychic Defusing",
"psychicdefusing_desc": "Wenn du dich in der Nähe der Bombe befindest, beginnst du, sie zu entschärfen",
"psychicdefusing_hud_info": "{0} Sekunden verbleibend bis zur Entschärfung",
"planter": "Freier Planter",
"planter_desc": "Du kannst die Bombe überall platzieren, die Detonationszeit beträgt 60 Sekunden.",
"planter_planting": "Bombe wird gelegt ({0})...",
"pilot": "Pilot",
"pilot_desc": "Fliege für begrenzte Zeit. Doppelklick auf Sprung zum Fliegen",
"pilot_hud_info": "Treibstoff",
"poison": "Gift",
"poison_desc": "Wähle einen Spieler aus, der alle paar Sekunden Schaden nimmt",
"poison_enemy_info": "Du wurdest vergiftet",
"poison_player_info": "Der Spieler ‚{0}‘ wurde vergiftet",
"poison_select_info": "Einen Spieler vergiften:",
"planter": "Freier Planter",
"planter_desc": "Du kannst die Bombe überall platzieren, die Detonationszeit beträgt 60 Sekunden.",
"planter_planting": "Bombe wird gelegt ({0})...",
"primaryban": "Keine Gewehre",
"primaryban_desc": "Wähle einen Spieler aus, der keine Gewehre verwenden kann",
"primaryban_enemy_info": "Du kannst keine Gewehre mehr verwenden.",
"primaryban_player_info": "Der Spieler ‚{0}‘ kann keine Gewehre mehr verwenden.",
"primaryban_select_info": "Gewehre für Spieler verbieten:",
"poison": "Gift",
"poison_desc": "Wähle einen Spieler aus, der alle paar Sekunden Schaden nimmt",
"poison_enemy_info": "Du wurdest vergiftet",
"poison_player_info": "Der Spieler ‚{0}‘ wurde vergiftet",
"poison_select_info": "Einen Spieler vergiften:",
"prosthesis": "Prothese",
"prosthesis_desc": "Arme und Beine sind kugelsicher",
"primaryban": "Keine Gewehre",
"primaryban_desc": "Wähle einen Spieler aus, der keine Gewehre verwenden kann",
"primaryban_enemy_info": "Du kannst keine Gewehre mehr verwenden.",
"primaryban_player_info": "Der Spieler ‚{0}‘ kann keine Gewehre mehr verwenden.",
"primaryban_select_info": "Gewehre für Spieler verbieten:",
"push": "Pusher",
"push_desc": "Du hast eine zufällige Chance, einen Gegner zurückzustoßen, wenn du ihn triffst",
"push_desc2": "Deine Chancen, den Gegner zurückzustoßen, betragen: {0} %",
"prosthesis": "Prothese",
"prosthesis_desc": "Arme und Beine sind kugelsicher",
"pyro": "Pyro",
"pyro_desc": "Molotow-Cocktail stellt Gesundheit wieder her",
"push": "Pusher",
"push_desc": "Du hast eine zufällige Chance, einen Gegner zurückzustoßen, wenn du ihn triffst",
"push_desc2": "Deine Chancen, den Gegner zurückzustoßen, betragen: {0} %",
"quickshot": "Schnellfeuer",
"quickshot_desc": "Alle Kugeln werden sehr schnell abgefeuert",
"pyro": "Pyro",
"pyro_desc": "Molotow-Cocktail stellt Gesundheit wieder her",
"radarhack": "Radar-Hack",
"radarhack_desc": "Gegner sind auf dem Radar sichtbar",
"quickshot": "Schnellfeuer",
"quickshot_desc": "Alle Kugeln werden sehr schnell abgefeuert",
"rambo": "Rambo",
"rambo_desc": "Du erhältst zu Beginn der Runde eine zufällige Menge an Gesundheit",
"radarhack": "Radar-Hack",
"radarhack_desc": "Gegner sind auf dem Radar sichtbar",
"randomweapon": "Zufällige Waffe",
"randomweapon_desc": "Klicke auf [css_useSkill], um eine zufällige Waffe zu erhalten",
"rambo": "Rambo",
"rambo_desc": "Du erhältst zu Beginn der Runde eine zufällige Menge an Gesundheit",
"rezombie": "Re-Zombie",
"rezombie_desc": "Nach dem Tod spawnst du als Zombie mit erhöhter Gesundheit und ohne Waffen",
"randomweapon": "Zufällige Waffe",
"randomweapon_desc": "Klicke auf [css_useSkill], um eine zufällige Waffe zu erhalten",
"reactivearmor": "Reaktive Rüstung",
"reactivearmor_desc": "Die Rüstung absorbiert den ersten erlittenen Schaden",
"rezombie": "Re-Zombie",
"rezombie_desc": "Nach dem Tod spawnst du als Zombie mit erhöhter Gesundheit und ohne Waffen",
"regeneration": "Regeneration",
"regeneration_desc": "Du stellst alle paar Sekunden Gesundheit wieder her",
"reactivearmor": "Reaktive Rüstung",
"reactivearmor_desc": "Die Rüstung absorbiert den ersten erlittenen Schaden",
"replicator": "Replikator",
"replicator_desc": "Klicke auf [css_useSkill], um eine Replik zu erstellen, die bei Treffer Schaden verursacht",
"regeneration": "Regeneration",
"regeneration_desc": "Du stellst alle paar Sekunden Gesundheit wieder her",
"retreat": "Rückzug",
"retreat_desc": "Klicke auf [css_useSkill], um zum Spawn zurückzukehren",
"replicator": "Replikator",
"replicator_desc": "Klicke auf [css_useSkill], um eine Replik zu erstellen, die bei Treffer Schaden verursacht",
"returntosender": "Zurück zum Absender",
"returntosender_desc": "Der erste Treffer eines Gegners schickt ihn zurück zu seinem Spawn",
"retreat": "Rückzug",
"retreat_desc": "Klicke auf [css_useSkill], um zum Spawn zurückzukehren",
"richboy": "Rich Boy",
"richboy_desc": "Du erhältst zu Beginn der Runde einen zufälligen Geldbetrag",
"returntosender": "Zurück zum Absender",
"returntosender_desc": "Der erste Treffer eines Gegners schickt ihn zurück zu seinem Spawn",
"robinhood": "Robin Hood",
"robinhood_desc": "Wenn du einem Gegner Schaden zufügst, stiehlst du ihm sein Geld",
"richboy": "Rich Boy",
"richboy_desc": "Du erhältst zu Beginn der Runde einen zufälligen Geldbetrag",
"rubber": "Gummigeschosse",
"rubber_desc": "Deine Kugeln verlangsamen Spieler erheblich",
"robinhood": "Robin Hood",
"robinhood_desc": "Wenn du einem Gegner Schaden zufügst, stiehlst du ihm sein Geld",
"saper": "Sapper",
"saper_desc": "Du kannst Bomben schneller legen und entschärfen",
"rubber": "Gummigeschosse",
"rubber_desc": "Deine Kugeln verlangsamen Spieler erheblich",
"secondlife": "Zweite Chance",
"secondlife_desc": "Nach dem Tod spawnst du mit derselben Gesundheitsanzeige wieder",
"saper": "Sapper",
"saper_desc": "Du kannst Bomben schneller legen und entschärfen",
"shade": "Schatten",
"shade_desc": "Du hast eine zufällige Chance, dich hinter einen getroffenen Gegner zu teleportieren",
"shade_desc2": "Deine Chancen, dich hinter einen getroffenen Gegner zu teleportieren, betragen: {0} %",
"shade_nospace": "Kein Platz verfügbar",
"secondlife": "Zweite Chance",
"secondlife_desc": "Nach dem Tod spawnst du mit derselben Gesundheitsanzeige wieder",
"shortbomb": "Kurze Zündschnur",
"shortbomb_desc": "Die Bombe explodiert viel schneller",
"shade": "Schatten",
"shade_desc": "Du hast eine zufällige Chance, dich hinter einen getroffenen Gegner zu teleportieren",
"shade_desc2": "Deine Chancen, dich hinter einen getroffenen Gegner zu teleportieren, betragen: {0} %",
"shade_nospace": "Kein Platz verfügbar",
"silent": "Leise",
"silent_desc": "Deine Schritte und Sprünge sind für ANDERE Spieler lautlos",
"shortbomb": "Kurze Zündschnur",
"shortbomb_desc": "Die Bombe explodiert viel schneller",
"smoker": "Smoker",
"smoker_desc": "Deine Rauchgranaten gehen nie aus",
"silent": "Leise",
"silent_desc": "Deine Schritte und Sprünge sind für ANDERE Spieler lautlos",
"sniperelite": "Sniper Elite",
"sniperelite_customname": "Sniper-Elite-Skill",
"sniperelite_desc": "Klicke auf [css_useSkill], um deine aktuelle Waffe gegen eine AWP auszutauschen",
"smoker": "Smoker",
"smoker_desc": "Deine Rauchgranaten gehen nie aus",
"soldier": "Soldat",
"soldier_desc": "Du hast einen zufälligen Schadensmultiplikator",
"soldier_desc2": "Dein Schadensmultiplikator beträgt: {0}x",
"sniperelite": "Sniper Elite",
"sniperelite_customname": "Sniper-Elite-Skill",
"sniperelite_desc": "Klicke auf [css_useSkill], um deine aktuelle Waffe gegen eine AWP auszutauschen",
"soundmaker": "Soundmaker",
"soundmaker_desc": "Klicke auf [css_useSkill], um für jeden Gegner einen Sound auszulösen",
"soldier": "Soldat",
"soldier_desc": "Du hast einen zufälligen Schadensmultiplikator",
"soldier_desc2": "Dein Schadensmultiplikator beträgt: {0}x",
"spectator": "Zuschauer",
"spectator_desc": "Klicke auf [css_useSkill], um einen zufälligen Gegner zu beobachten",
"soundmaker": "Soundmaker",
"soundmaker_desc": "Klicke auf [css_useSkill], um für jeden Gegner einen Sound auszulösen",
"swapposition": "Positionstausch",
"swapposition_desc": "Klicke auf [css_useSkill], um mit einem zufälligen Gegner die Plätze zu tauschen",
"spectator": "Zuschauer",
"spectator_desc": "Klicke auf [css_useSkill], um einen zufälligen Gegner zu beobachten",
"teleporter": "Teleporter",
"teleporter_desc": "Du hast die Chance, die Plätze mit einem getroffenen Gegner zu tauschen",
"teleporter_desc2": "Deine Chance auf Platztausch nach einem Treffer: {0}%",
"swapposition": "Positionstausch",
"swapposition_desc": "Klicke auf [css_useSkill], um mit einem zufälligen Gegner die Plätze zu tauschen",
"thief": "Dieb",
"thief_desc": "Du kannst einem ausgewählten Spieler eine Fertigkeit stehlen",
"thief_enemy_info": "Deine Fertigkeit wurde gestohlen",
"thief_player_info": "Die Fertigkeit des Spielers ‚{0}‘ wurde gestohlen",
"thief_select_info": "Fähigkeit eines Spielers stehlen:",
"thief_incorrect_skill": "Diese Fähigkeit kann nicht ausgewählt werden!",
"teleporter": "Teleporter",
"teleporter_desc": "Du hast die Chance, die Plätze mit einem getroffenen Gegner zu tauschen",
"teleporter_desc2": "Deine Chance auf Platztausch nach einem Treffer: {0}%",
"thirdeye": "Drittes Auge",
"thirdeye_desc": "Klicke auf [css_useSkill], um die Third-Person-Ansicht zu aktivieren",
"thief": "Dieb",
"thief_desc": "Du kannst einem ausgewählten Spieler eine Fertigkeit stehlen",
"thief_enemy_info": "Deine Fertigkeit wurde gestohlen",
"thief_player_info": "Die Fertigkeit des Spielers ‚{0}‘ wurde gestohlen",
"thief_select_info": "Fähigkeit eines Spielers stehlen:",
"thief_incorrect_skill": "Diese Fähigkeit kann nicht ausgewählt werden!",
"thorns": "Dornen",
"thorns_desc": "Dein Gegner erhält einen Teil des Schadens, den er dir zugefügt hat",
"thirdeye": "Drittes Auge",
"thirdeye_desc": "Klicke auf [css_useSkill], um die Third-Person-Ansicht zu aktivieren",
"throwingknife": "Wurfmesser",
"throwingknife_desc": "Klicke [css_useSkill], um ein Messer zu werfen. Aber nimm dich vor anderen in Acht",
"thorns": "Dornen",
"thorns_desc": "Dein Gegner erhält einen Teil des Schadens, den er dir zugefügt hat",
"toxicsmoke": "Giftiger Rauch",
"toxicsmoke_desc": "Deine Rauchgranaten verursachen Schaden",
"throwingknife": "Wurfmesser",
"throwingknife_desc": "Klicke [css_useSkill], um ein Messer zu werfen. Aber nimm dich vor anderen in Acht",
"wallhack": "Wallhack",
"wallhack_desc": "Du kannst Feinde durch Wände hindurch sehen",
"toxicsmoke": "Giftiger Rauch",
"toxicsmoke_desc": "Deine Rauchgranaten verursachen Schaden",
"watchmaker": "Uhrmacher",
"watchmaker_desc": "Jeder Granatenwurf verändert die Rundenzeit",
"watchmaker_ct": "Rundenzeit um {0} Sekunden verkürzt",
"watchmaker_tt": "Rundenzeit um {0} Sekunden verlängert",
"wallhack": "Wallhack",
"wallhack_desc": "Du kannst Feinde durch Wände hindurch sehen",
"weaponsswap": "Waffenwechsel",
"weaponsswap_desc": "Klicke auf [css_useSkill], um mit einem zufälligen Gegner die Waffen zu tauschen",
"weaponsswap_hud_info2": "Du hast keine Waffe zum Tauschen",
"watchmaker": "Uhrmacher",
"watchmaker_desc": "Jeder Granatenwurf verändert die Rundenzeit",
"watchmaker_ct": "Rundenzeit um {0} Sekunden verkürzt",
"watchmaker_tt": "Rundenzeit um {0} Sekunden verlängert",
"weightless": "Schwerelosigkeit",
"weightless_desc": "Deine Granaten werden nicht von der Schwerkraft beeinflusst und fliegen schneller",
"weaponsswap": "Waffenwechsel",
"weaponsswap_desc": "Klicke auf [css_useSkill], um mit einem zufälligen Gegner die Waffen zu tauschen",
"weaponsswap_hud_info2": "Du hast keine Waffe zum Tauschen",
"wildthrow": "Wilder Wurf",
"wildthrow_desc": "Wähle einen Spieler aus, der Probleme beim Werfen von Granaten haben wird",
"wildthrow_player_info": "Spieler '{0}' hat all seine Lineups vergessen",
"wildthrow_select_info": "Wähle einen Spieler aus:",
"zeus": "Zeus",
"zeus_desc": "Zeus x27 lädt sich sofort wieder auf",
"your_skill": "Deine aktuelle Fertigkeit",
"enemy_skill": "Fähigkeit des Gegners",
"observer_skill": "Fähigkeit des Spielers",
"welcome_message": "Willkommen {PLAYER} bei {SERVER_NAME}",
"drawing_skill": "Eine Fertigkeit zeichnen",
"disabled_weapon": "Du kannst diese Waffe nicht verwenden",
"hud_info": "Warte weitere {0} Sekunden",
"hud_info_no_enemy": "Kein Feind gefunden",
"active_hud_info": "Noch {0} Millisekunden aktiv",
"skills_menu": "Fähigkeitenliste",
"no_player": "Kein passender Spieler gefunden.",
"duplicate_player": "Mehr als ein Spieler mit demselben Namen gefunden.",
"selectplayerskill_command": "Gib /t ein",
"selectplayerskill_incorrect_enemy_index": "Es wurden keine Spieler gefunden, die ausgewählt werden können.",
"skill_not_found_setskill": "Keine solche CHATCOLORS.REDskill gefunden",
"player_not_found_setskill": "Kein solcher CHATCOLORS.REDplayer gefunden",
"correct_form_setskill": "Korrekte Verwendung: CHATCOLORS.RED!setskill <Fähigkeit>",
"correct_form_setscore": "Korrekte Verwendung: CHATCOLORS.RED!setscore ",
"done_setskill": "Fähigkeit festgelegt",
"error_setskill": "CHATCOLORS.REDskill konnte nicht festgelegt werden",
"for_setskill": "für",
"invalid_map": "Kartenname falsch eingegeben!",
"loading_map": "Neue Karte wird geladen",
"pause": "Spiel wurde unterbrochen",
"unpause": "Spiel wurde fortgesetzt",
"healed": "Du wurdest geheilt.",
"game_start": "Spiel gestartet!",
"reload": "Sprachen und Konfigurationen wurden neu geladen.",
"hud_on": "HUD wurde aktiviert.",
"hud_off": "HUD wurde deaktiviert.",
"vote_started": "Abstimmung gestartet: ‚{0}‘",
"vote_timeout": "Zeitlimit für Abstimmung ‚{0}‘ abgelaufen!",
"vote_wait": "Sie müssen warten, bevor Sie eine weitere Abstimmung starten können!",
"vote_same_wait": "Sie müssen warten, bevor Sie dieselbe Abstimmung erneut starten können!",
"vote_not_enough_players": "Nicht genügend Spieler, um eine Abstimmung zu starten!",
"vote_alredy_voted": "Du hast bereits abgestimmt!",
"vote_vote": "Abstimmen",
"bombsite_a": "Bombenplatz A",
"bombsite_b": "Bombenplatz B",
"bombplanted": "Die Bombe wurde gelegt\n{0} Sekunden bis zur Detonation",
"teammate_skills": "Die Fähigkeiten Ihrer Teamkollegen",
"summary": "Zusammenfassung der letzten runde",
"menu_controlls_scroll": "W/S – Scrollen",
"menu_controlls_padding": " | ",
"menu_controlls_select": "E – Auswählen"
"weightless": "Schwerelosigkeit",
"weightless_desc": "Deine Granaten werden nicht von der Schwerkraft beeinflusst und fliegen schneller",
"wildthrow": "Wilder Wurf",
"wildthrow_desc": "Wähle einen Spieler aus, der Probleme beim Werfen von Granaten haben wird",
"wildthrow_player_info": "Spieler '{0}' hat all seine Lineups vergessen",
"wildthrow_select_info": "Wähle einen Spieler aus:",
"zeus": "Zeus",
"zeus_desc": "Zeus x27 lädt sich sofort wieder auf",
"your_skill": "Deine aktuelle Fertigkeit",
"enemy_skill": "Fähigkeit des Gegners",
"observer_skill": "Fähigkeit des Spielers",
"welcome_message": "Willkommen {PLAYER} bei {SERVER_NAME}",
"drawing_skill": "Eine Fertigkeit zeichnen",
"disabled_weapon": "Du kannst diese Waffe nicht verwenden",
"hud_info": "Warte weitere {0} Sekunden",
"hud_info_no_enemy": "Kein Feind gefunden",
"active_hud_info": "Noch {0} Millisekunden aktiv",
"skills_menu": "Fähigkeitenliste",
"no_player": "Kein passender Spieler gefunden.",
"duplicate_player": "Mehr als ein Spieler mit demselben Namen gefunden.",
"selectplayerskill_command": "Gib /t ein",
"selectplayerskill_incorrect_enemy_index": "Es wurden keine Spieler gefunden, die ausgewählt werden können.",
"skill_not_found_setskill": "Keine solche CHATCOLORS.REDskill gefunden",
"player_not_found_setskill": "Kein solcher CHATCOLORS.REDplayer gefunden",
"correct_form_setskill": "Korrekte Verwendung: CHATCOLORS.RED!setskill <Fähigkeit>",
"correct_form_setscore": "Korrekte Verwendung: CHATCOLORS.RED!setscore ",
"done_setskill": "Fähigkeit festgelegt",
"error_setskill": "CHATCOLORS.REDskill konnte nicht festgelegt werden",
"for_setskill": "für",
"invalid_map": "Kartenname falsch eingegeben!",
"loading_map": "Neue Karte wird geladen",
"pause": "Spiel wurde unterbrochen",
"unpause": "Spiel wurde fortgesetzt",
"healed": "Du wurdest geheilt.",
"game_start": "Spiel gestartet!",
"reload": "Sprachen und Konfigurationen wurden neu geladen.",
"hud_on": "HUD wurde aktiviert.",
"hud_off": "HUD wurde deaktiviert.",
"vote_started": "Abstimmung gestartet: ‚{0}‘",
"vote_timeout": "Zeitlimit für Abstimmung ‚{0}‘ abgelaufen!",
"vote_wait": "Sie müssen warten, bevor Sie eine weitere Abstimmung starten können!",
"vote_same_wait": "Sie müssen warten, bevor Sie dieselbe Abstimmung erneut starten können!",
"vote_not_enough_players": "Nicht genügend Spieler, um eine Abstimmung zu starten!",
"vote_alredy_voted": "Du hast bereits abgestimmt!",
"vote_vote": "Abstimmen",
"bombsite_a": "Bombenplatz A",
"bombsite_b": "Bombenplatz B",
"bombplanted": "Die Bombe wurde gelegt\n{0} Sekunden bis zur Detonation",
"teammate_skills": "Die Fähigkeiten Ihrer Teamkollegen",
"summary": "Zusammenfassung der letzten runde",
"menu_controlls_scroll": "W/S – Scrollen",
"menu_controlls_padding": " | ",
"menu_controlls_select": "E – Auswählen"
}

View file

@ -275,9 +275,9 @@
"bankrupt_player_info": "Player '{0}' has gone bankrupt.",
"bankrupt_select_info": "Pick a player to go bankrupt:",
"muhammed": "Muhammed",
"muhammed_desc": "You explode upon death, killing nearby players",
"muhammed_explosion": "ALLAHU AKBAR!!!",
"deathbomb": "Death Bomb",
"deathbomb_desc": "You explode upon death, killing nearby players",
"deathbomb_explosion": "Kaboom!",
"ninja": "Ninja",
"ninja_desc": "Standing still increases your invisibility by 33%, crouching by 33%, and holding a knife by 33%",

View file

@ -275,9 +275,9 @@
"bankrupt_player_info": "Le joueur « {0} » est en faillite.",
"bankrupt_select_info": "Mettre un joueur en faillite :",
"muhammed": "Bombe",
"muhammed_desc": "Vous explosez à votre mort, tuant les joueurs proches",
"muhammed_explosion": "ALLAHU AKBAR!!!",
"deathbomb": "Bombe",
"deathbomb_desc": "Vous explosez à votre mort, tuant les joueurs proches",
"deathbomb_explosion": "Kaboom!",
"ninja": "Ninja",
"ninja_desc": "Rester immobile augmente votre invisibilité de 33%, s’accroupir de 33%, et tenir un couteau de 33%",

View file

@ -275,9 +275,9 @@
"moneyswap_player_info": "Wymieniłeś swoje pieniądze z graczem '{0}'.",
"moneyswap_select_info": "Zamień się kasą z graczem:",
"muhammed": "Muhammed",
"muhammed_desc": "Po śmierci eksplodujesz i zabijasz graczy znajdujących się w zasięgu",
"muhammed_explosion": "ALLAHU AKBAR!!!",
"deathbomb": "Ludzka bomba",
"deathbomb_desc": "Po śmierci eksplodujesz i zabijasz graczy znajdujących się w zasięgu",
"deathbomb_explosion": "Kaboom!",
"ninja": "Ninja",
"ninja_desc": "Stojąc nieruchomo zwiększasz swoją niewidzialność o 33%, kucając o 33%, a trzymając nóż o 33%",

View file

@ -52,10 +52,10 @@
"blademaster": "Mestre das Lâminas",
"blademaster_desc": "Enquanto segura a faca, você tem chance de desviar de um tiro",
"bunnyhop": "Coelho",
"bunnyhop_desc": "Você ganha \"BunnyHop\" automático",
"c4camouflage": "Camuflagem C4",
"c4camouflage_desc": "Você fica invisível enquanto segura a bomba",
@ -68,122 +68,122 @@
"catapult": "Catapulta",
"catapult_desc": "Você tem uma chance aleatória de lançar um inimigo para cima",
"catapult_desc2": "Sua chance de lançar um inimigo ao acertá-lo é: {0}%",
"chicken": "Galinha",
"chicken_desc": "Você é uma galinha com +10% de movimento mais rápido e -50 HP",
"chillout": "Esqueci a Senha",
"chillout_desc": "Plantar a bomba leva significativamente mais tempo",
"cutter": "Corte Rápido",
"cutter_desc": "Você mata instantaneamente com a faca",
"cypher": "CFTV",
"cypher_desc": "Clique em [css_useSkill] para criar/mudar para uma câmera",
"cypher_nospace": "A câmera deve ser posicionada em ângulo reto com a parede",
"darkness": "Escuridão",
"darkness_desc": "Aplica um efeito de escuridão a um inimigo escolhido",
"darkness_enemy_info": "Que as luzes se apaguem.",
"darkness_player_info": "A escuridão tomou conta do jogador '{0}'.",
"darkness_select_info": "Escolha jogador: escuridão:",
"deactivator": "Desativador",
"deactivator_desc": "Escolha um jogador para desativar a habilidade",
"deactivator_enemy_info": "Sua habilidade foi desativada.",
"deactivator_player_info": "A habilidade do jogador '{0}' foi desativada.",
"deactivator_select_info": "Desativar skill do jogador:",
"deaf": "Surdo",
"deaf_desc": "Escolha um jogador para desativar todos os sons",
"deaf_enemy_info": "Seus fones de ouvido saíram do jogo.",
"deaf_player_info": "O som foi desativado para o jogador '{0}'.",
"deaf_select_info": "Silenciar jogador:",
"disarmament": "Desarmamento",
"disarmament_desc": "Você tem uma chance aleatória de fazer um inimigo dropar a arma ao acertá-lo",
"disarmament_desc2": "Sua chance de desarmar um inimigo é: {0}%",
"distancer": "Medidor de Distância",
"distancer_desc": "Você pode ver a distância até o inimigo mais próximo",
"dash": "Impulso",
"dash_desc": "Pule novamente para receber um impulso",
"dracula": "Drácula",
"dracula_desc": "Acertar um inimigo restaura sua vida igual a ao dano causado",
"duplicator": "ctrl+c ctrl+v",
"duplicator_desc": "Escolha um jogador para copiar a habilidade",
"duplicator_player_info": "A habilidade do jogador '{0}' foi copiada.",
"duplicator_select_info": "Copiar skill do jogador:",
"dwarf": "Anão",
"dwarf_desc": "Sua altura agora é aleatória",
"dwarf_desc2": "Seu multiplicador de altura é: {0}x",
"enemyspawn": "Spawn Inimigo",
"enemyspawn_desc": "Clique em [css_useSkill] para se teletransportar para a base inimiga",
"explosiveshot": "Tiro Explosivo",
"explosiveshot_desc": "Chance aleatória de disparar uma bala explosiva enquanto atira",
"explosiveshot_desc2": "Sua chance de disparar uma bala explosiva: {0}%",
"falconeye": "Olho de Águia",
"falconeye_desc": "Clique em [css_useSkill] para ativar uma câmera 360 com visão aérea",
"fastreload": "Recarga Rápida",
"fastreload_desc": "Clique em [css_useSkill] para recarregar a arma que você está segurando",
"flash": "Ligeirinho",
"flash_desc": "Velocidade de movimentação aleatória no início da rodada",
"flash_desc2": "Seu multiplicador de velocidade é: {0}x",
"fortnite": "Fortnite",
"fortnite_desc": "Clique em [css_useSkill] para criar uma barreira destrutível",
"fragilebomb": "Bomba Frágil",
"fragilebomb_desc": "Atirar na bomba a danifica",
"fragilebomb_bomb_health": "Vida da bomba",
"friendlyfire": "Fogo Amigo",
"friendlyfire_desc": "Atirar em companheiros de equipe os cura",
"frozendecoy": "Decoy Congelante",
"frozendecoy_desc": "Sua decoy congela os players próximos",
"gambler": "Tigrinho",
"gambler_desc": "Selecione uma habilidade da lista.",
"gambler_select_info": "Escolha sua habilidade:",
"gambler_more": "#00FF00|Atualizar por ${0}",
"gambler_no_money": "Yetersiz bakiye.",
"ghost": "Fantasma",
"ghost_desc": "Você é completamente invisível",
"glaz": "Smoke Transparente",
"glaz_desc": "Smokes tornam-se transparentes para você",
"glitch": "Sem Mapa",
"glitch_desc": "Desativa o radar de um inimigo escolhido",
"glitch_enemy_info": "Seu radar foi desativado.",
"glitch_player_info": "O radar do jogador '{0}' foi desativado.",
"glitch_select_info": "Desativar radar do jogador:",
"glue": "Semtex",
"glue_desc": "Suas granadas grudam nas paredes",
"godmode": "Modo Deus",
"godmode_desc": "Clique em [css_useSkill] para se tornar imortal por alguns segundos",
"godmode_off": "Imortalidade desativada",
"godmode_on": "Imortalidade ativada",
"grenadier": "Bomberman",
"grenadier_desc": "Você tem HEs infinitas",
"healingsmoke": "Smoke Amiga",
"healingsmoke_desc": "Suas smokes curam",
"hermit": "Sanguessuga",
"hermit_desc": "Matar restaura munição e uma parte da sua vida",
@ -199,7 +199,7 @@
"iana": "Holograma",
"iana_desc": "Clique em [css_useSkill] para controlar seu holograma por alguns segundos",
"illiterate": "Analfabeto",
"illiterate_desc": "Enquanto você estiver vivo, seus inimigos não conseguem ler",
@ -208,10 +208,10 @@
"impostor": "Impostor",
"impostor_desc": "Você começa a rodada vestido do time inimigo",
"infiniteammo": "Munição Infinita",
"infiniteammo_desc": "Você recebe munição infinita para todas as suas armas",
"jackal": "Lesma",
"jackal_desc": "Cada adversário deixa um rastro atrás de si",
@ -220,37 +220,37 @@
"jammer_enemy_info": "Sua mira foi desativada.",
"jammer_player_info": "A mira do jogador '{0}' foi desativada.",
"jammer_select_info": "Desativar mira do jogador:",
"jester": "Palhaço",
"jester_desc": "No modo bobo você não pode causar nem receber dano. Esse modo muda a cada poucos segundos.",
"jester_mode": "Modo Palhaço",
"jester_on": "LIG.",
"jester_off": "DESL.",
"jumpban": "Perneta",
"jumpban_desc": "Escolha um jogador que não poderá pular",
"jumpban_enemy_info": "Cortaram as suas pernas.",
"jumpban_player_info": "O jogador '{0}' não pode mais pular.",
"jumpban_select_info": "Banir pulo do jogador:",
"jumpingjack": "Pula-Pula",
"jumpingjack_desc": "Pular restaura vida",
"killerflash": "Flash Mortal",
"killerflash_desc": "Qualquer pessoa cega pela sua flash morre (incluindo você)",
"lifeswap": "Troca de Vida",
"lifeswap_desc": "Escolha um jogador para trocar de vida",
"lifeswap_enemy_info": "Alguém pegou sua vida emprestada.",
"lifeswap_player_info": "Você trocou vida com o jogador '{0}'.",
"lifeswap_select_info": "Trocar de vida com jogador:",
"longknife": "Espada",
"longknife_desc": "Um ataque com faca causa danos independentemente da distância",
"longzeus": "Zeus Longo",
"longzeus_desc": "Zeus causa dano independentemente da distância",
"magneticdecoy": "Decoy Magnético",
"magneticdecoy_desc": "Seu decoy atrai jogadores próximos para si mesmo",
@ -262,10 +262,10 @@
"magnifier_enemy_info": "Seu campo de visão foi distorcido!",
"magnifier_player_info": "O jogador ‘{0}’ foi forçado a entrar no modo zoom.",
"magnifier_select_info": "Ampliar tela do jogador:",
"medic": "Médico",
"medic_desc": "Clique em [css_useSkill] para usar uma injeção que restaura 50 de vida",
"miner": "Mineiro de Bombas",
"miner_desc": "Sua granada HE só explode quando há um inimigo por perto",
@ -274,131 +274,131 @@
"moneyswap_enemy_info": "Você provavelmente virou classe B",
"moneyswap_player_info": "Você trocou dinheiro com o jogador '{0}'.",
"moneyswap_select_info": "Trocar dinheiro c/ jogador:",
"muhammed": "Muhammed",
"muhammed_desc": "Você explode ao morrer, matando os jogadores próximos",
"muhammed_explosion": "ALLAHU AKBAR!!!",
"deathbomb": "Bomba mortal",
"deathbomb_desc": "Você explode ao morrer, matando os jogadores próximos",
"deathbomb_explosion": "Kaboom!",
"ninja": "Ninja",
"ninja_desc": "Ficar parado aumenta sua invisibilidade em 33%, agachar em 33%, e segurar uma faca em 33%",
"nonades": "Imune a Granadas",
"nonades_desc": "Granadas não causam dano a você",
"norecoil": "Sem Recoil",
"norecoil_desc": "Sem recoil ao atirar",
"noclip": "NoClip",
"noclip_desc": "Clique em [css_useSkill] para ativar noclip por poucos segundos",
"oneshot": "Ignorante",
"oneshot_desc": "Acertar um inimigo o mata instantaneamente",
"onlyhead": "Só na Cabeçinha",
"onlyhead_desc": "Você só recebe headshot",
"paweljumper": "Parkourista",
"paweljumper_desc": "Você recebe um número aleatório de pulos extras",
"paweljumper_desc2": "Você ganha {0} pulos extras",
"phoenix": "Fênix",
"phoenix_desc": "Você tem uma chance aleatória de renascer após a morte",
"phoenix_desc2": "Sua chance de renascer após a morte: {0}%",
"phoenix_respawn": "Você foi ressuscitado das cinzas graças ao poder de: CHATCOLORS.REDPhoenix",
"psychicdefusing": "Desarme Psíquico",
"psychicdefusing_desc": "Quando você está proximo da bomba, começa a desarmá-la automaticamente",
"psychicdefusing_hud_info": "{0} segundos restantes para desarmar",
"pilot": "Jetpack",
"pilot_desc": "Voe por tempo limitado. Clique duas vezes no pulo para voar",
"pilot_hud_info": "Combustível",
"planter": "Meu Bombsite Minha Vida",
"planter_desc": "Você pode plantar a bomba em qualquer lugar, com um tempo de detonação de 60 segundos.",
"planter_planting": "Plantando ({0})...",
"poison": "Veneno",
"poison_desc": "Escolha um jogador que receberá dano a cada poucos segundos",
"poison_enemy_info": "Você foi envenenado.",
"poison_player_info": "O jogador '{0}' foi envenenado.",
"poison_select_info": "Envenenar jogador:",
"primaryban": "Sem Rifle",
"primaryban_desc": "Escolha um jogador que não poderá usar rifles",
"primaryban_enemy_info": "Você não pode mais usar rifles.",
"primaryban_player_info": "O jogador '{0}' não pode mais usar rifles.",
"primaryban_select_info": "Banir rifles do jogador:",
"prosthesis": "Prótese",
"prosthesis_desc": "Braços e pernas são à prova de balas",
"push": "Empurrão",
"push_desc": "Você tem uma chance aleatória de empurrar um inimigo ao acertá-lo",
"push_desc2": "Suas chances de empurrar o inimigo são: {0}%",
"pyro": "Pirotecnia",
"pyro_desc": "Molotov recupera vida",
"quickshot": "Tiro Rápido",
"quickshot_desc": "Todas as balas são disparadas extremamente rapidas",
"radarhack": "Hack de Mapa",
"radarhack_desc": "Inimigos são visíveis no mapa",
"rambo": "Rambo",
"rambo_desc": "Você recebe uma quantidade aleatória de vida no início da rodada",
"randomweapon": "Arma Aleatória",
"randomweapon_desc": "Clique em [css_useSkill] para receber uma arma aleatória",
"rezombie": "Walking Dead",
"rezombie_desc": "Após morrer, você renasce como um zumbi com mais vida porém sem armas",
"reactivearmor": "Armadura Reativa",
"reactivearmor_desc": "A armadura absorve o primeiro dano recebido",
"regeneration": "Regeneração",
"regeneration_desc": "Você restaura vida a cada poucos segundos",
"replicator": "Clone",
"replicator_desc": "Clique em [css_useSkill] para criar um clone que causa dano ao ser atingido",
"retreat": "De Volta as Origens",
"retreat_desc": "Clique em [css_useSkill] para retornar ao spawn",
"returntosender": "Devolução ao Remetente",
"returntosender_desc": "O primeiro tiro em um inimigo o envia de volta a sua base",
"richboy": "Filhinho de Papai",
"richboy_desc": "Você recebe uma quantidade aleatória de dinheiro no início da rodada",
"robinhood": "Robin Hood",
"robinhood_desc": "Atirar em um inimigo rouba seu dinheiro",
"rubber": "Balas de Borracha",
"rubber_desc": "Seus tiros deixam os jogadores lentos ao serem atingidos",
"saper": "Especialista",
"saper_desc": "Você pode plantar e desarmar bombas mais rápido",
"secondlife": "Segunda Chance",
"secondlife_desc": "Após morrer, você renasce com a mesma quantidade de vida",
"shade": "Sombra",
"shade_desc": "Você tem uma chance aleatória de teletransportar para trás de um inimigo ao atingi-lo",
"shade_desc2": "Suas chances de se teletransportar para trás de um inimigo atingido são: {0}%",
"shade_nospace": "Sem espaço disponível",
"shortbomb": "Pavio Longo",
"shortbomb_desc": "A bomba demora muito mais para explodir",
"silent": "Shhhiu!",
"silent_desc": "Seus passos e pulos são silenciosos para OUTROS jogadores",
"smoker": "Tiryaki",
"smoker_desc": "Sis bombalarınız asla bitmez",
"sniperelite": "Sniper do BOPE",
"sniperelite_desc": "Clique em [css_useSkill] para trocar sua arma atual por uma AWP",
"sniperelite_customname": "Keskin Nişancı Elit Yeteneği",
@ -406,51 +406,51 @@
"soldier": "Soldado",
"soldier_desc": "Seus tiros causam mais dano",
"soldier_desc2": "Seu multiplicador de dano é: {0}x",
"soundmaker": "Criador de Som",
"soundmaker_desc": "Clique em [css_useSkill] para tocar um som para cada inimigo",
"spectator": "Espectador",
"spectator_desc": "Clique em [css_useSkill] para ver a tela de um inimigo aleatório",
"swapposition": "Troca de Posição",
"swapposition_desc": "Clique em [css_useSkill] para trocar de lugar com um inimigo aleatório",
"teleporter": "Teletransportador",
"teleporter_desc": "Você tem a chance de trocar de lugar com um inimigo atingido",
"teleporter_desc2": "Sua chance de trocar de lugar após o acerto: {0}%",
"thief": "Lula",
"thief_desc": "Você pode roubar uma habilidade de um jogador escolhido",
"thief_enemy_info": "Sua habilidade foi roubada.",
"thief_player_info": "A habilidade do jogador '{0}' foi roubada.",
"thief_select_info": "Roubar skill do jogador:",
"thief_incorrect_skill": "Esta habilidade não pode ser selecionada!",
"thirdeye": "Terceiro Olho",
"thirdeye_desc": "Clique em [css_useSkill] para ativar a terceira pessoa",
"thorns": "Porco Espinho",
"thorns_desc": "Seu oponente receberá uma parte do dano que causou a você",
"throwingknife": "Faca de Arremesso",
"throwingknife_desc": "Clique em [css_useSkill] para lançar uma faca. Mas cuidado com os outros",
"toxicsmoke": "Smoke Tóxica",
"toxicsmoke_desc": "Suas smokes causam dano",
"wallhack": "Wallhack",
"wallhack_desc": "Você pode ver inimigos através das paredes",
"watchmaker": "Relojoeiro",
"watchmaker_desc": "Cada arremesso de granada altera o tempo da rodada",
"watchmaker_ct": "Tempo da rodada reduzido em {0} segundos.",
"watchmaker_tt": "Tempo da rodada estendido em {0} segundos.",
"weaponsswap": "Troca de Armas",
"weaponsswap_desc": "Clique em [css_useSkill] para trocar armas com um inimigo aleatório",
"weaponsswap_hud_info2": "Você não tem arma para trocar",
"weightless": "Gravidade Zero",
"weightless_desc": "Suas granadas não são afetadas pela gravidade e voam mais rápido",
@ -461,24 +461,24 @@
"zeus": "Zeus",
"zeus_desc": "Zeus x27 recarrega instantaneamente",
"your_skill": "Sua habilidade atual",
"enemy_skill": "Habilidade do inimigo",
"observer_skill": "Habilidade do jogador",
"welcome_message": "Bem-vindo {PLAYER} ao {SERVER_NAME}!\nVersão atual do jRandomSkills: {VERSION} ({SKILLS_COUNT} habilidades).\n\nCriado originalmente por:\n{AUTHOR1}\nModificado e aprimorado por:\n{AUTHOR2}\nDiscord oficial: https://discord.gg/9H8EZYBpPF",
"drawing_skill": "Sorteando uma habilidade",
"disabled_weapon": "Você não pode usar esta arma",
"hud_info": "Espere mais {0} segundos",
"hud_info_no_enemy": "Nenhum inimigo encontrado",
"active_hud_info": "Ativo por mais {0} milissegundos",
"skills_menu": "Lista de Habilidades",
"no_player": "Nenhum jogador correspondente encontrado.",
"duplicate_player": "Mais de um jogador encontrado com o mesmo nome.",
"selectplayerskill_command": "Digite /t",
"selectplayerskill_incorrect_enemy_index": "Não foram encontrados jogadores para selecionar.",
"skill_not_found_setskill": "Nenhuma habilidade CHATCOLORS.RED encontrada",
"player_not_found_setskill": "Nenhum jogador CHATCOLORS.RED encontrado",
"correct_form_setskill": "Uso correto: CHATCOLORS.RED!setskill <apelido> <habilidade>",
@ -486,10 +486,10 @@
"done_setskill": "Habilidade definida",
"error_setskill": "Falha ao definir a habilidade CHATCOLORS.RED",
"for_setskill": "para",
"invalid_map": "Nome do mapa inválido!",
"loading_map": "Carregando um novo mapa",
"pause": "Partida pausada.",
"unpause": "Partida retomada.",
"healed": "Você foi curado.",
@ -497,7 +497,7 @@
"reload": "Os idiomas e as configurações foram recarregados.",
"hud_on": "O HUD foi ativado.",
"hud_off": "O HUD foi desativado.",
"vote_started": "Votação iniciada: '{0}'",
"vote_timeout": "Votação '{0}' expirou!",
"vote_wait": "Você precisa esperar antes de iniciar outra votação!",
@ -505,14 +505,14 @@
"vote_not_enough_players": "Não há jogadores suficientes para iniciar uma votação!",
"vote_alredy_voted": "Você já votou!",
"vote_vote": "Votar",
"bombsite_a": "Bombsite A",
"bombsite_b": "Bombsite B",
"bombplanted": "A bomba foi plantada\n{0} segundos até a detonação",
"teammate_skills": "Habilidades dos seus companheiros de equipe",
"summary": "Resumo da última rodada",
"menu_controlls_scroll": "W/S - Rolar",
"menu_controlls_padding": " | ",
"menu_controlls_select": "E - Selecionar"

View file

@ -0,0 +1,519 @@
{
"none": "Нет навыка",
"none_desc": "У вас нет навыка",
"aimbot": "Аимбот",
"aimbot_desc": "Каждое ваше попадание считается хедшотом",
"aimlock": "Захват прицела",
"aimlock_desc": "Нажмите [css_useSkill], чтобы зафиксировать прицел на ближайшем враге",
"anomaly": "Аномалия",
"anomaly_desc": "Вы отматываете время на несколько секунд назад",
"antyflash": "Антифлеш",
"antyflash_desc": "Вы невосприимчивы к флешкам, а ваши флешки действуют 7 секунд",
"antyhead": "Железная голова",
"antyhead_desc": "Вы не получаете урон от выстрелов в голову",
"areareaper": "Жнец зоны",
"areareaper_desc": "Вы можете выбрать бомб-сайт для деактивации",
"areareaper_incorrect_site": "Такой бомб-сайт не найден.",
"areareaper_no_site": "Бомб-сайты не найдены.",
"areareaper_select_info": "Выберите сайт для деактивации:",
"areareaper_site_disabled": "Бомб-сайт {0} деактивирован — бомбу нельзя установить там!",
"areareaper_used_info": "Ваш навык уже был использован.",
"areareaper_bombsite_disabled": "Этот бомб-сайт отключён!",
"armored": "Бронированный",
"armored_desc": "У вас случайный множитель получаемого урона",
"armored_desc2": "Ваш множитель получаемого урона: {0}x",
"assassin": "Ассасин",
"assassin_desc": "Вы наносите увеличенный урон врагам со спины",
"astronaut": "Астронавт",
"astronaut_desc": "В начале раунда вам выдаётся случайное значение гравитации",
"astronaut_desc2": "Ваша случайная гравитация: {0}x",
"moneyswap": "Налоговик",
"moneyswap_desc": "Выберите игрока для обмена деньгами",
"moneyswap_enemy_info": "Налоговая служба добралась до вас.",
"moneyswap_player_info": "Вы обменялись деньгами с игроком '{0}'.",
"moneyswap_select_info": "Обменять деньги с игроком:",
"baseball": "Бейсболист",
"baseball_desc": "Ваша ложная граната отскакивает от стен и мгновенно убивает врага при попадании",
"behind": "Разворот врага",
"behind_desc": "Есть шанс развернуть врага на 180° при попадании",
"behind_desc2": "Ваш шанс развернуть врага при попадании: {0}%",
"blademaster": "Мастер клинка",
"blademaster_desc": "С ножом в руках у вас высокий шанс отразить выстрел",
"bunnyhop": "Заяц",
"bunnyhop_desc": "Вы получаете автоматический «БанниХоп»",
"c4camouflage": "Маскировка бомбы",
"c4camouflage_desc": "Вы невидимы, пока несёте бомбу",
"carefulbullets": "Осторожные пули",
"carefulbullets_desc": "Выберите игрока, который будет получать урон за каждое ваше промахивание",
"carefulbullets_enemy_info": "Точность теперь буквально имеет значение.",
"carefulbullets_player_info": "'{0}' теперь должен быть осторожнее.",
"carefulbullets_select_info": "Промахи ранят игрока:",
"catapult": "Катапульта",
"catapult_desc": "Есть шанс подбросить врага вверх при попадании",
"catapult_desc2": "Ваш шанс подбросить врага при попадании: {0}%",
"chicken": "Курица",
"chicken_desc": "Вы получаете модель курицы + 10% к скорости передвижения - 50 HP",
"chillout": "Чилл",
"chillout_desc": "Установка бомбы занимает значительно больше времени",
"cutter": "Резак",
"cutter_desc": "Мгновенное убийство ножом",
"cypher": "Шифровальщик",
"cypher_desc": "Нажмите [css_useSkill], чтобы создать/переключиться на камеру",
"cypher_nospace": "Камера должна быть расположена под прямым углом к стене",
"darkness": "Тьма",
"darkness_desc": "Накладывает эффекть тьмы на выбранного врага",
"darkness_enemy_info": "Пусть свет погаснет.",
"darkness_player_info": "Тьма охватила игрока '{0}'.",
"darkness_select_info": "Выберите игрока для тьмы:",
"deactivator": "Деактиватор",
"deactivator_desc": "Выберите игрока, чей навык вы хотите отключить",
"deactivator_enemy_info": "Ваш навык был отключён.",
"deactivator_player_info": "Навык игрока '{0}' был отключён.",
"deactivator_select_info": "Отключить навык игрока:",
"deaf": "Глухой",
"deaf_desc": "Выберите игрока, у которого будет отключён весь звук",
"deaf_enemy_info": "Ваши наушники покинули игру.",
"deaf_player_info": "Звук отключён для игрока '{0}'.",
"deaf_select_info": "Отключить звук для игрока:",
"disarmament": "Разоружение",
"disarmament_desc": "Есть шанс заставить врага выронить оружие при попадании",
"disarmament_desc2": "Ваш шанс разоружить врага: {0}%",
"distancer": "Дальномер",
"distancer_desc": "Вы можете видеть расстояние до ближайшего врага",
"dash": "Рывок",
"dash_desc": "Выполните второй прыжок для рывка",
"dracula": "Дракула",
"dracula_desc": "Попадание по врагу восстанавливает здоровье в размере процента от нанесённого урона",
"duplicator": "Дупликатор",
"duplicator_desc": "Выберите игрока, чтобы скопировать его навык",
"duplicator_player_info": "Навык игрока '{0}' был скопирован.",
"duplicator_select_info": "Скопировать навык игрока:",
"dwarf": "Гном",
"dwarf_desc": "Случайный размер персонажа в начале раунда",
"dwarf_desc2": "Ваш множитель размера: {0}x",
"enemyspawn": "Спавн врагов",
"enemyspawn_desc": "Нажмите [css_useSkill], чтобы телепортироваться на спавн врагов",
"explosiveshot": "Взрывной выстрел",
"explosiveshot_desc": "Случайный шанс выстрелить взрывной пулей при стрельбе",
"explosiveshot_desc2": "Ваш шанс выстрелить взрывной пулей: {0}%",
"falconeye": "Глаз сокола",
"falconeye_desc": "Нажмите [css_useSkill], чтобы активировать камеру с высоты птичьего полёта",
"fastreload": "Быстрая перезарядка",
"fastreload_desc": "Нажмите [css_useSkill], чтобы перезарядить текущее оружие",
"flash": "Флеш",
"flash_desc": "Случайная скорость игрока в начале раунда",
"flash_desc2": "Ваш множитель скорости: {0}x",
"fortnite": "Фортнайт",
"fortnite_desc": "Нажмите [css_useSkill], чтобы создать разрушаемую баррикаду",
"fragilebomb": "Хрупкая бомба",
"fragilebomb_desc": "Стрельба по бомбе повреждает её",
"fragilebomb_bomb_health": "Здоровье бомбы",
"friendlyfire": "Дружественный огонь",
"friendlyfire_desc": "Стрельба по союзникам лечит их",
"frozendecoy": "Замораживающая ловушка",
"frozendecoy_desc": "Ваша ложная граната замораживает всех ближайших игроков",
"gambler": "Азартный игрок",
"gambler_desc": "Выберите навык из предложенного списка.",
"gambler_select_info": "Выберите ваш навык:",
"gambler_more": "#00FF00|Обновить за ${0}",
"gambler_no_money": "Недостаточно денег.",
"ghost": "Призрак",
"ghost_desc": "Вы полностью невидимы",
"glaz": "Глаз",
"glaz_desc": "Вы видите сквозь дымовые гранаты",
"glitch": "Глитч",
"glitch_desc": "Отключает радар выбранному врагу",
"glitch_enemy_info": "Ваш радар был отключён.",
"glitch_player_info": "Радар игрока '{0}' был отключён.",
"glitch_select_info": "Отключить радар игроку:",
"glue": "Клей",
"glue_desc": "Ваши гранаты прилипают к стенам",
"godmode": "Режим бога",
"godmode_desc": "Нажмите [css_useSkill], чтобы стать неуязвимым на короткое время",
"godmode_off": "Неуязвимость отключена",
"godmode_on": "Неуязвимость включена",
"grenadier": "Гренадёр",
"grenadier_desc": "У вас бесконечные осколочные гранаты",
"healingsmoke": "Лечащий дым",
"healingsmoke_desc": "Ваши дымовые гранаты лечат",
"hermit": "Отшельник",
"hermit_desc": "Убийства восстанавливают боеприпасы и часть здоровья",
"holyhandgrenade": "Святая граната",
"holyhandgrenade_desc": "Ваши осколочные гранаты наносят двойной урон и имеют двойную дальность",
"homingnades": "Самонаводящиеся гранаты",
"homingnades_desc": "Ваши гранаты (кроме дымовых) притягиваются к врагам",
"hotbomb": "Горячая бомба",
"hotbomb_desc": "Пока вы живы, бомба наносит урон её носителю",
"hotbomb_hint": "Осторожно, бомба горячая!",
"iana": "Голограмма",
"iana_desc": "Нажмите [css_useSkill], чтобы управлять своей голограммой несколько секунд",
"illiterate": "Неграмотный",
"illiterate_desc": "Пока вы живы, ваши враги не могут читать (чат)",
"illusionist": "Иллюзионист",
"illusionist_desc": "Нажмите [css_useSkill], чтобы создать копию, идущую вперёд",
"impostor": "Импостер",
"impostor_desc": "Вы начинаете раунд с моделью игрока вражеской команды",
"infiniteammo": "Бесконечные патроны",
"infiniteammo_desc": "Вы получаете бесконечные патроны для всего оружия",
"jackal": "Трекер",
"jackal_desc": "Каждый противник оставляет за собой след",
"jammer": "Глушилка",
"jammer_desc": "Выберите игрока, чтобы отключить его прицел",
"jammer_enemy_info": "Ваш прицел был отключён.",
"jammer_player_info": "Прицел игрока '{0}' был отключён.",
"jammer_select_info": "Отключить прицел игроку:",
"jester": "Шут",
"jester_desc": "В режиме шута вы не можете получать или наносить урон. Режим переключается каждые несколько секунд.",
"jester_mode": "Режим шута",
"jester_on": "ВКЛ",
"jester_off": "ВЫКЛ",
"jumpban": "Безногий",
"jumpban_desc": "Выберите игрока, который не сможет прыгать",
"jumpban_enemy_info": "Кто-то отрезал вам ноги.",
"jumpban_player_info": "Игрок '{0}' больше не может прыгать.",
"jumpban_select_info": "Запретить прыжки игроку:",
"jumpingjack": "Прыгающий Джек",
"jumpingjack_desc": "Прыжки восстанавливают здоровье",
"killerflash": "Смертельная флешка",
"killerflash_desc": "Любой, полностью ослеплённый вашей флешкой, погибает (включая вас)",
"lifeswap": "Обмен жизнями",
"lifeswap_desc": "Выберите игрока для обмена здоровьем",
"lifeswap_enemy_info": "Кто-то занял ваше здоровье.",
"lifeswap_player_info": "Вы обменялись здоровьем с игроком '{0}'.",
"lifeswap_select_info": "Обменять здоровье с игроком:",
"longknife": "Длинный нож",
"longknife_desc": "Удар ножом наносит урон независимо от расстояния",
"longzeus": "Длинный Зевс",
"longzeus_desc": "Зевс наносит урон независимо от расстояния",
"magneticdecoy": "Магнитная ловушка",
"magneticdecoy_desc": "Ваша ложная граната притягивает ближайших игроков к себе",
"magneto": "Магнето",
"magneto_desc": "Все вражеские гранаты отталкиваются от вас",
"magnifier": "Лупа",
"magnifier_desc": "Приближает экран врага, уменьшая его поле зрения",
"magnifier_enemy_info": "Ваше поле зрения было искажено!",
"magnifier_player_info": "Игрок '{0}' принудительно переведён в режим увеличения.",
"magnifier_select_info": "Увеличить экран игрока:",
"medic": "Медик",
"medic_desc": "Нажмите [css_useSkill], чтобы использовать заряд лечения, восстанавливающий 50 HP",
"miner": "Минёр",
"miner_desc": "Ваша осколочная граната взрывается только когда рядом есть враг",
"bankrupt": "Банкрот",
"bankrupt_desc": "Выберите игрока, который потеряет все свои деньги",
"bankrupt_enemy_info": "Вы обанкротились.",
"bankrupt_player_info": "Игрок '{0}' обанкротился.",
"bankrupt_select_info": "Выберите игрока для банкротства:",
"deathbomb": "Смертельная бомба",
"deathbomb_desc": "Вы взрываетесь при смерти, убивая ближайших игроков",
"deathbomb_explosion": "АЛЛАХУ АКБАР!!!",
"ninja": "Ниндзя",
"ninja_desc": "Стоя на месте, ваша невидимость увеличивается на 33%, в приседе на 33%, с ножом на 33%",
"nonades": "Антигранаты",
"nonades_desc": "Гранаты не наносят вам урон",
"norecoil": "Фокус",
"norecoil_desc": "Нет отдачи при стрельбе",
"noclip": "Ноклип",
"noclip_desc": "Нажмите [css_useSkill], чтобы включить ноклип на короткое время",
"oneshot": "Один выстрел",
"oneshot_desc": "Попадание по врагу мгновенно убивает его",
"onlyhead": "Только голова",
"onlyhead_desc": "Вы получаете урон только в голову",
"paweljumper": "Павел-прыгун",
"paweljumper_desc": "Вы получаете случайное количество дополнительных прыжков",
"paweljumper_desc2": "Вы получаете {0} дополнительных прыжков",
"phoenix": "Феникс",
"phoenix_desc": "Есть шанс возродиться после смерти",
"phoenix_desc2": "Ваш шанс возродиться после смерти: {0}%",
"phoenix_respawn": "Вы были воскрешены из пепла благодаря силе CHATCOLORS.REDФеникса",
"psychicdefusing": "Психическое разминирование",
"psychicdefusing_desc": "Когда вы рядом с бомбой, вы начинаете её разминировать",
"psychicdefusing_hud_info": "{0} секунд осталось до разминирования",
"pilot": "Пилот",
"pilot_desc": "Летайте ограниченное время. Двойной прыжок для полёта",
"pilot_hud_info": "Топливо",
"planter": "Свободная установка",
"planter_desc": "Вы можете установить бомбу где угодно, с таймером взрыва 60 секунд.",
"planter_planting": "Установка ({0})...",
"poison": "Яд",
"poison_desc": "Выберите игрока, который будет получать урон каждые несколько секунд",
"poison_enemy_info": "Вы были отравлены.",
"poison_player_info": "Игрок '{0}' был отравлен.",
"poison_select_info": "Отравить игрока:",
"primaryban": "Без винтовок",
"primaryban_desc": "Выберите игрока, который не сможет использовать винтовки",
"primaryban_enemy_info": "Вы больше не можете использовать винтовки.",
"primaryban_player_info": "Игрок '{0}' больше не может использовать винтовки.",
"primaryban_select_info": "Запретить винтовки игроку:",
"prosthesis": "Протез",
"prosthesis_desc": "Руки и ноги защищены от пуль",
"push": "Толкач",
"push_desc": "Есть шанс оттолкнуть врага назад при попадании",
"push_desc2": "Ваш шанс оттолкнуть врага: {0}%",
"pyro": "Пироман",
"pyro_desc": "Молотов восстанавливает здоровье",
"quickshot": "Скорострельность",
"quickshot_desc": "Все пули выпускаются очень быстро",
"radarhack": "Взлом радара",
"radarhack_desc": "Враги видны на радаре",
"rambo": "Рэмбо",
"rambo_desc": "Вы получаете случайное количество здоровья в начале раунда",
"randomweapon": "Случайное оружие",
"randomweapon_desc": "Нажмите [css_useSkill], чтобы получить случайное оружие",
"rezombie": "Ре-зомби",
"rezombie_desc": "После смерти вы возрождаетесь как зомби с увеличенным здоровьем и без оружия",
"reactivearmor": "Реактивная броня",
"reactivearmor_desc": "Броня поглощает первый полученный урон",
"regeneration": "Регенерация",
"regeneration_desc": "Вы восстанавливаете здоровье каждые несколько секунд",
"replicator": "Репликатор",
"replicator_desc": "Нажмите [css_useSkill], чтобы создать копию, наносящую урон при попадании",
"retreat": "Отступление",
"retreat_desc": "Нажмите [css_useSkill], чтобы вернуться на спавн",
"returntosender": "Вернуть отправителю",
"returntosender_desc": "Первое попадание по врагу отправляет его обратно на спавн",
"richboy": "Богач",
"richboy_desc": "Вы получаете случайную сумму денег в начале раунда",
"robinhood": "Робин Гуд",
"robinhood_desc": "Нанесение урона врагу крадёт его деньги",
"rubber": "Резиновые пули",
"rubber_desc": "Ваши пули значительно замедляют игроков",
"saper": "Сапёр",
"saper_desc": "Вы можете устанавливать и обезвреживать бомбы быстрее",
"secondlife": "Второй шанс",
"secondlife_desc": "После смерти вы возрождаетесь с тем же количеством здоровья",
"shade": "Тень",
"shade_desc": "Есть шанс телепортироваться за спину врагу при попадании",
"shade_desc2": "Ваш шанс телепортироваться за спину врагу: {0}%",
"shade_nospace": "Нет места",
"shortbomb": "Короткий фитиль",
"shortbomb_desc": "Бомба взрывается гораздо быстрее",
"silent": "Тишина",
"silent_desc": "Ваши шаги и прыжки не слышны ДРУГИМ игрокам",
"smoker": "Курильщик",
"smoker_desc": "Ваши дымовые гранаты никогда не заканчиваются",
"sniperelite": "Снайпер-элита",
"sniperelite_customname": "Навык снайпера-элиты",
"sniperelite_desc": "Нажмите [css_useSkill], чтобы заменить текущее оружие на AWP",
"soldier": "Солдат",
"soldier_desc": "У вас случайный множитель урона",
"soldier_desc2": "Ваш множитель урона: {0}x",
"soundmaker": "Звуковик",
"soundmaker_desc": "Время от времени вы слышите крики игроков",
"spectator": "Наблюдатель",
"spectator_desc": "Нажмите [css_useSkill], чтобы наблюдать за случайным врагом",
"swapposition": "Обмен позициями",
"swapposition_desc": "Нажмите [css_useSkill], чтобы поменяться местами со случайным врагом",
"teleporter": "Телепортер",
"teleporter_desc": "Есть шанс поменяться местами с врагом при попадании",
"teleporter_desc2": "Ваш шанс обмена местами после попадания: {0}%",
"thief": "Вор",
"thief_desc": "Вы можете украсть навык у выбранного игрока",
"thief_enemy_info": "Ваш навык был украден.",
"thief_player_info": "Навык игрока '{0}' был украден.",
"thief_select_info": "Украсть навык у игрока:",
"thief_incorrect_skill": "Этот навык нельзя выбрать!",
"thirdeye": "Третий глаз",
"thirdeye_desc": "Нажмите [css_useSkill], чтобы активировать вид от третьего лица",
"thorns": "Шипы",
"thorns_desc": "Противник получает часть урона, который нанёс вам",
"throwingknife": "Метательный нож",
"throwingknife_desc": "Нажмите [css_useSkill], чтобы метнуть нож. Но остерегайтесь других",
"toxicsmoke": "Токсичный дым",
"toxicsmoke_desc": "Ваши дымовые гранаты наносят урон",
"wallhack": "Воллхак",
"wallhack_desc": "Вы видите врагов сквозь стены",
"watchmaker": "Часовщик",
"watchmaker_desc": "Каждый бросок гранаты изменяет время раунда",
"watchmaker_ct": "Время раунда сокращено на {0} секунд.",
"watchmaker_tt": "Время раунда увеличено на {0} секунд.",
"weaponsswap": "Обмен оружием",
"weaponsswap_desc": "Нажмите [css_useSkill], чтобы обменяться оружием со случайным врагом",
"weaponsswap_hud_info2": "У вас нет оружия для обмена",
"weightless": "Невесомость",
"weightless_desc": "Ваши гранаты не подвержены гравитации и летают быстрее",
"wildthrow": "Дикие броски",
"wildthrow_desc": "Выберите игрока, у которого будут проблемы с бросанием гранат",
"wildthrow_player_info": "Игрок '{0}' забыл все свои гранатлайны",
"wildthrow_select_info": "Выберите игрока:",
"zeus": "Зевс",
"zeus_desc": "Зевс x27 мгновенно перезаряжается",
"your_skill": "Ваш текущий навык",
"enemy_skill": "Навык врага",
"observer_skill": "Навык игрока",
"welcome_message": "Добро пожаловать {PLAYER} на {SERVER_NAME}!\nТекущая версия jRandomSkills: {VERSION} ({SKILLS_COUNT} навыков).\n\nОригинал создан:\n{AUTHOR1}\nМодифицирован и улучшен:\n{AUTHOR2}\nОфициальный Discord: https://discord.gg/9H8EZYBpPF",
"drawing_skill": "Получение навыка",
"disabled_weapon": "Вы не можете использовать это оружие",
"hud_info": "Подождите ещё {0} секунд",
"hud_info_no_enemy": "Враг не найден",
"active_hud_info": "Активно ещё {0} миллисекунд",
"skills_menu": "Список навыков",
"no_player": "Подходящий игрок не найден.",
"duplicate_player": "Найдено несколько игроков с таким именем.",
"selectplayerskill_command": "Введите /t",
"selectplayerskill_incorrect_enemy_index": "Игроки для выбора не найдены.",
"skill_not_found_setskill": "Навык не найден",
"player_not_found_setskill": "Игрок не найден",
"correct_form_setskill": "Правильное использование: CHATCOLORS.RED!setskill <ник> <навык>",
"correct_form_setscore": "Правильное использование: CHATCOLORS.RED!setscore <CT> <TT>",
"done_setskill": "Навык установлен",
"error_setskill": "Не удалось установить CHATCOLORS.REDнавык",
"for_setskill": "для",
"invalid_map": "Название карты введено неверно!",
"loading_map": "Загрузка новой карты",
"pause": "Матч приостановлен.",
"unpause": "Матч возобновлён.",
"healed": "Вы были вылечены.",
"game_start": "Игра началась!",
"reload": "Языки и конфигурации перезагружены.",
"hud_on": "HUD включён.",
"hud_off": "HUD выключен.",
"vote_started": "Голосование начато: '{0}'",
"vote_timeout": "Голосование '{0}' истекло!",
"vote_wait": "Нужно подождать перед началом нового голосования!",
"vote_same_wait": "Нужно подождать перед повторным голосованием по той же теме!",
"vote_not_enough_players": "Недостаточно игроков для начала голосования!",
"vote_alredy_voted": "Вы уже проголосовали!",
"vote_vote": "Голосование",
"bombsite_a": "Бомб-сайт A",
"bombsite_b": "Бомб-сайт B",
"bombplanted": "Бомба установлена\n{0} секунд до взрыва",
"teammate_skills": "Навыки ваших тиммейтов",
"summary": "Итоги прошедшего раунда",
"menu_controlls_scroll": "W/S — Прокрутка",
"menu_controlls_padding": " | ",
"menu_controlls_select": "E — Выбрать"
}

View file

@ -3,52 +3,52 @@
"none_desc": "Hiçbir yeteneğin yok",
"aimbot": "Aimbot",
"aimbot_desc": "Vurduğun her mermi kafadan vuruş (headshot) sayılır",
"aimbot_desc": "Vurduğunda kafadan (HS) sayılır",
"aimlock": "Nişan Kilidi",
"aimlock": "Kitlenme",
"aimlock_desc": "En yakın düşmana nişan almak için [css_useSkill] tuşuna basın",
"anomaly": "Anomali",
"anomaly": "Zaman Büken",
"anomaly_desc": "Zamanı birkaç saniye geriye alırsın",
"antyflash": "Anti-Flash",
"antyflash_desc": "Flaş bombalarından etkilenmezsin ve senin flaşların 7 saniye sürer",
"antyflash_desc": "Flaşa kör olmazsın ve flaşların 7 saniye sürer",
"antyhead": "Demir Kafa",
"antyhead_desc": "Kafadan vuruşlardan hasar almazsın",
"antyhead": "Beton Kafa",
"antyhead_desc": "Kafadan hasar almazsın",
"areareaper": "Bölge Azraili",
"areareaper_desc": "Devre dışı bırakmak için bir bomba alanı seçebilirsin",
"areareaper_incorrect_site": "Böyle bir bomba alanı bulunamadı.",
"areareaper_no_site": "Hiçbir bomba alanı bulunamadı.",
"areareaper_select_info": "Devre dışı bırakılacak alanı seçin:",
"areareaper_site_disabled": "Bomba alanı {0} devre dışı bırakıldı - buraya bomba kurulamaz!",
"areareaper_used_info": "Yeteneğin zaten kullanıldı.",
"areareaper_bombsite_disabled": "Bu bomba alanı devre dışı bırakıldı!",
"areareaper": "Mekan Kapatan",
"areareaper_desc": "Haritadaki bir bomba alanını tamamen devre dışı bırakabilirsin",
"areareaper_incorrect_site": "Böyle bir bomba alanı yok uydurma",
"areareaper_no_site": "Haritada bomba alanı bulunamadı",
"areareaper_select_info": "Kapatılacak bomba alanını seç:",
"areareaper_site_disabled": "{0} alanı mühürlendi - artık buraya bomba kurulamaz!",
"areareaper_used_info": "Yeteneğini zaten kullandın, açgözlülük yapma",
"areareaper_bombsite_disabled": "Bu bomba alanı kullanıma kapatıldı!",
"armored": "Zırhlı",
"armored_desc": "Rastgele bir hasar alma çarpanına sahip olursun",
"armored_desc2": "Hasar alma çarpanın: {0}x",
"armored_desc": "Rastgele hasar alma çarpanına sahip olursun",
"armored_desc2": "Hasar alma: {0}x",
"assassin": "Suikastçı",
"assassin_desc": "Düşmanlara arkadan vurduğunda daha fazla hasar verirsin",
"assassin_desc": "Düşmanlara arkadan daha fazla hasar verirsin",
"astronaut": "Astronot",
"astronaut_desc": "Raund başında rastgele bir yerçekimi değeri alırsın",
"astronaut_desc2": "Rastgele yerçekimin: {0}x",
"astronaut_desc": "Rastgele bir yerçekimi değerine sahip olursun",
"astronaut_desc2": "Yerçekimin: {0}x",
"moneyswap": "Vergi Memuru",
"moneyswap_desc": "Para takas etmek için bir oyuncu seç",
"moneyswap_enemy_info": "Vergi dairesi seni yakaladı.",
"moneyswap_player_info": "'{0}' isimli oyuncuyla paraları takas ettin.",
"moneyswap_select_info": "Para takası yapılacak oyuncu:",
"moneyswap_desc": "Bir düşmanla paranı takasla",
"moneyswap_enemy_info": "Maliye kapına dayandı",
"moneyswap_player_info": "'{0}' isimli oyuncuyla paraları takas ettin",
"moneyswap_select_info": "Para takasla biriyle:",
"baseball": "Beyzbolcu",
"baseball_desc": "Yanıltıcı bomban (decoy) duvarlardan seker ve çarptığı düşmanı anında öldürür",
"baseball_desc": "Yanıltıcı bomban (decoy) duvarlardan seker ve çarptığı düşmanı öldürür",
"behind": "Düşman Döndürücü",
"behind_desc": "Düşmana vurduğunda onu 180 derece döndürme şansın olur",
"behind_desc2": "Vuruşta düşmanı döndürme şansın: %{0}",
"behind": "Baş Döndüren",
"behind_desc": "Vurduğunda düşmanı 180 derece döndürme şansın olur",
"behind_desc2": "Baş döndürme şansın: %{0}",
"blademaster": "Kılıç Ustası",
"blademaster_desc": "Bıçak tutarken mermileri sektirme şansın artar",
@ -57,105 +57,105 @@
"bunnyhop_desc": "Otomatik \"BunnyHop\" yaparsın",
"c4camouflage": "C4 Kamuflajı",
"c4camouflage_desc": "Bombayı taşırken görünmez olursun",
"c4camouflage_desc": "Elinde C4 varken tamamen görünmez olursun",
"carefulbullets": "Dikkatli Mermiler",
"carefulbullets_desc": "Iskaladığın her mermi için hasar alacak bir oyuncu seç",
"carefulbullets_enemy_info": "Artık isabetsiz atışlar canını yakacak.",
"carefulbullets_player_info": "'{0}' artık daha dikkatli olmalı.",
"carefulbullets_desc": "Düşman mermi kaçırırsa hasar alır",
"carefulbullets_enemy_info": "Mermi kaçırmak canını yakacak",
"carefulbullets_player_info": "'{0}' artık mermi sıkarken iki kere düşünecek",
"carefulbullets_select_info": "İsabetsiz atışların hasar vereceği oyuncu:",
"catapult": "Mancınık",
"catapult_desc": "Düşmanı havaya fırlatma şansın olur",
"catapult_desc2": "Vuruşta düşmanı fırlatma şansın: %{0}",
"catapult_desc": "Vurduğun rakibi uzaya (yukarı doğru) fırlatma şansın var",
"catapult_desc2": "Fırlatma şansın: %{0}",
"chicken": "Tavuk",
"chicken_desc": "Tavuk modeli + %10 daha hızlı hareket - 50 HP alırsın",
"chicken_desc": "Tavuk modeli ve %10 daha hızlısın fakat 50 HP",
"chillout": "Sakin Ol",
"chillout": "Ağırdan Al",
"chillout_desc": "Bombayı kurmak çok daha uzun sürer",
"cutter": "Kesici",
"cutter_desc": "Bıçakla tek atışta öldürme",
"cutter": "Kasap",
"cutter_desc": "Bıçakla tek atarsın",
"cypher": "Cypher",
"cypher_desc": "Kamera oluşturmak/kameraya geçmek için E tuşuna bas",
"cypher_nospace": "Kamera duvara dik açıyla yerleştirilmelidir",
"cypher": "Gözcü",
"cypher_desc": "Kamera oluşturmak/geçmek için [css_useSkill] tuşuna bas",
"cypher_nospace": "Kamerayı duvara dik yerleştir",
"darkness": "Karanlık",
"darkness_desc": "Seçilen bir düşmana karanlık efekti uygular",
"darkness_enemy_info": "Işıklar sönsün.",
"darkness_player_info": "Karanlık, '{0}' isimli oyuncuyu ele geçirdi.",
"darkness_select_info": "Karanlık uygulanacak oyuncuyu seç:",
"darkness_desc": "Bir düşmanın ekranını karart",
"darkness_enemy_info": "Işıklar sönsün",
"darkness_player_info": "'{0}' isimli oyuncunun dünyasını kararttın",
"darkness_select_info": "Karanlık bir oyuncuyu seç:",
"deactivator": "Devre Dışı Bırakıcı",
"deactivator_desc": "Yeteneğini kapatmak istediğin bir oyuncu seç",
"deactivator_enemy_info": "Yeteneğin devre dışı bırakıldı.",
"deactivator_player_info": "'{0}' isimli oyuncunun yeteneği devre dışı bırakıldı.",
"deactivator_select_info": "Bir oyuncunun yeteneğini devre dışı bırak:",
"deactivator": "Silgi",
"deactivator_desc": "Bir düşmanın yeteneğini sil",
"deactivator_enemy_info": "Yeteneğin silindi",
"deactivator_player_info": "'{0}' isimli oyuncunun yeteneği silindi",
"deactivator_select_info": "Yetenek silmek için oyuncu seç:",
"deaf": "Sağır",
"deaf_desc": "Tüm seslerini kapatmak için bir oyuncu seç",
"deaf_enemy_info": "Kulaklıkların oyundan ayrıldı.",
"deaf_desc": "Bir düşmanın kulağını kapat ve sesleri duymaz hale getir",
"deaf_enemy_info": "Kulaklıkların tıkandı",
"deaf_player_info": "'{0}' isimli oyuncu için sesler kapatıldı.",
"deaf_select_info": "Sesleri kapatılacak oyuncuyu seç:",
"deaf_select_info": "Sağır bir oyuncuyu seç:",
"disarmament": "Silahsızlandırma",
"disarmament_desc": "Vurduğun düşmanın silahını düşürme şansın olur",
"disarmament_desc2": "Düşmanı silahsızlandırma şansın: %{0}",
"disarmament_desc": "Vurduğunda rakibin elindeki silahı yere düşürme şansın olur",
"disarmament_desc2": "Silahsızlandırma şansın: %{0}",
"distancer": "Mesafe Ölçer",
"distancer_desc": "En yakın düşmana olan mesafeni görebilirsin",
"distancer": "Kronometre",
"distancer_desc": "En yakın düşmanın mesafesini görürsün",
"dash": "Atılma",
"dash_desc": "Atılmak (dash) için ikinci kez zıpla",
"dash_desc": "Atılmak için ikinci kez zıpla",
"dracula": "Dracula",
"dracula_desc": "Düşmana vurmak, verdiğin hasarın bir yüzdesi kadar canını yeniler",
"dracula": "Drakula",
"dracula_desc": "Rakiplere verdiğin hasarın belirli bir yüzdesi kadar can alırsın",
"duplicator": "Kopyalayıcı",
"duplicator": "Kopyacı",
"duplicator_desc": "Yeteneğini kopyalamak için bir oyuncu seç",
"duplicator_player_info": "'{0}' isimli oyuncunun yeteneği kopyalandı.",
"duplicator_select_info": "Yeteneği kopyalanacak oyuncu:",
"dwarf": "Cüce",
"dwarf_desc": "Raund başında rastgele karakter boyutu",
"dwarf_desc2": "Boyut çarpanın: {0}x",
"dwarf_desc2": "Boyutun: {0}x",
"enemyspawn": "Düşman Başlangıcı",
"enemyspawn_desc": "Düşman başlangıç noktasına ışınlanmak için E tuşuna bas",
"enemyspawn": "Base Baskını",
"enemyspawn_desc": "[css_useSkill] tuşuna basarak düşman doğma noktasına ışınlan",
"explosiveshot": "Patlayıcı Atış",
"explosiveshot_desc": "Ateş ederken rastgele patlayıcı mermi atma şansı",
"explosiveshot_desc2": "Patlayıcı mermi atma şansın: %{0}",
"explosiveshot": "Patlayıcı Mermi",
"explosiveshot_desc": "Ateş ederken rastgele mermilerin patlayabilir",
"explosiveshot_desc2": "Patlayan mermi şansı: %{0}",
"falconeye": "Şahin Gözü",
"falconeye_desc": "Kuş bakışı kamerayı aktif etmek için E tuşuna bas",
"falconeye_desc": "[css_useSkill] tuşuna basarak kuş bakışına geç",
"fastreload": "Hızlı Şarjör",
"fastreload_desc": "Eldeki silahı anında doldurmak için E tuşuna bas",
"fastreload": "Şipşak Şarjör",
"fastreload_desc": "[css_useSkill] tuşuna basarak şarjörünü hızlıca değiştir",
"flash": "Flash",
"flash_desc": "Raund başında rastgele oyuncu hızı",
"flash_desc2": "Hız çarpanın: {0}x",
"flash_desc2": "Hızın: {0}x",
"fortnite": "Fortnite",
"fortnite_desc": "Parçalanabilir bir barikat oluşturmak için E tuşuna bas",
"fortnite_desc": "[css_useSkill] tuşuna basarak barikat kur",
"fragilebomb": "Hassas Bomba",
"fragilebomb_desc": "Bombaya ateş etmek ona hasar verir",
"fragilebomb_bomb_health": "Bomba canı",
"fragilebomb_desc": "Kurulu bombaya ateş etmek bombanın canını azaltır",
"fragilebomb_bomb_health": "Bombanın canı",
"friendlyfire": "Dost Ateşi",
"friendlyfire": "Dost Şifası",
"friendlyfire_desc": "Takım arkadaşlarına ateş etmek onları iyileştirir",
"frozendecoy": "Dondurucu Yem",
"frozendecoy_desc": "Yanıltıcı bomban (decoy) yakındaki tüm oyuncuları dondurur",
"frozendecoy": "Buz Kıran",
"frozendecoy_desc": "Yanıltıcı bomba (decoy) yakındaki tüm oyuncuları dondurur",
"gambler": "Kumarbaz",
"gambler_desc": "Sunulan listeden bir yetenek seç.",
"gambler_select_info": "Yeteneğini seç:",
"gambler_more": "#00FF00|${0} karşılığında yenile",
"gambler_more": "#00FF00|${0} karşılığında yeni yetenekler",
"gambler_no_money": "Yeterli para yok.",
"ghost": "Hayalet",
@ -165,71 +165,71 @@
"glaz_desc": "Sis bombalarının içini görebilirsin",
"glitch": "Glitç",
"glitch_desc": "Seçilen bir düşmanın radarını devre dışı bırakır",
"glitch_enemy_info": "Radarın devre dışı bırakıldı.",
"glitch_desc": "Seçilen bir düşmanın radarını kapatır",
"glitch_enemy_info": "Radarın kapandı",
"glitch_player_info": "'{0}' isimli oyuncunun radarı devre dışı bırakıldı.",
"glitch_select_info": "Radarı kapatılacak oyuncuyu seç:",
"glue": "Yapıştırıcı",
"glue_desc": "Bombaların duvarlara yapışır",
"godmode": "Ölümsüzlük",
"godmode_desc": "Kısa süreliğine ölümsüz olmak için E tuşuna bas",
"godmode_off": "Ölümsüzlük kapalı",
"godmode_on": "Ölümsüzlük açık",
"godmode": "Ölümsüz",
"godmode_desc": "[css_useSkill] tuşuna basarak kısa süreli ölümsüz ol",
"godmode_off": "Ölümsüzlük kapandı",
"godmode_on": "Ölümsüzlük açıldı",
"grenadier": "Bombacı",
"grenadier_desc": "Sınırsız el bombasına sahipsin",
"healingsmoke": "İyileştiren Sis",
"healingsmoke": "Şifalı Sis",
"healingsmoke_desc": "Sis bombaların iyileştirir",
"hermit": "Münzevi",
"hermit_desc": "Öldürmek, mermilerini ve canının bir kısmını yeniler",
"hermit_desc": "Öldüğünde mernin ve canının biraz yenilenir",
"holyhandgrenade": "Kutsal El Bombası",
"holyhandgrenade_desc": "El bombaların iki kat hasar verir ve iki kat menzile sahiptir",
"holyhandgrenade_desc": "El bomban iki kat hasara ve menzile sahip",
"homingnades": "Güdümlü El Bombaları",
"homingnades_desc": "El bombalarınız (sis hariç) düşmanlara yönelir",
"homingnades": "Güdümlü Bomba",
"homingnades_desc": "Bombalarınız (sis hariç) düşmanlara yönelir",
"hotbomb": "Sıcak Bomba",
"hotbomb_desc": "Siz hayatta olduğunuz sürece, bomba taşıyıcısına hasar verir",
"hotbomb_hint": "Dikkatli ol, bomba çok sıcak!",
"hotbomb": "Sıcak C4",
"hotbomb_desc": "Yaşadığın sürece bombacının canı azalıyor",
"hotbomb_hint": "Bomba çok sıcak!",
"iana": "Hologram",
"iana_desc": "Hologramını birkaç saniyeliğine kontrol etmek için E tuşuna bas",
"iana_desc": "[css_useSkill] tuşuna basarak bir hologram oluştur",
"illiterate": "Okuryazar Olmayan",
"illiterate_desc": "Siz hayatta olduğunuz sürece, düşmanlarınız yazıları okuyamaz",
"illiterate": "Cahiliye",
"illiterate_desc": "Yaşadığın sürece rakibin sohbeti (chat) veya oyun yazılarını okuyamaz",
"illusionist": "İllüzyonist",
"illusionist_desc": "Düz ilerleyen bir kopya oluşturmak için [css_useSkill] tuşuna basın",
"illusionist_desc": "[css_useSkill] tuşuna basarak düz ilerleyen illüzyon oluştur",
"impostor": "Sahtekar",
"impostor_desc": "Raunda düşman oyuncu modeliyle başlarsın",
"impostor_desc": "Düşman oyuncu modeline dönüşürsün",
"infiniteammo": "Sınırsız Mermi",
"infiniteammo_desc": "Tüm silahların için sınırsız mermi alırsın",
"infiniteammo_desc": "Tüm silahların sınırsız mermisi olur",
"jackal": "İzci",
"jackal_desc": "Her rakip arkasında bir iz bırakır",
"jackal_desc": "Her rakip yürüdüğünde ayak izi bırakır",
"jammer": "Sinyal Kesici",
"jammer_desc": "Bir oyuncunun nişangahını (crosshair) kapatmak için seç",
"jammer_enemy_info": "Nişangahın devre dışı bırakıldı.",
"jammer_player_info": "'{0}' isimli oyuncunun nişangahı devre dışı bırakıldı.",
"jammer_enemy_info": "Nişangahın kapatıldı.",
"jammer_player_info": "'{0}' isimli oyuncunun nişangahı kapatıldı.",
"jammer_select_info": "Nişangahı kapatılacak oyuncuyu seç:",
"jester": "Joker",
"jester_desc": "Joker modunda hasar alamazsın ve veremezsin. Bu mod birkaç saniyede bir değişir.",
"jester_mode": "Joker Modu",
"jester": "Soytarı",
"jester_desc": "Soytarı modunda hasar alamazsın ve veremezsin. Bu mod birkaç saniyede bir değişir.",
"jester_mode": "Soytarı Modu",
"jester_on": "AÇIK",
"jester_off": "KAPALI",
"jumpban": "Bacaksız",
"jumpban_desc": "Zıplayamayacak bir oyuncu seç",
"jumpban_enemy_info": "Birisi bacaklarını kesti.",
"jumpban_enemy_info": "Bacakların kesildi",
"jumpban_player_info": "'{0}' artık zıplayamaz.",
"jumpban_select_info": "Zıplaması yasaklanacak oyuncu:",
@ -237,59 +237,59 @@
"jumpingjack_desc": "Zıplamak canını yeniler",
"killerflash": "Ölümcül Flaş",
"killerflash_desc": "Flaş bombanla tamamen kör olan herkes ölür (sen dahil)",
"killerflash_desc": "Flaşına tamamen kör olan herkes ölür (sen dahil)",
"lifeswap": "Can Takası",
"lifeswap_desc": "Can değerlerini takas etmek için bir oyuncu seç",
"lifeswap_enemy_info": "Birisi canını ödünç aldı.",
"lifeswap_enemy_info": "Birisi canını çaldı",
"lifeswap_player_info": "'{0}' isimli oyuncuyla canlarını takas ettin.",
"lifeswap_select_info": "Can takası yapılacak oyuncu:",
"longknife": "Uzun Bıçak",
"longknife_desc": "Bıçak saldırısı mesafeden bağımsız olarak hasar verir",
"longknife_desc": "Bıçağın uzaktaki rakibe hasar verebilir",
"longzeus": "Uzak Zeus",
"longzeus_desc": "Zeus mesafeden bağımsız olarak hasar verir",
"longzeus_desc": "Zeus uzaktaki rakibe hasar verebilir",
"magneticdecoy": "Manyetik Yanıltıcı",
"magneticdecoy_desc": "Yanıltıcı bombanız yakındaki oyuncuları kendine çeker",
"magneto": "Magneto",
"magneto_desc": "Tüm düşman el bombaları sizden uzaklaştırılır",
"magneto_desc": "Tüm düşman bombaları sizden uzaklaştırılır",
"magnifier": "Büyüteç",
"magnifier_desc": "Düşmanın ekranını yakınlaştırarak görüş alanını daraltır",
"magnifier_enemy_info": "Görüş alanın bozuldu!",
"magnifier_enemy_info": "Görüşün bozuldu!",
"magnifier_player_info": "'{0}' isimli oyuncunun ekranı yakınlaştırıldı.",
"magnifier_select_info": "Ekranı büyütülecek oyuncuyu seç:",
"medic": "Sıhhiye",
"medic_desc": "50 can yenileyen bir iyileştirme yükü kullanmak için E tuşuna bas",
"medic_desc": "[css_useSkill] tuşuna basarak kendine anında 50 HP bas",
"miner": "Bomba Madencisi",
"miner": "Mayın",
"miner_desc": "El bombanız (HE) sadece yakında bir düşman olduğunda patlar",
"bankrupt": "İflas",
"bankrupt_desc": "Tüm parasını kaybedecek bir oyuncu seç",
"bankrupt_enemy_info": "İflas ettin.",
"bankrupt_enemy_info": "İflas ettin!",
"bankrupt_player_info": "'{0}' isimli oyuncu iflas etti.",
"bankrupt_select_info": "İflas edecek oyuncuyu seç:",
"muhammed": "Bombacı",
"muhammed_desc": "Öldüğünde patlayarak etraftaki oyuncuları öldürürsün",
"muhammed_explosion": "ALLAHU EKBER!!!",
"deathbomb": "Canlı Bomba",
"deathbomb_desc": "Öldüğünde patlayarak etraftaki oyuncuları öldürürsün",
"deathbomb_explosion": "BOOM!!!",
"ninja": "Ninja",
"ninja_desc": "Hareketsiz durmak görünmezliğini %33, çömelmek %33 ve bıçak tutmak %33 artırır",
"ninja_desc": "Görünmezliğini sabit durmak %33, eğilmek %33 ve bıçak tutmak %33 artırır",
"nonades": "Bomba Geçirmez",
"nonades_desc": "Bombalar sana hasar vermez",
"norecoil": "Odaklanma",
"norecoil_desc": "Ateş ederken geri tepme olmaz",
"norecoil_desc": "Silahın hiç sekmez",
"noclip": "Noclip",
"noclip_desc": "Kısa süreliğine noclip açmak için E tuşuna bas",
"noclip_desc": "[css_useSkill] tuşuna basarak duvarların içinden geç",
"oneshot": "Tek Atış",
"oneshot_desc": "Düşmana vurmak onu anında öldürür",
@ -297,18 +297,18 @@
"onlyhead": "Sadece Kafa",
"onlyhead_desc": "Sadece kafadan hasar alırsın",
"paweljumper": "Ekstra Zıplama",
"paweljumper_desc": "Rastgele sayıda ekstra zıplama hakkı kazanırsın",
"paweljumper_desc2": "{0} tane ekstra zıplama hakkın var",
"paweljumper": "Zıppır",
"paweljumper_desc": "Rastgele sayıda ekstra zıplaman olur",
"paweljumper_desc2": "{0} kez ekstra zıplayabilirsin",
"phoenix": "Anka Kuşu",
"phoenix_desc": "Öldükten sonra rastgele yeniden doğma şansın olur",
"phoenix_desc2": "Ölümden sonra yeniden doğma şansın: %{0}",
"phoenix_respawn": "Anka Kuşu'nun gücü sayesinde küllerinden yeniden doğdun!",
"phoenix_desc2": "Yeniden doğma şansın: %{0}",
"phoenix_respawn": "Küllerinden yeniden doğdun!",
"psychicdefusing": "Psişik İmha",
"psychicdefusing_desc": "Bombanın yanındayken onu otomatik imha etmeye başlarsın",
"psychicdefusing_hud_info": "İmha için {0} saniye kaldı",
"psychicdefusing_hud_info": "Bombanın çözülmesi için son {0} saniye",
"pilot": "Pilot",
"pilot_desc": "Sınırlı bir süre uçun. Uçmak için zıplama tuşuna iki kez basın",
@ -326,7 +326,7 @@
"primaryban": "Tüfek Yasak",
"primaryban_desc": "Tüfek kullanamayacak bir oyuncu seç",
"primaryban_enemy_info": "Artık tüfek kullanamazsın.",
"primaryban_enemy_info": "Tüfek kullanmayı unuttun",
"primaryban_player_info": "'{0}' artık tüfek kullanamaz.",
"primaryban_select_info": "Tüfek kullanımı yasaklanacak oyuncu:",
@ -335,13 +335,13 @@
"push": "İtici",
"push_desc": "Düşmana vurduğunda onu geri itme şansın olur",
"push_desc2": "Düşmanı geri itme şansın: %{0}",
"push_desc2": "Geri itme şansın: %{0}",
"pyro": "Piromani",
"pyro": "Ateşbaz",
"pyro_desc": "Molotof canını yeniler",
"quickshot": "Seri Ateş",
"quickshot_desc": "Tüm mermiler çok hızlı ateşlenir",
"quickshot": "Seri Atış",
"quickshot_desc": "Silahın daha hızlı ateş eder",
"radarhack": "Radar Hack",
"radarhack_desc": "Düşmanlar radarda görünür",
@ -349,34 +349,34 @@
"rambo": "Rambo",
"rambo_desc": "Raund başında rastgele miktarda can alırsın",
"randomweapon": "Rastgele Silah",
"randomweapon_desc": "Rastgele bir silah almak için E tuşuna bas",
"randomweapon": "Silah Kumarı",
"randomweapon_desc": "[css_useSkill] tuşuna basarak rastgele bir silah al",
"rezombie": "Zombi Dönüşümü",
"rezombie_desc": "Öldükten sonra daha fazla canla ve silahsız bir zombi olarak yeniden doğarsın",
"rezombie": "Zombi",
"rezombie_desc": "Öldükten sonra daha fazla canla ve silahsız zombi olarak doğarsın",
"reactivearmor": "Reaktif Zırh",
"reactivearmor_desc": "Zırh alınan ilk hasarı emmer",
"reactivearmor_desc": "Zırhın alınan ilk hasarı emmer",
"regeneration": "Yenilenme",
"regeneration_desc": "Birkaç saniyede bir canın yenilenir",
"replicator": "Kopyacı",
"replicator_desc": "Vurulduğunda hasar veren bir kopya oluşturmak için E tuşuna bas",
"replicator_desc": "[css_useSkill] tuşuna basarak kopya oluştur ve ölürse rakibe hasar verir",
"retreat": "Geri Çekilme",
"retreat_desc": "Başlangıç noktasına dönmek için E tuşuna bas",
"retreat": "Geri Çekil",
"retreat_desc": "[css_useSkill] tuşuna basarak başlangıç noktasına ışınlan",
"returntosender": "İade",
"returntosender_desc": "Düşmana ilk vuruşun onu kendi başlangıç noktasına geri gönderir",
"returntosender_desc": "Düşmana ilk vuruşun onu kendi başlangıç noktasına ışınlar",
"richboy": "Zengin Çocuk",
"richboy": "Zengin Bebe",
"richboy_desc": "Raund başında rastgele miktarda para alırsın",
"robinhood": "Robin Hood",
"robinhood_desc": "Düşmana hasar vermek onun parasını çalar",
"rubber": "Lastik Mermiler",
"rubber": "Lastik Mermi",
"rubber_desc": "Mermilerin oyuncuları önemli ölçüde yavaşlatır",
"saper": "İstihkamcı",
@ -387,48 +387,48 @@
"shade": "Gölge",
"shade_desc": "Vurduğun düşmanın arkasına ışınlanma şansın olur",
"shade_desc2": "Düşmanın arkasına ışınlanma şansın: %{0}",
"shade_desc2": "Arkasına ışınlanma şansın: %{0}",
"shade_nospace": "Uygun alan yok",
"shortbomb": "Kısa Fünye",
"shortbomb_desc": "Bomba çok daha hızlı patlar",
"silent": "Sessiz",
"silent_desc": "Ayak seslerin ve zıplamaların DİĞER oyunculara duyulmaz",
"silent_desc": "Ayak seslerini ve zıplamalarını DİĞER oyuncular duyamaz",
"smoker": "Tiryaki",
"smoker_desc": "Sis bombalarınız asla bitmez",
"sniperelite": "Keskin Nişancı",
"sniperelite_customname": "Keskin Nişancı Yeteneği",
"sniperelite_desc": "Mevcut silahını bir AWP ile değiştirmek için E tuşuna bas",
"sniperelite_customname": "Keskin Nişancı",
"sniperelite_desc": "[css_useSkill] tuşuna basarak silahını AWP ile değiştir",
"soldier": "Asker",
"soldier_desc": "Rastgele bir hasar çarpanına sahip olursun",
"soldier_desc2": "Hasar çarpanın: {0}x",
"soldier": "Teğmen",
"soldier_desc": "Rastgele bir oranda fazla hasar verirsin",
"soldier_desc2": "Hasarın: {0}x",
"soundmaker": "Gürültücü",
"soundmaker_desc": "Her düşman için bir ses tetiklemek için E tuşuna bas",
"soundmaker": "Halüsinasyon",
"soundmaker_desc": "[css_useSkill] tuşuna basarak rakibinin çığlık atmasını sağla",
"spectator": "İzleyici",
"spectator_desc": "Rastgele bir düşmanı izlemek için E tuşuna bas",
"spectator": "Röntgen",
"spectator_desc": "[css_useSkill] tuşuna basarak rakibinin gözünden gör",
"swapposition": "Yer Değiştirme",
"swapposition_desc": "Rastgele bir düşmanla yer değiştirmek için E tuşuna bas",
"swapposition_desc": "[css_useSkill] tuşuna basarak vurduğun düşmanla yer değiştir",
"teleporter": "Işınlayıcı",
"teleporter_desc": "Vurulan bir düşmanla yer değiştirme şansınız var",
"teleporter_desc2": "Vuruştan sonra yer değiştirme şansınız: %{0}",
"teleporter_desc2": "Yer değiştirme şansın: %{0}",
"thief": "Hırsız",
"thief_desc": "Seçilen bir oyuncudan yeteneğini çalabilirsin",
"thief_enemy_info": "Yeteneğin çalındı.",
"thief_player_info": "'{0}' isimli oyuncunun yeteneği çalındı.",
"thief_select_info": "Yetenek çalınacak oyuncu:",
"thief_incorrect_skill": "Bu yetenek seçilemez!",
"thief_incorrect_skill": "Bu yetenek çalınamaz!",
"thirdeye": "Üçüncü Göz",
"thirdeye_desc": "Üçüncü şahıs bakış açısını aktif etmek için E tuşuna bas",
"thirdeye_desc": "[css_useSkill] tuşuna basarak üçüncü göze(thirdperson) geç",
"thorns": "Dikenler",
"thorns_desc": "Rakibin, sana verdiği hasarın bir kısmını geri alır",
@ -448,13 +448,13 @@
"watchmaker_tt": "Raund süresi {0} saniye uzatıldı.",
"weaponsswap": "Silah Takası",
"weaponsswap_desc": "Rastgele bir düşmanla silahları takas etmek için E tuşuna bas",
"weaponsswap_desc": "[css_useSkill] tuşuna basarak silahını düşmanla takasla",
"weaponsswap_hud_info2": "Takas edilecek silahın yok",
"weightless": "Yerçekimsiz",
"weightless_desc": "El bombalarınız yerçekiminden etkilenmez ve daha hızlı uçar",
"weightless_desc": "El bombalarınız yerçekiminden etkilenmez ve dümdüz gider",
"wildthrow": "Vahşi Atış",
"wildthrow": "Unutkan Bombacı",
"wildthrow_desc": "El bombası atmakta zorluk çekecek bir oyuncu seçin",
"wildthrow_player_info": "'{0}' adlı oyuncu tüm taktiklerini unuttu",
"wildthrow_select_info": "Bir oyuncu seçin:",
@ -462,25 +462,25 @@
"zeus": "Zeus",
"zeus_desc": "Zeus x27 anında şarj olur",
"your_skill": "Mevcut yeteneğin",
"your_skill": "Yeteneğin",
"enemy_skill": "Düşmanın yeteneği",
"observer_skill": "Oyuncunun yeteneği",
"welcome_message": "{PLAYER}, {SERVER_NAME} sunucusuna hoş geldin!\nGüncel jRandomSkills versiyonu: {VERSION} ({SKILLS_COUNT} yetenek).\n\nOrijinal yapımcı:\n{AUTHOR1}\nGeliştiren:\n{AUTHOR2}\nResmi Discord: https://discord.gg/9H8EZYBpPF",
"drawing_skill": "Yetenek çekiliyor",
"drawing_skill": "Yetenek çarkı dönüyor...",
"disabled_weapon": "Bu silahı kullanamazsın",
"hud_info": "{0} saniye daha bekle",
"hud_info_no_enemy": "Düşman bulunamadı",
"hud_info_no_enemy": "Düşman yok",
"active_hud_info": "{0} milisaniye daha aktif",
"skills_menu": "Yetenek Listesi",
"no_player": "Eşleşen oyuncu bulunamadı.",
"no_player": "Eşleşen oyuncu yok.",
"duplicate_player": "Aynı isimde birden fazla oyuncu bulundu.",
"selectplayerskill_command": "/t yazın",
"selectplayerskill_incorrect_enemy_index": "Seçilecek oyuncu bulunamadı.",
"selectplayerskill_command": "Sohbete /t yazın",
"selectplayerskill_incorrect_enemy_index": "Seçilecek oyuncu yok.",
"skill_not_found_setskill": "Böyle bir yetenek bulunamadı",
"player_not_found_setskill": "Böyle bir oyuncu bulunamadı",
"skill_not_found_setskill": "Böyle bir yetenek yok",
"player_not_found_setskill": "Böyle bir oyuncu yok",
"correct_form_setskill": "Doğru kullanım: !setskill <isim> <yetenek>",
"correct_form_setscore": "Doğru kullanım: !setscore <CT> <TT>",
"done_setskill": "yetenek ayarlandı",
@ -506,12 +506,12 @@
"vote_alredy_voted": "Zaten oy kullandın!",
"vote_vote": "Oy ver",
"bombsite_a": "Bomba Alanı A",
"bombsite_b": "Bomba Alanı B",
"bombsite_a": "A Bölgesi",
"bombsite_b": "B Bölgesi",
"bombplanted": "Bomba kuruldu\nPatlamaya {0} saniye",
"teammate_skills": "Takım arkadaşlarının yetenekleri",
"summary": "Son raundun özeti",
"teammate_skills": "Takımının yetenekleri",
"summary": "Raundun özeti",
"menu_controlls_scroll": "W/S - Kaydır",
"menu_controlls_padding": " | ",

View file

@ -275,9 +275,9 @@
"moneyswap_player_info": "你与玩家 '{0}' 交换了金钱。",
"moneyswap_select_info": "选择你想与之交换金钱的玩家:",
"muhammed": "穆罕默德",
"muhammed_desc": "你死亡时会爆炸,杀死附近的玩家",
"muhammed_explosion": "真主至大!!!",
"deathbomb": "死亡炸弹",
"deathbomb_desc": "你死亡时会爆炸,杀死附近的玩家",
"deathbomb_explosion": "砰!",
"ninja": "忍者",
"ninja_desc": "站立不动增加33%隐形,蹲下增加33%,持刀增加33%",

View file

@ -79,6 +79,7 @@ public enum Skills
Darkness,
Deactivator,
Deaf,
DeathBomb,
Disarmament,
Distancer,
Dash,
@ -126,7 +127,6 @@ public enum Skills
Medic,
Miner,
MoneySwap,
Muhammed,
Ninja,
NoNades,
NoRecoil,

View file

@ -2,14 +2,12 @@ using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes;
using CounterStrikeSharp.API.Modules.Admin;
using CounterStrikeSharp.API.Modules.Commands.Targeting;
using CounterStrikeSharp.API.Modules.Cvars;
using CounterStrikeSharp.API.Modules.Events;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.UserMessages;
using CounterStrikeSharp.API.Modules.Utils;
using Microsoft.Extensions.Logging;
using RayTraceAPI;
using src.player.skills;
using src.utils;
@ -465,6 +463,9 @@ namespace src.player
CCSPlayerController player = pawn.Controller.Value.As<CCSPlayerController>();
if (player == null || !player.IsValid) return HookResult.Continue;
var playerInfo = PlayerManager.GetPlayerByIndex(player.Index);
if (playerInfo == null) return HookResult.Continue;
CCSWeaponBaseVData vdata = VirtualFunctions.GetCSWeaponDataFromKeyFunc.Invoke(-1, econItem.ItemDefinitionIndex.ToString());
if (vdata == null) return HookResult.Continue;
@ -483,7 +484,8 @@ namespace src.player
break;
}
}
return block ? HookResult.Stop : HookResult.Continue;
return block ? HookResult.Handled : HookResult.Continue;
}
}
@ -510,7 +512,7 @@ namespace src.player
break;
}
}
return block ? HookResult.Stop : HookResult.Continue;
return block ? HookResult.Handled : HookResult.Continue;
}
}
@ -570,7 +572,7 @@ namespace src.player
string welcomeMsg = player.GetTranslation("welcome_message", "welcome");
foreach (string line in welcomeMsg.Split("\n"))
player.PrintToChat($" {ChatColors.Green}" + line.Replace("{PLAYER}", $" {ChatColors.Red}{player.PlayerName}{ChatColors.Green}", StringComparison.OrdinalIgnoreCase)
player.PrintToChat($" {ChatColors.Green}" + line.Replace("{PLAYER}", $" {ChatColors.Red}\u202A{player.PlayerName}\u202C{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)
@ -731,16 +733,22 @@ namespace src.player
lock (setLock)
{
isTransmitRegistered = false;
Instance.AddTimer(.1f, () => {
DisableAll();
ConVar.Find("sv_legacy_jump")?.SetValue("1");
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
Instance.RemoveListener<CheckTransmit>(CheckTransmit);
playersSkills.Clear();
staticSkills.Clear();
ctSkill = noneSkill;
tSkill = noneSkill;
allSkill = noneSkill;
PlayerManager.Clear();
}
}
@ -766,7 +774,7 @@ namespace src.player
var skillInfo = SkillData.Skills.FirstOrDefault(p => p.Skill == _playerSkill.Skill);
var specialSkillInfo = SkillData.Skills.FirstOrDefault(s => s.Skill == _playerSkill.SpecialSkill);
if (skillInfo == null) continue;
skillsText += $" {ChatColors.DarkRed}{_player.PlayerName}{ChatColors.Lime}: {(_playerSkill.SpecialSkill == Skills.None || specialSkillInfo == null ? player.GetSkillName(skillInfo.Skill, _playerSkill.SkillChance) : $"{player.GetSkillName(specialSkillInfo.Skill)} -> {player.GetSkillName(skillInfo.Skill, _playerSkill.SkillChance)}")}\n";
skillsText += $" {ChatColors.DarkRed}\u202A{_player.PlayerName}\u202C{ChatColors.Lime}: {(_playerSkill.SpecialSkill == Skills.None || specialSkillInfo == null ? player.GetSkillName(skillInfo.Skill, _playerSkill.SkillChance) : $"{player.GetSkillName(specialSkillInfo.Skill)} -> {player.GetSkillName(skillInfo.Skill, _playerSkill.SkillChance)}")}\n";
}
}
@ -824,7 +832,7 @@ namespace src.player
SkillUtils.PrintToChat(victim,
$"{ChatColors.DarkRed}{(attackerInfo.SpecialSkill == Skills.None ? victim.GetSkillName(skillData.Skill) : $"{victim.GetSkillName(specialSkillData.Skill)} -> {victim.GetSkillName(skillData.Skill)}")}{ChatColors.Lime} - {skillDesc}",
title: $"{victim.GetTranslation("enemy_skill")} {ChatColors.DarkRed}{attacker.PlayerName}{ChatColors.Lime}");
title: $"{victim.GetTranslation("enemy_skill")} {ChatColors.DarkRed}\u202A{attacker.PlayerName}\u202C{ChatColors.Lime}");
}
}
return HookResult.Continue;
@ -1064,9 +1072,9 @@ namespace src.player
float hudExpired = Config.LoadedConfig.SkillHudDuration;
skillPlayer.SkillHudExpired = hudExpired == -1 ? DateTime.MaxValue : DateTime.Now.AddSeconds(hudExpired);
float descriptionHudExpired = Config.LoadedConfig.SkillHudDuration;
float descriptionHudExpired = Config.LoadedConfig.SkillDescriptionDuration;
skillPlayer.SkillDescriptionHudExpired = descriptionHudExpired == -1 ? DateTime.MaxValue : DateTime.Now.AddSeconds(descriptionHudExpired);
if (Config.LoadedConfig.TeamMateSkillChatInfo)
{
Instance?.AddTimer(.6f, () =>
@ -1079,7 +1087,7 @@ namespace src.player
if (teammateInfo != null && teammateInfo?.Skill != null)
{
var skillInfo = SkillData.Skills.FirstOrDefault(p => p.Skill == teammateInfo.Skill);
teammateSkills += $" {ChatColors.DarkRed}{teammate.PlayerName}{ChatColors.Lime}: {(skillInfo == null ? player.GetSkillName(Skills.None) : player.GetSkillName(skillInfo.Skill, teammateInfo.SkillChance))}\n";
teammateSkills += $" {ChatColors.DarkRed}\u202A{teammate.PlayerName}\u202C{ChatColors.Lime}: {(skillInfo == null ? player.GetSkillName(Skills.None) : player.GetSkillName(skillInfo.Skill, teammateInfo.SkillChance))}\n";
}
}

View file

@ -15,6 +15,7 @@ namespace src.player
Instance.RegisterListener<OnTick>(() =>
{
UpdateGameRules();
if (Server.TickCount % 2 != 0) return;
foreach (var player in Utilities.GetPlayers())
{

View file

@ -1,13 +1,16 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Cvars;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
namespace src.player.skills
{
public class AntyFlash : ISkill
{
private const Skills skillName = Skills.AntyFlash;
private readonly static ConcurrentDictionary<uint, int> playersWithSkill = [];
public static void LoadSkill()
{
@ -38,15 +41,76 @@ namespace src.player.skills
}
}
public static void GrenadeThrown(EventGrenadeThrown @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Weapon;
if (weapon != "flashbang") return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
{
playersWithSkill[player.Index] = grenadesLeft - 1;
player!.GiveNamedItem($"weapon_{weapon}");
SkillUtils.UpdateGrenadeCount(player, CsItem.FlashbangGrenade, grenadesLeft - 1);
}
}
public static void WeaponEquip(EventItemEquip @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item;
if (player == null || !player.IsValid) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.FlashbangGrenade, grenadesLeft);
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Item;
if (string.IsNullOrEmpty(weapon) || weapon != "flashbang") return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.FlashbangGrenade, grenadesLeft);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
SkillUtils.TryGiveWeapon(player, CsItem.FlashbangGrenade);
int flashbangLimit = ConVar.Find("ammo_grenade_limit_flashbang")?.GetPrimitiveValue<int>() ?? 2;
int grenadeLimit = SkillsInfo.GetValue<int>(skillName, "grenadeLimit");
if (grenadeLimit > flashbangLimit)
{
playersWithSkill.TryAdd(player.Index, grenadeLimit);
SkillUtils.TryGiveWeapon(player, CsItem.FlashbangGrenade);
SkillUtils.UpdateGrenadeCount(player, CsItem.FlashbangGrenade, grenadeLimit);
}
else
SkillUtils.TryGiveWeapon(player, CsItem.FlashbangGrenade, grenadeLimit, false);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#D6E6FF", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float flashDuration = 7f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
playersWithSkill.TryRemove(player.Index, out _);
SkillUtils.UpdateGrenadeCount(player, CsItem.FlashbangGrenade, 1);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#D6E6FF", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float flashDuration = 7f, int grenadeLimit = 2) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public float FlashDuration { get; set; } = flashDuration;
public int GrenadeLimit { get; set; } = grenadeLimit;
}
}
}

View file

@ -41,7 +41,7 @@ namespace src.player.skills
foreach (var e in enemies)
{
int money = e.InGameMoneyServices?.Account ?? 0;
menuItems.Add(($"{e.PlayerName} : {money}$", e.Index.ToString()));
menuItems.Add(($"\u202A{e.PlayerName}\u202C : {money}$", e.Index.ToString()));
}
if (!menuItems.IsEmpty)
@ -61,7 +61,7 @@ namespace src.player.skills
var enemies = Utilities.GetPlayers().Where(p => p.IsValid && p.PawnIsAlive && p.Team != player.Team && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0)
{
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices?.Account ?? 0)}$", e.Index.ToString()))];
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"\u202A{e.PlayerName}\u202C : {(e.InGameMoneyServices?.Account ?? 0)}$", e.Index.ToString()))];
SkillUtils.CreateMenu(player, menuItems);
}
else

View file

@ -4,7 +4,6 @@ using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills
{
@ -12,6 +11,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Baseball;
private static readonly ConcurrentDictionary<uint, byte> decoys = [];
private readonly static ConcurrentDictionary<uint, int> playersWithSkill = [];
public static void LoadSkill()
{
@ -24,8 +24,17 @@ namespace src.player.skills
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var weapon = @event.Weapon;
if (weapon != "decoy") return;
if (!Instance.IsPlayerValid(victim) || !Instance.IsPlayerValid(attacker)) return;
if (weapon != "decoy")
return;
if (victim == null || !victim.IsValid || victim.PlayerPawn?.Value == null || !victim.PlayerPawn.Value.IsValid || victim.PlayerPawn.Value.Health <= 0)
return;
if (attacker == null || !attacker.IsValid || attacker.PlayerPawn?.Value == null || !attacker.PlayerPawn.Value.IsValid || attacker.PlayerPawn.Value.Health <= 0)
return;
if (victim.Index == attacker.Index || victim.Team == attacker.Team)
return;
var attackerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(attacker)!.Index);
if (attackerInfo?.Skill != skillName) return;
@ -108,16 +117,72 @@ namespace src.player.skills
}
}
public static void EnableSkill(CCSPlayerController player)
public static void GrenadeThrown(EventGrenadeThrown @event)
{
SkillUtils.TryGiveWeapon(player, CsItem.DecoyGrenade);
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Weapon;
if (weapon != "decoy") return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
{
playersWithSkill[player.Index] = grenadesLeft - 1;
player!.GiveNamedItem($"weapon_{weapon}");
SkillUtils.UpdateGrenadeCount(player, CsItem.DecoyGrenade, grenadesLeft - 1);
}
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#2effc7", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float speedMultipier = 2f, float maxSpeed = 900f, int damageDeal = 9999) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
public static void WeaponEquip(EventItemEquip @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item;
if (player == null || !player.IsValid) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.DecoyGrenade, grenadesLeft);
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Item;
if (string.IsNullOrEmpty(weapon) || weapon != "decoy") return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.DecoyGrenade, grenadesLeft);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
int grenadeLimit = SkillsInfo.GetValue<int>(skillName, "grenadeLimit");
playersWithSkill.TryAdd(player.Index, grenadeLimit);
SkillUtils.TryGiveWeapon(player, CsItem.DecoyGrenade);
SkillUtils.UpdateGrenadeCount(player, CsItem.DecoyGrenade, grenadeLimit);
}
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
playersWithSkill.TryRemove(player.Index, out _);
SkillUtils.UpdateGrenadeCount(player, CsItem.DecoyGrenade, 1);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#2effc7", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float speedMultipier = 2f, float maxSpeed = 900f, int damageDeal = 9999, int grenadeLimit = 3) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public float SpeedMultipier { get; set; } = speedMultipier;
public float MaxSpeed { get; set; } = maxSpeed;
public float DamageDeal { get; set; } = damageDeal;
public int GrenadeLimit { get; set; } = grenadeLimit;
}
}
}

View file

@ -125,14 +125,18 @@ namespace src.player.skills
var entity = Utilities.GetEntityFromIndex<CBaseEntity>((int)playerPawn.Index);
if (entity == null || !entity.IsValid) continue;
info.TransmitEntities.Remove(entity.Index);
if (info.TransmitEntities.Contains(entity.Index))
info.TransmitEntities.Remove(entity.Index);
var bombIndex = GetBombIndex();
if (bombIndex == null) continue;
var bombEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)bombIndex);
if (bombEntity == null || !bombEntity.IsValid) continue;
info.TransmitEntities.Remove(bombEntity.Index);
if (info.TransmitEntities.Contains(bombEntity.Index))
info.TransmitEntities.Remove(bombEntity.Index);
}
}
}
@ -141,6 +145,7 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player)
{
Event.EnableTransmit();
if (player == null || !player.IsValid) return;
var playerPawn = player.PlayerPawn.Value;
@ -157,6 +162,8 @@ namespace src.player.skills
invisiblePlayers.TryAdd(player.Index, 0);
SkillUtils.SetPlayerInvisibility(player, .5f);
SkillUtils.ForceFullUpdateToAll();
}
public static void DisableSkill(CCSPlayerController player)
@ -164,6 +171,8 @@ namespace src.player.skills
invisiblePlayers.TryRemove(player.Index, out _);
SkillUtils.SetPlayerInvisibility(player, 0);
EntityManager.DestroyPlayerEntities(player.Index);
SkillUtils.ForceFullUpdateToAll();
}
private static void CreatePlayerPosProp(CCSPlayerController player)

View file

@ -2,7 +2,6 @@ using System.Drawing;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
@ -19,7 +18,7 @@ namespace src.player.skills
"weapon_ump45", "weapon_p90", "weapon_mp5sd", "weapon_ssg08",
"weapon_awp", "weapon_scar20", "weapon_g3sg1", "weapon_nova",
"weapon_xm1014", "weapon_mag7", "weapon_sawedoff", "weapon_m249",
"weapon_negev"
"weapon_negev", "weapon_sg556"
];
private static readonly ConcurrentDictionary<uint, uint> chickens = [];
@ -82,8 +81,11 @@ namespace src.player.skills
{
playerPawn.VelocityModifier = 1f;
playerPawn.Health = Math.Min(playerPawn.Health + 50, 100);
Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_iHealth");
if (playerPawn.Health > 0)
{
playerPawn.Health = Math.Min(playerPawn.Health + 50, 100);
Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_iHealth");
}
SkillUtils.ChangePlayerScale(player, 1);

View file

@ -58,7 +58,8 @@ namespace src.player.skills
NextCamera = 0,
NoSpace = 0,
PlayerCameraRaw = player.PlayerPawn.Value.CameraServices.ViewEntity.Raw,
LastAngle = QAngle.Zero
LastPlayerAngle = QAngle.Zero,
LastCameraAngle = QAngle.Zero
});
}
@ -160,16 +161,20 @@ namespace src.player.skills
if (playerInfo.CameraActive && playerInfo.CameraProp != null)
{
if (pawn.AbsRotation != null)
playerInfo.LastAngle = new QAngle(pawn.V_angle.X, pawn.V_angle.Y, 0);
playerInfo.LastPlayerAngle = new QAngle(pawn.V_angle.X, pawn.V_angle.Y, 0);
var cameraProp = Utilities.GetEntityFromIndex<CDynamicProp>((int)playerInfo.CameraProp);
if (cameraProp == null || !cameraProp.IsValid) return;
if (cameraProp == null || !cameraProp.IsValid || cameraProp.AbsRotation == null) return;
pawn.Teleport(null, cameraProp.AbsRotation);
if (playerInfo.LastCameraAngle == QAngle.Zero)
playerInfo.LastCameraAngle = new QAngle(cameraProp.AbsRotation.X, cameraProp.AbsRotation.Y, 0);
pawn.Look(playerInfo.LastCameraAngle);
}
else if (!forceToDefault)
{
pawn.Look(playerInfo.LastAngle);
playerInfo.LastCameraAngle = new QAngle(pawn.V_angle.X, pawn.V_angle.Y, 0);
pawn.Look(playerInfo.LastPlayerAngle);
}
}
@ -399,7 +404,8 @@ namespace src.player.skills
public bool CameraActive { get; set; }
public float NextCamera { get; set; }
public float NoSpace { get; set; }
public required QAngle LastAngle { get; set; }
public required QAngle LastPlayerAngle { get; set; }
public required QAngle LastCameraAngle { get; set; }
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#34ebd5", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float cooldown = 30) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)

View file

@ -40,7 +40,7 @@ namespace src.player.skills
if (enemyInfo == null) continue;
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill);
if (skillData == null) continue;
menuItems.Add(($"{enemy.PlayerName} : {player.GetSkillName(skillData.Skill)}", enemy.Index.ToString()));
menuItems.Add(($"\u202A{enemy.PlayerName}\u202C : {player.GetSkillName(skillData.Skill)}", enemy.Index.ToString()));
}
SkillUtils.UpdateMenu(player, menuItems);
}
@ -82,7 +82,7 @@ namespace src.player.skills
if (enemyInfo == null) continue;
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill);
if (skillData == null) continue;
menuItems.Add(($"{enemy.PlayerName} : {player.GetSkillName(skillData.Skill)}", enemy.Index.ToString()));
menuItems.Add(($"\u202A{enemy.PlayerName}\u202C : {player.GetSkillName(skillData.Skill)}", enemy.Index.ToString()));
}
SkillUtils.CreateMenu(player, menuItems);
}

View file

@ -4,14 +4,13 @@ using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
namespace src.player.skills
{
public class Muhammed : ISkill
public class DeathBomb : ISkill
{
private const Skills skillName = Skills.Muhammed;
private const Skills skillName = Skills.DeathBomb;
private static readonly QAngle angle = new(10, -5, 9);
private static readonly ConcurrentDictionary<int, byte> nades = [];
@ -57,7 +56,7 @@ namespace src.player.skills
SkillUtils.CreateHEGrenadeProjectile(pos, angle, new Vector(0, 0, -10), player.TeamNum);
foreach (var _p in Utilities.GetPlayers().Where(p => p.IsValid && p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist))
SkillUtils.PrintToChat(_p, $"{ChatColors.DarkRed}{player.PlayerName}: {ChatColors.Lime}{_p.GetTranslation("muhammed_explosion")}",
SkillUtils.PrintToChat(_p, $"{ChatColors.DarkRed}\u202A{player.PlayerName}\u202C: {ChatColors.Lime}{_p.GetTranslation("deathbomb_explosion")}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
var fileNames = new[] { "radiobotfallback01", "radiobotfallback02", "radiobotfallback04" };
@ -88,7 +87,7 @@ namespace src.player.skills
heProjectile.DetonateTime = 0;
if (nades.TryRemove(lastTick, out byte teamNum))
heProjectile.Globalname = $"muhammed_team_{teamNum}_{heProjectile.Index}";
heProjectile.Globalname = $"deathbomb_team_{teamNum}_{heProjectile.Index}";
});
}
@ -103,7 +102,7 @@ namespace src.player.skills
if (nade == null || !nade.IsValid) return;
if (nade.DesignerName != "hegrenade_projectile") return;
if (string.IsNullOrEmpty(nade.Globalname) || !nade.Globalname.StartsWith("muhammed_team_")) return;
if (string.IsNullOrEmpty(nade.Globalname) || !nade.Globalname.StartsWith("deathbomb_team_")) return;
if (!int.TryParse(nade.Globalname.Split('_')[2], out int nadeTeam)) return;

View file

@ -31,18 +31,18 @@ namespace src.player.skills
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Team != player.Team && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
var enemies = Utilities.GetPlayers().Where(p => p != null && p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p => p != null && p.IsValid && p.Index != player.Index && p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0 && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = [];
foreach (var enemy in enemies)
{
var enemyInfo = PlayerManager.GetPlayerByIndex(enemy.Index);
var enemyInfo = PlayerManager.GetPlayerByIndex(enemy?.Index);
if (enemyInfo == null) continue;
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill);
if (skillData == null) continue;
menuItems.Add(($"{enemy.PlayerName} : {player.GetSkillName(skillData.Skill)}", enemy.Index.ToString()));
menuItems.Add(($"\u202A{enemy!.PlayerName}\u202C : {player.GetSkillName(skillData.Skill)}", enemy.Index.ToString()));
}
SkillUtils.UpdateMenu(player, menuItems);
}
@ -82,10 +82,12 @@ namespace src.player.skills
{
var enemyInfo = PlayerManager.GetPlayerByIndex(enemy.Index);
if (enemyInfo == null) continue;
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill);
if (skillData == null) continue;
skills.Add(skillData.Skill.ToString());
menuItems.Add(($"{enemy.PlayerName} : {player.GetSkillName(skillData.Skill)}", enemy.Index.ToString()));
menuItems.Add(($"\u202A{enemy.PlayerName}\u202C : {player.GetSkillName(skillData.Skill)}", enemy.Index.ToString()));
}
int ctSkills = Event.counterterroristSkills.Count(s => skills.Contains(s.Name));

View file

@ -1,48 +1,73 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using static src.jRandomSkills;
namespace src.player.skills
{
public class FriendlyFire : ISkill
{
private const Skills skillName = Skills.FriendlyFire;
private static readonly string[] nades = ["inferno", "flashbang", "smokegrenade", "decoy", "hegrenade"];
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
}
public static void PlayerHurt(EventPlayerHurt @event)
public static void OnTakeDamage(DynamicHook h)
{
var damage = @event.DmgHealth;
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
var weapon = @event.Weapon;
CEntityInstance param = h.GetParam<CEntityInstance>(0);
CTakeDamageInfo param2 = h.GetParam<CTakeDamageInfo>(1);
if (nades.Contains(weapon)) return;
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return;
if (param == null || param.Entity == null || param2 == null || param2.Attacker == null || param2.Attacker.Value == null)
return;
var playerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
if (param2.AmmoType == 255)
return;
CCSPlayerPawn attackerPawn = new(param2.Attacker.Value.Handle);
CCSPlayerPawn victimPawn = new(param.Handle);
if (attackerPawn == null || !attackerPawn.IsValid || victimPawn == null || !victimPawn.IsValid)
return;
if (attackerPawn.DesignerName != "player" || victimPawn.DesignerName != "player")
return;
if (attackerPawn == null || attackerPawn.Controller?.Value == null || victimPawn == null || victimPawn.Controller?.Value == null)
return;
var attackerController = attackerPawn.Controller.Value;
if (attackerController == null || !attackerController.IsValid) return;
var victimController = victimPawn.Controller.Value;
if (victimController == null || !victimController.IsValid) return;
var attacker = attackerController.As<CCSPlayerController>();
if (attacker == null || !attacker.IsValid) return;
var victim = victimController.As<CCSPlayerController>();
if (victim == null || !victim.IsValid) return;
var playerInfo = PlayerManager.GetPlayerByIndex(PlayerManager.GetPlayerEvent(attacker)!.Index);
if (playerInfo?.Skill != skillName || attacker!.Team != victim!.Team) return;
float damage = param2.Damage;
param2.Damage = 0;
Server.ExecuteCommand("mp_autokick 0");
var pawn = victim.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return;
if (damage == 0)
damage = Instance.Random.Next(4, 6);
SkillUtils.AddHealth(pawn, damage + (int)(damage * SkillsInfo.GetValue<float>(skillName, "healthMultiplier")), pawn.MaxHealth);
SkillUtils.AddHealth(
victimPawn,
(int)(damage * SkillsInfo.GetValue<float>(skillName, "healthDamageMultiplier")),
victimPawn.MaxHealth
);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff0000", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = true, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float healthMultiplier = 1.5f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff0000", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = true, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float healthDamageMultiplier = .3f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public float HealthMultiplier { get; set; } = healthMultiplier;
public float HealthDamageMultiplier { get; set; } = healthDamageMultiplier;
}
}
}

View file

@ -11,6 +11,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.FrozenDecoy;
private static readonly ConcurrentDictionary<Vector, byte> decoys = [];
private readonly static ConcurrentDictionary<uint, int> playersWithSkill = [];
public static void LoadSkill()
{
@ -67,15 +68,71 @@ namespace src.player.skills
}
}
public static void EnableSkill(CCSPlayerController player)
public static void GrenadeThrown(EventGrenadeThrown @event)
{
SkillUtils.TryGiveWeapon(player, CsItem.DecoyGrenade);
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Weapon;
if (weapon != "decoy") return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
{
playersWithSkill[player.Index] = grenadesLeft - 1;
player!.GiveNamedItem($"weapon_{weapon}");
SkillUtils.UpdateGrenadeCount(player, CsItem.DecoyGrenade, grenadesLeft - 1);
}
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#00eaff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float triggerRadius = 180, int slownessMultiplier = 5) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
public static void WeaponEquip(EventItemEquip @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item;
if (player == null || !player.IsValid) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.DecoyGrenade, grenadesLeft);
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Item;
if (string.IsNullOrEmpty(weapon) || weapon != "decoy") return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.DecoyGrenade, grenadesLeft);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
int grenadeLimit = SkillsInfo.GetValue<int>(skillName, "grenadeLimit");
playersWithSkill.TryAdd(player.Index, grenadeLimit);
SkillUtils.TryGiveWeapon(player, CsItem.DecoyGrenade);
SkillUtils.UpdateGrenadeCount(player, CsItem.DecoyGrenade, grenadeLimit);
}
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
playersWithSkill.TryRemove(player.Index, out _);
SkillUtils.UpdateGrenadeCount(player, CsItem.DecoyGrenade, 1);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#00eaff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float triggerRadius = 180, int slownessMultiplier = 5, int grenadeLimit = 3) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public float TriggerRadius { get; set; } = triggerRadius;
public int SlownessMultiplier { get; set; } = slownessMultiplier;
public int GrenadeLimit { get; set; } = grenadeLimit;
}
}
}

View file

@ -13,17 +13,8 @@ namespace src.player.skills
public class Ghost : ISkill
{
private const Skills skillName = Skills.Ghost;
private static readonly string[] disabledWeapons =
[
"weapon_deagle", "weapon_revolver", "weapon_glock", "weapon_usp_silencer",
"weapon_cz75a", "weapon_fiveseven", "weapon_p250", "weapon_tec9",
"weapon_elite", "weapon_hkp2000", "weapon_ak47", "weapon_m4a1",
"weapon_m4a4", "weapon_m4a1_silencer", "weapon_famas", "weapon_galilar",
"weapon_aug", "weapon_sg553", "weapon_mp9", "weapon_mac10",
"weapon_bizon", "weapon_mp7", "weapon_ump45", "weapon_p90",
"weapon_mp5sd", "weapon_ssg08", "weapon_awp", "weapon_scar20",
"weapon_g3sg1", "weapon_nova", "weapon_xm1014", "weapon_mag7",
"weapon_sawedoff", "weapon_m249", "weapon_negev"
private static readonly string[] allowedWeapons = [
"weapon_molotov", "weapon_incgrenade", "weapon_flashbang", "weapon_smokegrenade", "weapon_decoy", "weapon_hegrenade", "weapon_knife", "weapon_bayonet"
];
private static readonly ConcurrentDictionary<uint, byte> invisiblePlayers = [];
private const string bloodParticle = "particles/blood_impact/blood_impact_high.vpcf";
@ -96,7 +87,8 @@ namespace src.player.skills
var entity = Utilities.GetEntityFromIndex<CBaseEntity>((int)playerPawn.Index);
if (entity == null || !entity.IsValid) continue;
info.TransmitEntities.Remove(entity.Index);
if (info.TransmitEntities.Contains(entity.Index))
info.TransmitEntities.Remove(entity.Index);
var bombIndex = GetBombIndex(playerController);
if (bombIndex == null) continue;
@ -104,7 +96,8 @@ namespace src.player.skills
var bombEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)bombIndex);
if (bombEntity == null || !bombEntity.IsValid) continue;
info.TransmitEntities.Remove(bombEntity.Index);
if (info.TransmitEntities.Contains(bombEntity.Index))
info.TransmitEntities.Remove(bombEntity.Index);
}
}
}
@ -113,12 +106,15 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player)
{
Event.EnableTransmit();
SetWeaponAttack(player, true);
SkillUtils.SetPlayerInvisibility(player, .5f);
invisiblePlayers.TryAdd(player.Index, 0);
if (EntityManager.GetPlayerEntities(player.Index, "empty_prop").Count == 0)
CreatePlayerPosProp(player);
SkillUtils.ForceFullUpdateToAll();
}
private static void CreatePlayerPosProp(CCSPlayerController player)
@ -154,6 +150,8 @@ namespace src.player.skills
invisiblePlayers.TryRemove(player.Index, out _);
EntityManager.DestroyPlayerEntities(player.Index);
SkillUtils.ForceFullUpdateToAll();
}
public static void OnTick()
@ -210,8 +208,10 @@ namespace src.player.skills
if (pawn == null || !pawn.IsValid || pawn.WeaponServices == null) return;
foreach (var weapon in pawn.WeaponServices.MyWeapons)
if (weapon != null && weapon.IsValid && weapon.Value != null && weapon.Value.IsValid)
if (disabledWeapons.Contains(weapon.Value.DesignerName))
if (weapon != null && weapon.IsValid && weapon.Value != null && weapon.Value.IsValid && !string.IsNullOrEmpty(weapon.Value.DesignerName))
{
string weaponName = weapon.Value.DesignerName;
if (!allowedWeapons.Contains(weaponName))
{
weapon.Value.NextPrimaryAttackTick = disableWeapon ? int.MaxValue : Server.TickCount;
weapon.Value.NextSecondaryAttackTick = disableWeapon ? int.MaxValue : Server.TickCount;
@ -219,6 +219,7 @@ namespace src.player.skills
Utilities.SetStateChanged(weapon.Value, "CBasePlayerWeapon", "m_nNextPrimaryAttackTick");
Utilities.SetStateChanged(weapon.Value, "CBasePlayerWeapon", "m_nNextSecondaryAttackTick");
}
}
}
private static void UpdateHUD(CCSPlayerController player)
@ -231,7 +232,7 @@ namespace src.player.skills
if (playerInfo == null) return;
var weapon = pawn.WeaponServices.ActiveWeapon.Value;
if (weapon == null || !weapon.IsValid || !disabledWeapons.Contains(weapon.DesignerName))
if (weapon == null || !weapon.IsValid || allowedWeapons.Contains(weapon.DesignerName))
{
playerInfo.PrintHTML = null;
return;

View file

@ -13,6 +13,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Glaz;
private readonly static ConcurrentDictionary<int, byte> smokes = [];
private readonly static ConcurrentDictionary<uint, int> playersWithSkill = [];
private static readonly object setLock = new();
public static void LoadSkill()
@ -51,19 +52,82 @@ namespace src.player.skills
{
var entity = Utilities.GetEntityFromIndex<CBaseEntity>((int)entityIndex);
if (entity == null || !entity.IsValid) continue;
info.TransmitEntities.Remove(entity.Index);
if (info.TransmitEntities.Contains(entity.Index))
info.TransmitEntities.Remove(entity.Index);
}
}
}
public static void EnableSkill(CCSPlayerController player)
public static void GrenadeThrown(EventGrenadeThrown @event)
{
Event.EnableTransmit();
SkillUtils.TryGiveWeapon(player, CsItem.SmokeGrenade);
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Weapon;
if (weapon != "smokegrenade") return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
{
playersWithSkill[player.Index] = grenadesLeft - 1;
player!.GiveNamedItem($"weapon_{weapon}");
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, grenadesLeft - 1);
}
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#5d00ff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
public static void WeaponEquip(EventItemEquip @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item;
if (player == null || !player.IsValid) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, grenadesLeft);
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Item;
if (string.IsNullOrEmpty(weapon) || weapon != "smokegrenade") return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, grenadesLeft);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
Event.EnableTransmit();
int grenadeLimit = SkillsInfo.GetValue<int>(skillName, "grenadeLimit");
playersWithSkill.TryAdd(player.Index, grenadeLimit);
SkillUtils.TryGiveWeapon(player, CsItem.SmokeGrenade);
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, grenadeLimit);
SkillUtils.ForceFullUpdateToAll();
}
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
playersWithSkill.TryRemove(player.Index, out _);
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, 1);
SkillUtils.ForceFullUpdateToAll();
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#5d00ff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, int grenadeLimit = 2) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public int GrenadeLimit { get; set; } = grenadeLimit;
}
}
}

View file

@ -13,6 +13,8 @@ namespace src.player.skills
private static readonly ConcurrentDictionary<uint, PlayerSkillInfo> SkillPlayerInfo = [];
private static readonly object setLock = new();
public static bool HaveHodMode(uint playerIndex) => SkillPlayerInfo.TryGetValue(playerIndex, out var skillInfo) && skillInfo.CanUse == false;
public static void LoadSkill()
{
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
@ -30,8 +32,12 @@ namespace src.player.skills
{
SteamID = player.Index,
CanUse = true,
HaveGodMode = false,
Cooldown = DateTime.MinValue,
});
if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
skillInfo.HaveGodMode = true;
}
public static void OnTick()
@ -90,11 +96,15 @@ namespace src.player.skills
{
skillInfo.CanUse = false;
skillInfo.Cooldown = DateTime.Now;
skillInfo.HaveGodMode = true;
PlayerManager.GetPlayerFromEvent(player)?.PrintToChat($" {ChatColors.Green} {player.GetTranslation("godmode_on")}");
player.PlayerPawn.Value.TakesDamage = false;
Instance.AddTimer(SkillsInfo.GetValue<float>(skillName, "duration"), () => {
if (SkillPlayerInfo.TryGetValue(playerIndex, out var skillInfo))
skillInfo.HaveGodMode = false;
var player = Utilities.GetPlayerFromIndex((int)playerIndex);
if (player != null && player.IsValid)
{
@ -102,6 +112,9 @@ namespace src.player.skills
player.PlayerPawn.Value.TakesDamage = true;
PlayerManager.GetPlayerFromEvent(player)?.PrintToChat($" {ChatColors.Red} {player.GetTranslation("godmode_off")}");
if (player.PlayerPawn.Value.Health <= 0)
player.CommitSuicide(false, true);
}
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
}
@ -112,6 +125,7 @@ namespace src.player.skills
{
public ulong SteamID { get; set; }
public bool CanUse { get; set; }
public bool HaveGodMode { get; set; }
public DateTime Cooldown { get; set; }
}

View file

@ -11,6 +11,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.HealingSmoke;
private static readonly ConcurrentDictionary<Vector, byte> smokes = [];
private readonly static ConcurrentDictionary<uint, int> playersWithSkill = [];
public static void LoadSkill()
{
@ -95,16 +96,72 @@ namespace src.player.skills
}
}
public static void EnableSkill(CCSPlayerController player)
public static void GrenadeThrown(EventGrenadeThrown @event)
{
SkillUtils.TryGiveWeapon(player, CsItem.SmokeGrenade);
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Weapon;
if (weapon != "smokegrenade") return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
{
playersWithSkill[player.Index] = grenadesLeft - 1;
player!.GiveNamedItem($"weapon_{weapon}");
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, grenadesLeft - 1);
}
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1fe070", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, int smokeHeal = 1, float smokeRadius = 180, int tickCooldown = 16) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
public static void WeaponEquip(EventItemEquip @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item;
if (player == null || !player.IsValid) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, grenadesLeft);
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Item;
if (string.IsNullOrEmpty(weapon) || weapon != "smokegrenade") return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, grenadesLeft);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
int grenadeLimit = SkillsInfo.GetValue<int>(skillName, "grenadeLimit");
playersWithSkill.TryAdd(player.Index, grenadeLimit);
SkillUtils.TryGiveWeapon(player, CsItem.SmokeGrenade);
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, grenadeLimit);
}
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
playersWithSkill.TryRemove(player.Index, out _);
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, 1);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#1fe070", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, int smokeHeal = 1, float smokeRadius = 180, int tickCooldown = 16, int grenadeLimit = 1) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public int SmokeHeal { get; set; } = smokeHeal;
public float SmokeRadius { get; set; } = smokeRadius;
public int TickCooldown { get; set; } = tickCooldown;
public int GrenadeLimit { get; set; } = grenadeLimit;
}
}
}

View file

@ -3,13 +3,14 @@ using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
namespace src.player.skills
{
public class HolyHandGrenade : ISkill
{
private const Skills skillName = Skills.HolyHandGrenade;
private readonly static ConcurrentDictionary<uint, int> playersWithSkill = [];
public static void LoadSkill()
{
@ -40,15 +41,71 @@ namespace src.player.skills
});
}
public static void EnableSkill(CCSPlayerController player)
public static void GrenadeThrown(EventGrenadeThrown @event)
{
SkillUtils.TryGiveWeapon(player, CsItem.HEGrenade);
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Weapon;
if (weapon != "hegrenade") return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
{
playersWithSkill[player.Index] = grenadesLeft - 1;
player!.GiveNamedItem($"weapon_{weapon}");
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadesLeft - 1);
}
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ffdd00", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float damageMultiplier = 2f, float damageRadiusMultiplier = 2f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
public static void WeaponEquip(EventItemEquip @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item;
if (player == null || !player.IsValid) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadesLeft);
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Item;
if (string.IsNullOrEmpty(weapon) || weapon != "hegrenade") return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadesLeft);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
int grenadeLimit = SkillsInfo.GetValue<int>(skillName, "grenadeLimit");
playersWithSkill.TryAdd(player.Index, grenadeLimit);
SkillUtils.TryGiveWeapon(player, CsItem.HEGrenade);
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadeLimit);
}
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
playersWithSkill.TryRemove(player.Index, out _);
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, 1);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ffdd00", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float damageMultiplier = 2f, float damageRadiusMultiplier = 2f, int grenadeLimit = 1) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public float DamageMultiplier { get; set; } = damageMultiplier;
public float DamageRadiusMultiplier { get; set; } = damageRadiusMultiplier;
public int GrenadeLimit { get; set; } = grenadeLimit;
}
}
}

View file

@ -11,6 +11,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.HomingNades;
private readonly static ConcurrentDictionary<uint, Vector> nades = [];
private readonly static ConcurrentDictionary<uint, int> playersWithSkill = [];
public static void LoadSkill()
{
@ -140,16 +141,72 @@ namespace src.player.skills
});
}
public static void EnableSkill(CCSPlayerController player)
public static void GrenadeThrown(EventGrenadeThrown @event)
{
SkillUtils.TryGiveWeapon(player, CsItem.HEGrenade);
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Weapon;
if (weapon != "hegrenade") return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
{
playersWithSkill[player.Index] = grenadesLeft - 1;
player!.GiveNamedItem($"weapon_{weapon}");
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadesLeft - 1);
}
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#384728", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float strength = 150, float maxVelocity = 2000, float detonationRange = 130) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
public static void WeaponEquip(EventItemEquip @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item;
if (player == null || !player.IsValid) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadesLeft);
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Item;
if (string.IsNullOrEmpty(weapon) || weapon != "hegrenade") return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadesLeft);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
int grenadeLimit = SkillsInfo.GetValue<int>(skillName, "grenadeLimit");
playersWithSkill.TryAdd(player.Index, grenadeLimit);
SkillUtils.TryGiveWeapon(player, CsItem.HEGrenade);
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadeLimit);
}
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
playersWithSkill.TryRemove(player.Index, out _);
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, 1);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#384728", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float strength = 150, float maxVelocity = 2000, float detonationRange = 130, int grenadeLimit = 2) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public float Strength { get; set; } = strength;
public float MaxVelocity { get; set; } = maxVelocity;
public float DetonationRange { get; set; } = detonationRange;
public int GrenadeLimit { get; set; } = grenadeLimit;
}
}
}

View file

@ -241,7 +241,7 @@ namespace src.player.skills
return clone;
}
private unsafe static bool CheckPosition(CCSPlayerController player, Vector endPos)
private static bool CheckPosition(CCSPlayerController player, Vector endPos)
{
var playerPawn = player.PlayerPawn.Value;
@ -340,10 +340,16 @@ namespace src.player.skills
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
if (victim == null || !victim.IsValid) return;
if (playersInfo.TryGetValue(victim.Index, out var playerSkill) && playerSkill.CloneProp != null)
if (playersInfo.TryGetValue(victim.Index, out var playerSkill))
{
KillClone(playerSkill);
SkillUtils.RestoreHealth(victim);
if (playerSkill.CloneProp != null)
{
KillClone(playerSkill);
playerSkill.LastHit = Server.TickCount;
}
if (playerSkill.LastHit + 4 > Server.TickCount)
SkillUtils.RestoreHealth(victim);
}
}
@ -429,6 +435,7 @@ namespace src.player.skills
public float NextUse { get; set; }
public float UseTime { get; set; }
public int InfoTime { get; set; }
public int LastHit { get; set; }
public List<ulong> Weapons { get; set; } = [];
}

View file

@ -1,6 +1,7 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
@ -75,7 +76,8 @@ namespace src.player.skills
if (relayEntity == null || !relayEntity.IsValid) continue;
if (player.Team == trailOwner.Team || !isJackalOwner)
info.TransmitEntities.Remove(relayEntity.Index);
if (info.TransmitEntities.Contains(relayEntity.Index))
info.TransmitEntities.Remove(relayEntity.Index);
}
}
}
@ -137,6 +139,8 @@ namespace src.player.skills
mainSkillTimer ??= Instance.AddTimer(2.5f, () => UpdateAllTrails(),
CounterStrikeSharp.API.Modules.Timers.TimerFlags.REPEAT | CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
SkillUtils.ForceFullUpdateToAll();
}
private static void UpdateAllTrails()
@ -159,6 +163,8 @@ namespace src.player.skills
mainSkillTimer.Kill();
mainSkillTimer = null;
}
SkillUtils.ForceFullUpdateToAll();
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#f542ef", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = 1, Rarity rarity = Rarity.Common, string particleName = "particles/ui/hud/ui_map_def_utility_trail.vpcf") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)

View file

@ -1,8 +1,9 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Commands.Targeting;
using CounterStrikeSharp.API.Modules.Cvars;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills
@ -10,6 +11,7 @@ namespace src.player.skills
public class KillerFlash : ISkill
{
private const Skills skillName = Skills.KillerFlash;
private readonly static ConcurrentDictionary<uint, int> playersWithSkill = [];
public static void LoadSkill()
{
@ -31,15 +33,77 @@ namespace src.player.skills
player?.PlayerPawn?.Value?.CommitSuicide(false, true);
}
public static void EnableSkill(CCSPlayerController player)
public static void GrenadeThrown(EventGrenadeThrown @event)
{
SkillUtils.TryGiveWeapon(player, CsItem.FlashbangGrenade);
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Weapon;
if (weapon != "flashbang") return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
{
playersWithSkill[player.Index] = grenadesLeft - 1;
player!.GiveNamedItem($"weapon_{weapon}");
SkillUtils.UpdateGrenadeCount(player, CsItem.FlashbangGrenade, grenadesLeft - 1);
}
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#57bcff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = 1, Rarity rarity = Rarity.Epic, float flashDuration = 1f, bool friendlyFire = true) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
public static void WeaponEquip(EventItemEquip @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item;
if (player == null || !player.IsValid) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.FlashbangGrenade, grenadesLeft);
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Item;
if (string.IsNullOrEmpty(weapon) || weapon != "flashbang") return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.FlashbangGrenade, grenadesLeft);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
int flashbangLimit = ConVar.Find("ammo_grenade_limit_flashbang")?.GetPrimitiveValue<int>() ?? 2;
int grenadeLimit = SkillsInfo.GetValue<int>(skillName, "grenadeLimit");
if (grenadeLimit > flashbangLimit)
{
playersWithSkill.TryAdd(player.Index, grenadeLimit);
SkillUtils.TryGiveWeapon(player, CsItem.FlashbangGrenade);
SkillUtils.UpdateGrenadeCount(player, CsItem.FlashbangGrenade, grenadeLimit);
}
else
SkillUtils.TryGiveWeapon(player, CsItem.FlashbangGrenade, grenadeLimit, false);
}
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
playersWithSkill.TryRemove(player.Index, out _);
SkillUtils.UpdateGrenadeCount(player, CsItem.FlashbangGrenade, 1);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#57bcff", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = 1, Rarity rarity = Rarity.Epic, float flashDuration = 1f, bool friendlyFire = true, int grenadeLimit = 1) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public float FlashDuration { get; set; } = flashDuration;
public bool FriendlyFire { get; set; } = friendlyFire;
public int GrenadeLimit { get; set; } = grenadeLimit;
}
}
}

View file

@ -33,7 +33,7 @@ namespace src.player.skills
if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"{e.PlayerName} : {e?.PlayerPawn?.Value?.Health ?? 0} HP", e.Index.ToString())));
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"\u202A{e.PlayerName}\u202C : {e?.PlayerPawn?.Value?.Health ?? 0} HP", e.Index.ToString())));
SkillUtils.UpdateMenu(player, menuItems);
}
}
@ -75,7 +75,7 @@ namespace src.player.skills
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0)
{
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"{e.PlayerName} : {e.PawnHealth} HP", e.Index.ToString())));
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"\u202A{e.PlayerName}\u202C : {e.PawnHealth} HP", e.Index.ToString())));
SkillUtils.CreateMenu(player, menuItems);
}
else

View file

@ -11,6 +11,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.MagneticDecoy;
private static readonly ConcurrentDictionary<Vector, byte> decoys = [];
private readonly static ConcurrentDictionary<uint, int> playersWithSkill = [];
public static void LoadSkill()
{
@ -74,15 +75,71 @@ namespace src.player.skills
}
}
public static void EnableSkill(CCSPlayerController player)
public static void GrenadeThrown(EventGrenadeThrown @event)
{
SkillUtils.TryGiveWeapon(player, CsItem.DecoyGrenade);
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Weapon;
if (weapon != "decoy") return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
{
playersWithSkill[player.Index] = grenadesLeft - 1;
player!.GiveNamedItem($"weapon_{weapon}");
SkillUtils.UpdateGrenadeCount(player, CsItem.DecoyGrenade, grenadesLeft - 1);
}
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#81f0c4", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float triggerRadius = 180, float strenght = 30) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
public static void WeaponEquip(EventItemEquip @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item;
if (player == null || !player.IsValid) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.DecoyGrenade, grenadesLeft);
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Item;
if (string.IsNullOrEmpty(weapon) || weapon != "decoy") return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.DecoyGrenade, grenadesLeft);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
int grenadeLimit = SkillsInfo.GetValue<int>(skillName, "grenadeLimit");
playersWithSkill.TryAdd(player.Index, grenadeLimit);
SkillUtils.TryGiveWeapon(player, CsItem.DecoyGrenade);
SkillUtils.UpdateGrenadeCount(player, CsItem.DecoyGrenade, grenadeLimit);
}
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
playersWithSkill.TryRemove(player.Index, out _);
SkillUtils.UpdateGrenadeCount(player, CsItem.DecoyGrenade, 1);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#81f0c4", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float triggerRadius = 180, float strenght = 30, int grenadeLimit = 3) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public float TriggerRadius { get; set; } = triggerRadius;
public float Strenght { get; set; } = strenght;
public int GrenadeLimit { get; set; } = grenadeLimit;
}
}
}

View file

@ -11,6 +11,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Miner;
private readonly static ConcurrentDictionary<uint, byte> nades = [];
private readonly static ConcurrentDictionary<uint, int> playersWithSkill = [];
public static void LoadSkill()
{
@ -20,6 +21,7 @@ namespace src.player.skills
public static void NewRound()
{
nades.Clear();
playersWithSkill.Clear();
}
public static void OnTick()
@ -39,7 +41,7 @@ namespace src.player.skills
if (nade.CreateTime + 3 > currentTime) return;
Vector currentPos = new(nade.AbsOrigin.X, nade.AbsOrigin.Y, nade.AbsOrigin.Z);
foreach (var enemy in Utilities.GetPlayers().Where(p => p.IsValid && p.PawnIsAlive && p.TeamNum != nade.TeamNum))
{
var enemyPawn = enemy.PlayerPawn.Value;
@ -101,12 +103,68 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
int grenadeLimit = SkillsInfo.GetValue<int>(skillName, "grenadeLimit");
playersWithSkill.TryAdd(player.Index, grenadeLimit);
SkillUtils.TryGiveWeapon(player, CsItem.HEGrenade);
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadeLimit);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#adf542", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float detonationRange = 130) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
public static void GrenadeThrown(EventGrenadeThrown @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Weapon;
if (weapon != "hegrenade") return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
{
playersWithSkill[player.Index] = grenadesLeft - 1;
player!.GiveNamedItem($"weapon_{weapon}");
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadesLeft - 1);
}
}
public static void WeaponEquip(EventItemEquip @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item;
if (player == null || !player.IsValid) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadesLeft);
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Item;
if (string.IsNullOrEmpty(weapon) || weapon != "hegrenade") return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadesLeft);
}
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
playersWithSkill.TryRemove(player.Index, out _);
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, 1);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#adf542", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float detonationRange = 130, int grenadeLimit = 3) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public float DetonationRange { get; set; } = detonationRange;
public int GrenadeLimit { get; set; } = grenadeLimit;
}
}
}

View file

@ -1,7 +1,6 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using static src.jRandomSkills;
using System.Collections.Concurrent;
using src.utils;
@ -33,7 +32,7 @@ namespace src.player.skills
if (playerInfo == null || playerInfo.Skill != skillName) continue;
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray();
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account + e.InGameMoneyServices.CashSpentThisRound)}$", e.Index.ToString()))];
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"\u202A{e.PlayerName}\u202C : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account + e.InGameMoneyServices.CashSpentThisRound)}$", e.Index.ToString()))];
SkillUtils.UpdateMenu(player, menuItems);
}
}
@ -75,7 +74,7 @@ namespace src.player.skills
var enemies = Utilities.GetPlayers().Where(p =>p != null &&p.IsValid).Select(p => PlayerManager.GetPlayerEvent(p)).Where(p =>p != null &&p.IsValid &&p.Team != player.Team &&p.PlayerPawn?.Value != null &&p.PlayerPawn.Value.IsValid &&p.PlayerPawn.Value.Health > 0 &&!p.IsHLTV &&p.Team != CsTeam.Spectator&& p.Team != CsTeam.None).ToArray();
if (enemies.Length > 0)
{
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account + e.InGameMoneyServices.CashSpentThisRound)}$", e.Index.ToString()))];
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"\u202A{e.PlayerName}\u202C : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account + e.InGameMoneyServices.CashSpentThisRound)}$", e.Index.ToString()))];
SkillUtils.CreateMenu(player, menuItems);
}
else

View file

@ -88,13 +88,17 @@ namespace src.player.skills
var entity = Utilities.GetEntityFromIndex<CBaseEntity>((int)playerPawn.Index);
if (entity == null || !entity.IsValid) continue;
info.TransmitEntities.Remove(entity.Index);
if (info.TransmitEntities.Contains(entity.Index))
info.TransmitEntities.Remove(entity.Index);
var bombIndex = GetBombIndex(playerController);
if (bombIndex == null) continue;
var bombEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)bombIndex);
if (bombEntity == null || !bombEntity.IsValid) continue;
info.TransmitEntities.Remove(bombEntity.Index);
if (info.TransmitEntities.Contains(bombEntity.Index))
info.TransmitEntities.Remove(bombEntity.Index);
}
}
}
@ -135,6 +139,8 @@ namespace src.player.skills
if (EntityManager.GetPlayerEntities(player.Index, "empty_prop").Count == 0)
CreatePlayerPosProp(player);
SkillUtils.ForceFullUpdateToAll();
}
public static void DisableSkill(CCSPlayerController player)
@ -142,6 +148,8 @@ namespace src.player.skills
SkillUtils.SetPlayerInvisibility(player, 0);
invisiblePlayers.TryRemove(player.Index, out _);
EntityManager.DestroyPlayerEntities(player.Index);
SkillUtils.ForceFullUpdateToAll();
}
private static void CreatePlayerPosProp(CCSPlayerController player)

View file

@ -2,6 +2,7 @@ using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills
@ -9,6 +10,7 @@ namespace src.player.skills
public class Phoenix : ISkill
{
private const Skills skillName = Skills.Phoenix;
private static readonly ConcurrentDictionary<uint, int> phoenixTicks = new();
public static void LoadSkill()
{
@ -26,12 +28,21 @@ namespace src.player.skills
var pawn = victim.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return;
bool isProtected = phoenixTicks.TryGetValue(victim.Index, out int tick);
if (isProtected && tick + 4 > Server.TickCount)
{
SkillUtils.AddHealth(pawn, 100 - pawn.Health);
return;
}
var playerInfo = PlayerManager.GetPlayerByIndex(victim.Index);
if (playerInfo?.Skill != skillName || pawn.Health > 0) return;
if (Instance.Random.NextDouble() > playerInfo.SkillChance) return;
if (victim.TeamChanged) return;
phoenixTicks[victim.Index] = Server.TickCount;
SkillUtils.AddHealth(pawn, 100 - pawn.Health);
SkillUtils.PrintToChat(user, user.GetTranslation("phoenix_respawn"));
@ -51,8 +62,10 @@ namespace src.player.skills
{
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo == null) return;
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
playerInfo.SkillChance = newChance;
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && p != player) ? "tb" : "t");
}

View file

@ -1,8 +1,8 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
using System.Collections.Concurrent;
using static src.jRandomSkills;
namespace src.player.skills
@ -10,6 +10,7 @@ namespace src.player.skills
public class Pyro : ISkill
{
private const Skills skillName = Skills.Pyro;
private readonly static ConcurrentDictionary<uint, int> playersWithSkill = [];
public static void LoadSkill()
{
@ -31,14 +32,77 @@ namespace src.player.skills
SkillUtils.AddHealth(pawn, (int)(damage * SkillsInfo.GetValue<float>(skillName, "regenerationMultiplier")));
}
public static void EnableSkill(CCSPlayerController player)
public static void GrenadeThrown(EventGrenadeThrown @event)
{
SkillUtils.TryGiveWeapon(player, player.Team == CsTeam.CounterTerrorist ? CsItem.IncendiaryGrenade : CsItem.Molotov);
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Weapon;
if (weapon != "molotov" && weapon != "incgrenade") return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
{
playersWithSkill[player.Index] = grenadesLeft - 1;
player!.GiveNamedItem($"weapon_{weapon}");
SkillUtils.UpdateGrenadeCount(player, CsItem.Molotov, grenadesLeft - 1);
SkillUtils.UpdateGrenadeCount(player, CsItem.IncendiaryGrenade, grenadesLeft - 1);
}
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#3c47de", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float regenerationMultiplier = 1.5f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
public static void WeaponEquip(EventItemEquip @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item;
if (player == null || !player.IsValid) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
{
SkillUtils.UpdateGrenadeCount(player, CsItem.Molotov, grenadesLeft);
SkillUtils.UpdateGrenadeCount(player, CsItem.IncendiaryGrenade, grenadesLeft);
}
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Item;
if (string.IsNullOrEmpty(weapon) || weapon != "hegrenade") return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadesLeft);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
int grenadeLimit = SkillsInfo.GetValue<int>(skillName, "grenadeLimit");
playersWithSkill.TryAdd(player.Index, grenadeLimit);
var item = player.Team == CsTeam.CounterTerrorist ? CsItem.IncendiaryGrenade : CsItem.Molotov;
SkillUtils.TryGiveWeapon(player, item);
SkillUtils.UpdateGrenadeCount(player, item, grenadeLimit);
}
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
playersWithSkill.TryRemove(player.Index, out _);
SkillUtils.UpdateGrenadeCount(player, CsItem.Molotov, 1);
SkillUtils.UpdateGrenadeCount(player, CsItem.IncendiaryGrenade, 1);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#3c47de", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float regenerationMultiplier = 1.5f, int grenadeLimit = 2) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public float RegenerationMultiplier { get; set; } = regenerationMultiplier;
public int GrenadeLimit { get; set; } = grenadeLimit;
}
}
}

View file

@ -11,7 +11,7 @@ namespace src.player.skills
public class ReZombie : ISkill
{
private const Skills skillName = Skills.ReZombie;
private static readonly ConcurrentDictionary<uint, byte> zombies = [];
private static readonly ConcurrentDictionary<uint, int> zombies = [];
private static readonly object setLock = new();
public static void LoadSkill()
@ -76,25 +76,57 @@ namespace src.player.skills
var pawn = victim.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return;
if (zombies.ContainsKey(victim.Index)) return;
bool isZombie = zombies.TryGetValue(victim.Index, out int tick);
if (isZombie && tick + 4 < Server.TickCount)
return;
var playerInfo = PlayerManager.GetPlayerByIndex(victim.Index);
if (playerInfo?.Skill != skillName || pawn.Health > 0) return;
if (playerInfo?.Skill != skillName) return;
lock (setLock)
var zombieHealth = SkillsInfo.GetValue<int>(skillName, "zombieHealth");
if (pawn.Health <= 0)
{
var zombieHealth = SkillsInfo.GetValue<int>(skillName, "zombieHealth");
bool isBlock = victim.TeamChanged;
zombies.TryAdd(victim.Index, 0);
zombies[victim.Index] = Server.TickCount;
if (isBlock) return;
DropAllBotWeapons(victim);
SetPlayerColor(pawn, false);
SkillUtils.AddHealth(pawn, zombieHealth - pawn.Health, zombieHealth);
victim.ExecuteClientCommand("slot3");
}
else if (isZombie && tick + 4 > Server.TickCount)
SkillUtils.AddHealth(pawn, zombieHealth - pawn.Health, zombieHealth);
}
private static void DropAllBotWeapons(CCSPlayerController player)
{
if (player == null || !player.IsValid || !player.IsBot) return;
var pawn = player.PlayerPawn?.Value;
if (pawn == null || !pawn.IsValid) return;
var itemServices = pawn.ItemServices?.As<CCSPlayer_ItemServices>();
if (itemServices == null || pawn.WeaponServices?.MyWeapons == null) return;
foreach (var item in pawn.WeaponServices.MyWeapons)
{
if (item == null || !item.IsValid) continue;
var weapon = item.Value;
if (weapon == null || !weapon.IsValid) continue;
var weaponName = weapon.DesignerName;
if (string.IsNullOrEmpty(weaponName) || weaponName.Contains("knife") || weaponName.Contains("bayonet"))
continue;
SkillUtils.SafeKillEntity<CBasePlayerWeapon>(weapon.Index);
}
}
public static bool OnWeaponCanAcquire(DynamicHook hook, CCSPlayerController player, CEconItemView econItem, CCSWeaponBaseVData vdata)

View file

@ -10,7 +10,7 @@ namespace src.player.skills
public class SecondLife : ISkill
{
private const Skills skillName = Skills.SecondLife;
private static readonly ConcurrentDictionary<nint, byte> secondLifePlayers = [];
private static readonly ConcurrentDictionary<nint, int> secondLifePlayers = [];
private static readonly object setLock = new();
public static void LoadSkill()
@ -26,24 +26,24 @@ namespace src.player.skills
public static void PlayerHurt(EventPlayerHurt @event)
{
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
int damage = @event.DmgHealth;
if (!Instance.IsPlayerValid(victim)) return;
var victimInfo = PlayerManager.GetPlayerByIndex(victim!.Index);
if (victimInfo == null || victimInfo.Skill != skillName) return;
var victimPawn = victim!.PlayerPawn.Value;
if (victimPawn!.Health > 0 || secondLifePlayers.ContainsKey(victim.Handle))
if (victimPawn!.Health > 0 || (secondLifePlayers.TryGetValue(victim.Handle, out int tick) && tick + 4 < Server.TickCount))
return;
lock (setLock)
{
secondLifePlayers.TryAdd(victim.Handle, 0);
SetHealth(victim, SkillsInfo.GetValue<int>(skillName, "startHealth"));
var spawnpoint = SkillUtils.GetSpawnPointVector(victim);
if (spawnpoint == null) return;
victimPawn.Teleport(spawnpoint, null, null);
secondLifePlayers.TryAdd(victim.Handle, Server.TickCount);
}
}

View file

@ -14,6 +14,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Smoker;
private readonly static ConcurrentDictionary<uint, List<Timer>> playerSmokes = [];
private readonly static ConcurrentDictionary<uint, int> playersWithSkill = [];
private static readonly object setLock = new();
public static void LoadSkill()
@ -31,15 +32,65 @@ namespace src.player.skills
}
}
public static void GrenadeThrown(EventGrenadeThrown @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Weapon;
if (weapon != "smokegrenade") return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
{
playersWithSkill[player.Index] = grenadesLeft - 1;
player!.GiveNamedItem($"weapon_{weapon}");
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, grenadesLeft - 1);
}
}
public static void WeaponEquip(EventItemEquip @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item;
if (player == null || !player.IsValid) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, grenadesLeft);
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Item;
if (string.IsNullOrEmpty(weapon) || weapon != "smokegrenade") return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, grenadesLeft);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
int grenadeLimit = SkillsInfo.GetValue<int>(skillName, "grenadeLimit");
playersWithSkill.TryAdd(player.Index, grenadeLimit);
SkillUtils.TryGiveWeapon(player, CsItem.SmokeGrenade);
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, grenadeLimit);
}
public static void DisableSkill(CCSPlayerController player)
{
if (playerSmokes.TryRemove(player.Index, out var timers))
timers.ForEach(t => t?.Kill());
playersWithSkill.TryRemove(player.Index, out _);
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, 1);
}
public static void SmokegrenadeDetonate(EventSmokegrenadeDetonate @event)
@ -72,8 +123,9 @@ namespace src.player.skills
playerSmokes.AddOrUpdate(player.Index, [smokeTimer], (_, list) => { list.Add(smokeTimer); return list; });
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#b5ab8f", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = 1, Rarity rarity = Rarity.Common) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#b5ab8f", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = 1, Rarity rarity = Rarity.Common, int grenadeLimit = 1) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public int GrenadeLimit { get; set; } = grenadeLimit;
}
}
}

View file

@ -58,6 +58,7 @@ namespace src.player.skills
foreach (var player in Utilities.GetPlayers())
if (cameras.TryGetValue(player.Index, out var cameraInfo) && cameraInfo.Item2 != 0)
{
if (player == null || !player.IsValid) return;
var enemy = Utilities.GetPlayerFromIndex((int)cameraInfo.Item3);
if (enemy == null || !enemy.IsValid || enemy.PlayerPawn == null)
@ -73,16 +74,18 @@ namespace src.player.skills
return;
}
if (enemyPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE
|| (player.PlayerPawn.Value != null && player.PlayerPawn.Value.LifeState != (byte)LifeState_t.LIFE_ALIVE))
if (enemyPawn.Health <= 0 || (player.PlayerPawn?.Value != null && player.PlayerPawn.Value.Health <= 0))
ChangeCamera(player, true);
}
}
private static void ChangeCamera(CCSPlayerController player, bool forceToDefault = false)
{
if (player == null || !player.IsValid) return;
uint orginalCameraRaw;
uint newCameraRaw = 0;
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || pawn.CameraServices == null) return;
@ -165,9 +168,9 @@ namespace src.player.skills
});
if (cameras.TryGetValue(player.Index, out var cameraInfo))
cameras.AddOrUpdate(player.Index, (cameraInfo.Item1, camera.Index, player.Index), (k, v) => (cameraInfo.Item1, camera.Index, player.Index));
cameras.AddOrUpdate(player.Index, (cameraInfo.Item1, camera.Index, enemy.Index), (k, v) => (cameraInfo.Item1, camera.Index, enemy.Index));
else
cameras.AddOrUpdate(player.Index, (pawn.CameraServices.ViewEntity.Raw, camera.Index, player.Index), (k, v) => (pawn.CameraServices.ViewEntity.Raw, camera.Index, player.Index));
cameras.AddOrUpdate(player.Index, (pawn.CameraServices.ViewEntity.Raw, camera.Index, enemy.Index), (k, v) => (pawn.CameraServices.ViewEntity.Raw, camera.Index, enemy.Index));
return camera.EntityHandle.Raw;
}

View file

@ -50,7 +50,7 @@ namespace src.player.skills
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill);
if (skillData == null) continue;
menuItems.Add(($"{enemy.PlayerName} : {player.GetSkillName(skillData.Skill)}", enemy.Index.ToString()));
menuItems.Add(($"\u202A{enemy.PlayerName}\u202C : {player.GetSkillName(skillData.Skill)}", enemy.Index.ToString()));
}
SkillUtils.UpdateMenu(player, menuItems);
}
@ -120,7 +120,7 @@ namespace src.player.skills
var skillData = SkillData.Skills.FirstOrDefault(s => s.Skill == enemyInfo.Skill);
if (skillData == null) continue;
menuItems.Add(($"{enemy.PlayerName} : {player.GetSkillName(skillData.Skill)}", enemy.Index.ToString()));
menuItems.Add(($"\u202A{enemy.PlayerName}\u202C : {player.GetSkillName(skillData.Skill)}", enemy.Index.ToString()));
}
SkillUtils.CreateMenu(player, menuItems);

View file

@ -1,4 +1,3 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using src.utils;
@ -36,14 +35,18 @@ namespace src.player.skills
var victimInfo = PlayerManager.GetPlayerByIndex(victimEvent!.Index);
if (victimInfo?.Skill == skillName)
{
SkillUtils.TakeHealth(attackerEvent.PlayerPawn.Value, (int)(@event.DmgHealth * SkillsInfo.GetValue<float>(skillName, "healthTakenScale")));
int damage = (int)(@event.DmgHealth * SkillsInfo.GetValue<float>(skillName, "healthTakenScale"));
damage = Math.Min(damage, SkillsInfo.GetValue<int>(skillName, "maxTakenDamagePerShot"));
SkillUtils.TakeHealth(attackerEvent.PlayerPawn.Value, damage);
attackerEvent.EmitSound("Player.DamageBody.Onlooker");
}
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#962631", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float healthTakenScale = .3f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#962631", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float healthTakenScale = .3f, int maxTakenDamagePerShot = 37) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public float HealthTakenScale { get; set; } = healthTakenScale;
public int MaxTakenDamagePerShot { get; set; } = maxTakenDamagePerShot;
}
}
}

View file

@ -1,6 +1,7 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Timers;
using CounterStrikeSharp.API.Modules.UserMessages;
@ -122,12 +123,15 @@ namespace src.player.skills
public static void EnableSkill(CCSPlayerController _)
{
Event.EnableTransmit();
SkillUtils.ForceFullUpdateToAll();
}
public static void DisableSkill(CCSPlayerController player)
{
if (knivesInfo.TryRemove(player.Index, out KnifeInfo? knifeInfo) && knifeInfo != null)
DisableKnifeSkill(knifeInfo);
SkillUtils.ForceFullUpdateToAll();
}
public static void DisableKnifeSkill(KnifeInfo knifeInfo)
@ -388,7 +392,8 @@ namespace src.player.skills
bool isObservingOwner = observedPlayerIndex.HasValue && observedPlayerIndex.Value == knifeOwnerIndex;
if (!isOwner && !isObservingOwner)
info.TransmitEntities.Remove(glowEntity.Index);
if (info.TransmitEntities.Contains(glowEntity.Index))
info.TransmitEntities.Remove(glowEntity.Index);
}
}
}

View file

@ -11,6 +11,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.ToxicSmoke;
private static readonly ConcurrentDictionary<Vector, byte> smokes = [];
private readonly static ConcurrentDictionary<uint, int> playersWithSkill = [];
public static void LoadSkill()
{
@ -95,16 +96,72 @@ namespace src.player.skills
}
}
public static void EnableSkill(CCSPlayerController player)
public static void GrenadeThrown(EventGrenadeThrown @event)
{
SkillUtils.TryGiveWeapon(player, CsItem.SmokeGrenade);
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Weapon;
if (weapon != "smokegrenade") return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
{
playersWithSkill[player.Index] = grenadesLeft - 1;
player!.GiveNamedItem($"weapon_{weapon}");
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, grenadesLeft - 1);
}
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#507529", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, int smokeDamage = 2, float smokeRadius = 180, int tickCooldown = 17) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
public static void WeaponEquip(EventItemEquip @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item;
if (player == null || !player.IsValid) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, grenadesLeft);
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Item;
if (string.IsNullOrEmpty(weapon) || weapon != "smokegrenade") return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, grenadesLeft);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
int grenadeLimit = SkillsInfo.GetValue<int>(skillName, "grenadeLimit");
playersWithSkill.TryAdd(player.Index, grenadeLimit);
SkillUtils.TryGiveWeapon(player, CsItem.SmokeGrenade);
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, grenadeLimit);
}
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
playersWithSkill.TryRemove(player.Index, out _);
SkillUtils.UpdateGrenadeCount(player, CsItem.SmokeGrenade, 1);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#507529", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, int smokeDamage = 2, float smokeRadius = 180, int tickCooldown = 17, int grenadeLimit = 1) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public int SmokeDamage { get; set; } = smokeDamage;
public float SmokeRadius { get; set; } = smokeRadius;
public int TickCooldown { get; set; } = tickCooldown;
public int GrenadeLimit { get; set; } = grenadeLimit;
}
}
}

View file

@ -12,7 +12,8 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Wallhack;
private static readonly ConcurrentDictionary<uint, byte> playersInAction = new();
private static ConcurrentDictionary<uint, (uint RelayIndex, uint GlowIndex, CsTeam Team)> glows = new();
private static readonly ConcurrentDictionary<uint, (uint RelayIndex, uint GlowIndex, CsTeam Team)> glows = new();
private static readonly ConcurrentDictionary<uint, DateTime> temporaryBlockList = new();
public static void LoadSkill()
{
@ -21,6 +22,12 @@ namespace src.player.skills
public static void CheckTransmit([CastFrom(typeof(nint))] CCheckTransmitInfoList infoList)
{
foreach (var kvp in temporaryBlockList)
{
if (DateTime.Now > kvp.Value)
temporaryBlockList.TryRemove(kvp.Key, out _);
}
foreach (var (info, player) in infoList)
{
if (player == null || !player.IsValid) continue;
@ -54,11 +61,20 @@ namespace src.player.skills
var glowEntity1 = Utilities.GetEntityFromIndex<CBaseEntity>((int)glowInfo.RelayIndex);
if (glowEntity1 == null || !glowEntity1.IsValid) continue;
var glowEntity2 = Utilities.GetEntityFromIndex<CBaseEntity>((int)glowInfo.GlowIndex);
if (glowEntity2 == null || !glowEntity2.IsValid) continue;
info.TransmitEntities.Remove(glowEntity1.Index);
info.TransmitEntities.Remove(glowEntity2.Index);
if (info.TransmitEntities.Contains(glowEntity1.Index))
info.TransmitEntities.Remove(glowEntity1.Index);
if (info.TransmitEntities.Contains(glowEntity2.Index))
info.TransmitEntities.Remove(glowEntity2.Index);
}
foreach (var kvp in temporaryBlockList)
if (info.TransmitEntities.Contains(kvp.Key))
info.TransmitEntities.Remove(kvp.Key);
}
}
@ -71,6 +87,9 @@ namespace src.player.skills
SkillUtils.SafeKillEntity<CDynamicProp>(relayIndex);
SkillUtils.SafeKillEntity<CDynamicProp>(glowIndex);
temporaryBlockList.TryAdd(relayIndex, DateTime.Now.AddSeconds(2));
temporaryBlockList.TryAdd(glowIndex, DateTime.Now.AddSeconds(2));
}
glows.Clear();
@ -81,15 +100,21 @@ namespace src.player.skills
{
Event.EnableTransmit();
playersInAction.TryAdd(player.Index, 0);
if (glows.IsEmpty)
SetGlowEffectForAll();
SkillUtils.ForceFullUpdateToAll();
}
public static void DisableSkill(CCSPlayerController player)
{
playersInAction.TryRemove(player.Index, out _);
if (playersInAction.IsEmpty)
NewRound();
SkillUtils.ForceFullUpdateToAll();
}
private static void SetGlowEffectForAll()

View file

@ -15,7 +15,7 @@ namespace src.player.skills
private static readonly HashSet<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_mp9", "weapon_mac10", "weapon_bizon", "weapon_mp7", "weapon_ump45", "weapon_p90", "weapon_sg556",
"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" ];
@ -114,10 +114,10 @@ namespace src.player.skills
return;
}
string[]? playerWeapon = GetWeapons(player);
string[]? enemyWeapon = GetWeapons(enemy);
(WeaponInfo[]? playerWeapon, bool playerC4) = GetWeapons(player);
(WeaponInfo[]? enemyWeapon, bool enemyC4) = GetWeapons(enemy);
if (playerWeapon == null || !playerWeapon.Any(w => weapons.Contains(w)))
if (playerWeapon == null || !playerWeapon.Any(w => weapons.Contains(w.Name)))
{
skillInfo.FindedEnemy = true;
skillInfo.HaveWeapon = false;
@ -139,8 +139,8 @@ namespace src.player.skills
if (enemy == null || !enemy.IsValid) return;
player.RemoveWeapons();
enemy.RemoveWeapons();
GiveWeapons(player, enemyWeapon, playerWeapon.Contains("weapon_c4"));
GiveWeapons(enemy, playerWeapon, (enemyWeapon != null && enemyWeapon.Contains("weapon_c4")));
GiveWeapons(player, enemyWeapon, playerC4);
GiveWeapons(enemy, playerWeapon, (enemyWeapon != null && enemyC4));
});
}
else
@ -148,28 +148,76 @@ namespace src.player.skills
}
}
private static string[]? GetWeapons(CCSPlayerController player)
private static (WeaponInfo[]?, bool) GetWeapons(CCSPlayerController player)
{
bool haveC4 = false;
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return null;
if (pawn.WeaponServices == null) return null;
if (pawn == null || !pawn.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return (null, haveC4);
if (pawn.WeaponServices == null) return (null, haveC4);
var list = new List<string>();
var list = new List<WeaponInfo>();
foreach (var weapon in pawn.WeaponServices.MyWeapons)
if (weapon != null && weapon.IsValid && weapon.Value != null && weapon.Value.IsValid)
list.Add(SkillUtils.GetDesignerName(weapon.Value));
if (weapon != null && weapon.IsValid && weapon.Value != null && weapon.Value.IsValid && !string.IsNullOrEmpty(weapon.Value.DesignerName))
{
if (weapon.Value.DesignerName == "weapon_c4")
haveC4 = true;
else
{
list.Add(
new WeaponInfo
{
Name = SkillUtils.GetDesignerName(weapon.Value),
Clip1 = weapon.Value.Clip1,
Clip2 = weapon.Value.Clip2,
Reserve = weapon.Value.ReserveAmmo.Length >= 1 ? weapon.Value.ReserveAmmo[0] : 0,
});
}
}
return list.Count == 0 ? null : [.. list];
return (list.Count == 0 ? null : [.. list], haveC4);
}
private static void GiveWeapons(CCSPlayerController player, string[]? weapons, bool addC4)
private static void GiveWeapons(CCSPlayerController player, WeaponInfo[]? weapons, bool addC4)
{
if (weapons == null) return;
uint index = player.Index;
foreach (var weapon in weapons)
if (weapon != "weapon_c4")
player.GiveNamedItem(weapon);
player.GiveNamedItem(weapon.Name);
if (addC4)
player.GiveNamedItem("weapon_c4");
Server.NextFrame(() =>
{
var player = Utilities.GetPlayerFromIndex((int)index);
if (player == null || !player.IsValid) return;
var pawn = player.PlayerPawn.Value;
if (pawn == null || !pawn.IsValid) return;
if (pawn.WeaponServices == null) return;
foreach (var item in pawn.WeaponServices.MyWeapons)
if (item != null && item.IsValid)
{
var weapon = item.Value;
if (weapon == null || !weapon.IsValid || string.IsNullOrEmpty(weapon.DesignerName)) continue;
var enemyWeapon = weapons.FirstOrDefault(w => w.Name == SkillUtils.GetDesignerName(weapon));
if (enemyWeapon == null) continue;
weapon.Clip1 = enemyWeapon.Clip1;
weapon.Clip2 = enemyWeapon.Clip2;
weapon.ReserveAmmo.Fill(enemyWeapon.Reserve);
Utilities.SetStateChanged(weapon, "CBasePlayerWeapon", "m_iClip1");
Utilities.SetStateChanged(weapon, "CBasePlayerWeapon", "m_iClip2");
Utilities.SetStateChanged(weapon, "CBasePlayerWeapon", "m_pReserveAmmo");
}
});
}
private static CCSPlayerController? GetRandomEnemy(CCSPlayerController player)
@ -199,6 +247,15 @@ namespace src.player.skills
public bool HaveWeapon { get; set; }
}
public class WeaponInfo
{
public required string Name { get; set; }
public required int Clip1 { get; set; }
public required int Clip2 { get; set; }
public required int Reserve { get; set; }
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#c7e03a", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, float cooldown = 30f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public float Cooldown { get; set; } = cooldown;

View file

@ -11,6 +11,7 @@ namespace src.player.skills
{
private const Skills skillName = Skills.Weightless;
private readonly static ConcurrentDictionary<uint, byte> nades = [];
private readonly static ConcurrentDictionary<uint, int> playersWithSkill = [];
public static void LoadSkill()
{
@ -79,13 +80,69 @@ namespace src.player.skills
});
}
public static void EnableSkill(CCSPlayerController player)
public static void GrenadeThrown(EventGrenadeThrown @event)
{
SkillUtils.TryGiveWeapon(player, CsItem.HEGrenade);
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Weapon;
if (weapon != "hegrenade") return;
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
if (playerInfo?.Skill != skillName) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
{
playersWithSkill[player.Index] = grenadesLeft - 1;
player!.GiveNamedItem($"weapon_{weapon}");
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadesLeft - 1);
}
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8f6dc9", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
public static void WeaponEquip(EventItemEquip @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
var weapon = @event.Item;
if (player == null || !player.IsValid) return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadesLeft);
}
public static void WeaponPickup(EventItemPickup @event)
{
var player = PlayerManager.GetPlayerEvent(@event.Userid);
if (player == null || !player.IsValid) return;
var weapon = @event.Item;
if (string.IsNullOrEmpty(weapon) || weapon != "hegrenade") return;
if (playersWithSkill.TryGetValue(player.Index, out int grenadesLeft) && grenadesLeft > 1)
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadesLeft);
}
public static void EnableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
int grenadeLimit = SkillsInfo.GetValue<int>(skillName, "grenadeLimit");
playersWithSkill.TryAdd(player.Index, grenadeLimit);
SkillUtils.TryGiveWeapon(player, CsItem.HEGrenade);
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, grenadeLimit);
}
public static void DisableSkill(CCSPlayerController player)
{
if (player == null || !player.IsValid) return;
playersWithSkill.TryRemove(player.Index, out _);
SkillUtils.UpdateGrenadeCount(player, CsItem.HEGrenade, 1);
}
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8f6dc9", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int maxPerServer = -1, Rarity rarity = Rarity.Common, int grenadeLimit = 2) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, maxPerServer, rarity)
{
public int GrenadeLimit { get; set; } = grenadeLimit;
}
}
}

View file

@ -0,0 +1,101 @@
// https://discord.com/channels/1160907911501991946/1508172390863994910/1508180670659166348
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory;
namespace jRandomSkills.src.utils
{
#region Native Structs
[StructLayout(LayoutKind.Sequential)]
public unsafe struct CUtlMemory<T> where T : unmanaged
{
public T* m_pMemory;
public int m_nAllocationCount;
public int m_nGrowSize;
}
[StructLayout(LayoutKind.Sequential)]
public unsafe struct CUtlVector<T> where T : unmanaged
{
public int m_Size;
public CUtlMemory<T> m_Memory;
public int Count => m_Size;
public ref T Element(int index)
{
if (index < 0 || index >= m_Size)
throw new IndexOutOfRangeException();
return ref m_Memory.m_pMemory[index];
}
}
#endregion
#region Network Services
public class INetworkServerService : NativeObject
{
private readonly VirtualFunctionWithReturn<nint, nint> GetIGameServerFunc;
public INetworkServerService() : base(NativeAPI.GetValveInterface(0, "NetworkServerService_001"))
{
GetIGameServerFunc = new VirtualFunctionWithReturn<nint, nint>(Handle, GameData.GetOffset("INetworkServerService_GetIGameServer"));
}
public INetworkGameServer GetIGameServer()
{
return new INetworkGameServer(GetIGameServerFunc.Invoke(Handle));
}
}
public unsafe class INetworkGameServer(nint ptr) : NativeObject(ptr)
{
private static readonly int SlotsOffset = GameData.GetOffset("INetworkGameServer_Slots");
private ref CUtlVector<nint> Slots => ref Unsafe.AsRef<CUtlVector<nint>>((void*)(Handle + SlotsOffset));
public CServerSideClient? GetClientBySlot(int slot)
{
if (slot < 0 || slot >= Slots.Count)
return null;
var ptr = Slots.Element(slot);
if (ptr == nint.Zero)
return null;
return new CServerSideClient(ptr);
}
}
#endregion
#region CServerSideClient
public unsafe class CServerSideClient(nint ptr) : NativeObject(ptr)
{
private static readonly int m_nDeltaTick = GameData.GetOffset("CServerSideClient_m_nDeltaTick");
private ref T Field<T>(int offset) where T : unmanaged
{
return ref Unsafe.AsRef<T>((void*)(Handle + offset));
}
public int DeltaTick
{
get => Field<int>(m_nDeltaTick);
set => Field<int>(m_nDeltaTick) = value;
}
public void ForceFullUpdate() => DeltaTick = -1;
}
#endregion
}

View file

@ -131,6 +131,7 @@ namespace src.utils
new LanguageInfo("PT-BR, PT, BR, AO, CV, GW, MZ, ST, TL", "pt-br"),
new LanguageInfo("FR, MC, HT", "fr"),
new LanguageInfo("DE, AT, CH, LI, LU, BE", "de"),
new LanguageInfo("RU, KZ, BY, KG, TJ, UZ, TM, AM, AZ, GE, MD", "ru"),
new LanguageInfo("TR", "tr"),
new LanguageInfo("CZ", "cs"),
new LanguageInfo("PL", "pl"),

View file

@ -4,8 +4,10 @@ using CounterStrikeSharp.API.Modules.Cvars;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API.Modules.Timers;
using CounterStrikeSharp.API.Modules.UserMessages;
using CounterStrikeSharp.API.Modules.Utils;
using jRandomSkills.src.utils;
using src.player;
using src.player.skills;
using System.Collections.Concurrent;
@ -56,7 +58,30 @@ namespace src.utils
SkillData.Skills.Add(new jSkill_SkillInfo(skill, color, display));
}
public static void TryGiveWeapon(CCSPlayerController player, CsItem item, int count = 1)
public static void UpdateGrenadeCount(CCSPlayerController player, CsItem item, int ammo)
{
string? itemString = EnumUtils.GetEnumMemberAttributeValue(item);
if (string.IsNullOrWhiteSpace(itemString)) return;
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid) return;
if (player.PlayerPawn.Value.WeaponServices == null) return;
var weapon = player.PlayerPawn.Value.WeaponServices.MyWeapons
.FirstOrDefault(w => w != null && w.IsValid && w.Value != null && w.Value.IsValid && !string.IsNullOrEmpty(w.Value.DesignerName) && w.Value.DesignerName == itemString);
if (weapon == null || !weapon.IsValid || weapon.Value == null || !weapon.Value.IsValid) return;
weapon.Value.Clip1 = ammo;
Utilities.SetStateChanged(weapon.Value, "CBasePlayerWeapon", "m_iClip1");
jRandomSkills.Instance.AddTimer(.1f, () =>
{
if (weapon == null || !weapon.IsValid || weapon.Value == null || !weapon.Value.IsValid) return;
weapon.Value.Clip1 = 1;
}, TimerFlags.STOP_ON_MAPCHANGE);
}
public static void TryGiveWeapon(CCSPlayerController player, CsItem item, int count = 1, bool existValidator = true)
{
string? itemString = EnumUtils.GetEnumMemberAttributeValue(item);
if (string.IsNullOrWhiteSpace(itemString)) return;
@ -66,7 +91,8 @@ namespace src.utils
var exists = player.PlayerPawn.Value.WeaponServices.MyWeapons
.FirstOrDefault(w => w != null && w.IsValid && w.Value != null && w.Value.IsValid && w.Value.DesignerName == itemString);
if (exists == null)
if (exists == null || !existValidator)
for (int i = 0; i < count; i++)
player.GiveNamedItem(item);
}
@ -259,6 +285,9 @@ namespace src.utils
var jester = Jester.GetJesterInfo(player.Index);
if (jester?.Active == true) return false;
if (playerInfo.Skill == Skills.GodMode && GodMode.HaveHodMode(player.Index))
return false;
}
int newHealth = (int)(pawn.Health - damage);
@ -291,9 +320,35 @@ namespace src.utils
return EntityManager.CreateTrackedTrigger(ownerPlayerIndex, name, radius, pos);
}
public static void ForceFullUpdate(CCSPlayerController player)
{
if (player == null || !player.IsValid)
return;
var pawn = player.PlayerPawn?.Value;
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
QAngle lastAngle = new(pawn.V_angle.X, pawn.V_angle.Y, pawn.V_angle.Z);
INetworkServerService networkServerService = new();
INetworkGameServer networkGameServer = networkServerService.GetIGameServer();
var client = networkGameServer.GetClientBySlot(player.Slot);
if (client == null) return;
client.ForceFullUpdate();
pawn.Look(lastAngle);
}
public static void ForceFullUpdateToAll()
{
foreach (var player in Utilities.GetPlayers())
ForceFullUpdate(player);
}
public static bool AddHealth(CCSPlayerPawn? pawn, int extraHealth, int? maxHealth = null)
{
if (pawn == null || !pawn.IsValid || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
if (pawn == null || !pawn.IsValid || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE || pawn.Health <= 0)
return false;
maxHealth ??= pawn.MaxHealth;
@ -381,6 +436,18 @@ namespace src.utils
return manager.HasMenu(player);
}
private static string GetInvisibleSignature(string id)
{
if (string.IsNullOrEmpty(id)) return "";
var sb = new System.Text.StringBuilder();
foreach (char c in id)
for (int i = 0; i < 8; i++)
sb.Append(((c >> i) & 1) == 1 ? "\u200B" : "\u200C");
return sb.ToString();
}
public static void UpdateMenu(CCSPlayerController? player, ConcurrentBag<(string, string)> items)
{
if (player == null) return;
@ -395,13 +462,19 @@ namespace src.utils
Dictionary<string, Action<CCSPlayerController, IWasdMenuOption>> list = [];
foreach (var item in items)
list.TryAdd(isIlliterate
{
string encodedText = isIlliterate
? System.Net.WebUtility.HtmlEncode(Illiterate.GetRandomText(item.Item1)!)
: System.Net.WebUtility.HtmlEncode(item.Item1), (p, option) =>
: System.Net.WebUtility.HtmlEncode(item.Item1);
string uniqueKey = GetInvisibleSignature(item.Item2) + $"\u202A{encodedText}\u202C";
list.TryAdd(uniqueKey, (p, option) =>
{
jRandomSkills.Instance.SkillAction(playerInfo.Skill.ToString(), "TypeSkill", [p, new[] { item.Item2 }]);
manager.CloseMenu(p);
});
}
manager.UpdateActiveMenu(player, list);
}
@ -445,11 +518,11 @@ namespace src.utils
string infoLine = string.IsNullOrEmpty(your_skill)
? ""
: $"<font class='fontWeight-Bold fontSize-{config.HeaderLineSize}' color='{config.HeaderLineColor}'>{your_skill}:</font><br>";
: $"<font class='fontWeight-Bold fontSize-{config.HeaderLineSize}' color='{config.HeaderLineColor}'>\u202A{your_skill}:\u202C</font><br>";
string skillLine = Illiterate.CheckIlliterateSkill(player)
? $"<font class='fontWeight-Bold fontSize-{config.SkillLineSize}'>{Illiterate.GetRandomText(player.GetSkillName(skillData.Skill))}</font><br>"
: $"<font class='fontWeight-Bold fontSize-{config.SkillLineSize}' color='{skillData.Color}'>{player.GetSkillName(skillData.Skill)}</font><br>";
? $"<font class='fontWeight-Bold fontSize-{config.SkillLineSize}'>\u202A{Illiterate.GetRandomText(player.GetSkillName(skillData.Skill))}\u202C</font><br>"
: $"<font class='fontWeight-Bold fontSize-{config.SkillLineSize}' color='{skillData.Color}'>\u202A{player.GetSkillName(skillData.Skill)}\u202C</font><br>";
var skill_select_info = player.GetTranslation($"{playerInfo.Skill.ToString().ToLower()}_select_info");
string remainingLine = string.IsNullOrWhiteSpace(skill_select_info)
@ -470,22 +543,34 @@ namespace src.utils
IWasdMenu menu = manager.CreateMenu(hudContent, itemText, itemHoverText, controllsLine);
foreach (var enemy in enemies)
menu.Add(isIlliterate
{
string encodedEnemyName = isIlliterate
? System.Net.WebUtility.HtmlEncode(Illiterate.GetRandomText(enemy.Item1)!)
: System.Net.WebUtility.HtmlEncode(enemy.Item1), (p, option) =>
: System.Net.WebUtility.HtmlEncode(enemy.Item1);
string uniqueKey = GetInvisibleSignature(enemy.Item2) + $"\u202A{encodedEnemyName}\u202C";
menu.Add(uniqueKey, (p, option) =>
{
jRandomSkills.Instance.SkillAction(playerInfo.Skill.ToString(), "TypeSkill", [p, new[] { enemy.Item2 }]);
manager.CloseMenu(p);
});
}
if (lastElement != null)
menu.Add(isIlliterate
{
string encodedLastElement = isIlliterate
? System.Net.WebUtility.HtmlEncode(Illiterate.GetRandomText(lastElement.Value.Item1)!)
: System.Net.WebUtility.HtmlEncode(lastElement.Value.Item1), (p, option) =>
: System.Net.WebUtility.HtmlEncode(lastElement.Value.Item1);
menu.Add($"\u202A{encodedLastElement}\u202C", (p, option) =>
{
jRandomSkills.Instance.SkillAction(playerInfo.Skill.ToString(), "TypeSkill", [p, new[] { lastElement.Value.Item2 }]);
if (lastElement.Value.Item3)
manager.CloseMenu(p);
});
}
manager.OpenMainMenu(player, menu);
}