commit
ca5ea47e89
59 changed files with 2248 additions and 458 deletions
|
|
@ -31,7 +31,7 @@ namespace src
|
|||
public override string ModuleName => "[CS2] [ jRandomSkills ]";
|
||||
public override string ModuleAuthor => "D3X (Original), Juzlus (Modifier), ByDexterTR (Contributor)";
|
||||
public override string ModuleDescription => "Plugin adds random skills every round for CS2 by D3X. Modified by Juzlus.";
|
||||
public override string ModuleVersion => "1.2.3.b4";
|
||||
public override string ModuleVersion => "1.2.3.b5";
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
|
|
@ -386,6 +386,10 @@ namespace src
|
|||
{
|
||||
public static ConcurrentBag<jSkill_SkillInfo> Skills { get; } = [];
|
||||
|
||||
private static jSkill_SkillInfo[]? _snapshot;
|
||||
|
||||
public static jSkill_SkillInfo[] GetSnapshot() => _snapshot ??= [.. Skills];
|
||||
|
||||
private static Dictionary<Skills, jSkill_SkillInfo>? _bySkill;
|
||||
|
||||
public static jSkill_SkillInfo? GetInfo(Skills skill)
|
||||
|
|
@ -401,7 +405,11 @@ namespace src
|
|||
return map.TryGetValue(skill, out var info) ? info : null;
|
||||
}
|
||||
|
||||
public static void Invalidate() => _bySkill = null;
|
||||
public static void Invalidate()
|
||||
{
|
||||
_bySkill = null;
|
||||
_snapshot = null;
|
||||
}
|
||||
}
|
||||
|
||||
public enum CS2ConsoleColors
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"none": "Keine",
|
||||
"none_desc": "Du hast keine Fertigkeit",
|
||||
|
||||
|
|
@ -77,6 +77,11 @@
|
|||
"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} %",
|
||||
|
||||
"chameleon": "Chamäleon",
|
||||
"chameleon_desc": "Der erste Spieler, den du tötest, gibt dir seine Fähigkeit",
|
||||
"chameleon_copied_info": "Fähigkeit kopiert: {0}",
|
||||
"chameleon_wrong_team_info": "'{0}' hatte eine Fähigkeit, die dein Team nicht nutzen kann.",
|
||||
|
||||
"chicken": "Huhn",
|
||||
"chicken_desc": "Du erhältst ein Huhn-Modell + 10 % schnellere Bewegung – 50 HP",
|
||||
|
||||
|
|
@ -220,6 +225,11 @@
|
|||
"godmode_off": "Unsterblichkeit deaktiviert",
|
||||
"godmode_on": "Unsterblichkeit aktiviert",
|
||||
|
||||
"grapple": "Enterhaken",
|
||||
"grapple_desc": "Drücke [css_useSkill], um einen Haken auf den anvisierten Punkt zu schießen und dich dorthin zu ziehen",
|
||||
"grapple_no_anchor_info": "Keine Oberfläche zum Einhaken.",
|
||||
"grapple_pulling_info": "ZUG",
|
||||
|
||||
"grenadier": "Grenadier",
|
||||
"grenadier_desc": "Du hast unendlich viele Granaten",
|
||||
|
||||
|
|
@ -259,6 +269,11 @@
|
|||
"infiniteammo": "Unendliche Munition",
|
||||
"infiniteammo_desc": "Du erhältst unendliche Munition für alle deine Waffen",
|
||||
|
||||
"inheritance": "Erbe",
|
||||
"inheritance_desc": "Wenn ein Teamkollege stirbt, kannst du seine Fähigkeit übernehmen",
|
||||
"inheritance_select_info": "Wähle die Fähigkeit, die du erbst:",
|
||||
"inheritance_player_info": "Du hast die Fähigkeit von '{0}' geerbt.",
|
||||
|
||||
"jackal": "Spürhund",
|
||||
"jackal_desc": "Jeder Gegner hinterlässt eine Spur",
|
||||
|
||||
|
|
@ -448,6 +463,9 @@
|
|||
"richboy": "Rich Boy",
|
||||
"richboy_desc": "Du erhältst zu Beginn der Runde einen zufälligen Geldbetrag",
|
||||
|
||||
"ricochet": "Querschläger",
|
||||
"ricochet_desc": "Deine Kugeln prallen von Wänden ab und können Gegner weiterhin treffen",
|
||||
|
||||
"robinhood": "Robin Hood",
|
||||
"robinhood_desc": "Wenn du einem Gegner Schaden zufügst, stiehlst du ihm sein Geld",
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"none": "None",
|
||||
"none_desc": "You have no skill",
|
||||
|
||||
|
|
@ -77,6 +77,11 @@
|
|||
"catapult_desc": "You have a random chance to launch an enemy upwards",
|
||||
"catapult_desc2": "Your chance to launch an enemy on hit is: {0}%",
|
||||
|
||||
"chameleon": "Chameleon",
|
||||
"chameleon_desc": "The first player you kill gives you their skill",
|
||||
"chameleon_copied_info": "You copied the skill: {0}",
|
||||
"chameleon_wrong_team_info": "'{0}' had a skill your team cannot use.",
|
||||
|
||||
"chicken": "Chicken",
|
||||
"chicken_desc": "You get a chicken model + 10% faster movement - 50 HP",
|
||||
|
||||
|
|
@ -213,6 +218,11 @@
|
|||
"godmode_off": "Immortality disabled",
|
||||
"godmode_on": "Immortality enabled",
|
||||
|
||||
"grapple": "Grapple Hook",
|
||||
"grapple_desc": "Press [css_useSkill] to fire a hook at the point you are aiming at and pull yourself there",
|
||||
"grapple_no_anchor_info": "No surface to hook onto.",
|
||||
"grapple_pulling_info": "PULLING",
|
||||
|
||||
"grenadier": "Grenadier",
|
||||
"grenadier_desc": "You have infinite hegrenade",
|
||||
|
||||
|
|
@ -252,6 +262,11 @@
|
|||
"infiniteammo": "Infinite Ammo",
|
||||
"infiniteammo_desc": "You receive infinite ammo for all your weapons",
|
||||
|
||||
"inheritance": "Inheritance",
|
||||
"inheritance_desc": "When a teammate dies you can take over their skill",
|
||||
"inheritance_select_info": "Choose the skill you inherit:",
|
||||
"inheritance_player_info": "You inherited the skill of '{0}'.",
|
||||
|
||||
"jackal": "Tracker",
|
||||
"jackal_desc": "Every opponent leaves a trail behind them",
|
||||
|
||||
|
|
@ -448,6 +463,9 @@
|
|||
"richboy": "Rich Boy",
|
||||
"richboy_desc": "You receive a random amount of money at the start of the round",
|
||||
|
||||
"ricochet": "Ricochet",
|
||||
"ricochet_desc": "Your bullets bounce off walls and can still hit enemies",
|
||||
|
||||
"robinhood": "Robin Hood",
|
||||
"robinhood_desc": "Dealing damage to an enemy steals their money",
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"none": "Aucune",
|
||||
"none_desc": "Vous n’avez aucune compétence",
|
||||
|
||||
|
|
@ -77,6 +77,11 @@
|
|||
"catapult_desc": "Vous avez une chance aléatoire de projeter un ennemi en l’air",
|
||||
"catapult_desc2": "Votre chance de projeter un ennemi à l’impact est : {0}%",
|
||||
|
||||
"chameleon": "Caméléon",
|
||||
"chameleon_desc": "Le premier joueur que vous tuez vous donne sa compétence",
|
||||
"chameleon_copied_info": "Compétence copiée : {0}",
|
||||
"chameleon_wrong_team_info": "'{0}' avait une compétence que votre équipe ne peut pas utiliser.",
|
||||
|
||||
"chicken": "Poulet",
|
||||
"chicken_desc": "Vous obtenez un modèle de poulet + 10% de vitesse de déplacement en plus - 50 PV",
|
||||
|
||||
|
|
@ -220,6 +225,11 @@
|
|||
"godmode_off": "Immortalité désactivée",
|
||||
"godmode_on": "Immortalité activée",
|
||||
|
||||
"grapple": "Grappin",
|
||||
"grapple_desc": "Appuyez sur [css_useSkill] pour lancer un grappin sur le point visé et vous y propulser",
|
||||
"grapple_no_anchor_info": "Aucune surface pour accrocher le grappin.",
|
||||
"grapple_pulling_info": "TRACTION",
|
||||
|
||||
"grenadier": "Grenadier",
|
||||
"grenadier_desc": "Tu as des grenades HE infinies",
|
||||
|
||||
|
|
@ -259,6 +269,11 @@
|
|||
"infiniteammo": "Munitions Infinies",
|
||||
"infiniteammo_desc": "Vous recevez des munitions infinies pour toutes vos armes",
|
||||
|
||||
"inheritance": "Héritage",
|
||||
"inheritance_desc": "Quand un coéquipier meurt, vous pouvez reprendre sa compétence",
|
||||
"inheritance_select_info": "Choisissez la compétence à hériter :",
|
||||
"inheritance_player_info": "Vous avez hérité de la compétence de '{0}'.",
|
||||
|
||||
"jackal": "Traqueur",
|
||||
"jackal_desc": "Chaque adversaire laisse une trace derrière lui",
|
||||
|
||||
|
|
@ -448,6 +463,9 @@
|
|||
"richboy": "Gosse de Riche",
|
||||
"richboy_desc": "Vous recevez une somme d’argent aléatoire au début du round",
|
||||
|
||||
"ricochet": "Ricochet",
|
||||
"ricochet_desc": "Vos balles rebondissent sur les murs et peuvent encore toucher les ennemis",
|
||||
|
||||
"robinhood": "Robin des Bois",
|
||||
"robinhood_desc": "Infliger des dégâts à un ennemi lui vole de l’argent",
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"none": "Brak",
|
||||
"none_desc": "Nie posiadasz żadnej supermocy",
|
||||
|
||||
|
|
@ -77,6 +77,11 @@
|
|||
"catapult_desc": "Masz losową szanse na podrzucenie wroga",
|
||||
"catapult_desc2": "Twoje szanse na podrzucenie wroga po trafieniu to: {0}%",
|
||||
|
||||
"chameleon": "Kameleon",
|
||||
"chameleon_desc": "Pierwszy zabity gracz oddaje ci swoją umiejętność",
|
||||
"chameleon_copied_info": "Skopiowano umiejętność: {0}",
|
||||
"chameleon_wrong_team_info": "'{0}' miał umiejętność, której twoja drużyna nie może użyć.",
|
||||
|
||||
"chicken": "Kurczak",
|
||||
"chicken_desc": "Otrzymujesz model kurczaka + jesteś o 10% szybszy - 50hp",
|
||||
|
||||
|
|
@ -220,6 +225,11 @@
|
|||
"godmode_off": "Nieśmiertelność wyłączona",
|
||||
"godmode_on": "Nieśmiertelność włączona",
|
||||
|
||||
"grapple": "Hak",
|
||||
"grapple_desc": "Naciśnij [css_useSkill], aby wystrzelić hak w celowany punkt i przyciągnąć się do niego",
|
||||
"grapple_no_anchor_info": "Brak powierzchni do zaczepienia haka.",
|
||||
"grapple_pulling_info": "PRZYCIĄGANIE",
|
||||
|
||||
"grenadier": "Granatnik",
|
||||
"grenadier_desc": "Masz nieskończone granaty odłamkowe",
|
||||
|
||||
|
|
@ -259,6 +269,11 @@
|
|||
"infiniteammo": "Nieskończone Ammo",
|
||||
"infiniteammo_desc": "Otrzymujesz nieskończoną ilość amunicji do wszystkich broni",
|
||||
|
||||
"inheritance": "Spadek",
|
||||
"inheritance_desc": "Gdy członek drużyny ginie, możesz przejąć jego umiejętność",
|
||||
"inheritance_select_info": "Wybierz dziedziczoną umiejętność:",
|
||||
"inheritance_player_info": "Odziedziczyłeś umiejętność gracza '{0}'.",
|
||||
|
||||
"jackal": "Stópkarz",
|
||||
"jackal_desc": "Każdy przeciwnik pozostawia za sobą ślad",
|
||||
|
||||
|
|
@ -448,6 +463,9 @@
|
|||
"richboy": "Bogacz",
|
||||
"richboy_desc": "Na początku rundy otrzymujesz losową kwotę gotówki",
|
||||
|
||||
"ricochet": "Rykoszet",
|
||||
"ricochet_desc": "Twoje pociski odbijają się od ścian i nadal mogą trafić przeciwników",
|
||||
|
||||
"robinhood": "Robin Hood",
|
||||
"robinhood_desc": "Zadanie obrażeń przeciwnikowi powoduje kradzież jego pieniędzy",
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"none": "Nenhuma",
|
||||
"none_desc": "Você não tem nenhuma habilidade",
|
||||
|
||||
|
|
@ -77,6 +77,11 @@
|
|||
"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}%",
|
||||
|
||||
"chameleon": "Camaleão",
|
||||
"chameleon_desc": "O primeiro jogador que você matar lhe dá a habilidade dele",
|
||||
"chameleon_copied_info": "Habilidade copiada: {0}",
|
||||
"chameleon_wrong_team_info": "'{0}' tinha uma habilidade que sua equipe não pode usar.",
|
||||
|
||||
"chicken": "Galinha",
|
||||
"chicken_desc": "Você é uma galinha com +10% de movimento mais rápido e -50 HP",
|
||||
|
||||
|
|
@ -220,6 +225,11 @@
|
|||
"godmode_off": "Imortalidade desativada",
|
||||
"godmode_on": "Imortalidade ativada",
|
||||
|
||||
"grapple": "Gancho",
|
||||
"grapple_desc": "Pressione [css_useSkill] para lançar um gancho no ponto mirado e se puxar até lá",
|
||||
"grapple_no_anchor_info": "Nenhuma superfície para prender o gancho.",
|
||||
"grapple_pulling_info": "PUXANDO",
|
||||
|
||||
"grenadier": "Bomberman",
|
||||
"grenadier_desc": "Você tem HEs infinitas",
|
||||
|
||||
|
|
@ -259,6 +269,11 @@
|
|||
"infiniteammo": "Munição Infinita",
|
||||
"infiniteammo_desc": "Você recebe munição infinita para todas as suas armas",
|
||||
|
||||
"inheritance": "Herança",
|
||||
"inheritance_desc": "Quando um companheiro de equipe morre, você pode assumir a habilidade dele",
|
||||
"inheritance_select_info": "Escolha a habilidade que você herda:",
|
||||
"inheritance_player_info": "Você herdou a habilidade de '{0}'.",
|
||||
|
||||
"jackal": "Lesma",
|
||||
"jackal_desc": "Cada adversário deixa um rastro atrás de si",
|
||||
|
||||
|
|
@ -448,6 +463,9 @@
|
|||
"richboy": "Filhinho de Papai",
|
||||
"richboy_desc": "Você recebe uma quantidade aleatória de dinheiro no início da rodada",
|
||||
|
||||
"ricochet": "Ricochete",
|
||||
"ricochet_desc": "Suas balas ricocheteiam nas paredes e ainda podem acertar inimigos",
|
||||
|
||||
"robinhood": "Robin Hood",
|
||||
"robinhood_desc": "Atirar em um inimigo rouba seu dinheiro",
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"none": "Нет навыка",
|
||||
"none_desc": "У вас нет навыка",
|
||||
|
||||
|
|
@ -77,6 +77,11 @@
|
|||
"catapult_desc": "Есть шанс подбросить врага вверх при попадании",
|
||||
"catapult_desc2": "Ваш шанс подбросить врага при попадании: {0}%",
|
||||
|
||||
"chameleon": "Хамелеон",
|
||||
"chameleon_desc": "Первый убитый вами игрок отдаёт свой навык",
|
||||
"chameleon_copied_info": "Навык скопирован: {0}",
|
||||
"chameleon_wrong_team_info": "У '{0}' был навык, недоступный вашей команде.",
|
||||
|
||||
"chicken": "Курица",
|
||||
"chicken_desc": "Вы получаете модель курицы + 10% к скорости передвижения - 50 HP",
|
||||
|
||||
|
|
@ -220,6 +225,11 @@
|
|||
"godmode_off": "Неуязвимость отключена",
|
||||
"godmode_on": "Неуязвимость включена",
|
||||
|
||||
"grapple": "Крюк",
|
||||
"grapple_desc": "Нажмите [css_useSkill], чтобы выстрелить крюком в точку прицеливания и притянуться к ней",
|
||||
"grapple_no_anchor_info": "Нет поверхности для зацепа.",
|
||||
"grapple_pulling_info": "ПРИТЯГИВАНИЕ",
|
||||
|
||||
"grenadier": "Гренадёр",
|
||||
"grenadier_desc": "У вас бесконечные осколочные гранаты",
|
||||
|
||||
|
|
@ -259,6 +269,11 @@
|
|||
"infiniteammo": "Бесконечные патроны",
|
||||
"infiniteammo_desc": "Вы получаете бесконечные патроны для всего оружия",
|
||||
|
||||
"inheritance": "Наследие",
|
||||
"inheritance_desc": "Когда союзник погибает, вы можете перенять его навык",
|
||||
"inheritance_select_info": "Выберите наследуемый навык:",
|
||||
"inheritance_player_info": "Вы унаследовали навык игрока '{0}'.",
|
||||
|
||||
"jackal": "Трекер",
|
||||
"jackal_desc": "Каждый противник оставляет за собой след",
|
||||
|
||||
|
|
@ -448,6 +463,9 @@
|
|||
"richboy": "Богач",
|
||||
"richboy_desc": "Вы получаете случайную сумму денег в начале раунда",
|
||||
|
||||
"ricochet": "Рикошет",
|
||||
"ricochet_desc": "Ваши пули отскакивают от стен и могут поразить врагов",
|
||||
|
||||
"robinhood": "Робин Гуд",
|
||||
"robinhood_desc": "Нанесение урона врагу крадёт его деньги",
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"none": "Yok",
|
||||
"none_desc": "Hiçbir yeteneğin yok",
|
||||
|
||||
|
|
@ -6,79 +6,84 @@
|
|||
"aimbot_desc": "Vurduğunda kafadan (HS) sayılır",
|
||||
|
||||
"aimlock": "Kitlenme",
|
||||
"aimlock_desc": "En yakın düşmana nişan almak için [css_useSkill] tuşuna basın",
|
||||
"aimlock_desc": "[css_useSkill] tuşuna basarak en yakın düşmana kitlen",
|
||||
|
||||
"anomaly": "Zaman Büken",
|
||||
"anomaly_desc": "[css_useSkill] tuşuna basarak zamanı birkaç saniye geriye alırsın",
|
||||
"anomaly_desc": "[css_useSkill] tuşuna basarak zamanı birkaç saniye geri al",
|
||||
|
||||
"antyflash": "Anti-Flash",
|
||||
"antyflash_desc": "Flaşa kör olmazsın ve flaşların 7 saniye sürer",
|
||||
"antyflash_desc": "Kör olmazsın ve flaşın 7 saniye sürer",
|
||||
|
||||
"antyhead": "Beton Kafa",
|
||||
"antyhead_desc": "Kafadan hasar almazsın",
|
||||
|
||||
"areareaper": "Mekan Kapatan",
|
||||
"areareaper_desc": "Haritadaki bir bomba alanını tamamen devre dışı bırakabilirsin",
|
||||
"areareaper_desc": "Haritadaki bir bomba alanını devre dışı bırak",
|
||||
"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} Bölgesi kapandı - artık buraya bomba kurulamaz!",
|
||||
"areareaper_used_info": "Yeteneğini zaten kullandın, açgözlülük yapma",
|
||||
"areareaper_select_info": "Alan seçin:",
|
||||
"areareaper_site_disabled": "{0} Bölgesi kapandı - artık buraya C4 kurulamaz!",
|
||||
"areareaper_used_info": "Yeteneğini zaten kullandın!",
|
||||
"areareaper_teammates_info": "{0} Bölgesi bomba kurmaya kapatıldı.",
|
||||
"areareaper_bombsite_disabled": "Bu bomba alanı kullanıma kapatıldı!",
|
||||
"areareaper_bombsite_disabled": "Bu bomba alanı kullanıma kapatıldı.",
|
||||
|
||||
"armored": "Zırhlı",
|
||||
"armored_desc": "Rastgele hasar alma çarpanına sahip olursun",
|
||||
"armored_desc": "Rastgele hasar alma çarpanın olur",
|
||||
"armored_desc2": "Hasar alma: {0}x",
|
||||
|
||||
"assassin": "Suikastçı",
|
||||
"assassin_desc": "Düşmanlara arkadan daha fazla hasar verirsin",
|
||||
"assassin_desc": "Düşmana arkadan daha fazla hasar verirsin",
|
||||
|
||||
"astronaut": "Astronot",
|
||||
"astronaut_desc": "Rastgele bir yerçekimi değerine sahip olursun",
|
||||
"astronaut_desc": "Rastgele bir yerçekimine sahipsin",
|
||||
"astronaut_desc2": "Yerçekimin: {0}x",
|
||||
|
||||
"moneyswap": "Vergi Memuru",
|
||||
"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:",
|
||||
"moneyswap_enemy_info": "Maliye kapına dayandı.",
|
||||
"moneyswap_player_info": "'{0}' ile paranı takasladın.",
|
||||
"moneyswap_select_info": "Birini seçin:",
|
||||
|
||||
"baseball": "Beyzbolcu",
|
||||
"baseball_desc": "Yanıltıcı bomban (decoy) duvarlardan seker ve çarptığı düşmanı öldürür",
|
||||
"baseball_desc": "Yanıltıcı bomban duvarlardan seker ve çarptığı düşmanı öldürür",
|
||||
|
||||
"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}",
|
||||
|
||||
"berserker": "Berserker",
|
||||
"berserker_desc": "Canın azaldıkça hasarın artar ve daha hızlanırsın",
|
||||
"berserker_desc": "Canın azaldıkça hasarın ve hızın artar",
|
||||
|
||||
"blademaster": "Kılıç Ustası",
|
||||
"blademaster_desc": "Bıçak tutarken mermileri sektirme şansın artar",
|
||||
"blademaster_desc": "Bıçak tutarken mermileri savuşturursun",
|
||||
|
||||
"blastshot": "Patlama Atışı",
|
||||
"blastshot_desc": "MP5 ile Sağ Tık'a basarak El bombası fırlat",
|
||||
"blastshot_desc": "MP5 ile sağ tıklayarak el bombası fırlat",
|
||||
|
||||
"bunnyhop": "Tavşan",
|
||||
"bunnyhop_desc": "Otomatik \"BunnyHop\" yaparsın",
|
||||
"bunnyhop_desc": "Otomatik BunnyHop yaparsın",
|
||||
|
||||
"c4camouflage": "C4 Kamuflaj",
|
||||
"c4camouflage_desc": "Elinde C4 varken tamamen görünmez olursun",
|
||||
"c4camouflage_desc": "Elinde C4 varken görünmezsin",
|
||||
|
||||
"carefulbullets": "Dikkatli Mermiler",
|
||||
"carefulbullets_desc": "Düşman mermi kaçırırsa hasar alır",
|
||||
"carefulbullets_enemy_info": "Mermi kaçırmak canını yakacak",
|
||||
"carefulbullets_enemy_info": "Mermi kaçırman can yakar.",
|
||||
"carefulbullets_disable_info": "Artık mermi kaçırmak can yakmayacak.",
|
||||
"carefulbullets_player_info": "'{0}' artık mermi sıkarken iki kere düşünecek",
|
||||
"carefulbullets_select_info": "İsabetsiz atışların hasar vereceği oyuncu:",
|
||||
"carefulbullets_player_info": "'{0}' mermi sıkarken iki kere düşünecek.",
|
||||
"carefulbullets_select_info": "Birini seçin:",
|
||||
|
||||
"catapult": "Mancınık",
|
||||
"catapult_desc": "Vurduğun rakibi uzaya (yukarı doğru) fırlatma şansın var",
|
||||
"catapult_desc2": "Fırlatma şansın: %{0}",
|
||||
|
||||
"chameleon": "Bukalemun",
|
||||
"chameleon_desc": "Öldürdüğün ilk oyuncunun yeteneği sana geçer",
|
||||
"chameleon_copied_info": "Yeteneği kopyaladın: {0}",
|
||||
"chameleon_wrong_team_info": "'{0}' takımının kullanamayacağı bir yeteneğe sahipti.",
|
||||
|
||||
"chicken": "Tavuk",
|
||||
"chicken_desc": "Tavuk modeli ve %10 daha hızlısın fakat 50 HP",
|
||||
"chicken_desc": "Tavuk modeli, %10 daha hızlı ama 50 HP",
|
||||
|
||||
"chillout": "Ağırdan Al",
|
||||
"chillout_desc": "Bombayı kurmak çok daha uzun sürer",
|
||||
|
|
@ -87,28 +92,28 @@
|
|||
"cutter_desc": "Bıçakla tek atarsın",
|
||||
|
||||
"cypher": "Gözcü",
|
||||
"cypher_desc": "Kamera oluşturmak/geçmek için [css_useSkill] tuşuna bas",
|
||||
"cypher_desc": "[css_useSkill] tuşuna basarak kamera kur ve kameraya geç",
|
||||
"cypher_nospace": "Kamerayı duvara dik yerleştir",
|
||||
|
||||
"darkness": "Karanlık",
|
||||
"darkness_desc": "Bir düşmanın ekranını karart",
|
||||
"darkness_enemy_info": "Işıklar sönsün",
|
||||
"darkness_desc": "Düşmanın ekranını karart",
|
||||
"darkness_enemy_info": "Işıklar sönsün.",
|
||||
"darkness_disable_info": "Işıklar geldi.",
|
||||
"darkness_player_info": "'{0}' isimli oyuncunun dünyasını kararttın",
|
||||
"darkness_select_info": "Karanlık bir oyuncuyu seç:",
|
||||
"darkness_player_info": "'{0}' ışıkları söndü.",
|
||||
"darkness_select_info": "Birini seçin:",
|
||||
|
||||
"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ç:",
|
||||
"deactivator_enemy_info": "Yeteneğin silindi.",
|
||||
"deactivator_player_info": "'{0}' isimli oyuncunun yeteneği silindi.",
|
||||
"deactivator_select_info": "Birini seçin:",
|
||||
|
||||
"deaf": "Sağır",
|
||||
"deaf_desc": "Bir düşmanın kulağını kapat ve sesleri duymaz hale getir",
|
||||
"deaf_enemy_info": "Kulaklıkların tıkandı",
|
||||
"deaf_desc": "Bir düşmanı sağır et",
|
||||
"deaf_enemy_info": "Kulaklıkların tıkandı.",
|
||||
"deaf_disable_info": "Kulakların açıldı.",
|
||||
"deaf_player_info": "'{0}' isimli oyuncu için sesler kapatıldı.",
|
||||
"deaf_select_info": "Sağır bir oyuncuyu seç:",
|
||||
"deaf_player_info": "'{0}' sesleri kapatıldı.",
|
||||
"deaf_select_info": "Birini seçin:",
|
||||
|
||||
"disarmament": "Silahsızlandırma",
|
||||
"disarmament_desc": "Vurduğunda rakibin elindeki silahı yere düşürme şansın olur",
|
||||
|
|
@ -121,15 +126,15 @@
|
|||
"dash_desc": "Atılmak için ikinci kez zıpla",
|
||||
|
||||
"dracula": "Drakula",
|
||||
"dracula_desc": "Rakiplere verdiğin hasarın belirli bir yüzdesi kadar can alırsın",
|
||||
"dracula_desc": "Rakibe verdiğin hasarın birazı kadar can alırsın",
|
||||
|
||||
"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:",
|
||||
"duplicator_desc": "Bir düşmanın yeteneğini kopyala",
|
||||
"duplicator_player_info": "'{0}' yeteneği kopyalandı.",
|
||||
"duplicator_select_info": "Birini seçin:",
|
||||
|
||||
"dwarf": "Cüce",
|
||||
"dwarf_desc": "Raund başında rastgele karakter boyutu",
|
||||
"dwarf_desc": "Rastgele karakter boyutu",
|
||||
"dwarf_desc2": "Boyutun: {0}x",
|
||||
|
||||
"enemyspawn": "Base Baskını",
|
||||
|
|
@ -137,16 +142,16 @@
|
|||
|
||||
"expensiveammo": "Pahalı Mermi",
|
||||
"expensiveammo_desc": "Seçtiğin rakip her ateş ettiğinde para kaybeder",
|
||||
"expensiveammo_disable_info": "Mermilerin yeniden bedava.",
|
||||
"expensiveammo_enemy_info": "Artık her atışın sana {0}$ mal oluyor.",
|
||||
"expensiveammo_player_info": "'{0}' artık her mermisinin parasını ödüyor.",
|
||||
"expensiveammo_select_info": "Mermisi pahalanacak oyuncu:",
|
||||
"expensiveammo_disable_info": "Mermi yeniden bedava.",
|
||||
"expensiveammo_enemy_info": "Her atışın sana {0}$ mal oluyor.",
|
||||
"expensiveammo_player_info": "'{0}' her mermisinin parasını ödüyor.",
|
||||
"expensiveammo_select_info": "Birini seçin:",
|
||||
|
||||
"explodingbarrel": "Patlayan Varil",
|
||||
"explodingbarrel_desc": "[css_useSkill] ile vurulunca patlayan bir varil koyarsın",
|
||||
"explodingbarrel_desc": "[css_useSkill] tuşuna basarak vurulunca patlayan varil koy",
|
||||
|
||||
"explosiveshot": "Patlayıcı Mermi",
|
||||
"explosiveshot_desc": "Ateş ederken rastgele mermilerin patlayabilir",
|
||||
"explosiveshot_desc": "Ateş ederken mermin patlayabilir",
|
||||
"explosiveshot_desc2": "Patlayan mermi şansı: %{0}",
|
||||
|
||||
"falconeye": "Şahin Gözü",
|
||||
|
|
@ -156,31 +161,31 @@
|
|||
"fastreload_desc": "[css_useSkill] tuşuna basarak şarjörünü hızlıca değiştir",
|
||||
|
||||
"firerain": "Ateş Yağmuru",
|
||||
"firerain_desc": "Molotof yağdırmak için bir decoy at",
|
||||
"firerain_desc": "Molotof yağdırmak için yanıltıcı bomba at",
|
||||
|
||||
"flash": "Flash",
|
||||
"flash_desc": "Raund başında rastgele oyuncu hızı",
|
||||
"flash_desc": "Rastgele oyuncu hızı",
|
||||
"flash_desc2": "Hızın: {0}x",
|
||||
|
||||
"flashlight": "El Feneri",
|
||||
"flashlight_desc": "[css_useSkill] tuşuna basarak El fenerini açarsın/kaparsın (Işığı düşmanları kör edebilir)",
|
||||
"flashlight_desc": "[css_useSkill] tuşuna basarak el fenerini aç veya kapat, ışığı düşmanı kör eder",
|
||||
|
||||
"fortnite": "Fortnite",
|
||||
"fortnite_desc": "[css_useSkill] tuşuna basarak barikat kur",
|
||||
|
||||
"fragilebomb": "Hassas C4",
|
||||
"fragilebomb_desc": "Kurulu C4'e ateş etmek C4'ün canını azaltır ve C4 imha edilir.",
|
||||
"fragilebomb_desc": "Kurulu C4'e ateş etmek canını azaltır ve C4'ü imha eder",
|
||||
"fragilebomb_bomb_health": "Bombanın canı",
|
||||
|
||||
"friendlyfire": "Dost Şifası",
|
||||
"friendlyfire_desc": "Takım arkadaşlarına ateş etmek onları iyileştirir",
|
||||
"friendlyfire_desc": "Takım arkadaşına ateş etmek onu iyileştirir",
|
||||
|
||||
"frozendecoy": "Buz Kıran",
|
||||
"frozendecoy_desc": "Yanıltıcı bomba (decoy) yakındaki tüm oyuncuları dondurur",
|
||||
"frozendecoy_desc": "Yanıltıcı bomban yakındaki herkesi yavaşlatır",
|
||||
|
||||
"gambler": "Kumarbaz",
|
||||
"gambler_desc": "Sunulan listeden bir yetenek seç.",
|
||||
"gambler_select_info": "Yeteneğini seç:",
|
||||
"gambler_select_info": "Birini seçin:",
|
||||
"gambler_more": "#00FF00|${0} yenile",
|
||||
"gambler_no_money": "Yeterli para yok.",
|
||||
|
||||
|
|
@ -188,106 +193,116 @@
|
|||
"ghost_desc": "Tamamen görünmezsin",
|
||||
|
||||
"giant": "Dev",
|
||||
"giant_desc": "Seçtiğin bir rakibi büyütür",
|
||||
"giant_desc2": "Seçtiğin bir rakibi {0}x büyütür",
|
||||
"giant_disable_info": "Normal boyutuna geri döndün.",
|
||||
"giant_enemy_info": "{0}x boyutuna büyütüldün.",
|
||||
"giant_player_info": "'{0}' oyuncusunu {1}x büyüttün.",
|
||||
"giant_select_info": "Büyütülecek oyuncu:",
|
||||
"giant_desc": "Seçtiğin rakibi büyüt",
|
||||
"giant_desc2": "Rakibin boyutu: {0}x",
|
||||
"giant_disable_info": "Normal boyutuna döndün.",
|
||||
"giant_enemy_info": "{0}x boyutuna büyüdün.",
|
||||
"giant_player_info": "'{0}' boyutunu {1}x büyüttün.",
|
||||
"giant_select_info": "Birini seçin:",
|
||||
|
||||
"glaz": "Glaz",
|
||||
"glaz_desc": "Sis bombalarının içini görebilirsin",
|
||||
"glaz_desc": "Sis bombasının içini görürsün",
|
||||
|
||||
"glitch": "Glitç",
|
||||
"glitch_desc": "Seçilen bir düşmanın radarını kapatır",
|
||||
"glitch_enemy_info": "Radarın kapandı",
|
||||
"glitch_disable_info": "Radarın açıldı",
|
||||
"glitch_player_info": "'{0}' isimli oyuncunun radarı devre dışı bırakıldı.",
|
||||
"glitch_select_info": "Radarı kapatılacak oyuncuyu seç:",
|
||||
"glitch_desc": "Bir düşmanın radarını kapat",
|
||||
"glitch_enemy_info": "Radarın kapandı.",
|
||||
"glitch_disable_info": "Radarın açıldı.",
|
||||
"glitch_player_info": "'{0}' radarı kapandı.",
|
||||
"glitch_select_info": "Birini seçin:",
|
||||
|
||||
"glue": "Yapıştırıcı",
|
||||
"glue_desc": "Bombaların duvarlara yapışır",
|
||||
"glue_desc": "Bomban duvara yapışır",
|
||||
|
||||
"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ı",
|
||||
|
||||
"grapple": "Kanca",
|
||||
"grapple_desc": "[css_useSkill] tuşuna basarak baktığın yere kanca at",
|
||||
"grapple_no_anchor_info": "Kanca atılacak yüzey yok",
|
||||
"grapple_pulling_info": "ÇEKİLİYOR",
|
||||
|
||||
"grenadier": "Bombacı",
|
||||
"grenadier_desc": "Sınırsız el bombasına sahipsin",
|
||||
"grenadier_desc": "El bomban sınırsız",
|
||||
|
||||
"healingchicken": "Şifacı Tavuk",
|
||||
"healingchicken_desc": "Yakınındayken tavukların seni iyileştirir",
|
||||
"healingchicken_desc": "Yakınındayken tavuğun seni iyileştirir",
|
||||
|
||||
"healingsmoke": "Şifalı Sis",
|
||||
"healingsmoke_desc": "Sis bombaların iyileştirir",
|
||||
"healingsmoke_desc": "Sis bomban iyileştirir",
|
||||
|
||||
"hermit": "Münzevi",
|
||||
"hermit_desc": "Birini öldürünce mermin ve canın yenilenir",
|
||||
|
||||
"holyhandgrenade": "Kutsal El Bombası",
|
||||
"holyhandgrenade_desc": "El bomban iki kat hasara ve menzile sahip",
|
||||
"holyhandgrenade_desc": "El bombanın hasarı ve menzili iki kat",
|
||||
|
||||
"homingnades": "Güdümlü Bomba",
|
||||
"homingnades_desc": "Bombalarınız (sis hariç) düşmanlara yönelir",
|
||||
"homingnades_desc": "Bomban (sis hariç) yakın düşmana yönelir",
|
||||
|
||||
"hotbomb": "Sıcak C4",
|
||||
"hotbomb_desc": "Yaşadığın sürece bombacının canı azalıyor",
|
||||
"hotbomb_hint": "Bomba çok sıcak!",
|
||||
"hotbomb_disable_info": "Bomba artık yakmıyor.",
|
||||
"hotbomb_desc": "Yaşadığın sürece bombacının canı azalır",
|
||||
"hotbomb_hint": "C4 ÇOK SICAK!",
|
||||
"hotbomb_disable_info": "C4 soğudu.",
|
||||
|
||||
"iana": "Hologram",
|
||||
"iana_desc": "[css_useSkill] tuşuna basarak bir hologram oluştur",
|
||||
|
||||
"illiterate": "Cahiliye",
|
||||
"illiterate_desc": "Yaşadığın sürece rakibin sohbeti (chat) veya oyun yazılarını okuyamaz",
|
||||
"illiterate_desc": "Yaşadığın sürece rakip hiçbir yazıyı okuyamaz",
|
||||
"illiterate_alert": "Cahiliye aktif! Bu yeteneğin sahibi ortadan kalkana kadar mesajları okuyamazsınız.",
|
||||
|
||||
"illusionist": "İllüzyonist",
|
||||
"illusionist_desc": "[css_useSkill] tuşuna basarak düz ilerleyen illüzyon oluştur",
|
||||
|
||||
"impostor": "Sahtekar",
|
||||
"impostor_desc": "Düşman oyuncu modeline dönüşürsün",
|
||||
"impostor_desc": "Düşman modeline dönüşürsün",
|
||||
|
||||
"infiniteammo": "Sınırsız Mermi",
|
||||
"infiniteammo_desc": "Tüm silahların sınırsız mermisi olur",
|
||||
"infiniteammo_desc": "Silahlarının mermisi sınırsız",
|
||||
|
||||
"inheritance": "Miras",
|
||||
"inheritance_desc": "Bir takım arkadaşın öldüğünde yeteneğini devralabilirsin",
|
||||
"inheritance_select_info": "Birini seçin:",
|
||||
"inheritance_player_info": "'{0}' yeteneğini devraldın.",
|
||||
|
||||
"jackal": "İzci",
|
||||
"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_desc": "Bir düşmanın nişangahını kapat",
|
||||
"jammer_enemy_info": "Nişangahın kapatıldı.",
|
||||
"jammer_disable_info": "Nişangahın açıldı",
|
||||
"jammer_disable_info": "Nişangahın açıldı.",
|
||||
"jammer_player_info": "'{0}' isimli oyuncunun nişangahı kapatıldı.",
|
||||
"jammer_select_info": "Nişangahı kapatılacak oyuncuyu seç:",
|
||||
"jammer_select_info": "Birini seçin:",
|
||||
|
||||
"jester": "Soytarı",
|
||||
"jester_desc": "Soytarı modunda hasar alamazsın ve veremezsin. Bu mod birkaç saniyede bir değişir.",
|
||||
"jester_desc": "Soytarı modunda hasar alamaz ve veremezsin, mod birkaç saniyede bir değişir",
|
||||
"jester_mode": "Soytarı Modu",
|
||||
"jester_on": "AÇIK",
|
||||
"jester_off": "KAPALI",
|
||||
|
||||
"jetkick": "Jetkick",
|
||||
"jetkick_desc": "Seçtiğin bir rakibin her atışı onu geriye iter",
|
||||
"jetkick_select_info": "Jetkick uygulanacak oyuncu:",
|
||||
"jetkick_desc": "Seçtiğin rakibi her atışı geriye iter",
|
||||
"jetkick_select_info": "Birini seçin:",
|
||||
"jetkick_player_info": "'{0}' adlı oyuncuya jetkick uygulandı.",
|
||||
"jetkick_enemy_info": "Her atış seni geriye doğru iter",
|
||||
"jetkick_disable_info": "Geri tepmen normale döndü.",
|
||||
|
||||
"jumpban": "Bacaksız",
|
||||
"jumpban_desc": "Zıplayamayacak bir oyuncu seç",
|
||||
"jumpban_enemy_info": "Bacakların kesildi",
|
||||
"jumpban_disable_info": "Bacaklarına kavuştun",
|
||||
"jumpban_desc": "Zıplayamayacak bir düşman seç",
|
||||
"jumpban_enemy_info": "Bacakların kesildi.",
|
||||
"jumpban_disable_info": "Tekrar zıplayabilirsin.",
|
||||
"jumpban_player_info": "'{0}' artık zıplayamaz.",
|
||||
"jumpban_select_info": "Zıplaması yasaklanacak oyuncu:",
|
||||
"jumpban_select_info": "Birini seçin:",
|
||||
|
||||
"jumpcurse": "Zıplama Laneti",
|
||||
"jumpcurse_desc": "Seçtiğin rakip, takım arkadaşları her zıpladığında zıplar",
|
||||
"jumpcurse_disable_info": "Bacakların yeniden senin.",
|
||||
"jumpcurse_enemy_info": "Artık takım arkadaşların zıpladıkça sen de zıplıyorsun.",
|
||||
"jumpcurse_player_info": "'{0}' artık takımıyla birlikte zıplıyor.",
|
||||
"jumpcurse_select_info": "Zıplama laneti verilecek oyuncu:",
|
||||
"jumpcurse_desc": "Seçtiğin rakip, takım arkadaşlarıyla zıpladıkça zıplar",
|
||||
"jumpcurse_disable_info": "Kendin için zıplayabilirsin.",
|
||||
"jumpcurse_enemy_info": "Takım arkadaşların zıpladıkça sen de zıplıyorsun.",
|
||||
"jumpcurse_player_info": "'{0}' takımıyla birlikte zıplıyor.",
|
||||
"jumpcurse_select_info": "Birini seçin:",
|
||||
|
||||
"jumpingjack": "Zıpzıp Jack",
|
||||
"jumpingjack_desc": "Zıplamak canını yeniler",
|
||||
|
|
@ -302,10 +317,10 @@
|
|||
"lastgasp_desc": "Öldükten sonra seni öldürene hasar verirsin",
|
||||
|
||||
"lifeswap": "Can Takası",
|
||||
"lifeswap_desc": "Can değerlerini takas etmek için bir oyuncu seç",
|
||||
"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:",
|
||||
"lifeswap_desc": "Bir düşmanla canını takasla",
|
||||
"lifeswap_enemy_info": "Birisi canını çaldı.",
|
||||
"lifeswap_player_info": "'{0}' ile canını takasladın.",
|
||||
"lifeswap_select_info": "Birini seçin:",
|
||||
|
||||
"longknife": "Uzun Bıçak",
|
||||
"longknife_desc": "Bıçağın uzaktaki rakibe hasar verebilir",
|
||||
|
|
@ -314,46 +329,46 @@
|
|||
"longzeus_desc": "Zeus uzaktaki rakibe hasar verebilir",
|
||||
|
||||
"magneticdecoy": "Manyetik Yanıltıcı",
|
||||
"magneticdecoy_desc": "Yanıltıcı bombanız yakındaki oyuncuları kendine çeker",
|
||||
"magneticdecoy_desc": "Yanıltıcı bomban yakındaki herkesi kendine çeker",
|
||||
|
||||
"magneto": "Mıknatıs",
|
||||
"magneto_desc": "Tüm düşman bombaları sizden uzaklaştırılır",
|
||||
"magneto_desc": "Tüm düşman bombası senden uzaklaşır",
|
||||
|
||||
"magnifier": "Büyüteç",
|
||||
"magnifier_desc": "Düşmanın ekranını yakınlaştırarak görüş alanını daraltır",
|
||||
"magnifier_desc": "Bir düşmanın görüş alanını daralt",
|
||||
"magnifier_enemy_info": "Görüşün bozuldu!",
|
||||
"magnifier_disable_info": "Görüşün düzeldi",
|
||||
"magnifier_player_info": "'{0}' isimli oyuncunun ekranı yakınlaştırıldı.",
|
||||
"magnifier_select_info": "Ekranı büyütülecek oyuncuyu seç:",
|
||||
"magnifier_select_info": "Birini seçin:",
|
||||
|
||||
"medic": "Sıhhiye",
|
||||
"medic_desc": "[css_useSkill] tuşuna basarak kendine anında 50 HP bas",
|
||||
|
||||
"miner": "Mayın",
|
||||
"miner_desc": "El bombanız (HE) sadece yakında bir düşman olduğunda patlar",
|
||||
"miner_desc": "El bomban sadece yakında düşman varken patlar",
|
||||
|
||||
"bankrupt": "İflas",
|
||||
"bankrupt_desc": "Tüm parasını kaybedecek bir oyuncu seç",
|
||||
"bankrupt_desc": "Tüm parasını kaybedecek bir düşman seç",
|
||||
"bankrupt_enemy_info": "İflas ettin!",
|
||||
"bankrupt_player_info": "'{0}' isimli oyuncu iflas etti.",
|
||||
"bankrupt_select_info": "İflas edecek oyuncuyu seç:",
|
||||
"bankrupt_player_info": "'{0}' iflas etti.",
|
||||
"bankrupt_select_info": "Birini seçin:",
|
||||
|
||||
"deathbomb": "Canlı Bomba",
|
||||
"deathbomb_desc": "Öldüğünde patlayarak etraftaki oyuncuları öldürürsün",
|
||||
"deathbomb_desc": "Öldüğünde patlayıp etrafındakilere hasar verirsin",
|
||||
"deathbomb_explosion": "BOOM!!!",
|
||||
|
||||
"demoneye": "Şeytani Göz",
|
||||
"demoneye_desc": "Baktığın tüm düşmanlara hasar verirsin",
|
||||
"demoneye_desc": "Baktığın tüm düşmana hasar verirsin",
|
||||
|
||||
"nightmare": "Kabus",
|
||||
"nightmare_desc": "Seçtiğin bir rakibe kabus görüntüsü verir",
|
||||
"nightmare_desc": "Seçtiğin rakibe kabus gördür",
|
||||
"nightmare_disable_info": "Kabus sona erdi.",
|
||||
"nightmare_enemy_info": "Gözlerini bir kabus bürüdü.",
|
||||
"nightmare_player_info": "'{0}' oyuncusuna kabus gördürdün.",
|
||||
"nightmare_select_info": "Kabus görecek oyuncu:",
|
||||
"nightmare_select_info": "Birini seçin:",
|
||||
|
||||
"ninja": "Ninja",
|
||||
"ninja_desc": "Görünmezliğini sabit durmak %33, eğilmek %33 ve bıçak tutmak %33 artırır",
|
||||
"ninja_desc": "Sabit durmak, eğilmek ve bıçak tutmak görünmezliğini %33 artırır",
|
||||
|
||||
"nonades": "Bomba Geçirmez",
|
||||
"nonades_desc": "Bombalar sana hasar vermez",
|
||||
|
|
@ -375,38 +390,38 @@
|
|||
"paweljumper_desc2": "{0} kez ekstra zıplayabilirsin",
|
||||
|
||||
"phoenix": "Anka Kuşu",
|
||||
"phoenix_desc": "Öldükten sonra rastgele yeniden doğma şansın olur",
|
||||
"phoenix_desc": "Öldükten sonra yeniden doğma şansın olur",
|
||||
"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_desc": "Bombanın yanındayken otomatik imhaya başlarsın",
|
||||
"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",
|
||||
"pilot_desc": "Uçmak için zıplama tuşuna iki kez bas",
|
||||
"pilot_hud_info": "Yakıt",
|
||||
|
||||
"planter": "Serbest Kurucu",
|
||||
"planter_desc": "Bombayı her yere kurabilirsin, patlama süresi 60 saniyedir.",
|
||||
"planter_desc": "Bombayı her yere kurabilirsin, patlama süresi 60 saniye",
|
||||
"planter_planting": "Kuruluyor ({0})...",
|
||||
|
||||
"poison": "Zehir",
|
||||
"poison_desc": "Birkaç saniyede bir hasar alacak bir oyuncu seç",
|
||||
"poison_desc": "Birkaç saniyede bir hasar alacak bir düşman seç",
|
||||
"poison_enemy_info": "Zehirlendin.",
|
||||
"poison_disable_info": "Zehire bağışıklık kazandın",
|
||||
"poison_player_info": "'{0}' isimli oyuncu zehirlendi.",
|
||||
"poison_select_info": "Zehirlenecek oyuncuyu seç:",
|
||||
"poison_select_info": "Birini seçin:",
|
||||
|
||||
"primaryban": "Tüfek Yasak",
|
||||
"primaryban_desc": "Tüfek kullanamayacak bir oyuncu seç",
|
||||
"primaryban_desc": "Tüfek kullanamayacak bir düşman seç",
|
||||
"primaryban_enemy_info": "Tüfek kullanmayı unuttun",
|
||||
"primaryban_disable_info": "Tüfek kullanabilirsin",
|
||||
"primaryban_player_info": "'{0}' artık tüfek kullanamaz.",
|
||||
"primaryban_select_info": "Tüfek kullanımı yasaklanacak oyuncu:",
|
||||
"primaryban_select_info": "Birini seçin:",
|
||||
|
||||
"prosthesis": "Protez",
|
||||
"prosthesis_desc": "Kollar ve bacaklar kurşun geçirmezdir",
|
||||
"prosthesis_desc": "Kolların ve bacakların kurşun geçirmez",
|
||||
|
||||
"push": "İtici",
|
||||
"push_desc": "Düşmana vurduğunda onu geri itme şansın olur",
|
||||
|
|
@ -422,43 +437,46 @@
|
|||
"radarhack_desc": "Düşmanlar radarda görünür",
|
||||
|
||||
"rambo": "Rambo",
|
||||
"rambo_desc": "Raund başında rastgele miktarda can alırsın",
|
||||
"rambo_desc": "Rastgele miktarda canın olur",
|
||||
|
||||
"randomweapon": "Silah Kumarı",
|
||||
"randomweapon_desc": "[css_useSkill] tuşuna basarak rastgele bir silah al",
|
||||
|
||||
"rezombie": "Zombi",
|
||||
"rezombie_desc": "Öldükten sonra daha fazla canla ve silahsız zombi olarak doğarsın",
|
||||
"rezombie_desc": "Öldüğünde silahsız zombi olarak daha çok canla dirilirsin",
|
||||
|
||||
"reactivearmor": "Reaktif Zırh",
|
||||
"reactivearmor_desc": "Zırhın alınan ilk hasarı emmer",
|
||||
"reactivearmor_desc": "Zırhın ilk hasarı emer",
|
||||
|
||||
"regeneration": "Yenilenme",
|
||||
"regeneration_desc": "Birkaç saniyede bir canın yenilenir",
|
||||
|
||||
"replicator": "Klon",
|
||||
"replicator_desc": "[css_useSkill] tuşuna basarak klon oluştur ve öldürene hasar verir",
|
||||
"replicator_desc": "[css_useSkill] tuşuna basarak klon oluştur, klonu öldürene hasar verir",
|
||||
|
||||
"retreat": "Geri Çekil",
|
||||
"retreat_desc": "[css_useSkill] tuşuna basarak başlangıç noktasına ışınlan",
|
||||
"retreat_desc": "[css_useSkill] tuşuna basarak başlangıcına ışınlan",
|
||||
|
||||
"returntosender": "İade",
|
||||
"returntosender_desc": "Düşmana ilk vuruşun onu kendi başlangıç noktasına ışınlar",
|
||||
"returntosender_desc": "Düşmana ilk vuruşun onu kendi başlangıcına ışınlar",
|
||||
|
||||
"richboy": "Zengin Çocuk",
|
||||
"richboy_desc": "Raund başında rastgele miktarda para alırsın",
|
||||
"richboy_desc": "Rastgele miktarda paran olur",
|
||||
|
||||
"ricochet": "Seken Mermi",
|
||||
"ricochet_desc": "Mermin duvardan seker ve düşmana isabet edebilir",
|
||||
|
||||
"robinhood": "Robin Hood",
|
||||
"robinhood_desc": "Düşmana hasar vermek onun parasını çalar",
|
||||
|
||||
"rubber": "Lastik Mermi",
|
||||
"rubber_desc": "Mermilerin oyuncuları önemli ölçüde yavaşlatır",
|
||||
"rubber_desc": "Mermin isabet edeni yavaşlatır",
|
||||
|
||||
"saper": "İstihkamcı",
|
||||
"saper_desc": "Bombayı daha hızlı kurabilir ve imha edebilirsin",
|
||||
"saper_desc": "Bombayı daha hızlı kurar ve imha edersin",
|
||||
|
||||
"secondlife": "İkinci Şans",
|
||||
"secondlife_desc": "Öldükten sonra aynı miktarda canla yeniden doğarsın",
|
||||
"secondlife_desc": "Öldüğünde aynı canla yeniden doğarsın",
|
||||
|
||||
"shade": "Gölge",
|
||||
"shade_desc": "Vurduğun düşmanın arkasına ışınlanma şansın olur",
|
||||
|
|
@ -466,24 +484,24 @@
|
|||
"shade_nospace": "Uygun alan yok",
|
||||
|
||||
"shortbomb": "Kısa Fünye",
|
||||
"shortbomb_desc": "Bomba çok daha hızlı patlar",
|
||||
"shortbomb_desc": "C4 çok daha hızlı patlar",
|
||||
|
||||
"silent": "Sessiz",
|
||||
"silent_desc": "Ayak seslerini ve zıplamalarını DİĞER oyuncular duyamaz",
|
||||
"silent_desc": "Ayak ve zıplama sesini kimse duyamaz",
|
||||
|
||||
"smoker": "Tiryaki",
|
||||
"smoker_desc": "Attığın Sis asla bitmez",
|
||||
"smoker_desc": "Attığın sis asla bitmez",
|
||||
|
||||
"sniperelite": "Keskin Nişancı",
|
||||
"sniperelite_customname": "Keskin Nişancı",
|
||||
"sniperelite_desc": "[css_useSkill] tuşuna basarak silahını AWP ile değiştir",
|
||||
|
||||
"soldier": "Teğmen",
|
||||
"soldier_desc": "Rastgele bir oranda fazla hasar verirsin",
|
||||
"soldier_desc": "Rastgele hasar verme çarpanın olur",
|
||||
"soldier_desc2": "Hasarın: {0}x",
|
||||
|
||||
"soundmaker": "Çığlık",
|
||||
"soundmaker_desc": "Rakiplerinin çığlıklarını duyarsın",
|
||||
"soundmaker_desc": "Rakibin çığlığını duyarsın",
|
||||
|
||||
"spectator": "Röntgen",
|
||||
"spectator_desc": "[css_useSkill] tuşuna basarak rakibinin gözünden gör",
|
||||
|
|
@ -492,47 +510,47 @@
|
|||
"swapposition_desc": "[css_useSkill] tuşuna basarak vurduğun düşmanla yer değiştir",
|
||||
|
||||
"takeammo": "Cephane Hırsızı",
|
||||
"takeammo_desc": "[css_useSkill] tuşuna basarak rastgele bir düşmanın silahının şarjörünü çalarsın",
|
||||
"takeammo_hud_info1": "Cephanesi olan bir oyuncu bulunamadı.",
|
||||
"takeammo_hud_info2": "Düşmanın cephanesi yok.",
|
||||
"takeammo_enemy_info": "Birisi cephaneni çaldı.",
|
||||
"takeammo_desc": "[css_useSkill] tuşuna basarak rastgele bir düşmanın şarjörünü çal",
|
||||
"takeammo_hud_info1": "Şarjörü olan bir oyuncu bulunamadı.",
|
||||
"takeammo_hud_info2": "Düşmanın şarjörü yok.",
|
||||
"takeammo_enemy_info": "Birisi şarjörünü çaldı.",
|
||||
|
||||
"teamteleport": "Takıma Işınlanma",
|
||||
"teamteleport_desc": "[css_useSkill] tuşuna basarak baktığın takım arkadaşına ışınlanırsın",
|
||||
"teamteleport_desc": "[css_useSkill] tuşuna basarak baktığın takım arkadaşına ışınlan",
|
||||
"teamteleport_noenemy": "Takım arkadaşı bulunamadı",
|
||||
"teamteleport_hud_info": "Bulundu: {0}",
|
||||
|
||||
"teleporter": "Işınlayıcı",
|
||||
"teleporter_desc": "Vurulan bir düşmanla yer değiştirme şansınız var",
|
||||
"teleporter_desc": "Vurduğun düşmanla yer değiştirme şansın olur",
|
||||
"teleporter_desc2": "Yer değiştirme şansın: %{0}",
|
||||
|
||||
"thief": "Hırsız",
|
||||
"thief_desc": "Seçilen bir oyuncudan yeteneğini çalabilirsin",
|
||||
"thief_desc": "Bir düşmanın yeteneğini çal",
|
||||
"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_select_info": "Birini seçin:",
|
||||
"thief_incorrect_skill": "Bu yetenek çalınamaz!",
|
||||
|
||||
"thirdeye": "Üçüncü Göz",
|
||||
"thirdeye_desc": "[css_useSkill] tuşuna basarak üçüncü göze(thirdperson) geç",
|
||||
"thirdeye_desc": "[css_useSkill] tuşuna basarak üçüncü şahıs görünümüne geç",
|
||||
|
||||
"thorns": "Dikenler",
|
||||
"thorns_desc": "Rakibin, sana verdiği hasarın bir kısmını geri alır",
|
||||
"thorns_desc": "Sana verilen hasarın bir kısmı rakibe döner",
|
||||
|
||||
"throwingknife": "Fırlatma Bıçağı",
|
||||
"throwingknife_desc": "Bıçak fırlatmak için [css_useSkill] tuşuna basın. Ama başkalarına dikkat edin",
|
||||
"throwingknife_desc": "[css_useSkill] tuşuna basarak bıçak fırlat",
|
||||
|
||||
"toxicsmoke": "Zehirli Sis",
|
||||
"toxicsmoke_desc": "Sis bombaların hasar verir",
|
||||
"toxicsmoke_desc": "Sis bomban hasar verir",
|
||||
|
||||
"tripwire": "Tel Tuzağı",
|
||||
"tripwire_desc": "[css_useSkill] ile iki duvar arasına tel ger. Tele değen düşman radarında görünür",
|
||||
"tripwire_desc": "[css_useSkill] tuşuna basarak iki duvar arasına tel ger, değen düşman radarda görünür",
|
||||
"tripwire_no_wall_info": "İki yanında da yeterince yakın duvar yok.",
|
||||
"tripwire_placed_info": "Tel gerildi.",
|
||||
"tripwire_triggered_info": "'{0}' teline takıldı.",
|
||||
|
||||
"wallhack": "Wallhack",
|
||||
"wallhack_desc": "Düşmanları duvarların arkasından görebilirsin",
|
||||
"wallhack_desc": "Düşmanları duvar arkasından görürsün",
|
||||
|
||||
"watchmaker": "Saat Ustası",
|
||||
"watchmaker_desc": "Atılan her bomba raund süresini değiştirir",
|
||||
|
|
@ -544,21 +562,21 @@
|
|||
"weaponsswap_hud_info2": "Takas edilecek silahın yok",
|
||||
|
||||
"weightless": "Yerçekimsiz",
|
||||
"weightless_desc": "El bombalarınız yerçekiminden etkilenmez ve dümdüz gider",
|
||||
"weightless_desc": "El bomban yerçekiminden etkilenmez ve dümdüz gider",
|
||||
|
||||
"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_desc": "El bombası atmakta zorlanacak bir düşman seç",
|
||||
"wildthrow_player_info": "'{0}' tüm taktiklerini unuttu.",
|
||||
"wildthrow_enemy_info": "Bomba atarken çok heyecanlanıyorsun.",
|
||||
"wildthrow_disable_info": "Bombaların düzeldi.",
|
||||
"wildthrow_select_info": "Bir oyuncu seçin:",
|
||||
"wildthrow_disable_info": "Bomban tekrardan düzgün.",
|
||||
"wildthrow_select_info": "Birini seçin:",
|
||||
|
||||
"zeus": "Zeus",
|
||||
"zeus_desc": "Zeus x27 anında şarj olur",
|
||||
|
||||
"your_skill": "Yeteneğin",
|
||||
"enemy_skill": "Düşmanın yeteneği",
|
||||
"observer_skill": "Oyuncunun yeteneği",
|
||||
"observer_skill": "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 çarkı dönüyor...",
|
||||
"disabled_weapon": "Bu silahı kullanamazsın",
|
||||
|
|
|
|||
|
|
@ -71,6 +71,11 @@
|
|||
"catapult_desc": "你有随机几率将敌人向上弹射",
|
||||
"catapult_desc2": "你击中敌人将其弹射的几率是:{0}%",
|
||||
|
||||
"chameleon": "变色龙",
|
||||
"chameleon_desc": "你击杀的第一名玩家会把技能传给你",
|
||||
"chameleon_copied_info": "已复制技能:{0}",
|
||||
"chameleon_wrong_team_info": "'{0}' 的技能你的队伍无法使用。",
|
||||
|
||||
"chicken": "小鸡",
|
||||
"chicken_desc": "你获得小鸡模型 + 移动速度提高10% - 50生命值",
|
||||
|
||||
|
|
@ -201,6 +206,11 @@
|
|||
"godmode_off": "无敌状态已禁用",
|
||||
"godmode_on": "无敌状态已启用",
|
||||
|
||||
"grapple": "钩爪",
|
||||
"grapple_desc": "按 [css_useSkill] 向准星所指位置发射钩爪并将自己拉过去",
|
||||
"grapple_no_anchor_info": "没有可以钩住的表面。",
|
||||
"grapple_pulling_info": "拉动中",
|
||||
|
||||
"grenadier": "投弹手",
|
||||
"grenadier_desc": "你拥有无限高爆手雷",
|
||||
|
||||
|
|
@ -237,6 +247,11 @@
|
|||
"infiniteammo": "无限弹药",
|
||||
"infiniteammo_desc": "你为所有武器获得无限弹药",
|
||||
|
||||
"inheritance": "继承",
|
||||
"inheritance_desc": "当队友阵亡时,你可以接管他的技能",
|
||||
"inheritance_select_info": "选择要继承的技能:",
|
||||
"inheritance_player_info": "你继承了 '{0}' 的技能。",
|
||||
|
||||
"jackal": "追踪者",
|
||||
"jackal_desc": "每个对手都会留下痕迹",
|
||||
|
||||
|
|
@ -418,6 +433,9 @@
|
|||
"richboy": "富少",
|
||||
"richboy_desc": "回合开始时你获得随机数量的钱",
|
||||
|
||||
"ricochet": "跳弹",
|
||||
"ricochet_desc": "你的子弹会从墙上弹开,并且仍能击中敌人",
|
||||
|
||||
"robinhood": "罗宾汉",
|
||||
"robinhood_desc": "对敌人造成伤害会偷取他们的钱",
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ using CounterStrikeSharp.API.Modules.Memory;
|
|||
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using static CounterStrikeSharp.API.Core.Listeners;
|
||||
using static src.jRandomSkills;
|
||||
|
||||
|
|
@ -96,33 +95,9 @@ namespace src.player
|
|||
WriteToDebug($"Map changed: {mapName}.");
|
||||
});
|
||||
|
||||
Instance.RegisterEventHandler<EventPlayerShoot>((@event, info) =>
|
||||
{
|
||||
var player = PlayerManager.GetPlayerEvent(@event.Userid);
|
||||
if (player == null || !player.IsValid) return HookResult.Continue;
|
||||
WriteToDebug($"{(player.IsBot ? "Bot" : "Player")} {player.PlayerName} fired a shot.");
|
||||
return HookResult.Continue;
|
||||
});
|
||||
|
||||
Instance.RegisterEventHandler<EventPlayerHurt>((@event, info) =>
|
||||
{
|
||||
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
|
||||
if (victim == null || !victim.IsValid) return HookResult.Continue;
|
||||
|
||||
if (!lastNativeHitGroup.TryRemove(victim.Index, out var native)) return HookResult.Continue;
|
||||
if (native.HitGroup == @event.Hitgroup) return HookResult.Continue;
|
||||
|
||||
WriteToDebug($"[HITGROUP] mismatch on {victim.PlayerName}: native={(HitGroup_t)native.HitGroup} event={(HitGroup_t)@event.Hitgroup} " +
|
||||
$"weapon={@event.Weapon} rawDmg={native.Damage:0.#} appliedDmg={@event.DmgHealth}");
|
||||
|
||||
return HookResult.Continue;
|
||||
});
|
||||
|
||||
VirtualFunctions.CBaseEntity_TakeDamageOldFunc.Hook(OnTakeDamage, HookMode.Pre);
|
||||
}
|
||||
|
||||
private static readonly ConcurrentDictionary<uint, (int HitGroup, float Damage)> lastNativeHitGroup = [];
|
||||
|
||||
public static void Unload()
|
||||
{
|
||||
try { VirtualFunctions.CBaseEntity_TakeDamageOldFunc.Unhook(OnTakeDamage, HookMode.Pre); }
|
||||
|
|
@ -131,16 +106,6 @@ namespace src.player
|
|||
lock (_writeLock) { _writer?.Dispose(); _writer = null; }
|
||||
}
|
||||
|
||||
private static string DescribeIdentitySplit(CCSPlayerController victim)
|
||||
{
|
||||
var routed = PlayerManager.GetPlayerEvent(victim);
|
||||
uint routedIndex = routed?.Index ?? victim.Index;
|
||||
if (routedIndex == victim.Index) return string.Empty;
|
||||
|
||||
return $" SPLIT(idx {victim.Index}->{routedIndex}, skill {PlayerManager.GetPlayerByIndex(victim.Index)?.Skill}" +
|
||||
$"->{PlayerManager.GetPlayerByIndex(routedIndex)?.Skill}, controllingBot={victim.ControllingBot})";
|
||||
}
|
||||
|
||||
private static HookResult OnTakeDamage(DynamicHook h)
|
||||
{
|
||||
CEntityInstance param = h.GetParam<CEntityInstance>(0);
|
||||
|
|
@ -165,12 +130,10 @@ namespace src.player
|
|||
if (playerInfo == null) return HookResult.Continue;
|
||||
|
||||
var nativeHitGroup = SkillUtils.GetHitGroup(param2);
|
||||
lastNativeHitGroup[victim.Index] = ((int)nativeHitGroup, param2.Damage);
|
||||
|
||||
WriteToDebug($"{(victim.IsBot ? "Bot" : "Player")} {victim.PlayerName} took damage from {(attacker.IsBot ? "bot" : "player")} {attacker.PlayerName}. " +
|
||||
$"[dmg={param2.Damage:0.#} hp={victimPawn.Health}/{victimPawn.MaxHealth} armor={victimPawn.ArmorValue} hitgroup={nativeHitGroup} " +
|
||||
$"takes={victimPawn.TakesDamage} vskill={PlayerManager.GetPlayerByIndex(victim.Index)?.Skill} askill={playerInfo.Skill}" +
|
||||
$"{DescribeIdentitySplit(victim)}]");
|
||||
$"takes={victimPawn.TakesDamage} vskill={PlayerManager.GetPlayerByIndex(victim.Index)?.Skill} askill={playerInfo.Skill}]");
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ public enum Skills
|
|||
C4Camouflage,
|
||||
CarefulBullets,
|
||||
Catapult,
|
||||
Chameleon,
|
||||
Chicken,
|
||||
ChillOut,
|
||||
Cutter,
|
||||
|
|
@ -114,6 +115,7 @@ public enum Skills
|
|||
Glitch,
|
||||
Glue,
|
||||
GodMode,
|
||||
Grapple,
|
||||
Grenadier,
|
||||
HealingChicken,
|
||||
HealingSmoke,
|
||||
|
|
@ -126,6 +128,7 @@ public enum Skills
|
|||
Illusionist,
|
||||
Impostor,
|
||||
InfiniteAmmo,
|
||||
Inheritance,
|
||||
Jackal,
|
||||
Jammer,
|
||||
Jester,
|
||||
|
|
@ -173,6 +176,7 @@ public enum Skills
|
|||
Retreat,
|
||||
ReturnToSender,
|
||||
RichBoy,
|
||||
Ricochet,
|
||||
RobinHood,
|
||||
Rubber,
|
||||
Saper,
|
||||
|
|
|
|||
|
|
@ -226,8 +226,11 @@ namespace src.player
|
|||
if (controller == null || !controller.IsValid) return string.Empty;
|
||||
|
||||
uint routedIndex = PlayerManager.GetPlayerEvent(controller)?.Index ?? controller.Index;
|
||||
return $" on {controller.PlayerName} [idx={controller.Index} skill={PlayerManager.GetPlayerByIndex(controller.Index)?.Skill}" +
|
||||
$" routedIdx={routedIndex} routedSkill={PlayerManager.GetPlayerByIndex(routedIndex)?.Skill}]";
|
||||
string routing = routedIndex == controller.Index
|
||||
? string.Empty
|
||||
: $" routedIdx={routedIndex} routedSkill={PlayerManager.GetPlayerByIndex(routedIndex)?.Skill}";
|
||||
|
||||
return $" on {controller.PlayerName} [idx={controller.Index} skill={PlayerManager.GetPlayerByIndex(controller.Index)?.Skill}{routing}]";
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace src.player
|
|||
Instance.RegisterListener<OnTick>(() =>
|
||||
{
|
||||
UpdateGameRules();
|
||||
if (Server.TickCount % 2 != 0) return;
|
||||
if (!SkillUtils.IsHudFrame()) return;
|
||||
|
||||
if (PerfLog.Enabled && Server.TickCount % 1920 == 0)
|
||||
{
|
||||
|
|
@ -99,26 +99,20 @@ namespace src.player
|
|||
bool showDescriptionHUD = skillPlayer.SkillDescriptionHudExpired >= now || Config.LoadedConfig.DisplayAlwaysDescription;
|
||||
bool isDescription = true;
|
||||
|
||||
var skills = SkillData.Skills;
|
||||
var skills = SkillData.GetSnapshot();
|
||||
|
||||
if (skills == null || skills.IsEmpty)
|
||||
if (skills.Length == 0)
|
||||
{
|
||||
infoLine = player.GetTranslationWithoutIlliterate("your_skill");
|
||||
skillLine = player.GetTranslationWithoutIlliterate("none");
|
||||
}
|
||||
else if (skillPlayer.IsDrawing && player.PawnIsAlive)
|
||||
{
|
||||
int skillCount = skills.Count;
|
||||
|
||||
if (skillCount > 0)
|
||||
{
|
||||
var skillsArray = skills.ToArray();
|
||||
var randomSkill = skillsArray[Instance.Random.Next(skillCount)];
|
||||
var randomSkill = skills[Instance.Random.Next(skills.Length)];
|
||||
|
||||
infoLine = player.GetTranslationWithoutIlliterate("drawing_skill");
|
||||
skillLine = $"<font color='{randomSkill.Color}'>{player.GetSkillName(randomSkill.Skill)}</font>";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (player.PawnIsAlive)
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ namespace src.player.skills
|
|||
{
|
||||
if (player == null || !player.IsValid) return;
|
||||
SkillPlayerInfo.TryRemove(player.Index, out _);
|
||||
SkillUtils.ResetPrintHTML(player);
|
||||
}
|
||||
|
||||
public static void OnTick()
|
||||
|
|
|
|||
166
jRandomSkills - SRC Files/src/player/skills/Chameleon.cs
Normal file
166
jRandomSkills - SRC Files/src/player/skills/Chameleon.cs
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using static src.jRandomSkills;
|
||||
|
||||
namespace src.player.skills
|
||||
{
|
||||
public class Chameleon : ISkill
|
||||
{
|
||||
private const Skills skillName = Skills.Chameleon;
|
||||
|
||||
private static readonly ConcurrentDictionary<uint, byte> holders = [];
|
||||
private static jRandomSkills? registeredOn;
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
|
||||
if (ReferenceEquals(registeredOn, Instance)) return;
|
||||
|
||||
registeredOn = Instance;
|
||||
Instance.RegisterEventHandler<EventPlayerDeath>(OnAnyDeath);
|
||||
}
|
||||
|
||||
public static void NewRound()
|
||||
{
|
||||
holders.Clear();
|
||||
}
|
||||
|
||||
public static void EnableSkill(CCSPlayerController player)
|
||||
{
|
||||
if (player == null || !player.IsValid) return;
|
||||
holders[player.Index] = 0;
|
||||
}
|
||||
|
||||
public static void DisableSkill(CCSPlayerController player)
|
||||
{
|
||||
if (player == null) return;
|
||||
holders.TryRemove(player.Index, out _);
|
||||
}
|
||||
|
||||
public static void PlayerDisconnect(uint playerIndex)
|
||||
{
|
||||
holders.TryRemove(playerIndex, out _);
|
||||
}
|
||||
|
||||
private static HookResult OnAnyDeath(EventPlayerDeath @event, GameEventInfo info)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (holders.IsEmpty) return HookResult.Continue;
|
||||
|
||||
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
|
||||
if (attacker == null || !attacker.IsValid) return HookResult.Continue;
|
||||
|
||||
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
|
||||
if (victim == null || !victim.IsValid) return HookResult.Continue;
|
||||
|
||||
if (attacker.Index == victim.Index) return HookResult.Continue;
|
||||
if (attacker.Team == victim.Team) return HookResult.Continue;
|
||||
if (!holders.ContainsKey(attacker.Index)) return HookResult.Continue;
|
||||
|
||||
var victimInfo = PlayerManager.GetPlayerByIndex(victim.Index);
|
||||
if (victimInfo == null || victimInfo.IsDrawing) return HookResult.Continue;
|
||||
|
||||
CopySkill(attacker, victim.PlayerName, victimInfo.Skill);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Server.PrintToConsole($"[jRandomSkills] Chameleon.OnAnyDeath failed: {ex.Message}");
|
||||
}
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
private static void CopySkill(CCSPlayerController player, string victimName, Skills victimSkill)
|
||||
{
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player.Index);
|
||||
if (playerInfo == null) return;
|
||||
|
||||
var playerEvent = PlayerManager.GetPlayerFromEvent(player);
|
||||
|
||||
if (!CanCopy(player, victimSkill, out string? blockReason))
|
||||
{
|
||||
if (blockReason != null && playerEvent != null && playerEvent.IsValid)
|
||||
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation(blockReason, victimName));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uint playerIndex = player.Index;
|
||||
Skills previousSkill = playerInfo.Skill;
|
||||
|
||||
if (!holders.TryRemove(playerIndex, out _)) return;
|
||||
|
||||
Instance.AddTimer(.1f, () =>
|
||||
{
|
||||
var target = Utilities.GetPlayerFromIndex((int)playerIndex);
|
||||
if (target == null || !target.IsValid) return;
|
||||
|
||||
var targetInfo = PlayerManager.GetPlayerByIndex(playerIndex);
|
||||
if (targetInfo == null || targetInfo.Skill != previousSkill) return;
|
||||
|
||||
Instance.SkillAction(previousSkill.ToString(), "DisableSkill", [target]);
|
||||
|
||||
targetInfo.Skill = victimSkill;
|
||||
targetInfo.SpecialSkill = skillName;
|
||||
targetInfo.SkillChance = null;
|
||||
|
||||
if (target.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
|
||||
|
||||
if (SkillsInfo.GetValue<bool>(victimSkill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
|
||||
Instance.AddTimer(Math.Max((float)(Event.GetFreezeTimeEnd() - DateTime.Now).TotalSeconds, 0), () =>
|
||||
{
|
||||
var heir = Utilities.GetPlayerFromIndex((int)playerIndex);
|
||||
if (heir == null || !heir.IsValid) return;
|
||||
|
||||
if (PlayerManager.GetPlayerByIndex(playerIndex)?.Skill != victimSkill) return;
|
||||
Instance.SkillAction(victimSkill.ToString(), "EnableSkill", [heir]);
|
||||
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||
else
|
||||
Instance.SkillAction(victimSkill.ToString(), "EnableSkill", [target]);
|
||||
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||
|
||||
if (playerEvent != null && playerEvent.IsValid)
|
||||
playerEvent.PrintToChat($" {ChatColors.Green}" + playerEvent.GetTranslation("chameleon_copied_info", player.GetSkillName(victimSkill)));
|
||||
}
|
||||
|
||||
private static bool CanCopy(CCSPlayerController player, Skills victimSkill, out string? blockReason)
|
||||
{
|
||||
blockReason = null;
|
||||
|
||||
if (victimSkill == Skills.None || victimSkill == skillName) return false;
|
||||
if (SkillData.GetInfo(victimSkill) == null) return false;
|
||||
|
||||
bool ctOnly = Event.counterterroristSkills.Any(s => s.Name == victimSkill.ToString());
|
||||
bool ttOnly = Event.terroristSkills.Any(s => s.Name == victimSkill.ToString());
|
||||
|
||||
if ((player.Team == CsTeam.Terrorist && ctOnly) || (player.Team == CsTeam.CounterTerrorist && ttOnly))
|
||||
{
|
||||
blockReason = "chameleon_wrong_team_info";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!player.IsBot)
|
||||
{
|
||||
string permission = SkillsInfo.GetValue<string>(victimSkill, "requiredPermission");
|
||||
if (!string.IsNullOrEmpty(permission) && !AdminManager.PlayerHasPermissions(player, permission))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SkillsInfo.GetValue<bool>(victimSkill, "needsTeammates")) return true;
|
||||
|
||||
return PlayerManager.GetTickPlayers().Any(p =>
|
||||
p != null && p.IsValid && p.Index != player.Index && p.Team == player.Team
|
||||
&& p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0);
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#5fd98a", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = 2, Rarity rarity = Rarity.Rare) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -78,6 +78,7 @@ namespace src.player.skills
|
|||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (!SkillUtils.IsHudFrame()) return;
|
||||
if (plantingPlayers.IsEmpty) return;
|
||||
|
||||
float currentTime = Server.CurrentTime;
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ namespace src.player.skills
|
|||
KillCamera(playerSkill);
|
||||
}
|
||||
playersInfo.TryRemove(player.Index, out _);
|
||||
SkillUtils.ResetPrintHTML(player);
|
||||
}
|
||||
|
||||
private static void KillCamera(PlayerSkill playerSkill)
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ namespace src.player.skills
|
|||
if (playerInfo?.Skill == skillName)
|
||||
if (SkillPlayerInfo.TryGetValue(eventPlayer!.Index, out var skillInfo))
|
||||
{
|
||||
UpdateHUD(player, skillInfo);
|
||||
if (SkillUtils.IsHudFrame()) UpdateHUD(player, skillInfo);
|
||||
HandleDash(player, skillInfo);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ namespace src.player.skills
|
|||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (distancerPlayers.IsEmpty) return;
|
||||
|
||||
if (!SkillUtils.IsHudFrame()) return;
|
||||
|
||||
if (SkillUtils.IsFreezeTime()) return;
|
||||
foreach (var playerIndex in distancerPlayers.Keys)
|
||||
{
|
||||
|
|
@ -41,8 +45,10 @@ namespace src.player.skills
|
|||
string closetEnemy = "Bot";
|
||||
double closetDistance = double.MaxValue;
|
||||
|
||||
foreach (var enemy in PlayerManager.GetTickPlayers().Where(p => p.Team != player.Team))
|
||||
foreach (var enemy in PlayerManager.GetTickPlayers())
|
||||
{
|
||||
if (enemy == null || enemy.Team == player.Team) continue;
|
||||
|
||||
var enemyPawn = enemy.PlayerPawn.Value;
|
||||
if (enemyPawn == null || !enemyPawn.IsValid) continue;
|
||||
if (enemyPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE || playerPawn.AbsOrigin == null || enemyPawn.AbsOrigin == null) continue;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ namespace src.player.skills
|
|||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (!SkillUtils.IsHudFrame()) return;
|
||||
if (SkillUtils.IsFreezeTime()) return;
|
||||
foreach (var player in PlayerManager.GetTickPlayers())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ namespace src.player.skills
|
|||
var pawn = player!.PlayerPawn.Value;
|
||||
if (pawn == null || !pawn.IsValid || pawn.CameraServices == null) return;
|
||||
|
||||
if (cameras.TryGetValue(player!.Index, out var cameraInfo) && cameraInfo.Item1 == pawn.CameraServices.ViewEntity.Raw)
|
||||
if (cameras.TryGetValue(player!.Index, out var cameraInfo) && cameraInfo.Item1 != pawn.CameraServices.ViewEntity.Raw)
|
||||
BlockWeapon(player, true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ namespace src.player.skills
|
|||
if (!SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
|
||||
continue;
|
||||
|
||||
UpdateHUD(player, skillInfo);
|
||||
if (SkillUtils.IsHudFrame()) UpdateHUD(player, skillInfo);
|
||||
|
||||
if (!skillInfo.IsActive || skillInfo.LightEntityIndex == 0)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ namespace src.player.skills
|
|||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (!SkillUtils.IsHudFrame()) return;
|
||||
foreach (var player in PlayerManager.GetTickPlayers())
|
||||
{
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
|
||||
|
|
|
|||
|
|
@ -46,10 +46,17 @@ namespace src.player.skills
|
|||
if (player == null || !player.IsValid) continue;
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex((PlayerManager.GetPlayerEvent(player)?.Index ?? player.Index));
|
||||
|
||||
var observedPlayer = PlayerManager.GetTickPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == player?.Pawn?.Value?.ObserverServices?.ObserverTarget?.Value?.Handle);
|
||||
var observerInfo = observedPlayer != null ? PlayerManager.GetPlayerByIndex(observedPlayer.Index) : null;
|
||||
if (playerInfo?.Skill != skillName)
|
||||
{
|
||||
var observerTarget = player.Pawn?.Value?.ObserverServices?.ObserverTarget?.Value?.Handle ?? nint.Zero;
|
||||
if (observerTarget == nint.Zero) continue;
|
||||
|
||||
var observedPlayer = PlayerManager.GetTickPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == observerTarget);
|
||||
if (observedPlayer == null) continue;
|
||||
|
||||
if (PlayerManager.GetPlayerByIndex(observedPlayer.Index)?.Skill != skillName) continue;
|
||||
}
|
||||
|
||||
if (playerInfo?.Skill != skillName && observerInfo?.Skill != skillName) continue;
|
||||
foreach (var entityIndex in smokes.Keys)
|
||||
{
|
||||
var entity = Utilities.GetEntityFromIndex<CBaseEntity>((int)entityIndex);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ namespace src.player.skills
|
|||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (!SkillUtils.IsHudFrame()) return;
|
||||
foreach (var player in PlayerManager.GetTickPlayers())
|
||||
{
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
|
||||
|
|
|
|||
316
jRandomSkills - SRC Files/src/player/skills/Grapple.cs
Normal file
316
jRandomSkills - SRC Files/src/player/skills/Grapple.cs
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Drawing;
|
||||
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
|
||||
|
||||
namespace src.player.skills
|
||||
{
|
||||
public class Grapple : ISkill
|
||||
{
|
||||
private const Skills skillName = Skills.Grapple;
|
||||
|
||||
private static readonly ConcurrentDictionary<uint, PlayerSkillInfo> SkillPlayerInfo = [];
|
||||
private static readonly ConcurrentDictionary<uint, byte> liveRopes = [];
|
||||
private static readonly object setLock = new();
|
||||
|
||||
private static readonly Color terroristRope = Color.FromArgb(255, 138, 84, 34);
|
||||
private static readonly Color counterTerroristRope = Color.FromArgb(255, 52, 92, 138);
|
||||
|
||||
private const double attemptCooldown = .3;
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
}
|
||||
|
||||
public static void NewRound()
|
||||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var skillInfo in SkillPlayerInfo.Values)
|
||||
DestroyRope(skillInfo);
|
||||
|
||||
SkillPlayerInfo.Clear();
|
||||
SweepOrphanRopes();
|
||||
}
|
||||
}
|
||||
|
||||
public static void RoundEnd()
|
||||
{
|
||||
foreach (var skillInfo in SkillPlayerInfo.Values)
|
||||
DestroyRope(skillInfo);
|
||||
|
||||
SweepOrphanRopes();
|
||||
}
|
||||
|
||||
public static void EnableSkill(CCSPlayerController player)
|
||||
{
|
||||
if (player == null || !player.IsValid) return;
|
||||
|
||||
SkillPlayerInfo[player.Index] = new PlayerSkillInfo
|
||||
{
|
||||
CanUse = true,
|
||||
Cooldown = DateTime.MinValue,
|
||||
};
|
||||
}
|
||||
|
||||
public static void DisableSkill(CCSPlayerController player)
|
||||
{
|
||||
if (player == null) return;
|
||||
|
||||
if (SkillPlayerInfo.TryRemove(player.Index, out var skillInfo))
|
||||
DestroyRope(skillInfo);
|
||||
|
||||
SkillUtils.ResetPrintHTML(player);
|
||||
}
|
||||
|
||||
public static void PlayerDisconnect(uint playerIndex)
|
||||
{
|
||||
if (SkillPlayerInfo.TryRemove(playerIndex, out var skillInfo))
|
||||
DestroyRope(skillInfo);
|
||||
}
|
||||
|
||||
public static void PlayerDeath(EventPlayerDeath @event)
|
||||
{
|
||||
var player = PlayerManager.GetPlayerEvent(@event.Userid);
|
||||
if (player == null || !player.IsValid) return;
|
||||
|
||||
if (SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo))
|
||||
DestroyRope(skillInfo);
|
||||
}
|
||||
|
||||
public static void UseSkill(CCSPlayerController player)
|
||||
{
|
||||
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
|
||||
|
||||
if (!SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo)) return;
|
||||
|
||||
if (skillInfo.Anchor != null)
|
||||
{
|
||||
DestroyRope(skillInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!skillInfo.CanUse) return;
|
||||
|
||||
if ((DateTime.Now - skillInfo.LastAttempt).TotalSeconds < attemptCooldown) return;
|
||||
skillInfo.LastAttempt = DateTime.Now;
|
||||
|
||||
var playerEvent = PlayerManager.GetPlayerFromEvent(player);
|
||||
|
||||
if (!TryAttach(player, skillInfo))
|
||||
{
|
||||
if (playerEvent != null && playerEvent.IsValid)
|
||||
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("grapple_no_anchor_info"));
|
||||
return;
|
||||
}
|
||||
|
||||
skillInfo.CanUse = false;
|
||||
skillInfo.Cooldown = DateTime.Now;
|
||||
}
|
||||
|
||||
private static bool TryAttach(CCSPlayerController player, PlayerSkillInfo skillInfo)
|
||||
{
|
||||
if (!RayTrace.IsAvailable) return false;
|
||||
|
||||
var pawn = player.PlayerPawn?.Value;
|
||||
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return false;
|
||||
|
||||
var result = RayTrace.EyeTrace(player);
|
||||
if (result == null || !result.Value.DidHit) return false;
|
||||
if (result.Value.HitPlayer(out _)) return false;
|
||||
|
||||
Vector anchor = new(result.Value.EndPosX, result.Value.EndPosY, result.Value.EndPosZ);
|
||||
|
||||
Vector eyePos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z);
|
||||
if (SkillUtils.GetDistance(eyePos, anchor) < SkillsInfo.GetValue<float>(skillName, "minDistance")) return false;
|
||||
|
||||
skillInfo.Anchor = anchor;
|
||||
skillInfo.EndTick = Server.TickCount + (int)(SkillsInfo.GetValue<float>(skillName, "maxPullSeconds") * 64);
|
||||
|
||||
if (!EntityManager.OverBudget())
|
||||
{
|
||||
Color ropeColor = player.Team == CsTeam.Terrorist ? terroristRope : counterTerroristRope;
|
||||
var rope = EntityManager.CreateTrackedBeam(player.Index, eyePos, anchor, ropeColor);
|
||||
|
||||
if (rope != null && rope.IsValid)
|
||||
{
|
||||
float width = SkillsInfo.GetValue<float>(skillName, "ropeWidth");
|
||||
rope.Width = width;
|
||||
rope.EndWidth = width;
|
||||
|
||||
Utilities.SetStateChanged(rope, "CBeam", "m_fWidth");
|
||||
Utilities.SetStateChanged(rope, "CBeam", "m_fEndWidth");
|
||||
|
||||
uint ropeIndex = rope.Index;
|
||||
skillInfo.RopeIndex = ropeIndex;
|
||||
liveRopes[ropeIndex] = 0;
|
||||
|
||||
jRandomSkills.Instance.AddTimer(SkillsInfo.GetValue<float>(skillName, "maxPullSeconds") + 1f,
|
||||
() => KillRope(ropeIndex),
|
||||
CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
player.EmitSound("SolidMetal.BulletImpact");
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void DestroyRope(PlayerSkillInfo skillInfo)
|
||||
{
|
||||
skillInfo.Anchor = null;
|
||||
skillInfo.EndTick = 0;
|
||||
|
||||
if (skillInfo.RopeIndex == null) return;
|
||||
|
||||
uint ropeIndex = skillInfo.RopeIndex.Value;
|
||||
skillInfo.RopeIndex = null;
|
||||
|
||||
KillRope(ropeIndex);
|
||||
}
|
||||
|
||||
private static void KillRope(uint ropeIndex)
|
||||
{
|
||||
if (!liveRopes.TryRemove(ropeIndex, out _)) return;
|
||||
|
||||
var rope = Utilities.GetEntityFromIndex<CBeam>((int)ropeIndex);
|
||||
if (rope != null && rope.IsValid)
|
||||
{
|
||||
rope.Width = 0;
|
||||
rope.EndWidth = 0;
|
||||
rope.Render = Color.FromArgb(0, 0, 0, 0);
|
||||
|
||||
Utilities.SetStateChanged(rope, "CBeam", "m_fWidth");
|
||||
Utilities.SetStateChanged(rope, "CBeam", "m_fEndWidth");
|
||||
Utilities.SetStateChanged(rope, "CBaseModelEntity", "m_clrRender");
|
||||
}
|
||||
|
||||
EntityManager.DestroyEntity(ropeIndex);
|
||||
|
||||
Server.NextFrame(() =>
|
||||
{
|
||||
var leftover = Utilities.GetEntityFromIndex<CBeam>((int)ropeIndex);
|
||||
if (leftover != null && leftover.IsValid)
|
||||
leftover.Remove();
|
||||
});
|
||||
}
|
||||
|
||||
private static void SweepOrphanRopes()
|
||||
{
|
||||
foreach (uint ropeIndex in liveRopes.Keys)
|
||||
KillRope(ropeIndex);
|
||||
}
|
||||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (SkillPlayerInfo.IsEmpty) return;
|
||||
|
||||
bool hudFrame = SkillUtils.IsHudFrame();
|
||||
|
||||
foreach (var player in PlayerManager.GetTickPlayers())
|
||||
{
|
||||
if (player == null || !player.IsValid) continue;
|
||||
if (!SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo)) continue;
|
||||
if (PlayerManager.GetPlayerByIndex(player.Index)?.Skill != skillName) continue;
|
||||
|
||||
if (skillInfo.Anchor != null)
|
||||
HandlePull(player, skillInfo);
|
||||
|
||||
if (hudFrame)
|
||||
UpdateHUD(player, skillInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private static void HandlePull(CCSPlayerController player, PlayerSkillInfo skillInfo)
|
||||
{
|
||||
var pawn = player.PlayerPawn?.Value;
|
||||
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
|
||||
{
|
||||
DestroyRope(skillInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Server.TickCount >= skillInfo.EndTick)
|
||||
{
|
||||
DestroyRope(skillInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
Vector anchor = skillInfo.Anchor!;
|
||||
Vector eyePos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z);
|
||||
|
||||
float dx = anchor.X - eyePos.X;
|
||||
float dy = anchor.Y - eyePos.Y;
|
||||
float dz = anchor.Z - eyePos.Z;
|
||||
float distance = MathF.Sqrt(dx * dx + dy * dy + dz * dz);
|
||||
|
||||
if (distance <= SkillsInfo.GetValue<float>(skillName, "stopDistance"))
|
||||
{
|
||||
DestroyRope(skillInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
float pullSpeed = SkillsInfo.GetValue<float>(skillName, "pullSpeed");
|
||||
float invLength = pullSpeed / distance;
|
||||
|
||||
pawn.AbsVelocity.X = dx * invLength;
|
||||
pawn.AbsVelocity.Y = dy * invLength;
|
||||
pawn.AbsVelocity.Z = dz * invLength;
|
||||
|
||||
if (skillInfo.RopeIndex == null) return;
|
||||
|
||||
var rope = Utilities.GetEntityFromIndex<CBeam>((int)skillInfo.RopeIndex.Value);
|
||||
if (rope == null || !rope.IsValid)
|
||||
{
|
||||
liveRopes.TryRemove(skillInfo.RopeIndex.Value, out _);
|
||||
skillInfo.RopeIndex = null;
|
||||
return;
|
||||
}
|
||||
|
||||
rope.Teleport(eyePos);
|
||||
}
|
||||
|
||||
private static void UpdateHUD(CCSPlayerController player, PlayerSkillInfo skillInfo)
|
||||
{
|
||||
float time = (int)Math.Ceiling((skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue<float>(skillName, "cooldown")) - DateTime.Now).TotalSeconds);
|
||||
float cooldown = Math.Max(time, 0);
|
||||
|
||||
if (cooldown == 0 && !skillInfo.CanUse)
|
||||
skillInfo.CanUse = true;
|
||||
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
|
||||
if (playerInfo == null) return;
|
||||
|
||||
if (skillInfo.Anchor != null)
|
||||
playerInfo.PrintHTML = $"<font color='#00FF00'>{player.GetTranslation("grapple_pulling_info")}</font>";
|
||||
else if (cooldown == 0)
|
||||
playerInfo.PrintHTML = null;
|
||||
else
|
||||
playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
|
||||
}
|
||||
|
||||
public class PlayerSkillInfo
|
||||
{
|
||||
public bool CanUse { get; set; }
|
||||
public DateTime Cooldown { get; set; }
|
||||
public DateTime LastAttempt { get; set; }
|
||||
public Vector? Anchor { get; set; }
|
||||
public uint? RopeIndex { get; set; }
|
||||
public int EndTick { get; set; }
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#38e0c4", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = Rarity.Rare, float cooldown = 10f, float maxDistance = 1500f, float minDistance = 150f, float stopDistance = 90f, float pullSpeed = 850f, float maxPullSeconds = 3f, float ropeWidth = 0.8f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)
|
||||
{
|
||||
public float Cooldown { get; set; } = cooldown;
|
||||
public float MaxDistance { get; set; } = maxDistance;
|
||||
public float MinDistance { get; set; } = minDistance;
|
||||
public float StopDistance { get; set; } = stopDistance;
|
||||
public float PullSpeed { get; set; } = pullSpeed;
|
||||
public float MaxPullSeconds { get; set; } = maxPullSeconds;
|
||||
public float RopeWidth { get; set; } = ropeWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -139,12 +139,14 @@ namespace src.player.skills
|
|||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (activeChickens.IsEmpty) return;
|
||||
|
||||
int tickCooldown = SkillsInfo.GetValue<int>(skillName, "tickCooldown");
|
||||
if (Server.TickCount % tickCooldown == 0) return;
|
||||
|
||||
float boostFactor = SkillsInfo.GetValue<float>(skillName, "boostFactor");
|
||||
|
||||
var players = PlayerManager.GetTickPlayers().ToArray();
|
||||
var players = PlayerManager.GetTickPlayers();
|
||||
int healAmount = SkillsInfo.GetValue<int>(skillName, "heal");
|
||||
float healRadius = SkillsInfo.GetValue<float>(skillName, "healRadius");
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ namespace src.player.skills
|
|||
KillClone(playerSkill);
|
||||
playersInfo.TryRemove(player.Index, out _);
|
||||
EntityManager.DestroyPlayerEntities(player.Index);
|
||||
SkillUtils.ResetPrintHTML(player);
|
||||
}
|
||||
|
||||
private static void UpdateWeapons(CCSPlayerController player, PlayerSkill playerSkill)
|
||||
|
|
@ -146,6 +147,7 @@ namespace src.player.skills
|
|||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (!SkillUtils.IsHudFrame()) return;
|
||||
foreach (var playerSkill in playersInfo.Values)
|
||||
UpdateHUD(playerSkill);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ namespace src.player.skills
|
|||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (!SkillUtils.IsHudFrame()) return;
|
||||
foreach (var player in PlayerManager.GetTickPlayers())
|
||||
{
|
||||
if (player == null || !player.IsValid) continue;
|
||||
|
|
|
|||
201
jRandomSkills - SRC Files/src/player/skills/Inheritance.cs
Normal file
201
jRandomSkills - SRC Files/src/player/skills/Inheritance.cs
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using static src.jRandomSkills;
|
||||
|
||||
namespace src.player.skills
|
||||
{
|
||||
public class Inheritance : ISkill
|
||||
{
|
||||
private const Skills skillName = Skills.Inheritance;
|
||||
|
||||
private static readonly ConcurrentDictionary<uint, byte> holders = [];
|
||||
private static readonly ConcurrentDictionary<uint, FallenInfo> fallen = [];
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
}
|
||||
|
||||
public static void NewRound()
|
||||
{
|
||||
holders.Clear();
|
||||
fallen.Clear();
|
||||
|
||||
foreach (var player in PlayerManager.GetTickPlayers())
|
||||
SkillUtils.CloseMenu(player);
|
||||
}
|
||||
|
||||
public static void EnableSkill(CCSPlayerController player)
|
||||
{
|
||||
if (player == null || !player.IsValid) return;
|
||||
|
||||
holders[player.Index] = 0;
|
||||
RefreshMenu(player);
|
||||
}
|
||||
|
||||
public static void DisableSkill(CCSPlayerController player)
|
||||
{
|
||||
if (player == null) return;
|
||||
|
||||
holders.TryRemove(player.Index, out _);
|
||||
SkillUtils.CloseMenu(player);
|
||||
}
|
||||
|
||||
public static void PlayerDisconnect(uint playerIndex)
|
||||
{
|
||||
holders.TryRemove(playerIndex, out _);
|
||||
fallen.TryRemove(playerIndex, out _);
|
||||
}
|
||||
|
||||
public static void PlayerDeath(EventPlayerDeath @event)
|
||||
{
|
||||
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
|
||||
if (victim == null || !victim.IsValid) return;
|
||||
|
||||
holders.TryRemove(victim.Index, out _);
|
||||
|
||||
var victimInfo = PlayerManager.GetPlayerByIndex(victim.Index);
|
||||
if (victimInfo == null || victimInfo.IsDrawing) return;
|
||||
if (victimInfo.Skill == Skills.None || victimInfo.Skill == skillName) return;
|
||||
if (SkillData.GetInfo(victimInfo.Skill) == null) return;
|
||||
|
||||
fallen[victim.Index] = new FallenInfo
|
||||
{
|
||||
PlayerName = victim.PlayerName,
|
||||
Skill = victimInfo.Skill,
|
||||
Team = victim.Team,
|
||||
};
|
||||
|
||||
foreach (uint holderIndex in holders.Keys)
|
||||
{
|
||||
var holder = Utilities.GetPlayerFromIndex((int)holderIndex);
|
||||
if (holder == null || !holder.IsValid || holder.Team != victim.Team) continue;
|
||||
|
||||
RefreshMenu(holder);
|
||||
}
|
||||
}
|
||||
|
||||
public static void TypeSkill(CCSPlayerController player, string[] commands)
|
||||
{
|
||||
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
|
||||
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player.Index);
|
||||
if (playerInfo?.Skill != skillName) return;
|
||||
|
||||
var playerEvent = PlayerManager.GetPlayerFromEvent(player);
|
||||
if (playerEvent == null || !playerEvent.IsValid) return;
|
||||
|
||||
if (commands == null || commands.Length == 0 || !uint.TryParse(commands[0], out uint fallenIndex))
|
||||
{
|
||||
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fallen.TryGetValue(fallenIndex, out var fallenInfo) || !CanInherit(player, fallenInfo))
|
||||
{
|
||||
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("selectplayerskill_incorrect_enemy_index"));
|
||||
return;
|
||||
}
|
||||
|
||||
InheritSkill(player, fallenInfo);
|
||||
}
|
||||
|
||||
private static void InheritSkill(CCSPlayerController player, FallenInfo fallenInfo)
|
||||
{
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player.Index);
|
||||
if (playerInfo == null) return;
|
||||
|
||||
var playerEvent = PlayerManager.GetPlayerFromEvent(player);
|
||||
if (playerEvent == null || !playerEvent.IsValid) return;
|
||||
|
||||
uint playerIndex = player.Index;
|
||||
Skills inheritedSkill = fallenInfo.Skill;
|
||||
|
||||
holders.TryRemove(playerIndex, out _);
|
||||
SkillUtils.CloseMenu(player);
|
||||
|
||||
Instance.AddTimer(.1f, () =>
|
||||
{
|
||||
var target = Utilities.GetPlayerFromIndex((int)playerIndex);
|
||||
if (target == null || !target.IsValid) return;
|
||||
|
||||
var targetInfo = PlayerManager.GetPlayerByIndex(playerIndex);
|
||||
if (targetInfo == null || targetInfo.Skill != skillName) return;
|
||||
|
||||
targetInfo.Skill = inheritedSkill;
|
||||
targetInfo.SpecialSkill = skillName;
|
||||
|
||||
SkillUtils.CloseMenu(target);
|
||||
|
||||
if (SkillsInfo.GetValue<bool>(inheritedSkill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
|
||||
Instance?.AddTimer(Math.Max((float)(Event.GetFreezeTimeEnd() - DateTime.Now).TotalSeconds, 0), () =>
|
||||
{
|
||||
var heir = Utilities.GetPlayerFromIndex((int)playerIndex);
|
||||
if (heir == null || !heir.IsValid) return;
|
||||
|
||||
if (PlayerManager.GetPlayerByIndex(playerIndex)?.Skill != inheritedSkill) return;
|
||||
Instance?.SkillAction(inheritedSkill.ToString(), "EnableSkill", [heir]);
|
||||
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||
else
|
||||
Instance?.SkillAction(inheritedSkill.ToString(), "EnableSkill", [target]);
|
||||
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||
|
||||
playerEvent.PrintToChat($" {ChatColors.Green}" + playerEvent.GetTranslation("inheritance_player_info", fallenInfo.PlayerName));
|
||||
}
|
||||
|
||||
private static void RefreshMenu(CCSPlayerController player)
|
||||
{
|
||||
if (player == null || !player.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
|
||||
if (PlayerManager.GetPlayerByIndex(player.Index)?.Skill != skillName) return;
|
||||
|
||||
ConcurrentBag<(string, string)> menuItems = [];
|
||||
foreach (var (fallenIndex, fallenInfo) in fallen)
|
||||
{
|
||||
if (fallenIndex == player.Index) continue;
|
||||
if (!CanInherit(player, fallenInfo)) continue;
|
||||
|
||||
menuItems.Add(($"\u202A{fallenInfo.PlayerName}\u202C : {player.GetSkillName(fallenInfo.Skill)}", fallenIndex.ToString()));
|
||||
}
|
||||
|
||||
if (menuItems.IsEmpty) return;
|
||||
|
||||
if (SkillUtils.HasMenu(player))
|
||||
SkillUtils.UpdateMenu(player, menuItems);
|
||||
else
|
||||
SkillUtils.CreateMenu(player, menuItems);
|
||||
}
|
||||
|
||||
private static bool CanInherit(CCSPlayerController player, FallenInfo fallenInfo)
|
||||
{
|
||||
if (fallenInfo.Team != player.Team) return false;
|
||||
|
||||
if (!player.IsBot)
|
||||
{
|
||||
string permission = SkillsInfo.GetValue<string>(fallenInfo.Skill, "requiredPermission");
|
||||
if (!string.IsNullOrEmpty(permission) && !AdminManager.PlayerHasPermissions(player, permission))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SkillsInfo.GetValue<bool>(fallenInfo.Skill, "needsTeammates")) return true;
|
||||
|
||||
return PlayerManager.GetTickPlayers().Any(p =>
|
||||
p != null && p.IsValid && p.Index != player.Index && p.Team == player.Team
|
||||
&& p.PlayerPawn?.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0);
|
||||
}
|
||||
|
||||
private class FallenInfo
|
||||
{
|
||||
public required string PlayerName { get; set; }
|
||||
public required Skills Skill { get; set; }
|
||||
public required CsTeam Team { get; set; }
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#c9a227", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = true, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = 2, Rarity rarity = Rarity.Rare) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -38,9 +38,27 @@ namespace src.player.skills
|
|||
playersInAction.Clear();
|
||||
}
|
||||
|
||||
private static readonly List<(CsTeam OwnerTeam, uint RelayEntityIndex)> transmitTrails = [];
|
||||
|
||||
public static void CheckTransmit([CastFrom(typeof(nint))] CCheckTransmitInfoList infoList)
|
||||
{
|
||||
var snapshot = activeTrails.ToArray();
|
||||
if (activeTrails.IsEmpty) return;
|
||||
|
||||
transmitTrails.Clear();
|
||||
foreach (var (trackedPlayerIndex, relayIndex) in activeTrails)
|
||||
{
|
||||
if (relayIndex == null) continue;
|
||||
|
||||
var trailOwner = Utilities.GetPlayerFromIndex((int)trackedPlayerIndex);
|
||||
if (trailOwner == null || !trailOwner.IsValid) continue;
|
||||
|
||||
var relayEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)relayIndex);
|
||||
if (relayEntity == null || !relayEntity.IsValid) continue;
|
||||
|
||||
transmitTrails.Add((trailOwner.Team, relayEntity.Index));
|
||||
}
|
||||
|
||||
if (transmitTrails.Count == 0) return;
|
||||
|
||||
foreach (var (info, player) in infoList)
|
||||
{
|
||||
|
|
@ -65,19 +83,12 @@ namespace src.player.skills
|
|||
}
|
||||
}
|
||||
|
||||
foreach (var (trackedPlayerIndex, relayIndex) in snapshot)
|
||||
var playerTeam = player.Team;
|
||||
foreach (var (ownerTeam, relayEntityIndex) in transmitTrails)
|
||||
{
|
||||
if (relayIndex == null) continue;
|
||||
|
||||
var trailOwner = Utilities.GetPlayerFromIndex((int)trackedPlayerIndex);
|
||||
if (trailOwner == null || !trailOwner.IsValid) continue;
|
||||
|
||||
var relayEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)relayIndex);
|
||||
if (relayEntity == null || !relayEntity.IsValid) continue;
|
||||
|
||||
if (player.Team == trailOwner.Team || !isJackalOwner)
|
||||
if (info.TransmitEntities.Contains(relayEntity.Index))
|
||||
info.TransmitEntities.Remove(relayEntity.Index);
|
||||
if (playerTeam == ownerTeam || !isJackalOwner)
|
||||
if (info.TransmitEntities.Contains(relayEntityIndex))
|
||||
info.TransmitEntities.Remove(relayEntityIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -135,14 +146,6 @@ namespace src.player.skills
|
|||
Event.EnableTransmit();
|
||||
playersInAction.TryAdd(player.Index, 0);
|
||||
|
||||
var opponents = PlayerManager.GetTickPlayers()
|
||||
.Where(p => p != null
|
||||
&& p.IsValid
|
||||
&& p.Team != player.Team
|
||||
&& p.PawnIsAlive
|
||||
&& (p.Team is CsTeam.CounterTerrorist or CsTeam.Terrorist))
|
||||
.ToArray();
|
||||
|
||||
mainSkillTimer ??= Instance.AddTimer(2.5f, () => UpdateAllTrails(),
|
||||
CounterStrikeSharp.API.Modules.Timers.TimerFlags.REPEAT | CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||
|
||||
|
|
|
|||
|
|
@ -235,6 +235,7 @@ namespace src.player.skills
|
|||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (!SkillUtils.IsHudFrame()) return;
|
||||
if (SkillUtils.IsFreezeTime()) return;
|
||||
foreach (var player in PlayerManager.GetTickPlayers())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ namespace src.player.skills
|
|||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (!SkillUtils.IsHudFrame()) return;
|
||||
if (SkillUtils.IsFreezeTime()) return;
|
||||
foreach (var player in PlayerManager.GetTickPlayers())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ namespace src.player.skills
|
|||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (!SkillUtils.IsHudFrame()) return;
|
||||
foreach (var player in PlayerManager.GetTickPlayers())
|
||||
{
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@ namespace src.player.skills
|
|||
{
|
||||
foreach (var player in PlayerManager.GetTickPlayers())
|
||||
{
|
||||
if (!Instance.IsPlayerValid(player)) continue;
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
|
||||
if (player == null) continue;
|
||||
|
||||
if (PlayerManager.GetPlayerByIndex(player.Index)?.Skill != skillName) continue;
|
||||
if (!Instance.IsPlayerValid(player)) continue;
|
||||
|
||||
if (playerInfo?.Skill == skillName)
|
||||
{
|
||||
var pawn = player.PlayerPawn.Value!;
|
||||
var weaponServices = pawn.WeaponServices;
|
||||
if (weaponServices == null || weaponServices.ActiveWeapon == null || !weaponServices.ActiveWeapon.IsValid) continue;
|
||||
|
|
@ -45,7 +45,6 @@ namespace src.player.skills
|
|||
Schema.SetSchemaValue<Int32>(weapon.Handle, "CBasePlayerWeapon", "m_nNextSecondaryAttackTick", Server.TickCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8a42f5", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = Rarity.Common) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,10 +21,11 @@ namespace src.player.skills
|
|||
foreach (var player in PlayerManager.GetTickPlayers())
|
||||
{
|
||||
var playerEvent = PlayerManager.GetPlayerEvent(player);
|
||||
if (playerEvent == null) continue;
|
||||
|
||||
if (PlayerManager.GetPlayerByIndex(playerEvent.Index)?.Skill != skillName) continue;
|
||||
if (!Instance.IsPlayerValid(playerEvent)) continue;
|
||||
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(playerEvent!.Index);
|
||||
if (playerInfo?.Skill == skillName)
|
||||
SetEnemiesVisibleOnRadar(player);
|
||||
}
|
||||
}
|
||||
|
|
@ -36,8 +37,10 @@ namespace src.player.skills
|
|||
// SpottedByMask is indexed by player slot (0-63), not entity index.
|
||||
int slot = player.Slot;
|
||||
|
||||
foreach (var enemy in PlayerManager.GetTickPlayers().FindAll(p => p.Team != player.Team))
|
||||
foreach (var enemy in PlayerManager.GetTickPlayers())
|
||||
{
|
||||
if (enemy == null || enemy.Team == player.Team) continue;
|
||||
|
||||
var enemyEvent = PlayerManager.GetPlayerEvent(enemy);
|
||||
if (enemyEvent == null || !enemyEvent.IsValid) continue;
|
||||
|
||||
|
|
@ -59,7 +62,7 @@ namespace src.player.skills
|
|||
|
||||
public class SkillConfig : SkillsInfo.DefaultSkillInfo
|
||||
{
|
||||
public SkillConfig(Skills skill = skillName, bool active = true, string color = "#2effcb", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = utils.Rarity.Common) : base(skill, active, color, onlyTeam, needsTeammates)
|
||||
public SkillConfig(Skills skill = skillName, bool active = true, string color = "#2effcb", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = utils.Rarity.Common) : base(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ namespace src.player.skills
|
|||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (!SkillUtils.IsHudFrame()) return;
|
||||
var players = PlayerManager.GetTickPlayers().ToArray();
|
||||
foreach (var player in players)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ namespace src.player.skills
|
|||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (!SkillUtils.IsHudFrame()) return;
|
||||
foreach (var player in PlayerManager.GetTickPlayers())
|
||||
{
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace src.player.skills
|
|||
{
|
||||
public int HealthToAdd { get; set; }
|
||||
public float Cooldown { get; set; }
|
||||
public SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff462e", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = utils.Rarity.Common, int healthToAdd = 1, float cooldown = .25f) : base(skill, active, color, onlyTeam, needsTeammates)
|
||||
public SkillConfig(Skills skill = skillName, bool active = true, string color = "#ff462e", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = utils.Rarity.Common, int healthToAdd = 1, float cooldown = .25f) : base(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)
|
||||
{
|
||||
HealthToAdd = healthToAdd;
|
||||
Cooldown = cooldown;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ namespace src.player.skills
|
|||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (!SkillUtils.IsHudFrame()) return;
|
||||
foreach (var player in PlayerManager.GetTickPlayers())
|
||||
{
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ namespace src.player.skills
|
|||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (!SkillUtils.IsHudFrame()) return;
|
||||
foreach (var player in PlayerManager.GetTickPlayers())
|
||||
{
|
||||
var playerInfo = PlayerManager.GetPlayerByIndex(player!.Index);
|
||||
|
|
|
|||
661
jRandomSkills - SRC Files/src/player/skills/Ricochet.cs
Normal file
661
jRandomSkills - SRC Files/src/player/skills/Ricochet.cs
Normal file
|
|
@ -0,0 +1,661 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using jRandomSkills.src.utils;
|
||||
using RayTraceAPI;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Drawing;
|
||||
using System.Numerics;
|
||||
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
|
||||
|
||||
namespace src.player.skills
|
||||
{
|
||||
public class Ricochet : ISkill
|
||||
{
|
||||
private const Skills skillName = Skills.Ricochet;
|
||||
|
||||
private static readonly ConcurrentDictionary<uint, ImpactBudget> impactBudgets = [];
|
||||
private static readonly HashSet<uint> ownedTracers = [];
|
||||
private static readonly List<uint> tracerPool = [];
|
||||
private static readonly List<Flight> flights = [];
|
||||
private static readonly object flightLock = new();
|
||||
private static readonly Color tracerColor = Color.FromArgb(170, 255, 226, 140);
|
||||
private static readonly ulong worldOnlyMask = (ulong)InteractionLayers.MASK_WORLD_ONLY;
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
}
|
||||
|
||||
public static void NewRound()
|
||||
{
|
||||
impactBudgets.Clear();
|
||||
ResetPool(false);
|
||||
}
|
||||
|
||||
public static void RoundEnd()
|
||||
{
|
||||
ResetPool(true);
|
||||
}
|
||||
|
||||
public static void PlayerDisconnect(uint playerIndex)
|
||||
{
|
||||
impactBudgets.TryRemove(playerIndex, out _);
|
||||
}
|
||||
|
||||
public static void DisableSkill(CCSPlayerController player)
|
||||
{
|
||||
if (player == null) return;
|
||||
impactBudgets.TryRemove(player.Index, out _);
|
||||
}
|
||||
|
||||
public static void BulletImpact(EventBulletImpact @event)
|
||||
{
|
||||
var player = PlayerManager.GetPlayerEvent(@event.Userid);
|
||||
if (player == null || !player.IsValid) return;
|
||||
|
||||
if (PlayerManager.GetPlayerByIndex(player.Index)?.Skill != skillName) return;
|
||||
|
||||
if (!RayTrace.IsAvailable)
|
||||
{
|
||||
Trace("RayTrace module unavailable");
|
||||
return;
|
||||
}
|
||||
|
||||
var pawn = player.PlayerPawn?.Value;
|
||||
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
|
||||
{
|
||||
Trace("shooter pawn invalid or dead");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryConsumeBudget(player.Index)) return;
|
||||
|
||||
Vector3 eyePos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z);
|
||||
Vector3 impact = new(@event.X, @event.Y, @event.Z);
|
||||
|
||||
Vector3 toImpact = impact - eyePos;
|
||||
if (toImpact.LengthSquared() < 1f)
|
||||
{
|
||||
Trace("impact too close to eye");
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 direction = Vector3.Normalize(toImpact);
|
||||
|
||||
var surface = RayTrace.TraceShape(player, ToVector(eyePos), ToVector(impact + direction * 8f), worldOnlyMask, 0);
|
||||
if (surface == null)
|
||||
{
|
||||
Trace("surface trace returned null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!surface.Value.DidHit)
|
||||
{
|
||||
Trace($"surface trace missed (fraction={surface.Value.Fraction:0.###})");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryResolveNormal(player, surface.Value, direction, out Vector3 normal))
|
||||
{
|
||||
Trace("could not resolve surface normal");
|
||||
return;
|
||||
}
|
||||
|
||||
Bounce(player, pawn, surface.Value.EndPos, direction, normal);
|
||||
}
|
||||
|
||||
private static void Bounce(CCSPlayerController player, CCSPlayerPawn pawn, Vector3 point, Vector3 direction, Vector3 normal)
|
||||
{
|
||||
int bounces = Math.Max(SkillsInfo.GetValue<int>(skillName, "bounces"), 1);
|
||||
float segmentDistance = SkillsInfo.GetValue<float>(skillName, "segmentDistance");
|
||||
float damageFalloff = SkillsInfo.GetValue<float>(skillName, "damageFalloff");
|
||||
|
||||
var vdata = GetWeaponVData(pawn);
|
||||
float damage = GetBaseDamage(vdata);
|
||||
|
||||
KillfeedIcons? killfeedIcon = KillfeedIconsExtensions.FromWeaponName(SkillUtils.GetDesignerName(pawn.WeaponServices?.ActiveWeapon?.Value));
|
||||
|
||||
List<Vector3> path = [];
|
||||
|
||||
for (int i = 0; i < bounces; i++)
|
||||
{
|
||||
direction = Vector3.Reflect(direction, normal);
|
||||
|
||||
Vector3 start = point + normal * 2f;
|
||||
if (path.Count == 0) path.Add(start);
|
||||
|
||||
Vector3 end = start + direction * segmentDistance;
|
||||
|
||||
var hit = RayTrace.TraceShape(player, ToVector(start), ToVector(end));
|
||||
if (hit == null)
|
||||
{
|
||||
Trace($"bounce {i + 1}: segment trace returned null");
|
||||
break;
|
||||
}
|
||||
|
||||
Vector3 stop = hit.Value.DidHit ? hit.Value.EndPos : end;
|
||||
path.Add(stop);
|
||||
|
||||
if (!hit.Value.DidHit)
|
||||
{
|
||||
Trace($"bounce {i + 1}: no surface, len={Vector3.Distance(start, stop):0.#}");
|
||||
break;
|
||||
}
|
||||
|
||||
if (hit.Value.HitPlayer(out var victim))
|
||||
{
|
||||
DealDamage(player, victim, damage, vdata, killfeedIcon);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!TryResolveNormal(player, hit.Value, direction, out normal))
|
||||
{
|
||||
Trace($"bounce {i + 1}: could not resolve normal");
|
||||
break;
|
||||
}
|
||||
|
||||
point = hit.Value.EndPos;
|
||||
damage *= damageFalloff;
|
||||
}
|
||||
|
||||
StartFlight(player, path);
|
||||
}
|
||||
|
||||
public static void OnTick()
|
||||
{
|
||||
lock (flightLock)
|
||||
{
|
||||
if (flights.Count == 0) return;
|
||||
|
||||
float speed = MathF.Max(SkillsInfo.GetValue<float>(skillName, "tracerSpeed"), 100f);
|
||||
float trail = MathF.Max(SkillsInfo.GetValue<float>(skillName, "tracerLength"), 16f);
|
||||
float step = speed / 64f;
|
||||
int tick = Server.TickCount;
|
||||
|
||||
for (int i = flights.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var flight = flights[i];
|
||||
flight.Travelled += step;
|
||||
|
||||
if (flight.Travelled - trail >= flight.TotalLength || tick >= flight.DeadlineTick)
|
||||
{
|
||||
ReleaseTracer(flight);
|
||||
flights.RemoveAt(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
float head = MathF.Min(flight.Travelled, flight.TotalLength);
|
||||
int segment = SegmentAt(flight, head);
|
||||
float tail = MathF.Max(head - trail, flight.Cumulative[segment]);
|
||||
|
||||
UpdateTracer(flight, PointAt(flight, tail), PointAt(flight, head));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void StartFlight(CCSPlayerController player, List<Vector3> path)
|
||||
{
|
||||
if (path.Count < 2) return;
|
||||
if (!SkillsInfo.GetValue<bool>(skillName, "showTracer")) return;
|
||||
if (EntityManager.OverBudget()) return;
|
||||
|
||||
var points = path.ToArray();
|
||||
var cumulative = new float[points.Length];
|
||||
|
||||
for (int i = 1; i < points.Length; i++)
|
||||
cumulative[i] = cumulative[i - 1] + Vector3.Distance(points[i - 1], points[i]);
|
||||
|
||||
float total = cumulative[^1];
|
||||
if (total < 1f) return;
|
||||
|
||||
float speed = MathF.Max(SkillsInfo.GetValue<float>(skillName, "tracerSpeed"), 100f);
|
||||
|
||||
lock (flightLock)
|
||||
{
|
||||
if (flights.Count >= Math.Max(SkillsInfo.GetValue<int>(skillName, "maxActiveTracers"), 1)) return;
|
||||
|
||||
flights.Add(new Flight
|
||||
{
|
||||
OwnerIndex = player.Index,
|
||||
Points = points,
|
||||
Cumulative = cumulative,
|
||||
TotalLength = total,
|
||||
DeadlineTick = Server.TickCount + (int)(total / speed * 64f) + 128,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static int SegmentAt(Flight flight, float distance)
|
||||
{
|
||||
for (int i = flight.Points.Length - 2; i >= 0; i--)
|
||||
if (distance >= flight.Cumulative[i]) return i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static Vector3 PointAt(Flight flight, float distance)
|
||||
{
|
||||
int i = SegmentAt(flight, distance);
|
||||
|
||||
float segmentStart = flight.Cumulative[i];
|
||||
float segmentLength = flight.Cumulative[i + 1] - segmentStart;
|
||||
if (segmentLength <= .0001f) return flight.Points[i];
|
||||
|
||||
float t = Math.Clamp((distance - segmentStart) / segmentLength, 0f, 1f);
|
||||
return Vector3.Lerp(flight.Points[i], flight.Points[i + 1], t);
|
||||
}
|
||||
|
||||
private static void UpdateTracer(Flight flight, Vector3 tail, Vector3 head)
|
||||
{
|
||||
CBeam? beam = null;
|
||||
|
||||
if (flight.BeamIndex != null)
|
||||
{
|
||||
beam = ResolveTracer(flight.BeamIndex.Value);
|
||||
if (beam == null)
|
||||
{
|
||||
ownedTracers.Remove(flight.BeamIndex.Value);
|
||||
flight.BeamIndex = null;
|
||||
}
|
||||
}
|
||||
|
||||
beam ??= AcquireTracer(flight);
|
||||
if (beam == null) return;
|
||||
|
||||
beam.Teleport(ToVector(tail));
|
||||
|
||||
beam.EndPos.X = head.X;
|
||||
beam.EndPos.Y = head.Y;
|
||||
beam.EndPos.Z = head.Z;
|
||||
|
||||
Utilities.SetStateChanged(beam, "CBeam", "m_vecEndPos");
|
||||
}
|
||||
|
||||
private static CBeam? AcquireTracer(Flight flight)
|
||||
{
|
||||
float width = SkillsInfo.GetValue<float>(skillName, "tracerWidth");
|
||||
|
||||
while (tracerPool.Count > 0)
|
||||
{
|
||||
uint pooledIndex = tracerPool[^1];
|
||||
tracerPool.RemoveAt(tracerPool.Count - 1);
|
||||
|
||||
var pooled = ResolveTracer(pooledIndex);
|
||||
if (pooled == null)
|
||||
{
|
||||
ownedTracers.Remove(pooledIndex);
|
||||
continue;
|
||||
}
|
||||
|
||||
pooled.Width = width;
|
||||
pooled.EndWidth = width;
|
||||
pooled.Render = tracerColor;
|
||||
|
||||
Utilities.SetStateChanged(pooled, "CBeam", "m_fWidth");
|
||||
Utilities.SetStateChanged(pooled, "CBeam", "m_fEndWidth");
|
||||
Utilities.SetStateChanged(pooled, "CBaseModelEntity", "m_clrRender");
|
||||
|
||||
flight.BeamIndex = pooledIndex;
|
||||
return pooled;
|
||||
}
|
||||
|
||||
if (ownedTracers.Count >= Math.Max(SkillsInfo.GetValue<int>(skillName, "maxActiveTracers"), 1)) return null;
|
||||
if (EntityManager.OverBudget()) return null;
|
||||
|
||||
var beam = CreateTracerBeam(flight.Points[0], width);
|
||||
if (beam == null) return null;
|
||||
|
||||
ownedTracers.Add(beam.Index);
|
||||
flight.BeamIndex = beam.Index;
|
||||
return beam;
|
||||
}
|
||||
|
||||
private static CBeam? CreateTracerBeam(Vector3 at, float width)
|
||||
{
|
||||
try
|
||||
{
|
||||
var beam = Utilities.CreateEntityByName<CBeam>("beam");
|
||||
if (beam == null || !beam.IsValid) return null;
|
||||
|
||||
beam.Render = tracerColor;
|
||||
beam.Width = width;
|
||||
beam.EndWidth = width;
|
||||
|
||||
beam.Teleport(ToVector(at));
|
||||
|
||||
beam.EndPos.X = at.X;
|
||||
beam.EndPos.Y = at.Y;
|
||||
beam.EndPos.Z = at.Z;
|
||||
|
||||
beam.DispatchSpawn();
|
||||
return beam;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Trace($"beam create failed: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReleaseTracer(Flight flight)
|
||||
{
|
||||
if (flight.BeamIndex == null) return;
|
||||
|
||||
uint beamIndex = flight.BeamIndex.Value;
|
||||
flight.BeamIndex = null;
|
||||
|
||||
if (!ownedTracers.Contains(beamIndex)) return;
|
||||
|
||||
var beam = ResolveTracer(beamIndex);
|
||||
if (beam == null)
|
||||
{
|
||||
ownedTracers.Remove(beamIndex);
|
||||
Trace($"tracer {beamIndex} vanished before release");
|
||||
return;
|
||||
}
|
||||
|
||||
HideTracer(beam);
|
||||
tracerPool.Add(beamIndex);
|
||||
}
|
||||
|
||||
private static void HideTracer(CBeam beam)
|
||||
{
|
||||
beam.Width = 0;
|
||||
beam.EndWidth = 0;
|
||||
beam.Render = Color.FromArgb(0, 0, 0, 0);
|
||||
|
||||
Utilities.SetStateChanged(beam, "CBeam", "m_fWidth");
|
||||
Utilities.SetStateChanged(beam, "CBeam", "m_fEndWidth");
|
||||
Utilities.SetStateChanged(beam, "CBaseModelEntity", "m_clrRender");
|
||||
|
||||
if (beam.AbsOrigin == null) return;
|
||||
|
||||
beam.EndPos.X = beam.AbsOrigin.X;
|
||||
beam.EndPos.Y = beam.AbsOrigin.Y;
|
||||
beam.EndPos.Z = beam.AbsOrigin.Z;
|
||||
|
||||
Utilities.SetStateChanged(beam, "CBeam", "m_vecEndPos");
|
||||
}
|
||||
|
||||
private static void ResetPool(bool hideEntities)
|
||||
{
|
||||
lock (flightLock)
|
||||
{
|
||||
foreach (var flight in flights)
|
||||
flight.BeamIndex = null;
|
||||
|
||||
flights.Clear();
|
||||
|
||||
if (hideEntities)
|
||||
foreach (uint beamIndex in ownedTracers)
|
||||
{
|
||||
var beam = ResolveTracer(beamIndex);
|
||||
if (beam != null) HideTracer(beam);
|
||||
}
|
||||
|
||||
if (ownedTracers.Count > 0)
|
||||
Trace($"pool reset: {ownedTracers.Count} tracer(s) released");
|
||||
|
||||
tracerPool.Clear();
|
||||
ownedTracers.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private static CBeam? ResolveTracer(uint beamIndex)
|
||||
{
|
||||
var beam = Utilities.GetEntityFromIndex<CBeam>((int)beamIndex);
|
||||
if (beam == null || !beam.IsValid) return null;
|
||||
|
||||
return beam.DesignerName == "beam" ? beam : null;
|
||||
}
|
||||
|
||||
private static CCSWeaponBaseVData? GetWeaponVData(CCSPlayerPawn pawn)
|
||||
{
|
||||
var activeWeapon = pawn.WeaponServices?.ActiveWeapon?.Value;
|
||||
if (activeWeapon == null || !activeWeapon.IsValid) return null;
|
||||
|
||||
try
|
||||
{
|
||||
return activeWeapon.As<CCSWeaponBase>().GetVData<CCSWeaponBaseVData>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static float GetBaseDamage(CCSWeaponBaseVData? vdata)
|
||||
{
|
||||
float fallback = SkillsInfo.GetValue<float>(skillName, "fallbackDamage");
|
||||
if (vdata == null) return fallback;
|
||||
|
||||
float weaponDamage = vdata.Damage;
|
||||
if (weaponDamage <= 0) return fallback;
|
||||
|
||||
return weaponDamage * SkillsInfo.GetValue<float>(skillName, "damageMultiplier");
|
||||
}
|
||||
|
||||
private static void DealDamage(CCSPlayerController attacker, CCSPlayerController? victim, float damage, CCSWeaponBaseVData? vdata, KillfeedIcons? killfeedIcon)
|
||||
{
|
||||
if (victim == null || !victim.IsValid) return;
|
||||
|
||||
var victimEvent = PlayerManager.GetPlayerEvent(victim);
|
||||
if (victimEvent == null || !victimEvent.IsValid) return;
|
||||
if (victimEvent.Index == attacker.Index || victimEvent.Team == attacker.Team) return;
|
||||
|
||||
var victimPawn = victimEvent.PlayerPawn?.Value;
|
||||
if (victimPawn == null || !victimPawn.IsValid || victimPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
|
||||
|
||||
if (vdata != null && victimEvent.PawnArmor > 0 && SkillsInfo.GetValue<bool>(skillName, "respectArmor"))
|
||||
damage *= vdata.ArmorRatio * .5f;
|
||||
|
||||
int finalDamage = (int)MathF.Round(damage);
|
||||
if (finalDamage <= 0) return;
|
||||
|
||||
Trace($"hit {victimEvent.PlayerName} for {finalDamage}");
|
||||
SkillUtils.TakeHealth(victimPawn, finalDamage, attacker, killfeedIcon ?? KillfeedIcons.Leg);
|
||||
}
|
||||
|
||||
private static bool TryResolveNormal(CCSPlayerController player, CustomTraceResult result, Vector3 direction, out Vector3 normal)
|
||||
{
|
||||
normal = Vector3.Zero;
|
||||
|
||||
if (!TryRoughNormal(player, result, direction, out Vector3 rough)) return false;
|
||||
|
||||
if (TryRefineNormal(player, result.EndPos, direction, rough, out normal)) return true;
|
||||
|
||||
Trace("surface refine failed, using rough normal");
|
||||
normal = rough;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool TryRoughNormal(CCSPlayerController player, CustomTraceResult result, Vector3 direction, out Vector3 rough)
|
||||
{
|
||||
rough = result.Normal;
|
||||
if (rough.LengthSquared() > .0001f)
|
||||
{
|
||||
rough = Vector3.Normalize(rough);
|
||||
if (Vector3.Dot(direction, rough) < -.05f) return true;
|
||||
}
|
||||
|
||||
return TryPlaneFitNormal(player, result.EndPos, direction, out rough);
|
||||
}
|
||||
|
||||
private static bool TryRefineNormal(CCSPlayerController player, Vector3 baseHit, Vector3 direction, Vector3 rough, out Vector3 normal)
|
||||
{
|
||||
normal = Vector3.Zero;
|
||||
|
||||
Vector3 axis = MathF.Abs(rough.Z) > .9f ? Vector3.UnitX : Vector3.UnitZ;
|
||||
Vector3 first = Vector3.Cross(rough, axis);
|
||||
if (first.LengthSquared() < .0001f) return false;
|
||||
first = Vector3.Normalize(first);
|
||||
|
||||
Vector3 second = Vector3.Normalize(Vector3.Cross(rough, first));
|
||||
|
||||
float offset = MathF.Max(SkillsInfo.GetValue<float>(skillName, "normalProbeOffset"), 1f);
|
||||
float tolerance = offset * 2.5f;
|
||||
|
||||
Span<Vector3> ring = stackalloc Vector3[4];
|
||||
int count = 0;
|
||||
|
||||
if (SampleSurface(player, baseHit, rough, first * offset, tolerance, out Vector3 firstPlus)) ring[count++] = firstPlus;
|
||||
if (SampleSurface(player, baseHit, rough, second * offset, tolerance, out Vector3 secondPlus)) ring[count++] = secondPlus;
|
||||
if (SampleSurface(player, baseHit, rough, first * -offset, tolerance, out Vector3 firstMinus)) ring[count++] = firstMinus;
|
||||
if (SampleSurface(player, baseHit, rough, second * -offset, tolerance, out Vector3 secondMinus)) ring[count++] = secondMinus;
|
||||
|
||||
if (count == 2 && SampleSurface(player, baseHit, rough, Vector3.Zero, tolerance, out Vector3 center))
|
||||
ring[count++] = center;
|
||||
|
||||
if (count < 3) return false;
|
||||
|
||||
normal = NewellNormal(ring[..count]);
|
||||
if (normal.LengthSquared() < .0001f) return false;
|
||||
|
||||
normal = Vector3.Normalize(normal);
|
||||
float dot = Vector3.Dot(direction, normal);
|
||||
|
||||
if (MathF.Abs(dot) < .05f) return false;
|
||||
if (dot > 0f) normal = -normal;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool SampleSurface(CCSPlayerController player, Vector3 baseHit, Vector3 rough, Vector3 tangentOffset, float tolerance, out Vector3 point)
|
||||
{
|
||||
point = Vector3.Zero;
|
||||
|
||||
Vector3 anchor = baseHit + tangentOffset;
|
||||
Vector3 start = anchor + rough * 16f;
|
||||
Vector3 end = anchor - rough * 48f;
|
||||
|
||||
var sample = RayTrace.TraceShape(player, ToVector(start), ToVector(end), worldOnlyMask, 0);
|
||||
if (sample == null || !sample.Value.DidHit) return false;
|
||||
|
||||
point = sample.Value.EndPos;
|
||||
return MathF.Abs(Vector3.Dot(point - baseHit, rough)) <= tolerance;
|
||||
}
|
||||
|
||||
private static Vector3 NewellNormal(ReadOnlySpan<Vector3> points)
|
||||
{
|
||||
Vector3 normal = Vector3.Zero;
|
||||
|
||||
for (int i = 0; i < points.Length; i++)
|
||||
{
|
||||
Vector3 current = points[i];
|
||||
Vector3 next = points[(i + 1) % points.Length];
|
||||
|
||||
normal.X += (current.Y - next.Y) * (current.Z + next.Z);
|
||||
normal.Y += (current.Z - next.Z) * (current.X + next.X);
|
||||
normal.Z += (current.X - next.X) * (current.Y + next.Y);
|
||||
}
|
||||
|
||||
return normal;
|
||||
}
|
||||
|
||||
private static bool TryPlaneFitNormal(CCSPlayerController player, Vector3 baseHit, Vector3 direction, out Vector3 normal)
|
||||
{
|
||||
normal = Vector3.Zero;
|
||||
|
||||
Vector3 axis = MathF.Abs(direction.Z) > .9f ? Vector3.UnitX : Vector3.UnitZ;
|
||||
Vector3 right = Vector3.Cross(direction, axis);
|
||||
if (right.LengthSquared() < .0001f) return false;
|
||||
right = Vector3.Normalize(right);
|
||||
|
||||
Vector3 up = Vector3.Normalize(Vector3.Cross(right, direction));
|
||||
|
||||
float offset = MathF.Max(SkillsInfo.GetValue<float>(skillName, "normalProbeOffset"), 1f);
|
||||
float tolerance = offset * 6f;
|
||||
Vector3 origin = baseHit - direction * 24f;
|
||||
|
||||
if (!Probe(player, origin, direction, right * offset, baseHit, tolerance, out Vector3 rightHit)) return false;
|
||||
if (!Probe(player, origin, direction, right * -offset, baseHit, tolerance, out Vector3 leftHit)) return false;
|
||||
if (!Probe(player, origin, direction, up * offset, baseHit, tolerance, out Vector3 upHit)) return false;
|
||||
if (!Probe(player, origin, direction, up * -offset, baseHit, tolerance, out Vector3 downHit)) return false;
|
||||
|
||||
normal = Vector3.Cross(rightHit - leftHit, upHit - downHit);
|
||||
if (normal.LengthSquared() < .0001f) return false;
|
||||
|
||||
normal = Vector3.Normalize(normal);
|
||||
float dot = Vector3.Dot(direction, normal);
|
||||
|
||||
if (MathF.Abs(dot) < .05f) return false;
|
||||
if (dot > 0f) normal = -normal;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool Probe(CCSPlayerController player, Vector3 origin, Vector3 direction, Vector3 offset, Vector3 baseHit, float tolerance, out Vector3 point)
|
||||
{
|
||||
point = Vector3.Zero;
|
||||
|
||||
Vector3 start = origin + offset;
|
||||
Vector3 end = start + direction * 96f;
|
||||
|
||||
var probe = RayTrace.TraceShape(player, ToVector(start), ToVector(end), worldOnlyMask, 0);
|
||||
if (probe == null || !probe.Value.DidHit) return false;
|
||||
|
||||
point = probe.Value.EndPos;
|
||||
return Vector3.Distance(point, baseHit) <= tolerance;
|
||||
}
|
||||
|
||||
private static void Trace(string message)
|
||||
{
|
||||
Debug.WriteToDebug($"[Ricochet] {message}");
|
||||
}
|
||||
|
||||
private static bool TryConsumeBudget(uint playerIndex)
|
||||
{
|
||||
int tick = Server.TickCount;
|
||||
var budget = impactBudgets.GetOrAdd(playerIndex, _ => new ImpactBudget());
|
||||
|
||||
if (budget.Tick != tick)
|
||||
{
|
||||
budget.Tick = tick;
|
||||
budget.Count = 0;
|
||||
}
|
||||
|
||||
if (budget.Count >= Math.Max(SkillsInfo.GetValue<int>(skillName, "maxImpactsPerTick"), 1)) return false;
|
||||
|
||||
budget.Count++;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Vector ToVector(Vector3 vector) => new(vector.X, vector.Y, vector.Z);
|
||||
|
||||
private class ImpactBudget
|
||||
{
|
||||
public int Tick { get; set; } = int.MinValue;
|
||||
public int Count { get; set; }
|
||||
}
|
||||
|
||||
private class Flight
|
||||
{
|
||||
public required uint OwnerIndex { get; set; }
|
||||
public required Vector3[] Points { get; set; }
|
||||
public required float[] Cumulative { get; set; }
|
||||
public required float TotalLength { get; set; }
|
||||
public required int DeadlineTick { get; set; }
|
||||
public float Travelled { get; set; }
|
||||
public uint? BeamIndex { get; set; }
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#ffd75e", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = 2, Rarity rarity = Rarity.Rare, int bounces = 3, float segmentDistance = 1200f, float damageMultiplier = .5f, float fallbackDamage = 25f, bool respectArmor = true, float damageFalloff = .75f, int maxImpactsPerTick = 2, bool showTracer = true, float tracerWidth = 0.5f, float tracerSpeed = 2600f, float tracerLength = 220f, int maxActiveTracers = 12, float normalProbeOffset = 6f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)
|
||||
{
|
||||
public int Bounces { get; set; } = bounces;
|
||||
public float SegmentDistance { get; set; } = segmentDistance;
|
||||
public float DamageMultiplier { get; set; } = damageMultiplier;
|
||||
public float FallbackDamage { get; set; } = fallbackDamage;
|
||||
public bool RespectArmor { get; set; } = respectArmor;
|
||||
public float DamageFalloff { get; set; } = damageFalloff;
|
||||
public int MaxImpactsPerTick { get; set; } = maxImpactsPerTick;
|
||||
public bool ShowTracer { get; set; } = showTracer;
|
||||
public float TracerWidth { get; set; } = tracerWidth;
|
||||
public float TracerSpeed { get; set; } = tracerSpeed;
|
||||
public float TracerLength { get; set; } = tracerLength;
|
||||
public int MaxActiveTracers { get; set; } = maxActiveTracers;
|
||||
public float NormalProbeOffset { get; set; } = normalProbeOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -50,6 +50,8 @@ namespace src.player.skills
|
|||
|
||||
public static void PlayerMakeSound(UserMessage um)
|
||||
{
|
||||
if (SkillPlayerInfo.IsEmpty) return;
|
||||
|
||||
var soundevent = um.ReadUInt("soundevent_hash");
|
||||
if (soundevent != soundEventHash) return;
|
||||
|
||||
|
|
@ -96,7 +98,11 @@ namespace src.player.skills
|
|||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (Server.TickCount % (60 * SkillsInfo.GetValue<int>(skillName, "cooldown")) != 0) return;
|
||||
if (SkillPlayerInfo.IsEmpty) return;
|
||||
|
||||
int cooldown = SkillsInfo.GetValue<int>(skillName, "cooldown");
|
||||
if (cooldown < 1) cooldown = 1;
|
||||
if (Server.TickCount % (60 * cooldown) != 0) return;
|
||||
|
||||
foreach (var player in PlayerManager.GetTickPlayers()
|
||||
.Where(p => p != null && p.IsValid && p.PlayerPawn.Value != null && p.PlayerPawn.Value.IsValid && p.PlayerPawn.Value.Health > 0))
|
||||
|
|
|
|||
|
|
@ -133,7 +133,10 @@ namespace src.player.skills
|
|||
pawn.CameraServices.ViewEntity.Raw = defaultCam ? orginalCameraRaw : newCameraRaw;
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultCam = true;
|
||||
pawn.CameraServices.ViewEntity.Raw = orginalCameraRaw;
|
||||
}
|
||||
|
||||
Utilities.SetStateChanged(pawn, "CBasePlayerPawn", "m_pCameraServices");
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ namespace src.player.skills
|
|||
if (!SkillPlayerInfo.TryGetValue(player.Index, out var skillInfo)) continue;
|
||||
|
||||
GetTeamate(player, skillInfo);
|
||||
UpdateHUD(player, skillInfo);
|
||||
if (SkillUtils.IsHudFrame()) UpdateHUD(player, skillInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -400,14 +400,35 @@ namespace src.player.skills
|
|||
return (closet, minKnifeInfo);
|
||||
}
|
||||
|
||||
private static readonly List<(uint OwnerIndex, uint GlowEntityIndex)> transmitGlows = [];
|
||||
|
||||
public static void CheckTransmit([CastFrom(typeof(nint))] CCheckTransmitInfoList infoList)
|
||||
{
|
||||
var snapshot = knivesInfo.ToArray();
|
||||
if (knivesInfo.IsEmpty) return;
|
||||
|
||||
transmitGlows.Clear();
|
||||
foreach (var (knifeOwnerIndex, knifeInfo) in knivesInfo)
|
||||
{
|
||||
if (knifeInfo.GlowIndex == null) continue;
|
||||
|
||||
var glowEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)knifeInfo.GlowIndex);
|
||||
if (glowEntity == null || !glowEntity.IsValid)
|
||||
{
|
||||
knifeInfo.GlowIndex = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
transmitGlows.Add((knifeOwnerIndex, glowEntity.Index));
|
||||
}
|
||||
|
||||
if (transmitGlows.Count == 0) return;
|
||||
|
||||
foreach (var (info, player) in infoList)
|
||||
{
|
||||
if (player == null || !player.IsValid) continue;
|
||||
|
||||
uint viewerIndex = PlayerManager.GetPlayerEvent(player)?.Index ?? player.Index;
|
||||
|
||||
uint? observedPlayerIndex = null;
|
||||
var playerPawn = player.Pawn?.Value;
|
||||
if (playerPawn != null && playerPawn.IsValid)
|
||||
|
|
@ -423,23 +444,13 @@ namespace src.player.skills
|
|||
}
|
||||
}
|
||||
|
||||
foreach ((uint knifeOwnerIndex, KnifeInfo knifeInfo) in snapshot)
|
||||
foreach (var (knifeOwnerIndex, glowEntityIndex) in transmitGlows)
|
||||
{
|
||||
if (knifeInfo.GlowIndex == null) continue;
|
||||
if (knifeOwnerIndex == viewerIndex) continue;
|
||||
if (observedPlayerIndex.HasValue && observedPlayerIndex.Value == knifeOwnerIndex) continue;
|
||||
|
||||
var glowEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)knifeInfo.GlowIndex);
|
||||
if (glowEntity == null || !glowEntity.IsValid)
|
||||
{
|
||||
knifeInfo.GlowIndex = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isOwner = knifeOwnerIndex == (PlayerManager.GetPlayerEvent(player)?.Index ?? player.Index);
|
||||
bool isObservingOwner = observedPlayerIndex.HasValue && observedPlayerIndex.Value == knifeOwnerIndex;
|
||||
|
||||
if (!isOwner && !isObservingOwner)
|
||||
if (info.TransmitEntities.Contains(glowEntity.Index))
|
||||
info.TransmitEntities.Remove(glowEntity.Index);
|
||||
if (info.TransmitEntities.Contains(glowEntityIndex))
|
||||
info.TransmitEntities.Remove(glowEntityIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ namespace src.player.skills
|
|||
public static void NewRound()
|
||||
{
|
||||
buildInProgress = false;
|
||||
buildScheduled = false;
|
||||
|
||||
foreach (var kvp in glows)
|
||||
{
|
||||
|
|
@ -139,10 +140,21 @@ namespace src.player.skills
|
|||
Event.EnableTransmit();
|
||||
playersInAction.TryAdd(player.Index, 0);
|
||||
|
||||
if (glows.IsEmpty && !buildInProgress)
|
||||
SetGlowEffectForAll();
|
||||
if (buildScheduled || buildInProgress || !glows.IsEmpty) return;
|
||||
|
||||
SkillUtils.ForceFullUpdateToAll();
|
||||
buildScheduled = true;
|
||||
|
||||
float delay = SkillUtils.IsFreezeTime()
|
||||
? Math.Max((float)(Event.GetFreezeTimeEnd() - DateTime.Now).TotalSeconds, 0f)
|
||||
: 0f;
|
||||
|
||||
jRandomSkills.Instance.AddTimer(delay, () =>
|
||||
{
|
||||
buildScheduled = false;
|
||||
|
||||
if (playersInAction.IsEmpty || buildInProgress || !glows.IsEmpty) return;
|
||||
SetGlowEffectForAll();
|
||||
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||
}
|
||||
|
||||
public static void DisableSkill(CCSPlayerController player)
|
||||
|
|
@ -158,6 +170,7 @@ namespace src.player.skills
|
|||
|
||||
private const int GlowsPerFrame = 4;
|
||||
private static bool buildInProgress;
|
||||
private static bool buildScheduled;
|
||||
|
||||
private static void SetGlowEffectForAll()
|
||||
{
|
||||
|
|
@ -180,6 +193,7 @@ namespace src.player.skills
|
|||
if (start >= enemies.Count)
|
||||
{
|
||||
buildInProgress = false;
|
||||
SkillUtils.ForceFullUpdateToAllChunked();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,10 +65,15 @@ namespace src.utils
|
|||
return jRandomSkills.Instance?.GameRules?.FreezePeriod == true;
|
||||
}
|
||||
|
||||
public static bool IsHudFrame() => Server.TickCount % 4 == 0;
|
||||
|
||||
public static void RegisterSkill(Skills skill, string color, bool display = true)
|
||||
{
|
||||
if (!SkillData.Skills.Any(s => s.Skill == skill))
|
||||
{
|
||||
SkillData.Skills.Add(new jSkill_SkillInfo(skill, color, display));
|
||||
SkillData.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateGrenadeCount(CCSPlayerController player, CsItem item, int ammo)
|
||||
|
|
@ -187,11 +192,6 @@ namespace src.utils
|
|||
SnapViewAngles.Value?.Invoke(pawn, angle);
|
||||
}
|
||||
|
||||
public static CBeam? CreateLine(Vector start, Vector end, Color color, uint ownerPlayerIndex = EntityManager.SystemOwnerIndex)
|
||||
{
|
||||
return EntityManager.CreateTrackedBeam(ownerPlayerIndex, start, end, color);
|
||||
}
|
||||
|
||||
public static void SetPlayerCollisions(CCSPlayerController? player, bool enable)
|
||||
{
|
||||
return;
|
||||
|
|
@ -684,6 +684,50 @@ namespace src.utils
|
|||
});
|
||||
}
|
||||
|
||||
public static void ForceFullUpdateToAllChunked(int clientsPerFrame = 2)
|
||||
{
|
||||
if (!Config.LoadedConfig.EnableFullForceUpdate) return;
|
||||
|
||||
var pending = Utilities.GetPlayers().Where(p => p != null && p.IsValid && !p.IsBot).Select(p => p.Index).ToList();
|
||||
if (pending.Count == 0) return;
|
||||
|
||||
ForceFullUpdateChunk(pending, 0, Math.Max(clientsPerFrame, 1));
|
||||
}
|
||||
|
||||
private static void ForceFullUpdateChunk(List<uint> pending, int start, int clientsPerFrame)
|
||||
{
|
||||
if (start >= pending.Count) return;
|
||||
|
||||
int end = Math.Min(start + clientsPerFrame, pending.Count);
|
||||
var toRestore = new List<(uint PlayerIndex, QAngle LastAngle)>();
|
||||
|
||||
INetworkGameServer networkGameServer = new INetworkServerService().GetIGameServer();
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
var player = Utilities.GetPlayerFromIndex((int)pending[i]);
|
||||
if (player == null || !player.IsValid) continue;
|
||||
|
||||
ForceFullUpdate(player, toRestore, networkGameServer);
|
||||
}
|
||||
|
||||
if (toRestore.Count > 0)
|
||||
jRandomSkills.Instance.AddTickTimer(3, () =>
|
||||
{
|
||||
foreach (var item in toRestore)
|
||||
{
|
||||
var target = Utilities.GetPlayerFromIndex((int)item.PlayerIndex);
|
||||
if (target == null || !target.IsValid) continue;
|
||||
|
||||
var targetPawn = target.PlayerPawn?.Value;
|
||||
if (targetPawn == null || !targetPawn.IsValid || targetPawn.AbsOrigin == null) continue;
|
||||
|
||||
targetPawn.Look(item.LastAngle);
|
||||
}
|
||||
});
|
||||
|
||||
Server.NextFrame(() => ForceFullUpdateChunk(pending, end, clientsPerFrame));
|
||||
}
|
||||
|
||||
public static bool SetHealth(CCSPlayerPawn? pawn, int newHealth, int? maxHealth = null)
|
||||
{
|
||||
if (pawn == null || !pawn.IsValid)
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -405,6 +405,32 @@
|
|||
"MaxPerServer": -1,
|
||||
"Rarity": "Common"
|
||||
},
|
||||
{
|
||||
"Bounces": 3,
|
||||
"SegmentDistance": 1200.0,
|
||||
"DamageMultiplier": 0.5,
|
||||
"FallbackDamage": 25.0,
|
||||
"RespectArmor": true,
|
||||
"DamageFalloff": 0.75,
|
||||
"MaxImpactsPerTick": 2,
|
||||
"ShowTracer": true,
|
||||
"TracerWidth": 0.5,
|
||||
"TracerSpeed": 2600.0,
|
||||
"TracerLength": 220.0,
|
||||
"MaxActiveTracers": 12,
|
||||
"NormalProbeOffset": 6.0,
|
||||
"NeedsTeammates": false,
|
||||
"DisableOnFreezeTime": false,
|
||||
"OnlyTeam": 0,
|
||||
"Color": "#ffd75e",
|
||||
"Active": true,
|
||||
"Name": "Ricochet",
|
||||
"HudDuration": null,
|
||||
"DescriptionHudDuration": null,
|
||||
"RequiredPermission": "",
|
||||
"MaxPerServer": 2,
|
||||
"Rarity": "Rare"
|
||||
},
|
||||
{
|
||||
"MinMoney": 5000,
|
||||
"MaxMoney": 15000,
|
||||
|
|
@ -1102,6 +1128,19 @@
|
|||
"MaxPerServer": 1,
|
||||
"Rarity": "Common"
|
||||
},
|
||||
{
|
||||
"NeedsTeammates": true,
|
||||
"DisableOnFreezeTime": false,
|
||||
"OnlyTeam": 0,
|
||||
"Color": "#c9a227",
|
||||
"Active": true,
|
||||
"Name": "Inheritance",
|
||||
"HudDuration": null,
|
||||
"DescriptionHudDuration": null,
|
||||
"RequiredPermission": "",
|
||||
"MaxPerServer": 2,
|
||||
"Rarity": "Rare"
|
||||
},
|
||||
{
|
||||
"NeedsTeammates": false,
|
||||
"DisableOnFreezeTime": false,
|
||||
|
|
@ -1286,6 +1325,26 @@
|
|||
"MaxPerServer": -1,
|
||||
"Rarity": "Common"
|
||||
},
|
||||
{
|
||||
"Cooldown": 10.0,
|
||||
"MaxDistance": 1500.0,
|
||||
"MinDistance": 150.0,
|
||||
"StopDistance": 90.0,
|
||||
"PullSpeed": 850.0,
|
||||
"MaxPullSeconds": 3.0,
|
||||
"RopeWidth": 0.8,
|
||||
"NeedsTeammates": false,
|
||||
"DisableOnFreezeTime": true,
|
||||
"OnlyTeam": 0,
|
||||
"Color": "#38e0c4",
|
||||
"Active": true,
|
||||
"Name": "Grapple",
|
||||
"HudDuration": null,
|
||||
"DescriptionHudDuration": null,
|
||||
"RequiredPermission": "",
|
||||
"MaxPerServer": -1,
|
||||
"Rarity": "Rare"
|
||||
},
|
||||
{
|
||||
"Cooldown": 30.0,
|
||||
"Duration": 2.0,
|
||||
|
|
@ -1800,6 +1859,19 @@
|
|||
"MaxPerServer": -1,
|
||||
"Rarity": "Common"
|
||||
},
|
||||
{
|
||||
"NeedsTeammates": false,
|
||||
"DisableOnFreezeTime": false,
|
||||
"OnlyTeam": 0,
|
||||
"Color": "#5fd98a",
|
||||
"Active": true,
|
||||
"Name": "Chameleon",
|
||||
"HudDuration": null,
|
||||
"DescriptionHudDuration": null,
|
||||
"RequiredPermission": "",
|
||||
"MaxPerServer": 2,
|
||||
"Rarity": "Rare"
|
||||
},
|
||||
{
|
||||
"ChanceFrom": 0.2,
|
||||
"ChanceTo": 0.4,
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"none": "Keine",
|
||||
"none_desc": "Du hast keine Fertigkeit",
|
||||
|
||||
|
|
@ -77,6 +77,11 @@
|
|||
"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} %",
|
||||
|
||||
"chameleon": "Chamäleon",
|
||||
"chameleon_desc": "Der erste Spieler, den du tötest, gibt dir seine Fähigkeit",
|
||||
"chameleon_copied_info": "Fähigkeit kopiert: {0}",
|
||||
"chameleon_wrong_team_info": "'{0}' hatte eine Fähigkeit, die dein Team nicht nutzen kann.",
|
||||
|
||||
"chicken": "Huhn",
|
||||
"chicken_desc": "Du erhältst ein Huhn-Modell + 10 % schnellere Bewegung – 50 HP",
|
||||
|
||||
|
|
@ -220,6 +225,11 @@
|
|||
"godmode_off": "Unsterblichkeit deaktiviert",
|
||||
"godmode_on": "Unsterblichkeit aktiviert",
|
||||
|
||||
"grapple": "Enterhaken",
|
||||
"grapple_desc": "Drücke [css_useSkill], um einen Haken auf den anvisierten Punkt zu schießen und dich dorthin zu ziehen",
|
||||
"grapple_no_anchor_info": "Keine Oberfläche zum Einhaken.",
|
||||
"grapple_pulling_info": "ZUG",
|
||||
|
||||
"grenadier": "Grenadier",
|
||||
"grenadier_desc": "Du hast unendlich viele Granaten",
|
||||
|
||||
|
|
@ -259,6 +269,11 @@
|
|||
"infiniteammo": "Unendliche Munition",
|
||||
"infiniteammo_desc": "Du erhältst unendliche Munition für alle deine Waffen",
|
||||
|
||||
"inheritance": "Erbe",
|
||||
"inheritance_desc": "Wenn ein Teamkollege stirbt, kannst du seine Fähigkeit übernehmen",
|
||||
"inheritance_select_info": "Wähle die Fähigkeit, die du erbst:",
|
||||
"inheritance_player_info": "Du hast die Fähigkeit von '{0}' geerbt.",
|
||||
|
||||
"jackal": "Spürhund",
|
||||
"jackal_desc": "Jeder Gegner hinterlässt eine Spur",
|
||||
|
||||
|
|
@ -448,6 +463,9 @@
|
|||
"richboy": "Rich Boy",
|
||||
"richboy_desc": "Du erhältst zu Beginn der Runde einen zufälligen Geldbetrag",
|
||||
|
||||
"ricochet": "Querschläger",
|
||||
"ricochet_desc": "Deine Kugeln prallen von Wänden ab und können Gegner weiterhin treffen",
|
||||
|
||||
"robinhood": "Robin Hood",
|
||||
"robinhood_desc": "Wenn du einem Gegner Schaden zufügst, stiehlst du ihm sein Geld",
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"none": "None",
|
||||
"none_desc": "You have no skill",
|
||||
|
||||
|
|
@ -77,6 +77,11 @@
|
|||
"catapult_desc": "You have a random chance to launch an enemy upwards",
|
||||
"catapult_desc2": "Your chance to launch an enemy on hit is: {0}%",
|
||||
|
||||
"chameleon": "Chameleon",
|
||||
"chameleon_desc": "The first player you kill gives you their skill",
|
||||
"chameleon_copied_info": "You copied the skill: {0}",
|
||||
"chameleon_wrong_team_info": "'{0}' had a skill your team cannot use.",
|
||||
|
||||
"chicken": "Chicken",
|
||||
"chicken_desc": "You get a chicken model + 10% faster movement - 50 HP",
|
||||
|
||||
|
|
@ -213,6 +218,11 @@
|
|||
"godmode_off": "Immortality disabled",
|
||||
"godmode_on": "Immortality enabled",
|
||||
|
||||
"grapple": "Grapple Hook",
|
||||
"grapple_desc": "Press [css_useSkill] to fire a hook at the point you are aiming at and pull yourself there",
|
||||
"grapple_no_anchor_info": "No surface to hook onto.",
|
||||
"grapple_pulling_info": "PULLING",
|
||||
|
||||
"grenadier": "Grenadier",
|
||||
"grenadier_desc": "You have infinite hegrenade",
|
||||
|
||||
|
|
@ -252,6 +262,11 @@
|
|||
"infiniteammo": "Infinite Ammo",
|
||||
"infiniteammo_desc": "You receive infinite ammo for all your weapons",
|
||||
|
||||
"inheritance": "Inheritance",
|
||||
"inheritance_desc": "When a teammate dies you can take over their skill",
|
||||
"inheritance_select_info": "Choose the skill you inherit:",
|
||||
"inheritance_player_info": "You inherited the skill of '{0}'.",
|
||||
|
||||
"jackal": "Tracker",
|
||||
"jackal_desc": "Every opponent leaves a trail behind them",
|
||||
|
||||
|
|
@ -448,6 +463,9 @@
|
|||
"richboy": "Rich Boy",
|
||||
"richboy_desc": "You receive a random amount of money at the start of the round",
|
||||
|
||||
"ricochet": "Ricochet",
|
||||
"ricochet_desc": "Your bullets bounce off walls and can still hit enemies",
|
||||
|
||||
"robinhood": "Robin Hood",
|
||||
"robinhood_desc": "Dealing damage to an enemy steals their money",
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"none": "Aucune",
|
||||
"none_desc": "Vous n’avez aucune compétence",
|
||||
|
||||
|
|
@ -77,6 +77,11 @@
|
|||
"catapult_desc": "Vous avez une chance aléatoire de projeter un ennemi en l’air",
|
||||
"catapult_desc2": "Votre chance de projeter un ennemi à l’impact est : {0}%",
|
||||
|
||||
"chameleon": "Caméléon",
|
||||
"chameleon_desc": "Le premier joueur que vous tuez vous donne sa compétence",
|
||||
"chameleon_copied_info": "Compétence copiée : {0}",
|
||||
"chameleon_wrong_team_info": "'{0}' avait une compétence que votre équipe ne peut pas utiliser.",
|
||||
|
||||
"chicken": "Poulet",
|
||||
"chicken_desc": "Vous obtenez un modèle de poulet + 10% de vitesse de déplacement en plus - 50 PV",
|
||||
|
||||
|
|
@ -220,6 +225,11 @@
|
|||
"godmode_off": "Immortalité désactivée",
|
||||
"godmode_on": "Immortalité activée",
|
||||
|
||||
"grapple": "Grappin",
|
||||
"grapple_desc": "Appuyez sur [css_useSkill] pour lancer un grappin sur le point visé et vous y propulser",
|
||||
"grapple_no_anchor_info": "Aucune surface pour accrocher le grappin.",
|
||||
"grapple_pulling_info": "TRACTION",
|
||||
|
||||
"grenadier": "Grenadier",
|
||||
"grenadier_desc": "Tu as des grenades HE infinies",
|
||||
|
||||
|
|
@ -259,6 +269,11 @@
|
|||
"infiniteammo": "Munitions Infinies",
|
||||
"infiniteammo_desc": "Vous recevez des munitions infinies pour toutes vos armes",
|
||||
|
||||
"inheritance": "Héritage",
|
||||
"inheritance_desc": "Quand un coéquipier meurt, vous pouvez reprendre sa compétence",
|
||||
"inheritance_select_info": "Choisissez la compétence à hériter :",
|
||||
"inheritance_player_info": "Vous avez hérité de la compétence de '{0}'.",
|
||||
|
||||
"jackal": "Traqueur",
|
||||
"jackal_desc": "Chaque adversaire laisse une trace derrière lui",
|
||||
|
||||
|
|
@ -448,6 +463,9 @@
|
|||
"richboy": "Gosse de Riche",
|
||||
"richboy_desc": "Vous recevez une somme d’argent aléatoire au début du round",
|
||||
|
||||
"ricochet": "Ricochet",
|
||||
"ricochet_desc": "Vos balles rebondissent sur les murs et peuvent encore toucher les ennemis",
|
||||
|
||||
"robinhood": "Robin des Bois",
|
||||
"robinhood_desc": "Infliger des dégâts à un ennemi lui vole de l’argent",
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"none": "Brak",
|
||||
"none_desc": "Nie posiadasz żadnej supermocy",
|
||||
|
||||
|
|
@ -77,6 +77,11 @@
|
|||
"catapult_desc": "Masz losową szanse na podrzucenie wroga",
|
||||
"catapult_desc2": "Twoje szanse na podrzucenie wroga po trafieniu to: {0}%",
|
||||
|
||||
"chameleon": "Kameleon",
|
||||
"chameleon_desc": "Pierwszy zabity gracz oddaje ci swoją umiejętność",
|
||||
"chameleon_copied_info": "Skopiowano umiejętność: {0}",
|
||||
"chameleon_wrong_team_info": "'{0}' miał umiejętność, której twoja drużyna nie może użyć.",
|
||||
|
||||
"chicken": "Kurczak",
|
||||
"chicken_desc": "Otrzymujesz model kurczaka + jesteś o 10% szybszy - 50hp",
|
||||
|
||||
|
|
@ -220,6 +225,11 @@
|
|||
"godmode_off": "Nieśmiertelność wyłączona",
|
||||
"godmode_on": "Nieśmiertelność włączona",
|
||||
|
||||
"grapple": "Hak",
|
||||
"grapple_desc": "Naciśnij [css_useSkill], aby wystrzelić hak w celowany punkt i przyciągnąć się do niego",
|
||||
"grapple_no_anchor_info": "Brak powierzchni do zaczepienia haka.",
|
||||
"grapple_pulling_info": "PRZYCIĄGANIE",
|
||||
|
||||
"grenadier": "Granatnik",
|
||||
"grenadier_desc": "Masz nieskończone granaty odłamkowe",
|
||||
|
||||
|
|
@ -259,6 +269,11 @@
|
|||
"infiniteammo": "Nieskończone Ammo",
|
||||
"infiniteammo_desc": "Otrzymujesz nieskończoną ilość amunicji do wszystkich broni",
|
||||
|
||||
"inheritance": "Spadek",
|
||||
"inheritance_desc": "Gdy członek drużyny ginie, możesz przejąć jego umiejętność",
|
||||
"inheritance_select_info": "Wybierz dziedziczoną umiejętność:",
|
||||
"inheritance_player_info": "Odziedziczyłeś umiejętność gracza '{0}'.",
|
||||
|
||||
"jackal": "Stópkarz",
|
||||
"jackal_desc": "Każdy przeciwnik pozostawia za sobą ślad",
|
||||
|
||||
|
|
@ -448,6 +463,9 @@
|
|||
"richboy": "Bogacz",
|
||||
"richboy_desc": "Na początku rundy otrzymujesz losową kwotę gotówki",
|
||||
|
||||
"ricochet": "Rykoszet",
|
||||
"ricochet_desc": "Twoje pociski odbijają się od ścian i nadal mogą trafić przeciwników",
|
||||
|
||||
"robinhood": "Robin Hood",
|
||||
"robinhood_desc": "Zadanie obrażeń przeciwnikowi powoduje kradzież jego pieniędzy",
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"none": "Nenhuma",
|
||||
"none_desc": "Você não tem nenhuma habilidade",
|
||||
|
||||
|
|
@ -77,6 +77,11 @@
|
|||
"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}%",
|
||||
|
||||
"chameleon": "Camaleão",
|
||||
"chameleon_desc": "O primeiro jogador que você matar lhe dá a habilidade dele",
|
||||
"chameleon_copied_info": "Habilidade copiada: {0}",
|
||||
"chameleon_wrong_team_info": "'{0}' tinha uma habilidade que sua equipe não pode usar.",
|
||||
|
||||
"chicken": "Galinha",
|
||||
"chicken_desc": "Você é uma galinha com +10% de movimento mais rápido e -50 HP",
|
||||
|
||||
|
|
@ -220,6 +225,11 @@
|
|||
"godmode_off": "Imortalidade desativada",
|
||||
"godmode_on": "Imortalidade ativada",
|
||||
|
||||
"grapple": "Gancho",
|
||||
"grapple_desc": "Pressione [css_useSkill] para lançar um gancho no ponto mirado e se puxar até lá",
|
||||
"grapple_no_anchor_info": "Nenhuma superfície para prender o gancho.",
|
||||
"grapple_pulling_info": "PUXANDO",
|
||||
|
||||
"grenadier": "Bomberman",
|
||||
"grenadier_desc": "Você tem HEs infinitas",
|
||||
|
||||
|
|
@ -259,6 +269,11 @@
|
|||
"infiniteammo": "Munição Infinita",
|
||||
"infiniteammo_desc": "Você recebe munição infinita para todas as suas armas",
|
||||
|
||||
"inheritance": "Herança",
|
||||
"inheritance_desc": "Quando um companheiro de equipe morre, você pode assumir a habilidade dele",
|
||||
"inheritance_select_info": "Escolha a habilidade que você herda:",
|
||||
"inheritance_player_info": "Você herdou a habilidade de '{0}'.",
|
||||
|
||||
"jackal": "Lesma",
|
||||
"jackal_desc": "Cada adversário deixa um rastro atrás de si",
|
||||
|
||||
|
|
@ -448,6 +463,9 @@
|
|||
"richboy": "Filhinho de Papai",
|
||||
"richboy_desc": "Você recebe uma quantidade aleatória de dinheiro no início da rodada",
|
||||
|
||||
"ricochet": "Ricochete",
|
||||
"ricochet_desc": "Suas balas ricocheteiam nas paredes e ainda podem acertar inimigos",
|
||||
|
||||
"robinhood": "Robin Hood",
|
||||
"robinhood_desc": "Atirar em um inimigo rouba seu dinheiro",
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"none": "Нет навыка",
|
||||
"none_desc": "У вас нет навыка",
|
||||
|
||||
|
|
@ -77,6 +77,11 @@
|
|||
"catapult_desc": "Есть шанс подбросить врага вверх при попадании",
|
||||
"catapult_desc2": "Ваш шанс подбросить врага при попадании: {0}%",
|
||||
|
||||
"chameleon": "Хамелеон",
|
||||
"chameleon_desc": "Первый убитый вами игрок отдаёт свой навык",
|
||||
"chameleon_copied_info": "Навык скопирован: {0}",
|
||||
"chameleon_wrong_team_info": "У '{0}' был навык, недоступный вашей команде.",
|
||||
|
||||
"chicken": "Курица",
|
||||
"chicken_desc": "Вы получаете модель курицы + 10% к скорости передвижения - 50 HP",
|
||||
|
||||
|
|
@ -220,6 +225,11 @@
|
|||
"godmode_off": "Неуязвимость отключена",
|
||||
"godmode_on": "Неуязвимость включена",
|
||||
|
||||
"grapple": "Крюк",
|
||||
"grapple_desc": "Нажмите [css_useSkill], чтобы выстрелить крюком в точку прицеливания и притянуться к ней",
|
||||
"grapple_no_anchor_info": "Нет поверхности для зацепа.",
|
||||
"grapple_pulling_info": "ПРИТЯГИВАНИЕ",
|
||||
|
||||
"grenadier": "Гренадёр",
|
||||
"grenadier_desc": "У вас бесконечные осколочные гранаты",
|
||||
|
||||
|
|
@ -259,6 +269,11 @@
|
|||
"infiniteammo": "Бесконечные патроны",
|
||||
"infiniteammo_desc": "Вы получаете бесконечные патроны для всего оружия",
|
||||
|
||||
"inheritance": "Наследие",
|
||||
"inheritance_desc": "Когда союзник погибает, вы можете перенять его навык",
|
||||
"inheritance_select_info": "Выберите наследуемый навык:",
|
||||
"inheritance_player_info": "Вы унаследовали навык игрока '{0}'.",
|
||||
|
||||
"jackal": "Трекер",
|
||||
"jackal_desc": "Каждый противник оставляет за собой след",
|
||||
|
||||
|
|
@ -448,6 +463,9 @@
|
|||
"richboy": "Богач",
|
||||
"richboy_desc": "Вы получаете случайную сумму денег в начале раунда",
|
||||
|
||||
"ricochet": "Рикошет",
|
||||
"ricochet_desc": "Ваши пули отскакивают от стен и могут поразить врагов",
|
||||
|
||||
"robinhood": "Робин Гуд",
|
||||
"robinhood_desc": "Нанесение урона врагу крадёт его деньги",
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"none": "Yok",
|
||||
"none_desc": "Hiçbir yeteneğin yok",
|
||||
|
||||
|
|
@ -6,79 +6,84 @@
|
|||
"aimbot_desc": "Vurduğunda kafadan (HS) sayılır",
|
||||
|
||||
"aimlock": "Kitlenme",
|
||||
"aimlock_desc": "En yakın düşmana nişan almak için [css_useSkill] tuşuna basın",
|
||||
"aimlock_desc": "[css_useSkill] tuşuna basarak en yakın düşmana kitlen",
|
||||
|
||||
"anomaly": "Zaman Büken",
|
||||
"anomaly_desc": "[css_useSkill] tuşuna basarak zamanı birkaç saniye geriye alırsın",
|
||||
"anomaly_desc": "[css_useSkill] tuşuna basarak zamanı birkaç saniye geri al",
|
||||
|
||||
"antyflash": "Anti-Flash",
|
||||
"antyflash_desc": "Flaşa kör olmazsın ve flaşların 7 saniye sürer",
|
||||
"antyflash_desc": "Kör olmazsın ve flaşın 7 saniye sürer",
|
||||
|
||||
"antyhead": "Beton Kafa",
|
||||
"antyhead_desc": "Kafadan hasar almazsın",
|
||||
|
||||
"areareaper": "Mekan Kapatan",
|
||||
"areareaper_desc": "Haritadaki bir bomba alanını tamamen devre dışı bırakabilirsin",
|
||||
"areareaper_desc": "Haritadaki bir bomba alanını devre dışı bırak",
|
||||
"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} Bölgesi kapandı - artık buraya bomba kurulamaz!",
|
||||
"areareaper_used_info": "Yeteneğini zaten kullandın, açgözlülük yapma",
|
||||
"areareaper_select_info": "Alan seçin:",
|
||||
"areareaper_site_disabled": "{0} Bölgesi kapandı - artık buraya C4 kurulamaz!",
|
||||
"areareaper_used_info": "Yeteneğini zaten kullandın!",
|
||||
"areareaper_teammates_info": "{0} Bölgesi bomba kurmaya kapatıldı.",
|
||||
"areareaper_bombsite_disabled": "Bu bomba alanı kullanıma kapatıldı!",
|
||||
"areareaper_bombsite_disabled": "Bu bomba alanı kullanıma kapatıldı.",
|
||||
|
||||
"armored": "Zırhlı",
|
||||
"armored_desc": "Rastgele hasar alma çarpanına sahip olursun",
|
||||
"armored_desc": "Rastgele hasar alma çarpanın olur",
|
||||
"armored_desc2": "Hasar alma: {0}x",
|
||||
|
||||
"assassin": "Suikastçı",
|
||||
"assassin_desc": "Düşmanlara arkadan daha fazla hasar verirsin",
|
||||
"assassin_desc": "Düşmana arkadan daha fazla hasar verirsin",
|
||||
|
||||
"astronaut": "Astronot",
|
||||
"astronaut_desc": "Rastgele bir yerçekimi değerine sahip olursun",
|
||||
"astronaut_desc": "Rastgele bir yerçekimine sahipsin",
|
||||
"astronaut_desc2": "Yerçekimin: {0}x",
|
||||
|
||||
"moneyswap": "Vergi Memuru",
|
||||
"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:",
|
||||
"moneyswap_enemy_info": "Maliye kapına dayandı.",
|
||||
"moneyswap_player_info": "'{0}' ile paranı takasladın.",
|
||||
"moneyswap_select_info": "Birini seçin:",
|
||||
|
||||
"baseball": "Beyzbolcu",
|
||||
"baseball_desc": "Yanıltıcı bomban (decoy) duvarlardan seker ve çarptığı düşmanı öldürür",
|
||||
"baseball_desc": "Yanıltıcı bomban duvarlardan seker ve çarptığı düşmanı öldürür",
|
||||
|
||||
"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}",
|
||||
|
||||
"berserker": "Berserker",
|
||||
"berserker_desc": "Canın azaldıkça hasarın artar ve daha hızlanırsın",
|
||||
"berserker_desc": "Canın azaldıkça hasarın ve hızın artar",
|
||||
|
||||
"blademaster": "Kılıç Ustası",
|
||||
"blademaster_desc": "Bıçak tutarken mermileri sektirme şansın artar",
|
||||
"blademaster_desc": "Bıçak tutarken mermileri savuşturursun",
|
||||
|
||||
"blastshot": "Patlama Atışı",
|
||||
"blastshot_desc": "MP5 ile Sağ Tık'a basarak El bombası fırlat",
|
||||
"blastshot_desc": "MP5 ile sağ tıklayarak el bombası fırlat",
|
||||
|
||||
"bunnyhop": "Tavşan",
|
||||
"bunnyhop_desc": "Otomatik \"BunnyHop\" yaparsın",
|
||||
"bunnyhop_desc": "Otomatik BunnyHop yaparsın",
|
||||
|
||||
"c4camouflage": "C4 Kamuflaj",
|
||||
"c4camouflage_desc": "Elinde C4 varken tamamen görünmez olursun",
|
||||
"c4camouflage_desc": "Elinde C4 varken görünmezsin",
|
||||
|
||||
"carefulbullets": "Dikkatli Mermiler",
|
||||
"carefulbullets_desc": "Düşman mermi kaçırırsa hasar alır",
|
||||
"carefulbullets_enemy_info": "Mermi kaçırmak canını yakacak",
|
||||
"carefulbullets_enemy_info": "Mermi kaçırman can yakar.",
|
||||
"carefulbullets_disable_info": "Artık mermi kaçırmak can yakmayacak.",
|
||||
"carefulbullets_player_info": "'{0}' artık mermi sıkarken iki kere düşünecek",
|
||||
"carefulbullets_select_info": "İsabetsiz atışların hasar vereceği oyuncu:",
|
||||
"carefulbullets_player_info": "'{0}' mermi sıkarken iki kere düşünecek.",
|
||||
"carefulbullets_select_info": "Birini seçin:",
|
||||
|
||||
"catapult": "Mancınık",
|
||||
"catapult_desc": "Vurduğun rakibi uzaya (yukarı doğru) fırlatma şansın var",
|
||||
"catapult_desc2": "Fırlatma şansın: %{0}",
|
||||
|
||||
"chameleon": "Bukalemun",
|
||||
"chameleon_desc": "Öldürdüğün ilk oyuncunun yeteneği sana geçer",
|
||||
"chameleon_copied_info": "Yeteneği kopyaladın: {0}",
|
||||
"chameleon_wrong_team_info": "'{0}' takımının kullanamayacağı bir yeteneğe sahipti.",
|
||||
|
||||
"chicken": "Tavuk",
|
||||
"chicken_desc": "Tavuk modeli ve %10 daha hızlısın fakat 50 HP",
|
||||
"chicken_desc": "Tavuk modeli, %10 daha hızlı ama 50 HP",
|
||||
|
||||
"chillout": "Ağırdan Al",
|
||||
"chillout_desc": "Bombayı kurmak çok daha uzun sürer",
|
||||
|
|
@ -87,28 +92,28 @@
|
|||
"cutter_desc": "Bıçakla tek atarsın",
|
||||
|
||||
"cypher": "Gözcü",
|
||||
"cypher_desc": "Kamera oluşturmak/geçmek için [css_useSkill] tuşuna bas",
|
||||
"cypher_desc": "[css_useSkill] tuşuna basarak kamera kur ve kameraya geç",
|
||||
"cypher_nospace": "Kamerayı duvara dik yerleştir",
|
||||
|
||||
"darkness": "Karanlık",
|
||||
"darkness_desc": "Bir düşmanın ekranını karart",
|
||||
"darkness_enemy_info": "Işıklar sönsün",
|
||||
"darkness_desc": "Düşmanın ekranını karart",
|
||||
"darkness_enemy_info": "Işıklar sönsün.",
|
||||
"darkness_disable_info": "Işıklar geldi.",
|
||||
"darkness_player_info": "'{0}' isimli oyuncunun dünyasını kararttın",
|
||||
"darkness_select_info": "Karanlık bir oyuncuyu seç:",
|
||||
"darkness_player_info": "'{0}' ışıkları söndü.",
|
||||
"darkness_select_info": "Birini seçin:",
|
||||
|
||||
"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ç:",
|
||||
"deactivator_enemy_info": "Yeteneğin silindi.",
|
||||
"deactivator_player_info": "'{0}' isimli oyuncunun yeteneği silindi.",
|
||||
"deactivator_select_info": "Birini seçin:",
|
||||
|
||||
"deaf": "Sağır",
|
||||
"deaf_desc": "Bir düşmanın kulağını kapat ve sesleri duymaz hale getir",
|
||||
"deaf_enemy_info": "Kulaklıkların tıkandı",
|
||||
"deaf_desc": "Bir düşmanı sağır et",
|
||||
"deaf_enemy_info": "Kulaklıkların tıkandı.",
|
||||
"deaf_disable_info": "Kulakların açıldı.",
|
||||
"deaf_player_info": "'{0}' isimli oyuncu için sesler kapatıldı.",
|
||||
"deaf_select_info": "Sağır bir oyuncuyu seç:",
|
||||
"deaf_player_info": "'{0}' sesleri kapatıldı.",
|
||||
"deaf_select_info": "Birini seçin:",
|
||||
|
||||
"disarmament": "Silahsızlandırma",
|
||||
"disarmament_desc": "Vurduğunda rakibin elindeki silahı yere düşürme şansın olur",
|
||||
|
|
@ -121,15 +126,15 @@
|
|||
"dash_desc": "Atılmak için ikinci kez zıpla",
|
||||
|
||||
"dracula": "Drakula",
|
||||
"dracula_desc": "Rakiplere verdiğin hasarın belirli bir yüzdesi kadar can alırsın",
|
||||
"dracula_desc": "Rakibe verdiğin hasarın birazı kadar can alırsın",
|
||||
|
||||
"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:",
|
||||
"duplicator_desc": "Bir düşmanın yeteneğini kopyala",
|
||||
"duplicator_player_info": "'{0}' yeteneği kopyalandı.",
|
||||
"duplicator_select_info": "Birini seçin:",
|
||||
|
||||
"dwarf": "Cüce",
|
||||
"dwarf_desc": "Raund başında rastgele karakter boyutu",
|
||||
"dwarf_desc": "Rastgele karakter boyutu",
|
||||
"dwarf_desc2": "Boyutun: {0}x",
|
||||
|
||||
"enemyspawn": "Base Baskını",
|
||||
|
|
@ -137,16 +142,16 @@
|
|||
|
||||
"expensiveammo": "Pahalı Mermi",
|
||||
"expensiveammo_desc": "Seçtiğin rakip her ateş ettiğinde para kaybeder",
|
||||
"expensiveammo_disable_info": "Mermilerin yeniden bedava.",
|
||||
"expensiveammo_enemy_info": "Artık her atışın sana {0}$ mal oluyor.",
|
||||
"expensiveammo_player_info": "'{0}' artık her mermisinin parasını ödüyor.",
|
||||
"expensiveammo_select_info": "Mermisi pahalanacak oyuncu:",
|
||||
"expensiveammo_disable_info": "Mermi yeniden bedava.",
|
||||
"expensiveammo_enemy_info": "Her atışın sana {0}$ mal oluyor.",
|
||||
"expensiveammo_player_info": "'{0}' her mermisinin parasını ödüyor.",
|
||||
"expensiveammo_select_info": "Birini seçin:",
|
||||
|
||||
"explodingbarrel": "Patlayan Varil",
|
||||
"explodingbarrel_desc": "[css_useSkill] ile vurulunca patlayan bir varil koyarsın",
|
||||
"explodingbarrel_desc": "[css_useSkill] tuşuna basarak vurulunca patlayan varil koy",
|
||||
|
||||
"explosiveshot": "Patlayıcı Mermi",
|
||||
"explosiveshot_desc": "Ateş ederken rastgele mermilerin patlayabilir",
|
||||
"explosiveshot_desc": "Ateş ederken mermin patlayabilir",
|
||||
"explosiveshot_desc2": "Patlayan mermi şansı: %{0}",
|
||||
|
||||
"falconeye": "Şahin Gözü",
|
||||
|
|
@ -156,31 +161,31 @@
|
|||
"fastreload_desc": "[css_useSkill] tuşuna basarak şarjörünü hızlıca değiştir",
|
||||
|
||||
"firerain": "Ateş Yağmuru",
|
||||
"firerain_desc": "Molotof yağdırmak için bir decoy at",
|
||||
"firerain_desc": "Molotof yağdırmak için yanıltıcı bomba at",
|
||||
|
||||
"flash": "Flash",
|
||||
"flash_desc": "Raund başında rastgele oyuncu hızı",
|
||||
"flash_desc": "Rastgele oyuncu hızı",
|
||||
"flash_desc2": "Hızın: {0}x",
|
||||
|
||||
"flashlight": "El Feneri",
|
||||
"flashlight_desc": "[css_useSkill] tuşuna basarak El fenerini açarsın/kaparsın (Işığı düşmanları kör edebilir)",
|
||||
"flashlight_desc": "[css_useSkill] tuşuna basarak el fenerini aç veya kapat, ışığı düşmanı kör eder",
|
||||
|
||||
"fortnite": "Fortnite",
|
||||
"fortnite_desc": "[css_useSkill] tuşuna basarak barikat kur",
|
||||
|
||||
"fragilebomb": "Hassas C4",
|
||||
"fragilebomb_desc": "Kurulu C4'e ateş etmek C4'ün canını azaltır ve C4 imha edilir.",
|
||||
"fragilebomb_desc": "Kurulu C4'e ateş etmek canını azaltır ve C4'ü imha eder",
|
||||
"fragilebomb_bomb_health": "Bombanın canı",
|
||||
|
||||
"friendlyfire": "Dost Şifası",
|
||||
"friendlyfire_desc": "Takım arkadaşlarına ateş etmek onları iyileştirir",
|
||||
"friendlyfire_desc": "Takım arkadaşına ateş etmek onu iyileştirir",
|
||||
|
||||
"frozendecoy": "Buz Kıran",
|
||||
"frozendecoy_desc": "Yanıltıcı bomba (decoy) yakındaki tüm oyuncuları dondurur",
|
||||
"frozendecoy_desc": "Yanıltıcı bomban yakındaki herkesi yavaşlatır",
|
||||
|
||||
"gambler": "Kumarbaz",
|
||||
"gambler_desc": "Sunulan listeden bir yetenek seç.",
|
||||
"gambler_select_info": "Yeteneğini seç:",
|
||||
"gambler_select_info": "Birini seçin:",
|
||||
"gambler_more": "#00FF00|${0} yenile",
|
||||
"gambler_no_money": "Yeterli para yok.",
|
||||
|
||||
|
|
@ -188,106 +193,116 @@
|
|||
"ghost_desc": "Tamamen görünmezsin",
|
||||
|
||||
"giant": "Dev",
|
||||
"giant_desc": "Seçtiğin bir rakibi büyütür",
|
||||
"giant_desc2": "Seçtiğin bir rakibi {0}x büyütür",
|
||||
"giant_disable_info": "Normal boyutuna geri döndün.",
|
||||
"giant_enemy_info": "{0}x boyutuna büyütüldün.",
|
||||
"giant_player_info": "'{0}' oyuncusunu {1}x büyüttün.",
|
||||
"giant_select_info": "Büyütülecek oyuncu:",
|
||||
"giant_desc": "Seçtiğin rakibi büyüt",
|
||||
"giant_desc2": "Rakibin boyutu: {0}x",
|
||||
"giant_disable_info": "Normal boyutuna döndün.",
|
||||
"giant_enemy_info": "{0}x boyutuna büyüdün.",
|
||||
"giant_player_info": "'{0}' boyutunu {1}x büyüttün.",
|
||||
"giant_select_info": "Birini seçin:",
|
||||
|
||||
"glaz": "Glaz",
|
||||
"glaz_desc": "Sis bombalarının içini görebilirsin",
|
||||
"glaz_desc": "Sis bombasının içini görürsün",
|
||||
|
||||
"glitch": "Glitç",
|
||||
"glitch_desc": "Seçilen bir düşmanın radarını kapatır",
|
||||
"glitch_enemy_info": "Radarın kapandı",
|
||||
"glitch_disable_info": "Radarın açıldı",
|
||||
"glitch_player_info": "'{0}' isimli oyuncunun radarı devre dışı bırakıldı.",
|
||||
"glitch_select_info": "Radarı kapatılacak oyuncuyu seç:",
|
||||
"glitch_desc": "Bir düşmanın radarını kapat",
|
||||
"glitch_enemy_info": "Radarın kapandı.",
|
||||
"glitch_disable_info": "Radarın açıldı.",
|
||||
"glitch_player_info": "'{0}' radarı kapandı.",
|
||||
"glitch_select_info": "Birini seçin:",
|
||||
|
||||
"glue": "Yapıştırıcı",
|
||||
"glue_desc": "Bombaların duvarlara yapışır",
|
||||
"glue_desc": "Bomban duvara yapışır",
|
||||
|
||||
"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ı",
|
||||
|
||||
"grapple": "Kanca",
|
||||
"grapple_desc": "[css_useSkill] tuşuna basarak baktığın yere kanca at",
|
||||
"grapple_no_anchor_info": "Kanca atılacak yüzey yok",
|
||||
"grapple_pulling_info": "ÇEKİLİYOR",
|
||||
|
||||
"grenadier": "Bombacı",
|
||||
"grenadier_desc": "Sınırsız el bombasına sahipsin",
|
||||
"grenadier_desc": "El bomban sınırsız",
|
||||
|
||||
"healingchicken": "Şifacı Tavuk",
|
||||
"healingchicken_desc": "Yakınındayken tavukların seni iyileştirir",
|
||||
"healingchicken_desc": "Yakınındayken tavuğun seni iyileştirir",
|
||||
|
||||
"healingsmoke": "Şifalı Sis",
|
||||
"healingsmoke_desc": "Sis bombaların iyileştirir",
|
||||
"healingsmoke_desc": "Sis bomban iyileştirir",
|
||||
|
||||
"hermit": "Münzevi",
|
||||
"hermit_desc": "Birini öldürünce mermin ve canın yenilenir",
|
||||
|
||||
"holyhandgrenade": "Kutsal El Bombası",
|
||||
"holyhandgrenade_desc": "El bomban iki kat hasara ve menzile sahip",
|
||||
"holyhandgrenade_desc": "El bombanın hasarı ve menzili iki kat",
|
||||
|
||||
"homingnades": "Güdümlü Bomba",
|
||||
"homingnades_desc": "Bombalarınız (sis hariç) düşmanlara yönelir",
|
||||
"homingnades_desc": "Bomban (sis hariç) yakın düşmana yönelir",
|
||||
|
||||
"hotbomb": "Sıcak C4",
|
||||
"hotbomb_desc": "Yaşadığın sürece bombacının canı azalıyor",
|
||||
"hotbomb_hint": "Bomba çok sıcak!",
|
||||
"hotbomb_disable_info": "Bomba artık yakmıyor.",
|
||||
"hotbomb_desc": "Yaşadığın sürece bombacının canı azalır",
|
||||
"hotbomb_hint": "C4 ÇOK SICAK!",
|
||||
"hotbomb_disable_info": "C4 soğudu.",
|
||||
|
||||
"iana": "Hologram",
|
||||
"iana_desc": "[css_useSkill] tuşuna basarak bir hologram oluştur",
|
||||
|
||||
"illiterate": "Cahiliye",
|
||||
"illiterate_desc": "Yaşadığın sürece rakibin sohbeti (chat) veya oyun yazılarını okuyamaz",
|
||||
"illiterate_desc": "Yaşadığın sürece rakip hiçbir yazıyı okuyamaz",
|
||||
"illiterate_alert": "Cahiliye aktif! Bu yeteneğin sahibi ortadan kalkana kadar mesajları okuyamazsınız.",
|
||||
|
||||
"illusionist": "İllüzyonist",
|
||||
"illusionist_desc": "[css_useSkill] tuşuna basarak düz ilerleyen illüzyon oluştur",
|
||||
|
||||
"impostor": "Sahtekar",
|
||||
"impostor_desc": "Düşman oyuncu modeline dönüşürsün",
|
||||
"impostor_desc": "Düşman modeline dönüşürsün",
|
||||
|
||||
"infiniteammo": "Sınırsız Mermi",
|
||||
"infiniteammo_desc": "Tüm silahların sınırsız mermisi olur",
|
||||
"infiniteammo_desc": "Silahlarının mermisi sınırsız",
|
||||
|
||||
"inheritance": "Miras",
|
||||
"inheritance_desc": "Bir takım arkadaşın öldüğünde yeteneğini devralabilirsin",
|
||||
"inheritance_select_info": "Birini seçin:",
|
||||
"inheritance_player_info": "'{0}' yeteneğini devraldın.",
|
||||
|
||||
"jackal": "İzci",
|
||||
"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_desc": "Bir düşmanın nişangahını kapat",
|
||||
"jammer_enemy_info": "Nişangahın kapatıldı.",
|
||||
"jammer_disable_info": "Nişangahın açıldı",
|
||||
"jammer_disable_info": "Nişangahın açıldı.",
|
||||
"jammer_player_info": "'{0}' isimli oyuncunun nişangahı kapatıldı.",
|
||||
"jammer_select_info": "Nişangahı kapatılacak oyuncuyu seç:",
|
||||
"jammer_select_info": "Birini seçin:",
|
||||
|
||||
"jester": "Soytarı",
|
||||
"jester_desc": "Soytarı modunda hasar alamazsın ve veremezsin. Bu mod birkaç saniyede bir değişir.",
|
||||
"jester_desc": "Soytarı modunda hasar alamaz ve veremezsin, mod birkaç saniyede bir değişir",
|
||||
"jester_mode": "Soytarı Modu",
|
||||
"jester_on": "AÇIK",
|
||||
"jester_off": "KAPALI",
|
||||
|
||||
"jetkick": "Jetkick",
|
||||
"jetkick_desc": "Seçtiğin bir rakibin her atışı onu geriye iter",
|
||||
"jetkick_select_info": "Jetkick uygulanacak oyuncu:",
|
||||
"jetkick_desc": "Seçtiğin rakibi her atışı geriye iter",
|
||||
"jetkick_select_info": "Birini seçin:",
|
||||
"jetkick_player_info": "'{0}' adlı oyuncuya jetkick uygulandı.",
|
||||
"jetkick_enemy_info": "Her atış seni geriye doğru iter",
|
||||
"jetkick_disable_info": "Geri tepmen normale döndü.",
|
||||
|
||||
"jumpban": "Bacaksız",
|
||||
"jumpban_desc": "Zıplayamayacak bir oyuncu seç",
|
||||
"jumpban_enemy_info": "Bacakların kesildi",
|
||||
"jumpban_disable_info": "Bacaklarına kavuştun",
|
||||
"jumpban_desc": "Zıplayamayacak bir düşman seç",
|
||||
"jumpban_enemy_info": "Bacakların kesildi.",
|
||||
"jumpban_disable_info": "Tekrar zıplayabilirsin.",
|
||||
"jumpban_player_info": "'{0}' artık zıplayamaz.",
|
||||
"jumpban_select_info": "Zıplaması yasaklanacak oyuncu:",
|
||||
"jumpban_select_info": "Birini seçin:",
|
||||
|
||||
"jumpcurse": "Zıplama Laneti",
|
||||
"jumpcurse_desc": "Seçtiğin rakip, takım arkadaşları her zıpladığında zıplar",
|
||||
"jumpcurse_disable_info": "Bacakların yeniden senin.",
|
||||
"jumpcurse_enemy_info": "Artık takım arkadaşların zıpladıkça sen de zıplıyorsun.",
|
||||
"jumpcurse_player_info": "'{0}' artık takımıyla birlikte zıplıyor.",
|
||||
"jumpcurse_select_info": "Zıplama laneti verilecek oyuncu:",
|
||||
"jumpcurse_desc": "Seçtiğin rakip, takım arkadaşlarıyla zıpladıkça zıplar",
|
||||
"jumpcurse_disable_info": "Kendin için zıplayabilirsin.",
|
||||
"jumpcurse_enemy_info": "Takım arkadaşların zıpladıkça sen de zıplıyorsun.",
|
||||
"jumpcurse_player_info": "'{0}' takımıyla birlikte zıplıyor.",
|
||||
"jumpcurse_select_info": "Birini seçin:",
|
||||
|
||||
"jumpingjack": "Zıpzıp Jack",
|
||||
"jumpingjack_desc": "Zıplamak canını yeniler",
|
||||
|
|
@ -302,10 +317,10 @@
|
|||
"lastgasp_desc": "Öldükten sonra seni öldürene hasar verirsin",
|
||||
|
||||
"lifeswap": "Can Takası",
|
||||
"lifeswap_desc": "Can değerlerini takas etmek için bir oyuncu seç",
|
||||
"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:",
|
||||
"lifeswap_desc": "Bir düşmanla canını takasla",
|
||||
"lifeswap_enemy_info": "Birisi canını çaldı.",
|
||||
"lifeswap_player_info": "'{0}' ile canını takasladın.",
|
||||
"lifeswap_select_info": "Birini seçin:",
|
||||
|
||||
"longknife": "Uzun Bıçak",
|
||||
"longknife_desc": "Bıçağın uzaktaki rakibe hasar verebilir",
|
||||
|
|
@ -314,46 +329,46 @@
|
|||
"longzeus_desc": "Zeus uzaktaki rakibe hasar verebilir",
|
||||
|
||||
"magneticdecoy": "Manyetik Yanıltıcı",
|
||||
"magneticdecoy_desc": "Yanıltıcı bombanız yakındaki oyuncuları kendine çeker",
|
||||
"magneticdecoy_desc": "Yanıltıcı bomban yakındaki herkesi kendine çeker",
|
||||
|
||||
"magneto": "Mıknatıs",
|
||||
"magneto_desc": "Tüm düşman bombaları sizden uzaklaştırılır",
|
||||
"magneto_desc": "Tüm düşman bombası senden uzaklaşır",
|
||||
|
||||
"magnifier": "Büyüteç",
|
||||
"magnifier_desc": "Düşmanın ekranını yakınlaştırarak görüş alanını daraltır",
|
||||
"magnifier_desc": "Bir düşmanın görüş alanını daralt",
|
||||
"magnifier_enemy_info": "Görüşün bozuldu!",
|
||||
"magnifier_disable_info": "Görüşün düzeldi",
|
||||
"magnifier_player_info": "'{0}' isimli oyuncunun ekranı yakınlaştırıldı.",
|
||||
"magnifier_select_info": "Ekranı büyütülecek oyuncuyu seç:",
|
||||
"magnifier_select_info": "Birini seçin:",
|
||||
|
||||
"medic": "Sıhhiye",
|
||||
"medic_desc": "[css_useSkill] tuşuna basarak kendine anında 50 HP bas",
|
||||
|
||||
"miner": "Mayın",
|
||||
"miner_desc": "El bombanız (HE) sadece yakında bir düşman olduğunda patlar",
|
||||
"miner_desc": "El bomban sadece yakında düşman varken patlar",
|
||||
|
||||
"bankrupt": "İflas",
|
||||
"bankrupt_desc": "Tüm parasını kaybedecek bir oyuncu seç",
|
||||
"bankrupt_desc": "Tüm parasını kaybedecek bir düşman seç",
|
||||
"bankrupt_enemy_info": "İflas ettin!",
|
||||
"bankrupt_player_info": "'{0}' isimli oyuncu iflas etti.",
|
||||
"bankrupt_select_info": "İflas edecek oyuncuyu seç:",
|
||||
"bankrupt_player_info": "'{0}' iflas etti.",
|
||||
"bankrupt_select_info": "Birini seçin:",
|
||||
|
||||
"deathbomb": "Canlı Bomba",
|
||||
"deathbomb_desc": "Öldüğünde patlayarak etraftaki oyuncuları öldürürsün",
|
||||
"deathbomb_desc": "Öldüğünde patlayıp etrafındakilere hasar verirsin",
|
||||
"deathbomb_explosion": "BOOM!!!",
|
||||
|
||||
"demoneye": "Şeytani Göz",
|
||||
"demoneye_desc": "Baktığın tüm düşmanlara hasar verirsin",
|
||||
"demoneye_desc": "Baktığın tüm düşmana hasar verirsin",
|
||||
|
||||
"nightmare": "Kabus",
|
||||
"nightmare_desc": "Seçtiğin bir rakibe kabus görüntüsü verir",
|
||||
"nightmare_desc": "Seçtiğin rakibe kabus gördür",
|
||||
"nightmare_disable_info": "Kabus sona erdi.",
|
||||
"nightmare_enemy_info": "Gözlerini bir kabus bürüdü.",
|
||||
"nightmare_player_info": "'{0}' oyuncusuna kabus gördürdün.",
|
||||
"nightmare_select_info": "Kabus görecek oyuncu:",
|
||||
"nightmare_select_info": "Birini seçin:",
|
||||
|
||||
"ninja": "Ninja",
|
||||
"ninja_desc": "Görünmezliğini sabit durmak %33, eğilmek %33 ve bıçak tutmak %33 artırır",
|
||||
"ninja_desc": "Sabit durmak, eğilmek ve bıçak tutmak görünmezliğini %33 artırır",
|
||||
|
||||
"nonades": "Bomba Geçirmez",
|
||||
"nonades_desc": "Bombalar sana hasar vermez",
|
||||
|
|
@ -375,38 +390,38 @@
|
|||
"paweljumper_desc2": "{0} kez ekstra zıplayabilirsin",
|
||||
|
||||
"phoenix": "Anka Kuşu",
|
||||
"phoenix_desc": "Öldükten sonra rastgele yeniden doğma şansın olur",
|
||||
"phoenix_desc": "Öldükten sonra yeniden doğma şansın olur",
|
||||
"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_desc": "Bombanın yanındayken otomatik imhaya başlarsın",
|
||||
"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",
|
||||
"pilot_desc": "Uçmak için zıplama tuşuna iki kez bas",
|
||||
"pilot_hud_info": "Yakıt",
|
||||
|
||||
"planter": "Serbest Kurucu",
|
||||
"planter_desc": "Bombayı her yere kurabilirsin, patlama süresi 60 saniyedir.",
|
||||
"planter_desc": "Bombayı her yere kurabilirsin, patlama süresi 60 saniye",
|
||||
"planter_planting": "Kuruluyor ({0})...",
|
||||
|
||||
"poison": "Zehir",
|
||||
"poison_desc": "Birkaç saniyede bir hasar alacak bir oyuncu seç",
|
||||
"poison_desc": "Birkaç saniyede bir hasar alacak bir düşman seç",
|
||||
"poison_enemy_info": "Zehirlendin.",
|
||||
"poison_disable_info": "Zehire bağışıklık kazandın",
|
||||
"poison_player_info": "'{0}' isimli oyuncu zehirlendi.",
|
||||
"poison_select_info": "Zehirlenecek oyuncuyu seç:",
|
||||
"poison_select_info": "Birini seçin:",
|
||||
|
||||
"primaryban": "Tüfek Yasak",
|
||||
"primaryban_desc": "Tüfek kullanamayacak bir oyuncu seç",
|
||||
"primaryban_desc": "Tüfek kullanamayacak bir düşman seç",
|
||||
"primaryban_enemy_info": "Tüfek kullanmayı unuttun",
|
||||
"primaryban_disable_info": "Tüfek kullanabilirsin",
|
||||
"primaryban_player_info": "'{0}' artık tüfek kullanamaz.",
|
||||
"primaryban_select_info": "Tüfek kullanımı yasaklanacak oyuncu:",
|
||||
"primaryban_select_info": "Birini seçin:",
|
||||
|
||||
"prosthesis": "Protez",
|
||||
"prosthesis_desc": "Kollar ve bacaklar kurşun geçirmezdir",
|
||||
"prosthesis_desc": "Kolların ve bacakların kurşun geçirmez",
|
||||
|
||||
"push": "İtici",
|
||||
"push_desc": "Düşmana vurduğunda onu geri itme şansın olur",
|
||||
|
|
@ -422,43 +437,46 @@
|
|||
"radarhack_desc": "Düşmanlar radarda görünür",
|
||||
|
||||
"rambo": "Rambo",
|
||||
"rambo_desc": "Raund başında rastgele miktarda can alırsın",
|
||||
"rambo_desc": "Rastgele miktarda canın olur",
|
||||
|
||||
"randomweapon": "Silah Kumarı",
|
||||
"randomweapon_desc": "[css_useSkill] tuşuna basarak rastgele bir silah al",
|
||||
|
||||
"rezombie": "Zombi",
|
||||
"rezombie_desc": "Öldükten sonra daha fazla canla ve silahsız zombi olarak doğarsın",
|
||||
"rezombie_desc": "Öldüğünde silahsız zombi olarak daha çok canla dirilirsin",
|
||||
|
||||
"reactivearmor": "Reaktif Zırh",
|
||||
"reactivearmor_desc": "Zırhın alınan ilk hasarı emmer",
|
||||
"reactivearmor_desc": "Zırhın ilk hasarı emer",
|
||||
|
||||
"regeneration": "Yenilenme",
|
||||
"regeneration_desc": "Birkaç saniyede bir canın yenilenir",
|
||||
|
||||
"replicator": "Klon",
|
||||
"replicator_desc": "[css_useSkill] tuşuna basarak klon oluştur ve öldürene hasar verir",
|
||||
"replicator_desc": "[css_useSkill] tuşuna basarak klon oluştur, klonu öldürene hasar verir",
|
||||
|
||||
"retreat": "Geri Çekil",
|
||||
"retreat_desc": "[css_useSkill] tuşuna basarak başlangıç noktasına ışınlan",
|
||||
"retreat_desc": "[css_useSkill] tuşuna basarak başlangıcına ışınlan",
|
||||
|
||||
"returntosender": "İade",
|
||||
"returntosender_desc": "Düşmana ilk vuruşun onu kendi başlangıç noktasına ışınlar",
|
||||
"returntosender_desc": "Düşmana ilk vuruşun onu kendi başlangıcına ışınlar",
|
||||
|
||||
"richboy": "Zengin Çocuk",
|
||||
"richboy_desc": "Raund başında rastgele miktarda para alırsın",
|
||||
"richboy_desc": "Rastgele miktarda paran olur",
|
||||
|
||||
"ricochet": "Seken Mermi",
|
||||
"ricochet_desc": "Mermin duvardan seker ve düşmana isabet edebilir",
|
||||
|
||||
"robinhood": "Robin Hood",
|
||||
"robinhood_desc": "Düşmana hasar vermek onun parasını çalar",
|
||||
|
||||
"rubber": "Lastik Mermi",
|
||||
"rubber_desc": "Mermilerin oyuncuları önemli ölçüde yavaşlatır",
|
||||
"rubber_desc": "Mermin isabet edeni yavaşlatır",
|
||||
|
||||
"saper": "İstihkamcı",
|
||||
"saper_desc": "Bombayı daha hızlı kurabilir ve imha edebilirsin",
|
||||
"saper_desc": "Bombayı daha hızlı kurar ve imha edersin",
|
||||
|
||||
"secondlife": "İkinci Şans",
|
||||
"secondlife_desc": "Öldükten sonra aynı miktarda canla yeniden doğarsın",
|
||||
"secondlife_desc": "Öldüğünde aynı canla yeniden doğarsın",
|
||||
|
||||
"shade": "Gölge",
|
||||
"shade_desc": "Vurduğun düşmanın arkasına ışınlanma şansın olur",
|
||||
|
|
@ -466,24 +484,24 @@
|
|||
"shade_nospace": "Uygun alan yok",
|
||||
|
||||
"shortbomb": "Kısa Fünye",
|
||||
"shortbomb_desc": "Bomba çok daha hızlı patlar",
|
||||
"shortbomb_desc": "C4 çok daha hızlı patlar",
|
||||
|
||||
"silent": "Sessiz",
|
||||
"silent_desc": "Ayak seslerini ve zıplamalarını DİĞER oyuncular duyamaz",
|
||||
"silent_desc": "Ayak ve zıplama sesini kimse duyamaz",
|
||||
|
||||
"smoker": "Tiryaki",
|
||||
"smoker_desc": "Attığın Sis asla bitmez",
|
||||
"smoker_desc": "Attığın sis asla bitmez",
|
||||
|
||||
"sniperelite": "Keskin Nişancı",
|
||||
"sniperelite_customname": "Keskin Nişancı",
|
||||
"sniperelite_desc": "[css_useSkill] tuşuna basarak silahını AWP ile değiştir",
|
||||
|
||||
"soldier": "Teğmen",
|
||||
"soldier_desc": "Rastgele bir oranda fazla hasar verirsin",
|
||||
"soldier_desc": "Rastgele hasar verme çarpanın olur",
|
||||
"soldier_desc2": "Hasarın: {0}x",
|
||||
|
||||
"soundmaker": "Çığlık",
|
||||
"soundmaker_desc": "Rakiplerinin çığlıklarını duyarsın",
|
||||
"soundmaker_desc": "Rakibin çığlığını duyarsın",
|
||||
|
||||
"spectator": "Röntgen",
|
||||
"spectator_desc": "[css_useSkill] tuşuna basarak rakibinin gözünden gör",
|
||||
|
|
@ -492,47 +510,47 @@
|
|||
"swapposition_desc": "[css_useSkill] tuşuna basarak vurduğun düşmanla yer değiştir",
|
||||
|
||||
"takeammo": "Cephane Hırsızı",
|
||||
"takeammo_desc": "[css_useSkill] tuşuna basarak rastgele bir düşmanın silahının şarjörünü çalarsın",
|
||||
"takeammo_hud_info1": "Cephanesi olan bir oyuncu bulunamadı.",
|
||||
"takeammo_hud_info2": "Düşmanın cephanesi yok.",
|
||||
"takeammo_enemy_info": "Birisi cephaneni çaldı.",
|
||||
"takeammo_desc": "[css_useSkill] tuşuna basarak rastgele bir düşmanın şarjörünü çal",
|
||||
"takeammo_hud_info1": "Şarjörü olan bir oyuncu bulunamadı.",
|
||||
"takeammo_hud_info2": "Düşmanın şarjörü yok.",
|
||||
"takeammo_enemy_info": "Birisi şarjörünü çaldı.",
|
||||
|
||||
"teamteleport": "Takıma Işınlanma",
|
||||
"teamteleport_desc": "[css_useSkill] tuşuna basarak baktığın takım arkadaşına ışınlanırsın",
|
||||
"teamteleport_desc": "[css_useSkill] tuşuna basarak baktığın takım arkadaşına ışınlan",
|
||||
"teamteleport_noenemy": "Takım arkadaşı bulunamadı",
|
||||
"teamteleport_hud_info": "Bulundu: {0}",
|
||||
|
||||
"teleporter": "Işınlayıcı",
|
||||
"teleporter_desc": "Vurulan bir düşmanla yer değiştirme şansınız var",
|
||||
"teleporter_desc": "Vurduğun düşmanla yer değiştirme şansın olur",
|
||||
"teleporter_desc2": "Yer değiştirme şansın: %{0}",
|
||||
|
||||
"thief": "Hırsız",
|
||||
"thief_desc": "Seçilen bir oyuncudan yeteneğini çalabilirsin",
|
||||
"thief_desc": "Bir düşmanın yeteneğini çal",
|
||||
"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_select_info": "Birini seçin:",
|
||||
"thief_incorrect_skill": "Bu yetenek çalınamaz!",
|
||||
|
||||
"thirdeye": "Üçüncü Göz",
|
||||
"thirdeye_desc": "[css_useSkill] tuşuna basarak üçüncü göze(thirdperson) geç",
|
||||
"thirdeye_desc": "[css_useSkill] tuşuna basarak üçüncü şahıs görünümüne geç",
|
||||
|
||||
"thorns": "Dikenler",
|
||||
"thorns_desc": "Rakibin, sana verdiği hasarın bir kısmını geri alır",
|
||||
"thorns_desc": "Sana verilen hasarın bir kısmı rakibe döner",
|
||||
|
||||
"throwingknife": "Fırlatma Bıçağı",
|
||||
"throwingknife_desc": "Bıçak fırlatmak için [css_useSkill] tuşuna basın. Ama başkalarına dikkat edin",
|
||||
"throwingknife_desc": "[css_useSkill] tuşuna basarak bıçak fırlat",
|
||||
|
||||
"toxicsmoke": "Zehirli Sis",
|
||||
"toxicsmoke_desc": "Sis bombaların hasar verir",
|
||||
"toxicsmoke_desc": "Sis bomban hasar verir",
|
||||
|
||||
"tripwire": "Tel Tuzağı",
|
||||
"tripwire_desc": "[css_useSkill] ile iki duvar arasına tel ger. Tele değen düşman radarında görünür",
|
||||
"tripwire_desc": "[css_useSkill] tuşuna basarak iki duvar arasına tel ger, değen düşman radarda görünür",
|
||||
"tripwire_no_wall_info": "İki yanında da yeterince yakın duvar yok.",
|
||||
"tripwire_placed_info": "Tel gerildi.",
|
||||
"tripwire_triggered_info": "'{0}' teline takıldı.",
|
||||
|
||||
"wallhack": "Wallhack",
|
||||
"wallhack_desc": "Düşmanları duvarların arkasından görebilirsin",
|
||||
"wallhack_desc": "Düşmanları duvar arkasından görürsün",
|
||||
|
||||
"watchmaker": "Saat Ustası",
|
||||
"watchmaker_desc": "Atılan her bomba raund süresini değiştirir",
|
||||
|
|
@ -544,21 +562,21 @@
|
|||
"weaponsswap_hud_info2": "Takas edilecek silahın yok",
|
||||
|
||||
"weightless": "Yerçekimsiz",
|
||||
"weightless_desc": "El bombalarınız yerçekiminden etkilenmez ve dümdüz gider",
|
||||
"weightless_desc": "El bomban yerçekiminden etkilenmez ve dümdüz gider",
|
||||
|
||||
"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_desc": "El bombası atmakta zorlanacak bir düşman seç",
|
||||
"wildthrow_player_info": "'{0}' tüm taktiklerini unuttu.",
|
||||
"wildthrow_enemy_info": "Bomba atarken çok heyecanlanıyorsun.",
|
||||
"wildthrow_disable_info": "Bombaların düzeldi.",
|
||||
"wildthrow_select_info": "Bir oyuncu seçin:",
|
||||
"wildthrow_disable_info": "Bomban tekrardan düzgün.",
|
||||
"wildthrow_select_info": "Birini seçin:",
|
||||
|
||||
"zeus": "Zeus",
|
||||
"zeus_desc": "Zeus x27 anında şarj olur",
|
||||
|
||||
"your_skill": "Yeteneğin",
|
||||
"enemy_skill": "Düşmanın yeteneği",
|
||||
"observer_skill": "Oyuncunun yeteneği",
|
||||
"observer_skill": "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 çarkı dönüyor...",
|
||||
"disabled_weapon": "Bu silahı kullanamazsın",
|
||||
|
|
|
|||
|
|
@ -71,6 +71,11 @@
|
|||
"catapult_desc": "你有随机几率将敌人向上弹射",
|
||||
"catapult_desc2": "你击中敌人将其弹射的几率是:{0}%",
|
||||
|
||||
"chameleon": "变色龙",
|
||||
"chameleon_desc": "你击杀的第一名玩家会把技能传给你",
|
||||
"chameleon_copied_info": "已复制技能:{0}",
|
||||
"chameleon_wrong_team_info": "'{0}' 的技能你的队伍无法使用。",
|
||||
|
||||
"chicken": "小鸡",
|
||||
"chicken_desc": "你获得小鸡模型 + 移动速度提高10% - 50生命值",
|
||||
|
||||
|
|
@ -201,6 +206,11 @@
|
|||
"godmode_off": "无敌状态已禁用",
|
||||
"godmode_on": "无敌状态已启用",
|
||||
|
||||
"grapple": "钩爪",
|
||||
"grapple_desc": "按 [css_useSkill] 向准星所指位置发射钩爪并将自己拉过去",
|
||||
"grapple_no_anchor_info": "没有可以钩住的表面。",
|
||||
"grapple_pulling_info": "拉动中",
|
||||
|
||||
"grenadier": "投弹手",
|
||||
"grenadier_desc": "你拥有无限高爆手雷",
|
||||
|
||||
|
|
@ -237,6 +247,11 @@
|
|||
"infiniteammo": "无限弹药",
|
||||
"infiniteammo_desc": "你为所有武器获得无限弹药",
|
||||
|
||||
"inheritance": "继承",
|
||||
"inheritance_desc": "当队友阵亡时,你可以接管他的技能",
|
||||
"inheritance_select_info": "选择要继承的技能:",
|
||||
"inheritance_player_info": "你继承了 '{0}' 的技能。",
|
||||
|
||||
"jackal": "追踪者",
|
||||
"jackal_desc": "每个对手都会留下痕迹",
|
||||
|
||||
|
|
@ -418,6 +433,9 @@
|
|||
"richboy": "富少",
|
||||
"richboy_desc": "回合开始时你获得随机数量的钱",
|
||||
|
||||
"ricochet": "跳弹",
|
||||
"ricochet_desc": "你的子弹会从墙上弹开,并且仍能击中敌人",
|
||||
|
||||
"robinhood": "罗宾汉",
|
||||
"robinhood_desc": "对敌人造成伤害会偷取他们的钱",
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue