Improve illiterate text and FOV handling
This commit is contained in:
parent
cc32a11404
commit
ada2f4ff7b
36 changed files with 799 additions and 123 deletions
|
|
@ -112,10 +112,10 @@ namespace src.command
|
||||||
{
|
{
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
Server.PrintToConsole(Localization.GetTranslation("correct_form_setskill"));
|
Server.PrintToConsole(Localization.GetTranslationWithoutIlliterate("correct_form_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SkillUtils.PrintToChat(player, player.GetTranslation("correct_form_setskill"));
|
SkillUtils.PrintToChat(player, player.GetTranslationWithoutIlliterate("correct_form_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,10 +123,10 @@ namespace src.command
|
||||||
{
|
{
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
Server.PrintToConsole(Localization.GetTranslation("player_not_found_setskill"));
|
Server.PrintToConsole(Localization.GetTranslationWithoutIlliterate("player_not_found_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SkillUtils.PrintToChat(player, player.GetTranslation("player_not_found_setskill"));
|
SkillUtils.PrintToChat(player, player.GetTranslationWithoutIlliterate("player_not_found_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,10 +137,10 @@ namespace src.command
|
||||||
{
|
{
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
Server.PrintToConsole(Localization.GetTranslation("skill_not_found_setskill"));
|
Server.PrintToConsole(Localization.GetTranslationWithoutIlliterate("skill_not_found_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SkillUtils.PrintToChat(player, player.GetTranslation("skill_not_found_setskill"));
|
SkillUtils.PrintToChat(player, player.GetTranslationWithoutIlliterate("skill_not_found_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,11 +155,11 @@ namespace src.command
|
||||||
|
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
Server.PrintToConsole(Localization.GetTranslation("done_setskill"));
|
Server.PrintToConsole(Localization.GetTranslationWithoutIlliterate("done_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkillUtils.PrintToChat(player, $"{player.GetTranslation("done_setskill")}: {ChatColors.LightRed}{player.GetSkillName(skill.Skill)} {ChatColors.Lime}{player.GetTranslation("for_setskill")} {ChatColors.LightRed}\u202A{targetPlayer.PlayerName}\u202C");
|
SkillUtils.PrintToChat(player, $"{player.GetTranslationWithoutIlliterate("done_setskill")}: {ChatColors.LightRed}{player.GetSkillName(skill.Skill)} {ChatColors.Lime}{player.GetTranslationWithoutIlliterate("for_setskill")} {ChatColors.LightRed}\u202A{targetPlayer.PlayerName}\u202C");
|
||||||
|
|
||||||
if (skill.Display)
|
if (skill.Display)
|
||||||
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(skill.Skill)}", border: "b");
|
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(skill.Skill)}", border: "b");
|
||||||
|
|
@ -168,11 +168,11 @@ namespace src.command
|
||||||
{
|
{
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
Server.PrintToConsole(Localization.GetTranslation("error_setskill"));
|
Server.PrintToConsole(Localization.GetTranslationWithoutIlliterate("error_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkillUtils.PrintToChat(player, player.GetTranslation("error_setskill"));
|
SkillUtils.PrintToChat(player, player.GetTranslationWithoutIlliterate("error_setskill"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,16 +234,16 @@ namespace src.command
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(map))
|
if (string.IsNullOrEmpty(map))
|
||||||
{
|
{
|
||||||
command.ReplyToCommand($" {ChatColors.Red}{command.CallingPlayer?.GetTranslation("invalid_map")}");
|
command.ReplyToCommand($" {ChatColors.Red}{command.CallingPlayer?.GetTranslationWithoutIlliterate("invalid_map")}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Localization.PrintTranslationToChatAll($" {ChatColors.Yellow}{{0}} ({ChatColors.Green}{map}{ChatColors.Yellow})...", ["loading_map"]);
|
Localization.PrintTranslationToChatAll($" {ChatColors.Yellow}{{0}} ({ChatColors.Green}{map}{ChatColors.Yellow})...", ["loading_map"], false);
|
||||||
|
|
||||||
if (uint.TryParse(map, out _))
|
if (uint.TryParse(map, out _))
|
||||||
Server.ExecuteCommand($"host_workshop_map {map}");
|
Server.ExecuteCommand($"host_workshop_map {map}");
|
||||||
else if (!Server.IsMapValid(map))
|
else if (!Server.IsMapValid(map))
|
||||||
command.ReplyToCommand($" {ChatColors.Red}{command.CallingPlayer?.GetTranslation("invalid_map")}");
|
command.ReplyToCommand($" {ChatColors.Red}{command.CallingPlayer?.GetTranslationWithoutIlliterate("invalid_map")}");
|
||||||
else
|
else
|
||||||
Server.ExecuteCommand($"changelevel {map}");
|
Server.ExecuteCommand($"changelevel {map}");
|
||||||
}
|
}
|
||||||
|
|
@ -274,12 +274,12 @@ namespace src.command
|
||||||
if (Instance?.GameRules?.WarmupPeriod == true)
|
if (Instance?.GameRules?.WarmupPeriod == true)
|
||||||
{
|
{
|
||||||
Server.ExecuteCommand("mp_warmup_end");
|
Server.ExecuteCommand("mp_warmup_end");
|
||||||
Localization.PrintTranslationToChatAll($" {ChatColors.Green}{{0}}", ["game_start"]);
|
Localization.PrintTranslationToChatAll($" {ChatColors.Green}{{0}}", ["game_start"], false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Server.ExecuteCommand("mp_restartgame 2");
|
Server.ExecuteCommand("mp_restartgame 2");
|
||||||
Instance?.AddTimer(2.0f, () => Localization.PrintTranslationToChatAll($" {ChatColors.Green}{{0}}", ["game_start"]), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
Instance?.AddTimer(2.0f, () => Localization.PrintTranslationToChatAll($" {ChatColors.Green}{{0}}", ["game_start"], false), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -348,7 +348,7 @@ namespace src.command
|
||||||
|
|
||||||
private static void Pause()
|
private static void Pause()
|
||||||
{
|
{
|
||||||
Localization.PrintTranslationToChatAll($" {(gamePaused ? ChatColors.Green : ChatColors.Red)}{{0}}", [gamePaused ? "unpause" : "pause"]);
|
Localization.PrintTranslationToChatAll($" {(gamePaused ? ChatColors.Green : ChatColors.Red)}{{0}}", [gamePaused ? "unpause" : "pause"], false);
|
||||||
Server.ExecuteCommand(gamePaused ? "mp_unpause_match" : "mp_pause_match");
|
Server.ExecuteCommand(gamePaused ? "mp_unpause_match" : "mp_pause_match");
|
||||||
gamePaused = !gamePaused;
|
gamePaused = !gamePaused;
|
||||||
}
|
}
|
||||||
|
|
@ -360,7 +360,7 @@ namespace src.command
|
||||||
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
|
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
|
||||||
if (!string.IsNullOrEmpty(config.NormalCommands.HealCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.HealCommand.Permissions)) return;
|
if (!string.IsNullOrEmpty(config.NormalCommands.HealCommand.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.HealCommand.Permissions)) return;
|
||||||
SkillUtils.AddHealth(player.PlayerPawn.Value, 100);
|
SkillUtils.AddHealth(player.PlayerPawn.Value, 100);
|
||||||
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("healed")}");
|
player.PrintToChat($" {ChatColors.Green}{player.GetTranslationWithoutIlliterate("healed")}");
|
||||||
}
|
}
|
||||||
|
|
||||||
[CommandHelper(minArgs: 1, whoCanExecute: CommandUsage.CLIENT_ONLY)]
|
[CommandHelper(minArgs: 1, whoCanExecute: CommandUsage.CLIENT_ONLY)]
|
||||||
|
|
@ -374,7 +374,7 @@ namespace src.command
|
||||||
if (int.TryParse(command.GetArg(1), out int health))
|
if (int.TryParse(command.GetArg(1), out int health))
|
||||||
SkillUtils.AddHealth(pawn, health - pawn.Health, health);
|
SkillUtils.AddHealth(pawn, health - pawn.Health, health);
|
||||||
|
|
||||||
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("set_health")}");
|
player.PrintToChat($" {ChatColors.Green}{player.GetTranslationWithoutIlliterate("set_health")}");
|
||||||
}
|
}
|
||||||
|
|
||||||
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
|
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
|
||||||
|
|
@ -396,7 +396,7 @@ namespace src.command
|
||||||
time = 40;
|
time = 40;
|
||||||
|
|
||||||
bomb.C4Blow = Server.CurrentTime + time;
|
bomb.C4Blow = Server.CurrentTime + time;
|
||||||
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("planted_bomb_spawned", [time])}");
|
player.PrintToChat($" {ChatColors.Green}{player.GetTranslationWithoutIlliterate("planted_bomb_spawned", [time])}");
|
||||||
}
|
}
|
||||||
|
|
||||||
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
|
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
|
||||||
|
|
@ -415,7 +415,7 @@ namespace src.command
|
||||||
var bot = Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.IsBot && p.PawnIsAlive && (botSlot == -1 || p.Slot == botSlot)).FirstOrDefault();
|
var bot = Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.IsBot && p.PawnIsAlive && (botSlot == -1 || p.Slot == botSlot)).FirstOrDefault();
|
||||||
if (bot == null || bot.PlayerPawn.Value == null || !bot.PlayerPawn.Value.IsValid)
|
if (bot == null || bot.PlayerPawn.Value == null || !bot.PlayerPawn.Value.IsValid)
|
||||||
{
|
{
|
||||||
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("bot_placed_not_found")}");
|
player.PrintToChat($" {ChatColors.Green}{player.GetTranslationWithoutIlliterate("bot_placed_not_found")}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -426,7 +426,7 @@ namespace src.command
|
||||||
|| (int.TryParse(command.GetArg(2), out int godmodeInt) && godmodeInt == 1))
|
|| (int.TryParse(command.GetArg(2), out int godmodeInt) && godmodeInt == 1))
|
||||||
bot.PlayerPawn.Value.TakesDamage = false;
|
bot.PlayerPawn.Value.TakesDamage = false;
|
||||||
|
|
||||||
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("bot_placed")}");
|
player.PrintToChat($" {ChatColors.Green}{player.GetTranslationWithoutIlliterate("bot_placed")}");
|
||||||
}
|
}
|
||||||
|
|
||||||
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
|
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
|
||||||
|
|
@ -444,7 +444,7 @@ namespace src.command
|
||||||
|
|
||||||
playerInfo.HideHUD = isDisplayHUD ? int.MaxValue : int.MinValue;
|
playerInfo.HideHUD = isDisplayHUD ? int.MaxValue : int.MinValue;
|
||||||
SkillUtils.SetMenuPaused(player, isDisplayHUD);
|
SkillUtils.SetMenuPaused(player, isDisplayHUD);
|
||||||
player.PrintToChat($" {(!isDisplayHUD ? ChatColors.Green : ChatColors.Red)}{player.GetTranslation(!isDisplayHUD ? "hud_on" : "hud_off")}");
|
player.PrintToChat($" {(!isDisplayHUD ? ChatColors.Green : ChatColors.Red)}{player.GetTranslationWithoutIlliterate(!isDisplayHUD ? "hud_on" : "hud_off")}");
|
||||||
}
|
}
|
||||||
|
|
||||||
[CommandHelper(minArgs: 2, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
[CommandHelper(minArgs: 2, whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||||
|
|
@ -466,7 +466,7 @@ namespace src.command
|
||||||
if (!int.TryParse(command.GetArg(1), out int ctScore) || !int.TryParse(command.GetArg(2), out int tScore))
|
if (!int.TryParse(command.GetArg(1), out int ctScore) || !int.TryParse(command.GetArg(2), out int tScore))
|
||||||
{
|
{
|
||||||
if (player != null && player.IsValid)
|
if (player != null && player.IsValid)
|
||||||
SkillUtils.PrintToChat(player, player.GetTranslation("correct_form_setscore"));
|
SkillUtils.PrintToChat(player, player.GetTranslationWithoutIlliterate("correct_form_setscore"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -496,11 +496,11 @@ namespace src.command
|
||||||
{
|
{
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
Server.PrintToConsole(Localization.GetTranslation("correct_form_setskill"));
|
Server.PrintToConsole(Localization.GetTranslationWithoutIlliterate("correct_form_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkillUtils.PrintToChat(player, player.GetTranslation("correct_form_setskill"));
|
SkillUtils.PrintToChat(player, player.GetTranslationWithoutIlliterate("correct_form_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -508,11 +508,11 @@ namespace src.command
|
||||||
{
|
{
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
Server.PrintToConsole(Localization.GetTranslation("player_not_found_setskill"));
|
Server.PrintToConsole(Localization.GetTranslationWithoutIlliterate("player_not_found_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkillUtils.PrintToChat(player, player.GetTranslation("player_not_found_setskill"));
|
SkillUtils.PrintToChat(player, player.GetTranslationWithoutIlliterate("player_not_found_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -523,11 +523,11 @@ namespace src.command
|
||||||
{
|
{
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
Server.PrintToConsole(Localization.GetTranslation("skill_not_found_setskill"));
|
Server.PrintToConsole(Localization.GetTranslationWithoutIlliterate("skill_not_found_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkillUtils.PrintToChat(player, player.GetTranslation("skill_not_found_setskill"));
|
SkillUtils.PrintToChat(player, player.GetTranslationWithoutIlliterate("skill_not_found_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -547,11 +547,11 @@ namespace src.command
|
||||||
|
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
Server.PrintToConsole(Localization.GetTranslation("done_setskill"));
|
Server.PrintToConsole(Localization.GetTranslationWithoutIlliterate("done_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkillUtils.PrintToChat(player, $"{player.GetTranslation("done_setskill")}: {ChatColors.LightRed}{player.GetSkillName(skill.Skill)} {ChatColors.Lime}{player.GetTranslation("for_setskill")} {ChatColors.LightRed}\u202A{targetPlayer.PlayerName}\u202C");
|
SkillUtils.PrintToChat(player, $"{player.GetTranslationWithoutIlliterate("done_setskill")}: {ChatColors.LightRed}{player.GetSkillName(skill.Skill)} {ChatColors.Lime}{player.GetTranslationWithoutIlliterate("for_setskill")} {ChatColors.LightRed}\u202A{targetPlayer.PlayerName}\u202C");
|
||||||
|
|
||||||
if (skill.Display)
|
if (skill.Display)
|
||||||
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(skill.Skill)}", border: "b");
|
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(skill.Skill)}", border: "b");
|
||||||
|
|
@ -560,11 +560,11 @@ namespace src.command
|
||||||
{
|
{
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
Server.PrintToConsole(Localization.GetTranslation("error_setskill"));
|
Server.PrintToConsole(Localization.GetTranslationWithoutIlliterate("error_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkillUtils.PrintToChat(player, player.GetTranslation("error_setskill"));
|
SkillUtils.PrintToChat(player, player.GetTranslationWithoutIlliterate("error_setskill"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -607,9 +607,9 @@ namespace src.command
|
||||||
Event.InvalidateFreezeDisabledCache();
|
Event.InvalidateFreezeDisabledCache();
|
||||||
|
|
||||||
if (player != null && player.IsValid)
|
if (player != null && player.IsValid)
|
||||||
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("reload")}");
|
player.PrintToChat($" {ChatColors.Green}{player.GetTranslationWithoutIlliterate("reload")}");
|
||||||
else
|
else
|
||||||
Server.PrintToConsole($" {ChatColors.Green}{Localization.GetTranslation("reload")}");
|
Server.PrintToConsole($" {ChatColors.Green}{Localization.GetTranslationWithoutIlliterate("reload")}");
|
||||||
|
|
||||||
foreach (var target in Instance.SkillPlayer)
|
foreach (var target in Instance.SkillPlayer)
|
||||||
{
|
{
|
||||||
|
|
@ -645,10 +645,10 @@ namespace src.command
|
||||||
{
|
{
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
Server.PrintToConsole(Localization.GetTranslation("player_not_found_setskill"));
|
Server.PrintToConsole(Localization.GetTranslationWithoutIlliterate("player_not_found_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SkillUtils.PrintToChat(player, player.GetTranslation("player_not_found_setskill"));
|
SkillUtils.PrintToChat(player, player.GetTranslationWithoutIlliterate("player_not_found_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace src.command
|
||||||
|
|
||||||
vote.SetActive(false);
|
vote.SetActive(false);
|
||||||
vote.TimeToNextSameVoting = vote.TimeToNextVoting;
|
vote.TimeToNextSameVoting = vote.TimeToNextVoting;
|
||||||
Localization.PrintTranslationToChatAll($" {ChatColors.Red}{{0}}", ["vote_timeout"], [commandName]);
|
Localization.PrintTranslationToChatAll($" {ChatColors.Red}{{0}}", ["vote_timeout"], false, [commandName]);
|
||||||
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -38,7 +38,7 @@ namespace src.command
|
||||||
votes.TryAdd(vote, 0);
|
votes.TryAdd(vote, 0);
|
||||||
string commandName = $"!{VoteTypeCommands.GetCommand(vote.Type)?.Replace("css_", "")}{(!string.IsNullOrEmpty(vote?.Args) ? $" {vote?.Args}" : "")}";
|
string commandName = $"!{VoteTypeCommands.GetCommand(vote.Type)?.Replace("css_", "")}{(!string.IsNullOrEmpty(vote?.Args) ? $" {vote?.Args}" : "")}";
|
||||||
|
|
||||||
Localization.PrintTranslationToChatAll($" {ChatColors.Lime}{{0}}", ["vote_started"], [commandName]);
|
Localization.PrintTranslationToChatAll($" {ChatColors.Lime}{{0}}", ["vote_started"], false, [commandName]);
|
||||||
foreach (var player in Utilities.GetPlayers())
|
foreach (var player in Utilities.GetPlayers())
|
||||||
player.EmitSound("UIPanorama.tab_mainmenu_news");
|
player.EmitSound("UIPanorama.tab_mainmenu_news");
|
||||||
|
|
||||||
|
|
@ -61,12 +61,12 @@ namespace src.command
|
||||||
{
|
{
|
||||||
if (votes.Keys.Any(v => v.NextVoting() > DateTime.Now))
|
if (votes.Keys.Any(v => v.NextVoting() > DateTime.Now))
|
||||||
{
|
{
|
||||||
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("vote_wait")}");
|
player.PrintToChat($" {ChatColors.Red}{player.GetTranslationWithoutIlliterate("vote_wait")}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (votes.Keys.Any(v => v.Type == voteType && v.NextSameVoting() > DateTime.Now))
|
else if (votes.Keys.Any(v => v.Type == voteType && v.NextSameVoting() > DateTime.Now))
|
||||||
{
|
{
|
||||||
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("vote_same_wait")}");
|
player.PrintToChat($" {ChatColors.Red}{player.GetTranslationWithoutIlliterate("vote_same_wait")}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,12 +75,12 @@ namespace src.command
|
||||||
|
|
||||||
if (vote == null)
|
if (vote == null)
|
||||||
{
|
{
|
||||||
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("vote_not_enough_players")}");
|
player.PrintToChat($" {ChatColors.Red}{player.GetTranslationWithoutIlliterate("vote_not_enough_players")}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vote.PlayersVoted.TryAdd(player.SteamID, 0))
|
if (!vote.PlayersVoted.TryAdd(player.SteamID, 0))
|
||||||
player.PrintToChat($" {ChatColors.Red}{player.GetTranslation("vote_alredy_voted")}");
|
player.PrintToChat($" {ChatColors.Red}{player.GetTranslationWithoutIlliterate("vote_alredy_voted")}");
|
||||||
else CheckVote(vote);
|
else CheckVote(vote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,7 +100,7 @@ namespace src.command
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
StartVoteTimer(vote!, commandName);
|
StartVoteTimer(vote!, commandName);
|
||||||
Localization.PrintTranslationToChatAll($" {ChatColors.Yellow}{{0}} '': {ChatColors.Green}{voted}/{playersNeeded}", ["vote_vote"]);
|
Localization.PrintTranslationToChatAll($" {ChatColors.Yellow}{{0}} '': {ChatColors.Green}{voted}/{playersNeeded}", ["vote_vote"], false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -248,6 +248,7 @@
|
||||||
|
|
||||||
"illiterate": "Analphabet",
|
"illiterate": "Analphabet",
|
||||||
"illiterate_desc": "Solange du am Leben bist, können deine Feinde nichts lesen",
|
"illiterate_desc": "Solange du am Leben bist, können deine Feinde nichts lesen",
|
||||||
|
"illiterate_alert": "Analphabet ist aktiv! Du kannst keine Nachrichten lesen, bis der Besitzer dieser Fähigkeit eliminiert ist",
|
||||||
|
|
||||||
"illusionist": "Illusionist",
|
"illusionist": "Illusionist",
|
||||||
"illusionist_desc": "Klicke [css_useSkill], um ein Abbild zu schicken, das geradeaus läuft",
|
"illusionist_desc": "Klicke [css_useSkill], um ein Abbild zu schicken, das geradeaus läuft",
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,7 @@
|
||||||
|
|
||||||
"illiterate": "Illiterate",
|
"illiterate": "Illiterate",
|
||||||
"illiterate_desc": "As long as you are alive, your enemies cannot read",
|
"illiterate_desc": "As long as you are alive, your enemies cannot read",
|
||||||
|
"illiterate_alert": "Illiterate is active! You cannot read messages until the owner of this skill is eliminated",
|
||||||
|
|
||||||
"illusionist": "Illusionist",
|
"illusionist": "Illusionist",
|
||||||
"illusionist_desc": "Click [css_useSkill] to deploy a replica that walks straight ahead",
|
"illusionist_desc": "Click [css_useSkill] to deploy a replica that walks straight ahead",
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,8 @@
|
||||||
"iana_desc": "Cliquez sur [css_useSkill] pour contrôler votre hologramme pendant quelques secondes",
|
"iana_desc": "Cliquez sur [css_useSkill] pour contrôler votre hologramme pendant quelques secondes",
|
||||||
|
|
||||||
"illiterate": "Illettré",
|
"illiterate": "Illettré",
|
||||||
"illiterate_desc": "Tant que vous êtes en vie, vos ennemis ne mogą pas lire",
|
"illiterate_desc": "Tant que vous êtes en vie, vos ennemis ne peuvent pas lire",
|
||||||
|
"illiterate_alert": "Illettré est actif ! Vous ne pouvez pas lire les messages tant que le propriétaire de cette compétence n'est pas éliminé",
|
||||||
|
|
||||||
"illusionist": "Illusionniste",
|
"illusionist": "Illusionniste",
|
||||||
"illusionist_desc": "Cliquez sur [css_useSkill] pour déployer une réplique qui marche droit devant",
|
"illusionist_desc": "Cliquez sur [css_useSkill] pour déployer une réplique qui marche droit devant",
|
||||||
|
|
|
||||||
|
|
@ -248,6 +248,7 @@
|
||||||
|
|
||||||
"illiterate": "Analfabeta",
|
"illiterate": "Analfabeta",
|
||||||
"illiterate_desc": "Dopóki żyjesz, Twoi wrogowie nie potrafią czytać",
|
"illiterate_desc": "Dopóki żyjesz, Twoi wrogowie nie potrafią czytać",
|
||||||
|
"illiterate_alert": "Analfabeta jest aktywny! Nie możesz czytać wiadomości, dopóki właściciel tej umiejętności nie zostanie wyeliminowany",
|
||||||
|
|
||||||
"illusionist": "Iluzjonista",
|
"illusionist": "Iluzjonista",
|
||||||
"illusionist_desc": "Naciśnij [css_useSkill], aby wypuścić replikę idącą prosto przed siebie",
|
"illusionist_desc": "Naciśnij [css_useSkill], aby wypuścić replikę idącą prosto przed siebie",
|
||||||
|
|
|
||||||
|
|
@ -248,6 +248,7 @@
|
||||||
|
|
||||||
"illiterate": "Analfabeto",
|
"illiterate": "Analfabeto",
|
||||||
"illiterate_desc": "Enquanto você estiver vivo, seus inimigos não conseguem ler",
|
"illiterate_desc": "Enquanto você estiver vivo, seus inimigos não conseguem ler",
|
||||||
|
"illiterate_alert": "Analfabeto está ativo! Você não pode ler mensagens até que o proprietário desta habilidade seja eliminado",
|
||||||
|
|
||||||
"illusionist": "Ilusionista",
|
"illusionist": "Ilusionista",
|
||||||
"illusionist_desc": "Clique em [css_useSkill] para enviar uma réplica que caminha em frente",
|
"illusionist_desc": "Clique em [css_useSkill] para enviar uma réplica que caminha em frente",
|
||||||
|
|
|
||||||
|
|
@ -248,6 +248,7 @@
|
||||||
|
|
||||||
"illiterate": "Неграмотный",
|
"illiterate": "Неграмотный",
|
||||||
"illiterate_desc": "Пока вы живы, ваши враги не могут читать (чат)",
|
"illiterate_desc": "Пока вы живы, ваши враги не могут читать (чат)",
|
||||||
|
"illiterate_alert": "Неграмотный активен! Вы не можете читать сообщения, пока владелец этой способности не будет устранён",
|
||||||
|
|
||||||
"illusionist": "Иллюзионист",
|
"illusionist": "Иллюзионист",
|
||||||
"illusionist_desc": "Нажмите [css_useSkill], чтобы создать копию, идущую вперёд",
|
"illusionist_desc": "Нажмите [css_useSkill], чтобы создать копию, идущую вперёд",
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,7 @@
|
||||||
|
|
||||||
"illiterate": "Cahiliye",
|
"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 rakibin sohbeti (chat) veya oyun yazılarını okuyamaz",
|
||||||
|
"illiterate_alert": "Cahiliye aktif! Bu yeteneğin sahibi ortadan kalkana kadar mesajları okuyamazsınız.",
|
||||||
|
|
||||||
"illusionist": "İllüzyonist",
|
"illusionist": "İllüzyonist",
|
||||||
"illusionist_desc": "[css_useSkill] tuşuna basarak düz ilerleyen illüzyon oluştur",
|
"illusionist_desc": "[css_useSkill] tuşuna basarak düz ilerleyen illüzyon oluştur",
|
||||||
|
|
|
||||||
|
|
@ -226,6 +226,7 @@
|
||||||
|
|
||||||
"illiterate": "文盲",
|
"illiterate": "文盲",
|
||||||
"illiterate_desc": "只要你还活着,你的敌人就无法阅读",
|
"illiterate_desc": "只要你还活着,你的敌人就无法阅读",
|
||||||
|
"illiterate_alert": "文盲已激活!在该技能的拥有者被消灭之前,你无法阅读消息。",
|
||||||
|
|
||||||
"illusionist": "幻术师",
|
"illusionist": "幻术师",
|
||||||
"illusionist_desc": "点击 [css_useSkill] 部署一个直线行走的幻象",
|
"illusionist_desc": "点击 [css_useSkill] 部署一个直线行走的幻象",
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace src.menu
|
||||||
{
|
{
|
||||||
public static void DisplaySkillsList(CCSPlayerController player)
|
public static void DisplaySkillsList(CCSPlayerController player)
|
||||||
{
|
{
|
||||||
CenterHtmlMenu menu = new($"[ ★ {player.GetTranslation("skills_menu")} ★ ]", Instance);
|
CenterHtmlMenu menu = new($"[ ★ {player.GetTranslationWithoutIlliterate("skills_menu")} ★ ]", Instance);
|
||||||
|
|
||||||
foreach (var skillInfo in SkillData.Skills)
|
foreach (var skillInfo in SkillData.Skills)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ public interface ISkill
|
||||||
|
|
||||||
public static void NewRound() { }
|
public static void NewRound() { }
|
||||||
public static void RoundEnd() { }
|
public static void RoundEnd() { }
|
||||||
|
public static void PlayerDisconnect(uint playerIndex) { }
|
||||||
public static void PlayerMakeSound(UserMessage _) { }
|
public static void PlayerMakeSound(UserMessage _) { }
|
||||||
public static void PlayerBlind(EventPlayerBlind _) { }
|
public static void PlayerBlind(EventPlayerBlind _) { }
|
||||||
public static void PlayerHurt(EventPlayerHurt _) { }
|
public static void PlayerHurt(EventPlayerHurt _) { }
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ namespace src.player
|
||||||
|
|
||||||
private static readonly ConcurrentDictionary<uint, ConcurrentBag<jSkill_SkillInfo>> playersSkills = [];
|
private static readonly ConcurrentDictionary<uint, ConcurrentBag<jSkill_SkillInfo>> playersSkills = [];
|
||||||
public static readonly ConcurrentDictionary<uint, jSkill_SkillInfo> staticSkills = [];
|
public static readonly ConcurrentDictionary<uint, jSkill_SkillInfo> staticSkills = [];
|
||||||
|
public static readonly ConcurrentDictionary<uint, uint> playersCustomFOV = [];
|
||||||
private static readonly object setLock = new();
|
private static readonly object setLock = new();
|
||||||
|
|
||||||
public static void Load()
|
public static void Load()
|
||||||
|
|
@ -525,7 +526,7 @@ namespace src.player
|
||||||
|
|
||||||
Localization.PreResolveLanguage(player);
|
Localization.PreResolveLanguage(player);
|
||||||
|
|
||||||
string welcomeMsg = player.GetTranslation("welcome_message", "welcome");
|
string welcomeMsg = player.GetTranslationWithoutIlliterate("welcome_message", "welcome");
|
||||||
foreach (string line in welcomeMsg.Split("\n"))
|
foreach (string line in welcomeMsg.Split("\n"))
|
||||||
player.PrintToChat($" {ChatColors.Green}" + line.Replace("{PLAYER}", $" {ChatColors.Red}\u202A{player.PlayerName}\u202C{ChatColors.Green}", StringComparison.OrdinalIgnoreCase)
|
player.PrintToChat($" {ChatColors.Green}" + line.Replace("{PLAYER}", $" {ChatColors.Red}\u202A{player.PlayerName}\u202C{ChatColors.Green}", StringComparison.OrdinalIgnoreCase)
|
||||||
.Replace("{SERVER_NAME}", $" {ChatColors.Red}{ConVar.Find("hostname")?.StringValue ?? "Default Server"}{ChatColors.Green}", StringComparison.OrdinalIgnoreCase)
|
.Replace("{SERVER_NAME}", $" {ChatColors.Red}{ConVar.Find("hostname")?.StringValue ?? "Default Server"}{ChatColors.Green}", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|
@ -603,8 +604,11 @@ namespace src.player
|
||||||
|
|
||||||
player.ReplicateConVar("sv_disable_radar", "0");
|
player.ReplicateConVar("sv_disable_radar", "0");
|
||||||
|
|
||||||
player.DesiredFOV = 0;
|
if (SkillsInfo.GetValue<bool>(Skills.Magnifier, "active") && player.DesiredFOV == SkillsInfo.GetValue<uint>(Skills.Magnifier, "customFOV"))
|
||||||
Utilities.SetStateChanged(player, "CBasePlayerController", "m_iDesiredFOV");
|
{
|
||||||
|
player.DesiredFOV = playersCustomFOV.TryGetValue(player.Index, out uint fov) ? fov : 0;
|
||||||
|
Utilities.SetStateChanged(player, "CBasePlayerController", "m_iDesiredFOV");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HookResult PlayerDeathPre(EventPlayerDeath @event, GameEventInfo info)
|
private static HookResult PlayerDeathPre(EventPlayerDeath @event, GameEventInfo info)
|
||||||
|
|
@ -678,7 +682,7 @@ namespace src.player
|
||||||
|
|
||||||
SkillUtils.PrintToChat(victim,
|
SkillUtils.PrintToChat(victim,
|
||||||
$"{ChatColors.DarkRed}{(attackerInfo.SpecialSkill == Skills.None ? victim.GetSkillName(skillData.Skill) : $"{victim.GetSkillName(specialSkillData.Skill)} -> {victim.GetSkillName(skillData.Skill)}")}{ChatColors.Lime} - {skillDesc}",
|
$"{ChatColors.DarkRed}{(attackerInfo.SpecialSkill == Skills.None ? victim.GetSkillName(skillData.Skill) : $"{victim.GetSkillName(specialSkillData.Skill)} -> {victim.GetSkillName(skillData.Skill)}")}{ChatColors.Lime} - {skillDesc}",
|
||||||
title: $"{victim.GetTranslation("enemy_skill")} {ChatColors.DarkRed}\u202A{attacker.PlayerName}\u202C{ChatColors.Lime}");
|
title: $"{victim.GetTranslationWithoutIlliterate("enemy_skill")} {ChatColors.DarkRed}\u202A{attacker.PlayerName}\u202C{ChatColors.Lime}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return HookResult.Continue;
|
return HookResult.Continue;
|
||||||
|
|
@ -756,7 +760,6 @@ namespace src.player
|
||||||
|
|
||||||
if (Illiterate.CheckIlliterateSkill(player))
|
if (Illiterate.CheckIlliterateSkill(player))
|
||||||
{
|
{
|
||||||
headerLine = Illiterate.GetRandomText(headerLine);
|
|
||||||
centerLine = Illiterate.GetRandomText(centerLine);
|
centerLine = Illiterate.GetRandomText(centerLine);
|
||||||
extraLine = Illiterate.GetRandomText(extraLine);
|
extraLine = Illiterate.GetRandomText(extraLine);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,8 +103,8 @@ namespace src.player
|
||||||
|
|
||||||
if (skills == null || skills.IsEmpty)
|
if (skills == null || skills.IsEmpty)
|
||||||
{
|
{
|
||||||
infoLine = player.GetTranslation("your_skill");
|
infoLine = player.GetTranslationWithoutIlliterate("your_skill");
|
||||||
skillLine = player.GetTranslation("none");
|
skillLine = player.GetTranslationWithoutIlliterate("none");
|
||||||
}
|
}
|
||||||
else if (skillPlayer.IsDrawing && player.PawnIsAlive)
|
else if (skillPlayer.IsDrawing && player.PawnIsAlive)
|
||||||
{
|
{
|
||||||
|
|
@ -115,7 +115,7 @@ namespace src.player
|
||||||
var skillsArray = skills.ToArray();
|
var skillsArray = skills.ToArray();
|
||||||
var randomSkill = skillsArray[Instance.Random.Next(skillCount)];
|
var randomSkill = skillsArray[Instance.Random.Next(skillCount)];
|
||||||
|
|
||||||
infoLine = player.GetTranslation("drawing_skill");
|
infoLine = player.GetTranslationWithoutIlliterate("drawing_skill");
|
||||||
skillLine = $"<font color='{randomSkill.Color}'>{player.GetSkillName(randomSkill.Skill)}</font>";
|
skillLine = $"<font color='{randomSkill.Color}'>{player.GetSkillName(randomSkill.Skill)}</font>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -127,7 +127,7 @@ namespace src.player
|
||||||
|
|
||||||
if (skillInfo != null)
|
if (skillInfo != null)
|
||||||
{
|
{
|
||||||
infoLine = player.GetTranslation("your_skill");
|
infoLine = player.GetTranslationWithoutIlliterate("your_skill");
|
||||||
skillLine = $"<font color='{skillInfo.Color}'>{player.GetSkillName(skillInfo.Skill, skillPlayer.SkillChance)}</font>";
|
skillLine = $"<font color='{skillInfo.Color}'>{player.GetSkillName(skillInfo.Skill, skillPlayer.SkillChance)}</font>";
|
||||||
|
|
||||||
if (skillInfo.Skill != Skills.None)
|
if (skillInfo.Skill != Skills.None)
|
||||||
|
|
@ -177,7 +177,7 @@ namespace src.player
|
||||||
if (pName.Length > 18)
|
if (pName.Length > 18)
|
||||||
pName = $"{pName[..17]}...";
|
pName = $"{pName[..17]}...";
|
||||||
|
|
||||||
var observerSkill = player.GetTranslation("observer_skill");
|
var observerSkill = player.GetTranslationWithoutIlliterate("observer_skill");
|
||||||
infoLine = string.IsNullOrEmpty(observerSkill) ? pName : $"{observerSkill} {pName}";
|
infoLine = string.IsNullOrEmpty(observerSkill) ? pName : $"{observerSkill} {pName}";
|
||||||
|
|
||||||
if (observedSkill.SpecialSkill == Skills.None || observedSpecialInfo == null)
|
if (observedSkill.SpecialSkill == Skills.None || observedSpecialInfo == null)
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,7 @@ namespace src.player
|
||||||
SkillsUsedThisMap.Clear();
|
SkillsUsedThisMap.Clear();
|
||||||
nextRoundPicks.Clear();
|
nextRoundPicks.Clear();
|
||||||
|
|
||||||
|
playersCustomFOV.Clear();
|
||||||
playersSkills.Clear();
|
playersSkills.Clear();
|
||||||
staticSkills.Clear();
|
staticSkills.Clear();
|
||||||
|
|
||||||
|
|
@ -238,10 +239,10 @@ namespace src.player
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(skillsText)) continue;
|
if (string.IsNullOrEmpty(skillsText)) continue;
|
||||||
|
|
||||||
SkillUtils.PrintToChat(player, string.Empty, title: player.GetTranslation("summary"), border: "t");
|
SkillUtils.PrintToChat(player, string.Empty, title: player.GetTranslationWithoutIlliterate("summary"), border: "t");
|
||||||
foreach (string text in skillsText.Split("\n"))
|
foreach (string text in skillsText.Split("\n"))
|
||||||
if (!string.IsNullOrEmpty(text))
|
if (!string.IsNullOrEmpty(text))
|
||||||
SkillUtils.PrintToChat(player, text, title: player.GetTranslation("teammate_skills"), border: "");
|
SkillUtils.PrintToChat(player, text, title: player.GetTranslationWithoutIlliterate("teammate_skills"), border: "");
|
||||||
SkillUtils.PrintToChat(player, string.Empty, border: "b");
|
SkillUtils.PrintToChat(player, string.Empty, border: "b");
|
||||||
}
|
}
|
||||||
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||||
|
|
@ -578,11 +579,11 @@ namespace src.player
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(teammateSkills))
|
if (!string.IsNullOrEmpty(teammateSkills))
|
||||||
{
|
{
|
||||||
SkillUtils.PrintToChat(player, string.Empty, title: player.GetTranslation("teammate_skills"), border: "t");
|
SkillUtils.PrintToChat(player, string.Empty, title: player.GetTranslationWithoutIlliterate("teammate_skills"), border: "t");
|
||||||
foreach (string text in teammateSkills.Split("\n"))
|
foreach (string text in teammateSkills.Split("\n"))
|
||||||
if (!string.IsNullOrEmpty(text))
|
if (!string.IsNullOrEmpty(text))
|
||||||
SkillUtils.PrintToChat(player, text, title: player.GetTranslation("teammate_skills"), border: "");
|
SkillUtils.PrintToChat(player, text, title: player.GetTranslationWithoutIlliterate("teammate_skills"), border: "");
|
||||||
SkillUtils.PrintToChat(player, string.Empty, title: player.GetTranslation("teammate_skills"), border: "b");
|
SkillUtils.PrintToChat(player, string.Empty, title: player.GetTranslationWithoutIlliterate("teammate_skills"), border: "b");
|
||||||
}
|
}
|
||||||
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,6 @@ namespace src.player.skills
|
||||||
public float ExplosionRadius { get; set; } = explosionRadius;
|
public float ExplosionRadius { get; set; } = explosionRadius;
|
||||||
public int ExplosionDamage { get; set; } = explosionDamage;
|
public int ExplosionDamage { get; set; } = explosionDamage;
|
||||||
public float DmgReductionForTeamates { get; set; } = dmgReductionForTeamates;
|
public float DmgReductionForTeamates { get; set; } = dmgReductionForTeamates;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
451
jRandomSkills - SRC Files/src/player/skills/ExplosiveChicken.cs
Normal file
451
jRandomSkills - SRC Files/src/player/skills/ExplosiveChicken.cs
Normal file
|
|
@ -0,0 +1,451 @@
|
||||||
|
//using CounterStrikeSharp.API;
|
||||||
|
//using CounterStrikeSharp.API.Core;
|
||||||
|
//using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
|
||||||
|
//using CounterStrikeSharp.API.Modules.Utils;
|
||||||
|
//using jRandomSkills.src.utils;
|
||||||
|
//using src.utils;
|
||||||
|
//using System.Collections.Concurrent;
|
||||||
|
//using System.Drawing;
|
||||||
|
|
||||||
|
//namespace src.player.skills
|
||||||
|
//{
|
||||||
|
// public class ExplosiveChicken : ISkill
|
||||||
|
// {
|
||||||
|
// private const Skills skillName = Skills.ExplosiveChicken;
|
||||||
|
|
||||||
|
// private class PlayerInfo
|
||||||
|
// {
|
||||||
|
// public uint OwnerIndex { get; set; }
|
||||||
|
// public uint? ChickenIndex { get; set; }
|
||||||
|
// public Vector? ChickenLastOrigin { get; set; }
|
||||||
|
// public int ChickenHealth { get; set; }
|
||||||
|
// public bool PlayerActive { get; set; }
|
||||||
|
// public bool CanUse { get; set; }
|
||||||
|
// public int Cooldown { get; set; }
|
||||||
|
// public int InfoMessageTime { get; set; }
|
||||||
|
// public int InfoMessageType { get; set; }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private static readonly ConcurrentDictionary<uint, PlayerInfo> chickens = [];
|
||||||
|
// private static readonly ConcurrentDictionary<uint, uint> chickenOwner = [];
|
||||||
|
// private const string chickenParticle = "particles/critters/chicken/chicken_goop.vpcf";
|
||||||
|
// private static readonly QAngle angle = new(20, -15, 43);
|
||||||
|
// private static readonly ConcurrentDictionary<int, (byte Team, uint Owner)> nades = [];
|
||||||
|
|
||||||
|
// public static void LoadSkill()
|
||||||
|
// {
|
||||||
|
// SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||||
|
// jRandomSkills.Instance.AddToManifest(chickenParticle);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static void NewRound()
|
||||||
|
// {
|
||||||
|
// foreach (var key in chickens.Keys)
|
||||||
|
// {
|
||||||
|
// if (chickens.TryRemove(key, out _))
|
||||||
|
// EntityManager.DestroyPlayerEntities(key);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// chickens.Clear();
|
||||||
|
// chickenOwner.Clear();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static void EnableSkill(CCSPlayerController player)
|
||||||
|
// {
|
||||||
|
// if (player == null || !player.IsValid) return;
|
||||||
|
// int health = SkillsInfo.GetValue<int>(skillName, "health");
|
||||||
|
|
||||||
|
// chickens.TryAdd(player.Index, new PlayerInfo
|
||||||
|
// {
|
||||||
|
// OwnerIndex = player.Index,
|
||||||
|
// ChickenIndex = null,
|
||||||
|
// ChickenLastOrigin = null,
|
||||||
|
// ChickenHealth = 0,
|
||||||
|
// PlayerActive = true,
|
||||||
|
// CanUse = true,
|
||||||
|
// Cooldown = 0,
|
||||||
|
// InfoMessageTime = 0,
|
||||||
|
// InfoMessageType = 0,
|
||||||
|
// });
|
||||||
|
// chickens[player.Index].PlayerActive = true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static void DisableSkill(CCSPlayerController player)
|
||||||
|
// {
|
||||||
|
// if (player == null || !player.IsValid) return;
|
||||||
|
// chickens[player.Index].PlayerActive = false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static void UseSkill(CCSPlayerController player)
|
||||||
|
// {
|
||||||
|
// var playerPawn = player.PlayerPawn.Value;
|
||||||
|
// if (playerPawn?.CBodyComponent == null) return;
|
||||||
|
|
||||||
|
// if (chickens.TryGetValue(player.Index, out var skillInfo))
|
||||||
|
// {
|
||||||
|
// if (!player.IsValid || playerPawn.Health <= 0) return;
|
||||||
|
|
||||||
|
// if (skillInfo.CanUse && skillInfo.PlayerActive)
|
||||||
|
// {
|
||||||
|
// if (skillInfo.ChickenIndex != null)
|
||||||
|
// {
|
||||||
|
// skillInfo.InfoMessageTime = Server.TickCount;
|
||||||
|
// skillInfo.InfoMessageType = 1;
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// skillInfo.CanUse = false;
|
||||||
|
// skillInfo.Cooldown = Server.TickCount;
|
||||||
|
// SpawnChicken(player, skillInfo);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private static void SpawnChicken(CCSPlayerController player, PlayerInfo skillInfo)
|
||||||
|
// {
|
||||||
|
// if (player == null || !player.IsValid) return;
|
||||||
|
|
||||||
|
// var pawn = player.PlayerPawn.Value;
|
||||||
|
// if (pawn == null || !pawn.IsValid || pawn.AbsRotation == null || pawn.AbsOrigin == null || pawn.Health <= 0) return;
|
||||||
|
|
||||||
|
// float distance = 40;
|
||||||
|
// Vector pawnPos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + 10);
|
||||||
|
// Vector chickenPos = pawn.AbsOrigin + SkillUtils.GetForwardVector(pawn.AbsRotation) * distance;
|
||||||
|
// chickenPos.Z += 10;
|
||||||
|
|
||||||
|
// var trace = RayTrace.TraceShape(player, pawnPos, chickenPos, 0, null);
|
||||||
|
// if (trace != null && trace.Value.DidHit)
|
||||||
|
// {
|
||||||
|
// skillInfo.CanUse = true;
|
||||||
|
// skillInfo.Cooldown = 0;
|
||||||
|
// skillInfo.InfoMessageTime = Server.TickCount;
|
||||||
|
// skillInfo.InfoMessageType = 2;
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// CChicken? chicken = EntityManager.CreateTrackedChicken(player.Index);
|
||||||
|
// if (chicken == null || !chicken.IsValid) return;
|
||||||
|
|
||||||
|
// int health = SkillsInfo.GetValue<int>(skillName, "chickenHealth");
|
||||||
|
|
||||||
|
// chicken.Render = Color.Red;
|
||||||
|
// chicken.MaxHealth = health;
|
||||||
|
// chicken.Health = health;
|
||||||
|
// chickenOwner[chicken.Index] = player.Index;
|
||||||
|
|
||||||
|
// skillInfo.ChickenIndex = chicken.Index;
|
||||||
|
// skillInfo.ChickenLastOrigin = chickenPos;
|
||||||
|
// skillInfo.ChickenHealth = health;
|
||||||
|
|
||||||
|
// chicken.Teleport(chickenPos);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static void OnTakeDamage(DynamicHook h)
|
||||||
|
// {
|
||||||
|
// CEntityInstance param = h.GetParam<CEntityInstance>(0);
|
||||||
|
// CTakeDamageInfo param2 = h.GetParam<CTakeDamageInfo>(1);
|
||||||
|
|
||||||
|
// if (param == null || param.Entity == null || param2 == null) return;
|
||||||
|
// HandleChickenHit(param, param2);
|
||||||
|
// HandleExplosionHit(param, param2);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static void HandleChickenHit(CEntityInstance param, CTakeDamageInfo param2)
|
||||||
|
// {
|
||||||
|
// if (!chickenOwner.TryGetValue(param.Index, out var ownerIndex)) return;
|
||||||
|
|
||||||
|
// var owner = Utilities.GetPlayerFromIndex((int)ownerIndex);
|
||||||
|
// if (owner == null || !owner.IsValid) return;
|
||||||
|
|
||||||
|
// var attackerEnt = param2.Attacker?.Value;
|
||||||
|
// if (attackerEnt == null || !attackerEnt.IsValid) return;
|
||||||
|
|
||||||
|
// var attackerPawn = new CCSPlayerPawn(attackerEnt.Handle);
|
||||||
|
// if (!attackerPawn.IsValid || attackerPawn.DesignerName != "player") return;
|
||||||
|
|
||||||
|
// var ownerPawn = owner.PlayerPawn.Value;
|
||||||
|
// if (ownerPawn == null || !ownerPawn.IsValid) return;
|
||||||
|
|
||||||
|
// if (attackerPawn.Index != ownerPawn.Index && attackerPawn.TeamNum == owner.TeamNum)
|
||||||
|
// {
|
||||||
|
// param2.Damage = 0;
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var playerInfo = chickens[owner.Index];
|
||||||
|
// if (playerInfo == null) return;
|
||||||
|
|
||||||
|
// playerInfo.ChickenHealth = Math.Max(0, playerInfo.ChickenHealth - (int)param2.Damage);
|
||||||
|
|
||||||
|
// if (playerInfo.ChickenHealth > 0)
|
||||||
|
// CreateHitParticles(param.Index);
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// playerInfo.ChickenIndex = null;
|
||||||
|
// playerInfo.ChickenHealth = SkillsInfo.GetValue<int>(skillName, "chickenHealth");
|
||||||
|
// playerInfo.ChickenLastOrigin = null;
|
||||||
|
// chickenOwner.TryRemove(param.Index, out _);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static void HandleExplosionHit(CEntityInstance param, CTakeDamageInfo param2)
|
||||||
|
// {
|
||||||
|
// var nade = param2.Attacker.Value;
|
||||||
|
// if (nade == null || !nade.IsValid) return;
|
||||||
|
|
||||||
|
// if (nade.DesignerName != "hegrenade_projectile") return;
|
||||||
|
// if (string.IsNullOrEmpty(nade.Globalname) || !nade.Globalname.StartsWith("explosive_chicken_team_")) return;
|
||||||
|
|
||||||
|
// var parts = nade.Globalname.Split('_');
|
||||||
|
// if (parts.Length < 4) return;
|
||||||
|
// if (!int.TryParse(parts[2], out int nadeTeam)) return;
|
||||||
|
// if (!uint.TryParse(parts[3], out uint ownerIndex)) return;
|
||||||
|
|
||||||
|
// CCSPlayerPawn victimPawn = new(param.Handle);
|
||||||
|
|
||||||
|
// if (victimPawn.DesignerName != "player") return;
|
||||||
|
// if (victimPawn.Controller?.Value == null) return;
|
||||||
|
|
||||||
|
// var victim = victimPawn.Controller.Value.As<CCSPlayerController>();
|
||||||
|
// if (victim == null || !victim.IsValid || victim.Index == ownerIndex) return;
|
||||||
|
|
||||||
|
// var owner = Utilities.GetPlayerFromIndex((int)ownerIndex);
|
||||||
|
// if (owner != null && !owner.IsValid) owner = null;
|
||||||
|
|
||||||
|
// if (victimPawn.TeamNum == nadeTeam)
|
||||||
|
// param2.Damage *= SkillUtils.GetTeamDamageMultiplier(skillName);
|
||||||
|
|
||||||
|
// if (owner != null && param2.Damage >= victimPawn.Health)
|
||||||
|
// SkillUtils.RegisterKillCredit(victim.Index, owner.Index, KillfeedIcons.Explosion);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// private static void CreateHitParticles(uint chickenIndex)
|
||||||
|
// {
|
||||||
|
// var chicken = Utilities.GetEntityFromIndex<CChicken>((int)chickenIndex);
|
||||||
|
// if (chicken == null || !chicken.IsValid || chicken.AbsOrigin == null) return;
|
||||||
|
|
||||||
|
// var particle = EntityManager.CreateTrackedParticleSystem(chicken.Index, chickenParticle, autoDestroySeconds: 3f);
|
||||||
|
// if (particle == null) return;
|
||||||
|
|
||||||
|
// Vector pos = new(chicken.AbsOrigin.X, chicken.AbsOrigin.Y, chicken.AbsOrigin.Z + 10);
|
||||||
|
// particle.Teleport(pos);
|
||||||
|
// particle.AcceptInput("Start");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static void OnTick()
|
||||||
|
// {
|
||||||
|
// int tickCooldown = SkillsInfo.GetValue<int>(skillName, "tickCooldown");
|
||||||
|
// float boostFactor = SkillsInfo.GetValue<float>(skillName, "boostFactor");
|
||||||
|
// float triggerRadius = SkillsInfo.GetValue<float>(skillName, "triggerRadius");
|
||||||
|
// float cooldownDuration = SkillsInfo.GetValue<float>(skillName, "cooldown");
|
||||||
|
|
||||||
|
// bool processMovement = Server.TickCount % tickCooldown == 0;
|
||||||
|
|
||||||
|
// var players = PlayerManager.GetTickPlayers().ToArray();
|
||||||
|
|
||||||
|
// foreach (var player in players)
|
||||||
|
// {
|
||||||
|
// if (player == null || !player.IsValid) continue;
|
||||||
|
|
||||||
|
// var playerInfo = PlayerManager.GetPlayerByIndex(player.Index);
|
||||||
|
// if (playerInfo?.Skill != skillName) continue;
|
||||||
|
|
||||||
|
// var pawn = player.PlayerPawn.Value;
|
||||||
|
// if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null || pawn.Health <= 0) continue;
|
||||||
|
|
||||||
|
// if (!chickens.TryGetValue(player.Index, out var skillInfo) || skillInfo == null) continue;
|
||||||
|
|
||||||
|
// if (!skillInfo.CanUse && skillInfo.ChickenIndex == null)
|
||||||
|
// {
|
||||||
|
// float readyAtTick = skillInfo.Cooldown + (cooldownDuration * 64);
|
||||||
|
// if (Server.TickCount >= readyAtTick)
|
||||||
|
// {
|
||||||
|
// skillInfo.CanUse = true;
|
||||||
|
// skillInfo.Cooldown = 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// UpdateHUD(skillInfo);
|
||||||
|
|
||||||
|
// if (skillInfo.ChickenIndex == null || !processMovement) continue;
|
||||||
|
|
||||||
|
// var chicken = Utilities.GetEntityFromIndex<CChicken>((int)skillInfo.ChickenIndex.Value);
|
||||||
|
// if (chicken == null || !chicken.IsValid || chicken.AbsOrigin == null)
|
||||||
|
// {
|
||||||
|
// skillInfo.ChickenIndex = null;
|
||||||
|
// skillInfo.ChickenHealth = 0;
|
||||||
|
// skillInfo.ChickenLastOrigin = null;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Vector currentOrigin = new(chicken.AbsOrigin.X, chicken.AbsOrigin.Y, chicken.AbsOrigin.Z);
|
||||||
|
|
||||||
|
// CCSPlayerController? enemy = GetClosetEnemy(currentOrigin, player.TeamNum);
|
||||||
|
// if (enemy == null || !enemy.IsValid) continue;
|
||||||
|
|
||||||
|
// var enemyPawn = enemy.PlayerPawn?.Value;
|
||||||
|
// if (enemyPawn == null || !enemyPawn.IsValid || enemyPawn.AbsOrigin == null) continue;
|
||||||
|
|
||||||
|
// if (chicken.Leader.Raw != enemy.Pawn.Raw)
|
||||||
|
// chicken.Leader.Raw = enemy.Pawn.Raw;
|
||||||
|
|
||||||
|
// player.PrintToChat($"Closest enemy: {(enemy != null ? enemy.PlayerName : "None")}");
|
||||||
|
|
||||||
|
// if (skillInfo.ChickenLastOrigin != null)
|
||||||
|
// {
|
||||||
|
// float dx = currentOrigin.X - skillInfo.ChickenLastOrigin.X;
|
||||||
|
// float dy = currentOrigin.Y - skillInfo.ChickenLastOrigin.Y;
|
||||||
|
// float dist2D = MathF.Sqrt(dx * dx + dy * dy);
|
||||||
|
|
||||||
|
// if (dist2D > 0.05f && dist2D < 20.0f)
|
||||||
|
// {
|
||||||
|
// Vector newPos = new(
|
||||||
|
// currentOrigin.X + (dx * boostFactor),
|
||||||
|
// currentOrigin.Y + (dy * boostFactor),
|
||||||
|
// currentOrigin.Z
|
||||||
|
// );
|
||||||
|
|
||||||
|
// player.PrintToChat($"Chicken boost");
|
||||||
|
// chicken.Teleport(newPos, chicken.AbsRotation, chicken.AbsVelocity);
|
||||||
|
// skillInfo.ChickenLastOrigin = newPos;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// skillInfo.ChickenLastOrigin = currentOrigin;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// skillInfo.ChickenLastOrigin = currentOrigin;
|
||||||
|
|
||||||
|
// float pdx = enemyPawn.AbsOrigin.X - skillInfo.ChickenLastOrigin.X;
|
||||||
|
// float pdy = enemyPawn.AbsOrigin.Y - skillInfo.ChickenLastOrigin.Y;
|
||||||
|
// float pdz = enemyPawn.AbsOrigin.Z - skillInfo.ChickenLastOrigin.Z;
|
||||||
|
// float distToPlayer = MathF.Sqrt(pdx * pdx + pdy * pdy + pdz * pdz);
|
||||||
|
|
||||||
|
// if (distToPlayer <= triggerRadius)
|
||||||
|
// ExplodeChicken(player, chicken, skillInfo);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private static CCSPlayerController? GetClosetEnemy(Vector chickenPos, byte ownerTeam)
|
||||||
|
// {
|
||||||
|
// var players = PlayerManager.GetTickPlayers().ToArray();
|
||||||
|
// CCSPlayerController? closestEnemy = null;
|
||||||
|
|
||||||
|
// float closestDistance = float.MaxValue;
|
||||||
|
// foreach (var player in players)
|
||||||
|
// {
|
||||||
|
// if (player == null || !player.IsValid || player.TeamNum == ownerTeam) continue;
|
||||||
|
|
||||||
|
// var pawn = player.PlayerPawn?.Value;
|
||||||
|
// if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null || pawn.Health <= 0) continue;
|
||||||
|
|
||||||
|
// float distance = SkillUtils.Distance(chickenPos, pawn.AbsOrigin);
|
||||||
|
// if (distance < closestDistance)
|
||||||
|
// {
|
||||||
|
// closestDistance = distance;
|
||||||
|
// closestEnemy = player;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return closestEnemy;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private static void ExplodeChicken(CCSPlayerController owner, CChicken chicken, PlayerInfo skillInfo)
|
||||||
|
// {
|
||||||
|
// if (owner == null || !owner.IsValid || chicken == null || !chicken.IsValid || chicken.AbsOrigin == null) return;
|
||||||
|
// Vector pos = new(chicken.AbsOrigin.X, chicken.AbsOrigin.Y, chicken.AbsOrigin.Z + 10);
|
||||||
|
|
||||||
|
// EntityManager.DestroyEntity(chicken.Index, 0f);
|
||||||
|
|
||||||
|
// skillInfo.ChickenIndex = null;
|
||||||
|
// skillInfo.ChickenHealth = 0;
|
||||||
|
// skillInfo.ChickenLastOrigin = null;
|
||||||
|
|
||||||
|
// chickenOwner.TryRemove(chicken.Index, out _);
|
||||||
|
|
||||||
|
// jRandomSkills.Instance.AddTickTimer(4, () =>
|
||||||
|
// {
|
||||||
|
// SkillUtils.CreateHEGrenadeProjectile(pos, angle, new Vector(0, 0, -10), owner.TeamNum);
|
||||||
|
// nades.AddOrUpdate(Server.TickCount, (owner.TeamNum, owner.Index), (_, _) => (owner.TeamNum, owner.Index));
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static void OnEntitySpawned(CEntityInstance entity)
|
||||||
|
// {
|
||||||
|
// if (entity.DesignerName != "hegrenade_projectile") return;
|
||||||
|
|
||||||
|
// var heProjectile = entity.As<CBaseCSGrenadeProjectile>();
|
||||||
|
// if (heProjectile == null || !heProjectile.IsValid || heProjectile.AbsRotation == null) return;
|
||||||
|
|
||||||
|
// int lastTick = Server.TickCount;
|
||||||
|
|
||||||
|
// Server.NextFrame(() =>
|
||||||
|
// {
|
||||||
|
// if (heProjectile == null || !heProjectile.IsValid) return;
|
||||||
|
// if (!(NearlyEquals(angle.X, heProjectile.AbsRotation.X) && NearlyEquals(angle.Y, heProjectile.AbsRotation.Y) && NearlyEquals(angle.Z, heProjectile.AbsRotation.Z)))
|
||||||
|
// return;
|
||||||
|
|
||||||
|
// heProjectile.TicksAtZeroVelocity = 100;
|
||||||
|
// heProjectile.Damage = SkillsInfo.GetValue<int>(skillName, "explosionDamage");
|
||||||
|
// heProjectile.DmgRadius = SkillsInfo.GetValue<float>(skillName, "explosionRadius");
|
||||||
|
// heProjectile.DetonateTime = 0;
|
||||||
|
|
||||||
|
// if (nades.TryRemove(lastTick, out var source))
|
||||||
|
// heProjectile.Globalname = $"explosive_chicken_team_{source.Team}_{source.Owner}_{heProjectile.Index}";
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private static void UpdateHUD(PlayerInfo skillInfo)
|
||||||
|
// {
|
||||||
|
// if (skillInfo == null) return;
|
||||||
|
|
||||||
|
// var player = Utilities.GetPlayerFromIndex((int)skillInfo.OwnerIndex);
|
||||||
|
// if (player == null || !player.IsValid) return;
|
||||||
|
|
||||||
|
// var playerInfo = PlayerManager.GetPlayerByIndex(player.Index);
|
||||||
|
// if (playerInfo == null) return;
|
||||||
|
|
||||||
|
// float cooldownDuration = SkillsInfo.GetValue<float>(skillName, "cooldown");
|
||||||
|
|
||||||
|
// float cooldown = 0;
|
||||||
|
// if (!skillInfo.CanUse)
|
||||||
|
// {
|
||||||
|
// float readyAtTick = skillInfo.Cooldown + (cooldownDuration * 64);
|
||||||
|
// float time1 = (readyAtTick - Server.TickCount) / 64;
|
||||||
|
// cooldown = (int)Math.Ceiling(Math.Max(time1, 0));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool chickenActive = skillInfo.ChickenIndex != null;
|
||||||
|
|
||||||
|
// if (skillInfo.InfoMessageTime + (64 * 2) > Server.TickCount)
|
||||||
|
// {
|
||||||
|
// string? message = skillInfo.InfoMessageType switch
|
||||||
|
// {
|
||||||
|
// 1 => player.GetTranslation("chicken_already_active"),
|
||||||
|
// 2 => player.GetTranslation("chicken_blocked"),
|
||||||
|
// _ => null
|
||||||
|
// };
|
||||||
|
// playerInfo.PrintHTML = message;
|
||||||
|
// }
|
||||||
|
// else if (chickenActive)
|
||||||
|
// playerInfo.PrintHTML = $"{player.GetTranslation("chicken_hud_active", $"<font color='#00FF00'>{skillInfo.ChickenHealth}</font>")}";
|
||||||
|
// else if (cooldown > 0)
|
||||||
|
// playerInfo.PrintHTML = $"{player.GetTranslation("hud_info", $"<font color='#FF0000'>{cooldown}</font>")}";
|
||||||
|
// else
|
||||||
|
// playerInfo.PrintHTML = null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private static bool NearlyEquals(float a, float b, float epsilon = 0.001f) => Math.Abs(a - b) < epsilon;
|
||||||
|
|
||||||
|
// public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#b5ab8f", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = 1, Rarity rarity = Rarity.Legendary, float cooldown = 30, float triggerRadius = 150.0f, int chickenHealth = 100, int tickCooldown = 16, float boostFactor = 2.5f, float explosionDamage = 100, float explosionRadius = 150.0f, float dmgReductionForTeamates = 0.5f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)
|
||||||
|
// {
|
||||||
|
// public float Cooldown { get; set; } = cooldown;
|
||||||
|
// public float TriggerRadius { get; set; } = triggerRadius;
|
||||||
|
// public int ChickenHealth { get; set; } = chickenHealth;
|
||||||
|
// public int TickCooldown { get; set; } = tickCooldown;
|
||||||
|
// public float BoostFactor { get; set; } = boostFactor;
|
||||||
|
// public float ExplosionDamage { get; set; } = explosionDamage;
|
||||||
|
// public float ExplosionRadius { get; set; } = explosionRadius;
|
||||||
|
// public float DmgReductionForTeamates { get; set; } = dmgReductionForTeamates;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
@ -10,7 +10,6 @@ namespace src.player.skills
|
||||||
public class FireRain : ISkill
|
public class FireRain : ISkill
|
||||||
{
|
{
|
||||||
private const Skills skillName = Skills.FireRain;
|
private const Skills skillName = Skills.FireRain;
|
||||||
private static readonly QAngle angle = new(10, -4, 13);
|
|
||||||
private static readonly ConcurrentDictionary<uint, byte> decoys = [];
|
private static readonly ConcurrentDictionary<uint, byte> decoys = [];
|
||||||
private static int rainTick = -1;
|
private static int rainTick = -1;
|
||||||
private static CCSPlayerPawn? rainThrower;
|
private static CCSPlayerPawn? rainThrower;
|
||||||
|
|
@ -48,40 +47,156 @@ namespace src.player.skills
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const int grenadeCount = 5;
|
const int grenadeCount = 5;
|
||||||
const float maxSpawnHeight = 400.0f;
|
const int grenadeGroundCount = 2;
|
||||||
const float clusterRadius = 110.0f;
|
|
||||||
const float dropSpeed = 250.0f;
|
const float spawnHeight = 1500.0f;
|
||||||
|
const float approachDistance = 600.0f;
|
||||||
|
|
||||||
rainTick = Server.TickCount;
|
rainTick = Server.TickCount;
|
||||||
rainThrower = pawn;
|
rainThrower = pawn;
|
||||||
rainTeam = player.TeamNum;
|
rainTeam = player.TeamNum;
|
||||||
|
|
||||||
Vector decoyGround = new(targetPos.X, targetPos.Y, targetPos.Z + 8f);
|
float startAngle = Random.Shared.NextSingle() * MathF.Tau;
|
||||||
Vector dropVelocity = new(0, 0, -dropSpeed);
|
|
||||||
|
Vector? skyCenter = null;
|
||||||
|
bool foundPosition = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
float approachAngle = startAngle + i * (MathF.Tau / 8);
|
||||||
|
|
||||||
|
float dirX = MathF.Cos(approachAngle);
|
||||||
|
float dirY = MathF.Sin(approachAngle);
|
||||||
|
|
||||||
|
Vector testCenter = new(
|
||||||
|
targetPos.X + dirX * approachDistance,
|
||||||
|
targetPos.Y + dirY * approachDistance,
|
||||||
|
targetPos.Z + spawnHeight
|
||||||
|
);
|
||||||
|
|
||||||
|
var trace = RayTrace.TraceShape(player, targetPos, testCenter, null, 0);
|
||||||
|
|
||||||
|
if (!trace.HasValue || !trace.Value.DidHit)
|
||||||
|
{
|
||||||
|
skyCenter = testCenter;
|
||||||
|
foundPosition = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundPosition || skyCenter == null)
|
||||||
|
{
|
||||||
|
CreateMolotovSplash(targetPos, grenadeGroundCount, player.TeamNum);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateMolotovRaid(targetPos, skyCenter, grenadeCount, player.TeamNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateMolotovSplash(Vector targetPos, int grenadeCount, byte teamNum)
|
||||||
|
{
|
||||||
|
const float spreadSpeed = 100.0f;
|
||||||
|
const float upwardVelocity = 100.0f;
|
||||||
|
|
||||||
|
for (int i = 0; i < grenadeCount; i++)
|
||||||
|
{
|
||||||
|
float angle = Random.Shared.NextSingle() * MathF.Tau;
|
||||||
|
float speed = spreadSpeed * (0.7f + Random.Shared.NextSingle() * 0.6f);
|
||||||
|
|
||||||
|
float vx = MathF.Cos(angle) * speed;
|
||||||
|
float vy = MathF.Sin(angle) * speed;
|
||||||
|
float vz = upwardVelocity + Random.Shared.NextSingle() * 150.0f;
|
||||||
|
|
||||||
|
Vector velocity = new(vx, vy, vz);
|
||||||
|
|
||||||
|
Vector spawnPos = new(
|
||||||
|
targetPos.X,
|
||||||
|
targetPos.Y,
|
||||||
|
targetPos.Z + 10.0f
|
||||||
|
);
|
||||||
|
|
||||||
|
float yaw = MathF.Atan2(vy, vx) * (180.0f / MathF.PI);
|
||||||
|
float horizontalSpeed = MathF.Sqrt(vx * vx + vy * vy);
|
||||||
|
float pitch = -MathF.Atan2(vz, horizontalSpeed) * (180.0f / MathF.PI);
|
||||||
|
|
||||||
|
QAngle launchAngle = new(pitch, yaw, 0.0f);
|
||||||
|
SkillUtils.CreateMolotovProjectile(spawnPos, launchAngle, velocity, teamNum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateMolotovRaid(Vector targetPos, Vector? skyCenter, int grenadeCount, byte teamNum)
|
||||||
|
{
|
||||||
|
if (skyCenter == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const float clusterRadius = 130.0f;
|
||||||
|
const float flightTime = 1.2f;
|
||||||
|
const float gravity = 800.0f;
|
||||||
|
const float maxHorizontalVelocity = 700.0f;
|
||||||
|
|
||||||
|
Vector adjustedTarget = targetPos;
|
||||||
|
Vector direction = new(
|
||||||
|
skyCenter.X - targetPos.X,
|
||||||
|
skyCenter.Y - targetPos.Y,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
float length = MathF.Sqrt(direction.X * direction.X + direction.Y * direction.Y);
|
||||||
|
|
||||||
|
if (length > 0)
|
||||||
|
{
|
||||||
|
direction.X /= length;
|
||||||
|
direction.Y /= length;
|
||||||
|
|
||||||
|
const float aimOffset = 150.0f;
|
||||||
|
|
||||||
|
adjustedTarget = new Vector(
|
||||||
|
targetPos.X + direction.X * aimOffset,
|
||||||
|
targetPos.Y + direction.Y * aimOffset,
|
||||||
|
targetPos.Z
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
float dx = adjustedTarget.X - skyCenter.X;
|
||||||
|
float dy = adjustedTarget.Y - skyCenter.Y;
|
||||||
|
float dz = adjustedTarget.Z - skyCenter.Z;
|
||||||
|
|
||||||
|
float vx = dx / flightTime;
|
||||||
|
float vy = dy / flightTime;
|
||||||
|
float vz = (dz + 0.5f * gravity * flightTime * flightTime) / flightTime;
|
||||||
|
|
||||||
|
float horizontalSpeed = MathF.Sqrt(vx * vx + vy * vy);
|
||||||
|
|
||||||
|
if (horizontalSpeed > maxHorizontalVelocity)
|
||||||
|
{
|
||||||
|
float scale = maxHorizontalVelocity / horizontalSpeed;
|
||||||
|
vx *= scale;
|
||||||
|
vy *= scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector velocity = new(vx, vy, vz);
|
||||||
|
|
||||||
|
float yaw = MathF.Atan2(vy, vx) * (180.0f / MathF.PI);
|
||||||
|
float finalHorizontalSpeed = MathF.Sqrt(vx * vx + vy * vy);
|
||||||
|
float pitch = -MathF.Atan2(vz, finalHorizontalSpeed) * (180.0f / MathF.PI);
|
||||||
|
|
||||||
|
QAngle launchAngle = new(pitch, yaw, 0.0f);
|
||||||
|
|
||||||
for (int i = 0; i < grenadeCount; i++)
|
for (int i = 0; i < grenadeCount; i++)
|
||||||
{
|
{
|
||||||
float offsetAngle = Random.Shared.NextSingle() * MathF.Tau;
|
float offsetAngle = Random.Shared.NextSingle() * MathF.Tau;
|
||||||
float offsetDist = MathF.Sqrt(Random.Shared.NextSingle()) * clusterRadius;
|
float offsetDist = MathF.Sqrt(Random.Shared.NextSingle()) * clusterRadius;
|
||||||
|
|
||||||
Vector ground = new(
|
float offsetX = MathF.Cos(offsetAngle) * offsetDist;
|
||||||
decoyGround.X + MathF.Cos(offsetAngle) * offsetDist,
|
float offsetY = MathF.Sin(offsetAngle) * offsetDist;
|
||||||
decoyGround.Y + MathF.Sin(offsetAngle) * offsetDist,
|
|
||||||
decoyGround.Z
|
Vector spawnPos = new(
|
||||||
|
skyCenter.X + offsetX,
|
||||||
|
skyCenter.Y + offsetY,
|
||||||
|
skyCenter.Z
|
||||||
);
|
);
|
||||||
|
|
||||||
var reach = RayTrace.TraceShape(player, decoyGround, ground, null, 0);
|
SkillUtils.CreateMolotovProjectile(spawnPos, launchAngle, velocity, teamNum);
|
||||||
if (reach.HasValue && reach.Value.DidHit)
|
|
||||||
ground = decoyGround;
|
|
||||||
|
|
||||||
float height = maxSpawnHeight;
|
|
||||||
var ceiling = RayTrace.TraceShape(player, ground, new Vector(ground.X, ground.Y, ground.Z + maxSpawnHeight), null, 0);
|
|
||||||
if (ceiling.HasValue && ceiling.Value.DidHit)
|
|
||||||
height = Math.Clamp(maxSpawnHeight * ceiling.Value.Fraction - 24f, 24f, maxSpawnHeight);
|
|
||||||
|
|
||||||
Vector spawnPos = new(ground.X, ground.Y, ground.Z + height);
|
|
||||||
|
|
||||||
SkillUtils.CreateMolotovProjectile(spawnPos, angle, dropVelocity, player.TeamNum);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,6 +218,14 @@ namespace src.player.skills
|
||||||
molotov.Thrower.Raw = thrower.EntityHandle.Raw;
|
molotov.Thrower.Raw = thrower.EntityHandle.Raw;
|
||||||
molotov.OwnerEntity.Raw = thrower.EntityHandle.Raw;
|
molotov.OwnerEntity.Raw = thrower.EntityHandle.Raw;
|
||||||
rainMolotovs[molotov.Index] = (thrower.EntityHandle.Raw, rainTeam);
|
rainMolotovs[molotov.Index] = (thrower.EntityHandle.Raw, rainTeam);
|
||||||
|
|
||||||
|
Server.NextWorldUpdate(() =>
|
||||||
|
{
|
||||||
|
if (molotov == null || !molotov.IsValid) return;
|
||||||
|
molotov.DetonateTime += 30f;
|
||||||
|
Utilities.SetStateChanged(molotov, "CBaseGrenade", "m_flDetonateTime");
|
||||||
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ namespace src.player.skills
|
||||||
var skill = SkillData.Skills.FirstOrDefault(s => player.GetSkillName(s.Skill).Equals(commands[0], StringComparison.OrdinalIgnoreCase) || s.Skill.ToString().Equals(commands[0], StringComparison.OrdinalIgnoreCase));
|
var skill = SkillData.Skills.FirstOrDefault(s => player.GetSkillName(s.Skill).Equals(commands[0], StringComparison.OrdinalIgnoreCase) || s.Skill.ToString().Equals(commands[0], StringComparison.OrdinalIgnoreCase));
|
||||||
if (skill == null)
|
if (skill == null)
|
||||||
{
|
{
|
||||||
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslation("skill_not_found_setskill"));
|
playerEvent.PrintToChat($" {ChatColors.Red}" + playerEvent.GetTranslationWithoutIlliterate("skill_not_found_setskill"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,13 @@ namespace src.player.skills
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly ConcurrentDictionary<uint, List<ChickenState>> activeChickens = new();
|
private static readonly ConcurrentDictionary<uint, List<ChickenState>> activeChickens = new();
|
||||||
private static readonly ConcurrentDictionary<uint, uint> chickenOwners = new();
|
private static readonly ConcurrentDictionary<uint, (uint ownerIndex, int health)> chickenOwners = new();
|
||||||
|
private const string chickenParticle = "particles/critters/chicken/chicken_goop.vpcf";
|
||||||
|
|
||||||
public static void LoadSkill()
|
public static void LoadSkill()
|
||||||
{
|
{
|
||||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||||
|
jRandomSkills.Instance.AddToManifest(chickenParticle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void NewRound()
|
public static void NewRound()
|
||||||
|
|
@ -39,7 +41,10 @@ namespace src.player.skills
|
||||||
CTakeDamageInfo param2 = h.GetParam<CTakeDamageInfo>(1);
|
CTakeDamageInfo param2 = h.GetParam<CTakeDamageInfo>(1);
|
||||||
|
|
||||||
if (param == null || param2 == null) return;
|
if (param == null || param2 == null) return;
|
||||||
if (!chickenOwners.TryGetValue(param.Index, out uint ownerIndex)) return;
|
|
||||||
|
if (!chickenOwners.TryGetValue(param.Index, out var ownerData)) return;
|
||||||
|
uint ownerIndex = ownerData.ownerIndex;
|
||||||
|
int health = ownerData.health;
|
||||||
|
|
||||||
var owner = Utilities.GetPlayerFromIndex((int)ownerIndex);
|
var owner = Utilities.GetPlayerFromIndex((int)ownerIndex);
|
||||||
if (owner == null || !owner.IsValid) return;
|
if (owner == null || !owner.IsValid) return;
|
||||||
|
|
@ -50,9 +55,33 @@ namespace src.player.skills
|
||||||
var attackerPawn = new CCSPlayerPawn(attackerEnt.Handle);
|
var attackerPawn = new CCSPlayerPawn(attackerEnt.Handle);
|
||||||
if (!attackerPawn.IsValid || attackerPawn.DesignerName != "player") return;
|
if (!attackerPawn.IsValid || attackerPawn.DesignerName != "player") return;
|
||||||
|
|
||||||
if (attackerPawn.TeamNum != owner.TeamNum) return;
|
var ownerPawn = owner.PlayerPawn.Value;
|
||||||
|
if (ownerPawn == null || !ownerPawn.IsValid) return;
|
||||||
|
|
||||||
param2.Damage = 0;
|
if (attackerPawn.Index != ownerPawn.Index && attackerPawn.TeamNum == owner.TeamNum)
|
||||||
|
{
|
||||||
|
param2.Damage = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int newHealth = Math.Max(0, health - (int)param2.Damage);
|
||||||
|
chickenOwners[param.Index] = (ownerIndex, newHealth);
|
||||||
|
|
||||||
|
if (newHealth > 0)
|
||||||
|
CreateHitParticles(param.Index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateHitParticles(uint chickenIndex)
|
||||||
|
{
|
||||||
|
var chicken = Utilities.GetEntityFromIndex<CChicken>((int)chickenIndex);
|
||||||
|
if (chicken == null || !chicken.IsValid || chicken.AbsOrigin == null) return;
|
||||||
|
|
||||||
|
var particle = EntityManager.CreateTrackedParticleSystem(chicken.Index, chickenParticle, autoDestroySeconds: 3f);
|
||||||
|
if (particle == null) return;
|
||||||
|
|
||||||
|
Vector pos = new(chicken.AbsOrigin.X, chicken.AbsOrigin.Y, chicken.AbsOrigin.Z + 10);
|
||||||
|
particle.Teleport(pos);
|
||||||
|
particle.AcceptInput("Start");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void EnableSkill(CCSPlayerController player)
|
public static void EnableSkill(CCSPlayerController player)
|
||||||
|
|
@ -79,6 +108,7 @@ namespace src.player.skills
|
||||||
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
|
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
|
||||||
|
|
||||||
int amount = SkillsInfo.GetValue<int>(skillName, "amount");
|
int amount = SkillsInfo.GetValue<int>(skillName, "amount");
|
||||||
|
int health = SkillsInfo.GetValue<int>(skillName, "chickenHealth");
|
||||||
var list = new List<ChickenState>();
|
var list = new List<ChickenState>();
|
||||||
|
|
||||||
for (int i = 0; i < amount; i++)
|
for (int i = 0; i < amount; i++)
|
||||||
|
|
@ -87,7 +117,10 @@ namespace src.player.skills
|
||||||
if (chicken == null || !chicken.IsValid) continue;
|
if (chicken == null || !chicken.IsValid) continue;
|
||||||
|
|
||||||
chicken.Render = Color.LightGreen;
|
chicken.Render = Color.LightGreen;
|
||||||
chickenOwners[chicken.Index] = player.Index;
|
chicken.MaxHealth = health;
|
||||||
|
chicken.Health = health;
|
||||||
|
|
||||||
|
chickenOwners[chicken.Index] = (player.Index, health);
|
||||||
|
|
||||||
Vector offset = new(
|
Vector offset = new(
|
||||||
(float)(100 * Math.Cos(2 * Math.PI * i / amount)),
|
(float)(100 * Math.Cos(2 * Math.PI * i / amount)),
|
||||||
|
|
@ -109,6 +142,8 @@ namespace src.player.skills
|
||||||
int tickCooldown = SkillsInfo.GetValue<int>(skillName, "tickCooldown");
|
int tickCooldown = SkillsInfo.GetValue<int>(skillName, "tickCooldown");
|
||||||
if (Server.TickCount % tickCooldown == 0) return;
|
if (Server.TickCount % tickCooldown == 0) return;
|
||||||
|
|
||||||
|
float boostFactor = SkillsInfo.GetValue<float>(skillName, "boostFactor");
|
||||||
|
|
||||||
var players = PlayerManager.GetTickPlayers().ToArray();
|
var players = PlayerManager.GetTickPlayers().ToArray();
|
||||||
int healAmount = SkillsInfo.GetValue<int>(skillName, "heal");
|
int healAmount = SkillsInfo.GetValue<int>(skillName, "heal");
|
||||||
float healRadius = SkillsInfo.GetValue<float>(skillName, "healRadius");
|
float healRadius = SkillsInfo.GetValue<float>(skillName, "healRadius");
|
||||||
|
|
@ -121,7 +156,7 @@ namespace src.player.skills
|
||||||
if (playerInfo?.Skill != skillName) continue;
|
if (playerInfo?.Skill != skillName) continue;
|
||||||
|
|
||||||
var pawn = player.PlayerPawn.Value;
|
var pawn = player.PlayerPawn.Value;
|
||||||
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue;
|
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null || pawn.Health <= 0) continue;
|
||||||
|
|
||||||
if (!activeChickens.TryGetValue(player.Index, out var chickens)) continue;
|
if (!activeChickens.TryGetValue(player.Index, out var chickens)) continue;
|
||||||
|
|
||||||
|
|
@ -149,7 +184,6 @@ namespace src.player.skills
|
||||||
|
|
||||||
if (dist2D > 0.05f && dist2D < 20.0f)
|
if (dist2D > 0.05f && dist2D < 20.0f)
|
||||||
{
|
{
|
||||||
float boostFactor = 2.5f;
|
|
||||||
Vector newPos = new(
|
Vector newPos = new(
|
||||||
currentOrigin.X + (dx * boostFactor),
|
currentOrigin.X + (dx * boostFactor),
|
||||||
currentOrigin.Y + (dy * boostFactor),
|
currentOrigin.Y + (dy * boostFactor),
|
||||||
|
|
@ -185,12 +219,14 @@ namespace src.player.skills
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#b5ab8f", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = 1, Rarity rarity = Rarity.Legendary, int amount = 3, int heal = 2, int tickCooldown = 16, float healRadius = 150.0f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)
|
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#b5ab8f", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = 1, Rarity rarity = Rarity.Legendary, int amount = 3, int heal = 2, int tickCooldown = 16, float healRadius = 150.0f, int chickenHealth = 50, float boostFactor = 2.5f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)
|
||||||
{
|
{
|
||||||
public int Amount { get; set; } = amount;
|
public int Amount { get; set; } = amount;
|
||||||
public int Heal { get; set; } = heal;
|
public int Heal { get; set; } = heal;
|
||||||
public int TickCooldown { get; set; } = tickCooldown;
|
public int TickCooldown { get; set; } = tickCooldown;
|
||||||
public float HealRadius { get; set; } = healRadius;
|
public float HealRadius { get; set; } = healRadius;
|
||||||
|
public int ChickenHealth { get; set; } = chickenHealth;
|
||||||
|
public float BoostFactor { get; set; } = boostFactor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -35,6 +35,7 @@ namespace src.player.skills
|
||||||
public static void EnableSkill(CCSPlayerController _)
|
public static void EnableSkill(CCSPlayerController _)
|
||||||
{
|
{
|
||||||
isActive = true;
|
isActive = true;
|
||||||
|
SendAlertToAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Enable()
|
public static void Enable()
|
||||||
|
|
@ -47,6 +48,15 @@ namespace src.player.skills
|
||||||
isActive = false;
|
isActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void SendAlertToAll()
|
||||||
|
{
|
||||||
|
foreach (var player in PlayerManager.GetTickPlayers())
|
||||||
|
{
|
||||||
|
if (!CheckIlliterateSkill(player)) continue;
|
||||||
|
player.PrintToCenterAlert(player.GetTranslationWithoutIlliterate("illiterate_alert"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static bool CheckIlliterateSkill(CCSPlayerController? player)
|
public static bool CheckIlliterateSkill(CCSPlayerController? player)
|
||||||
{
|
{
|
||||||
if (!isActive || player == null || !player.IsValid) return false;
|
if (!isActive || player == null || !player.IsValid) return false;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ namespace src.player.skills
|
||||||
public class Magnifier : ISkill
|
public class Magnifier : ISkill
|
||||||
{
|
{
|
||||||
private const Skills skillName = Skills.Magnifier;
|
private const Skills skillName = Skills.Magnifier;
|
||||||
private static readonly ConcurrentDictionary<uint, uint> playersFOV = [];
|
private static readonly ConcurrentDictionary<uint, byte> playersWithFov = [];
|
||||||
private static readonly ConcurrentDictionary<uint, uint> playersToTarget = [];
|
private static readonly ConcurrentDictionary<uint, uint> playersToTarget = [];
|
||||||
|
|
||||||
public static void LoadSkill()
|
public static void LoadSkill()
|
||||||
|
|
@ -19,8 +19,9 @@ namespace src.player.skills
|
||||||
|
|
||||||
public static void PlayerDisconnect(uint playerIndex)
|
public static void PlayerDisconnect(uint playerIndex)
|
||||||
{
|
{
|
||||||
playersFOV.TryRemove(playerIndex, out _);
|
playersWithFov.TryRemove(playerIndex, out _);
|
||||||
playersToTarget.TryRemove(playerIndex, out _);
|
playersToTarget.TryRemove(playerIndex, out _);
|
||||||
|
Event.playersCustomFOV.TryRemove(playerIndex, out _);
|
||||||
|
|
||||||
foreach (var kvp in playersToTarget)
|
foreach (var kvp in playersToTarget)
|
||||||
if (kvp.Value == playerIndex)
|
if (kvp.Value == playerIndex)
|
||||||
|
|
@ -29,14 +30,14 @@ namespace src.player.skills
|
||||||
|
|
||||||
public static void NewRound()
|
public static void NewRound()
|
||||||
{
|
{
|
||||||
foreach (var playerIndex in playersFOV.Keys)
|
foreach (var playerIndex in playersWithFov.Keys)
|
||||||
{
|
{
|
||||||
var player = Utilities.GetPlayerFromIndex((int)playerIndex);
|
var player = Utilities.GetPlayerFromIndex((int)playerIndex);
|
||||||
if (player == null || !player.IsValid) continue;
|
if (player == null || !player.IsValid) continue;
|
||||||
DisableSkill(player);
|
DisableSkill(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
playersFOV.Clear();
|
playersWithFov.Clear();
|
||||||
playersToTarget.Clear();
|
playersToTarget.Clear();
|
||||||
|
|
||||||
foreach (var player in PlayerManager.GetTickPlayers())
|
foreach (var player in PlayerManager.GetTickPlayers())
|
||||||
|
|
@ -91,13 +92,21 @@ namespace src.player.skills
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
playersFOV.AddOrUpdate(enemy.Index, enemy.DesiredFOV, (k, v) => enemy.DesiredFOV);
|
uint magnifierFov = SkillsInfo.GetValue<uint>(skillName, "customFOV");
|
||||||
|
playersWithFov.TryAdd(enemy.Index, 0);
|
||||||
|
|
||||||
|
uint enemyFOV = enemy.DesiredFOV;
|
||||||
|
if (enemyFOV == 0)
|
||||||
|
Event.playersCustomFOV.TryRemove(enemy.Index, out _);
|
||||||
|
else if (enemyFOV != magnifierFov)
|
||||||
|
Event.playersCustomFOV.AddOrUpdate(enemy.Index, enemy.DesiredFOV, (k, v) => enemy.DesiredFOV);
|
||||||
|
|
||||||
playersToTarget[player.Index] = enemy.Index;
|
playersToTarget[player.Index] = enemy.Index;
|
||||||
|
|
||||||
var enemyEvent = PlayerManager.GetPlayerFromEvent(enemy);
|
var enemyEvent = PlayerManager.GetPlayerFromEvent(enemy);
|
||||||
if (enemyEvent == null || !enemyEvent.IsValid) return;
|
if (enemyEvent == null || !enemyEvent.IsValid) return;
|
||||||
|
|
||||||
enemyEvent.DesiredFOV = SkillsInfo.GetValue<uint>(skillName, "customFOV");
|
enemyEvent.DesiredFOV = magnifierFov;
|
||||||
Utilities.SetStateChanged(enemyEvent, "CBasePlayerController", "m_iDesiredFOV");
|
Utilities.SetStateChanged(enemyEvent, "CBasePlayerController", "m_iDesiredFOV");
|
||||||
playerInfo.SkillUsed = true;
|
playerInfo.SkillUsed = true;
|
||||||
|
|
||||||
|
|
@ -113,9 +122,15 @@ namespace src.player.skills
|
||||||
var player = @event.Userid;
|
var player = @event.Userid;
|
||||||
if (player == null || !player.IsValid) return;
|
if (player == null || !player.IsValid) return;
|
||||||
|
|
||||||
if (!playersFOV.ContainsKey(bot.Index)) return;
|
if (!playersWithFov.ContainsKey(bot.Index)) return;
|
||||||
|
|
||||||
player.DesiredFOV = SkillsInfo.GetValue<uint>(skillName, "customFOV");
|
uint magnifierFov = SkillsInfo.GetValue<uint>(skillName, "customFOV");
|
||||||
|
uint playerFOV = player.DesiredFOV;
|
||||||
|
|
||||||
|
if (playerFOV != 0 && playerFOV != magnifierFov)
|
||||||
|
Event.playersCustomFOV.AddOrUpdate(player.Index, player.DesiredFOV, (k, v) => player.DesiredFOV);
|
||||||
|
|
||||||
|
player.DesiredFOV = magnifierFov;
|
||||||
Utilities.SetStateChanged(player, "CBasePlayerController", "m_iDesiredFOV");
|
Utilities.SetStateChanged(player, "CBasePlayerController", "m_iDesiredFOV");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -147,16 +162,22 @@ namespace src.player.skills
|
||||||
var target = PlayerManager.GetPlayerFromEvent(Utilities.GetPlayerFromIndex((int)targetIndex));
|
var target = PlayerManager.GetPlayerFromEvent(Utilities.GetPlayerFromIndex((int)targetIndex));
|
||||||
if (target != null && target.IsValid)
|
if (target != null && target.IsValid)
|
||||||
{
|
{
|
||||||
if (playersFOV.TryGetValue(targetIndex, out uint fov))
|
if (target.DesiredFOV == SkillsInfo.GetValue<uint>(skillName, "customFOV"))
|
||||||
{
|
{
|
||||||
target.DesiredFOV = fov;
|
target.DesiredFOV = Event.playersCustomFOV.TryGetValue(target.Index, out uint fov) ? fov : 0;
|
||||||
Utilities.SetStateChanged(target, "CBasePlayerController", "m_iDesiredFOV");
|
Utilities.SetStateChanged(target, "CBasePlayerController", "m_iDesiredFOV");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.PawnIsAlive && !SkillUtils.IsFreezeTime())
|
if (target.PawnIsAlive && !SkillUtils.IsFreezeTime())
|
||||||
target.PrintToChat($" {ChatColors.Green}" + target.GetTranslation("magnifier_disable_info"));
|
target.PrintToChat($" {ChatColors.Green}" + target.GetTranslation("magnifier_disable_info"));
|
||||||
}
|
}
|
||||||
playersFOV.TryRemove(targetIndex, out _);
|
playersWithFov.TryRemove(targetIndex, out _);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.DesiredFOV != 0)
|
||||||
|
{
|
||||||
|
player.DesiredFOV = Event.playersCustomFOV.TryGetValue(player.Index, out uint fov) ? fov : 0;
|
||||||
|
Utilities.SetStateChanged(player, "CBasePlayerController", "m_iDesiredFOV");
|
||||||
}
|
}
|
||||||
|
|
||||||
SkillUtils.ResetPrintHTML(player);
|
SkillUtils.ResetPrintHTML(player);
|
||||||
|
|
@ -167,8 +188,12 @@ namespace src.player.skills
|
||||||
var player = @event.Userid;
|
var player = @event.Userid;
|
||||||
if (player == null || !player.IsValid) return;
|
if (player == null || !player.IsValid) return;
|
||||||
|
|
||||||
player.DesiredFOV = 0;
|
if (player.DesiredFOV == SkillsInfo.GetValue<uint>(skillName, "customFOV"))
|
||||||
Utilities.SetStateChanged(player, "CBasePlayerController", "m_iDesiredFOV");
|
{
|
||||||
|
player.DesiredFOV = Event.playersCustomFOV.TryGetValue(player.Index, out uint fov) ? fov : 0;
|
||||||
|
Utilities.SetStateChanged(player, "CBasePlayerController", "m_iDesiredFOV");
|
||||||
|
}
|
||||||
|
|
||||||
SkillUtils.ResetPrintHTML(player);
|
SkillUtils.ResetPrintHTML(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,9 @@ namespace src.player.skills
|
||||||
Instance.GameRules.RoundTime += player.Team == CsTeam.Terrorist ? roundTime : -roundTime;
|
Instance.GameRules.RoundTime += player.Team == CsTeam.Terrorist ? roundTime : -roundTime;
|
||||||
|
|
||||||
if (player.Team == CsTeam.Terrorist)
|
if (player.Team == CsTeam.Terrorist)
|
||||||
Localization.PrintTranslationToChatAll($" {ChatColors.Orange}{{0}}", ["watchmaker_tt"], [roundTime]);
|
Localization.PrintTranslationToChatAll($" {ChatColors.Orange}{{0}}", ["watchmaker_tt"], true, [roundTime]);
|
||||||
else
|
else
|
||||||
Localization.PrintTranslationToChatAll($" {ChatColors.LightBlue}{{0}}", ["watchmaker_ct"], [roundTime]);
|
Localization.PrintTranslationToChatAll($" {ChatColors.LightBlue}{{0}}", ["watchmaker_ct"], true, [roundTime]);
|
||||||
|
|
||||||
player.EmitSound(SkillsInfo.GetValue<string>(skillName, "SoundEvent"));
|
player.EmitSound(SkillsInfo.GetValue<string>(skillName, "SoundEvent"));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,14 +25,14 @@ namespace src.utils
|
||||||
if (targetresult.Players.Count == 0)
|
if (targetresult.Players.Count == 0)
|
||||||
{
|
{
|
||||||
if (!ignoreMessage && command.CallingPlayer != null)
|
if (!ignoreMessage && command.CallingPlayer != null)
|
||||||
command.ReplyToCommand(command.CallingPlayer.GetTranslation("no_player"));
|
command.ReplyToCommand(command.CallingPlayer.GetTranslationWithoutIlliterate("no_player"));
|
||||||
|
|
||||||
return (new List<CCSPlayerController>(), string.Empty);
|
return (new List<CCSPlayerController>(), string.Empty);
|
||||||
}
|
}
|
||||||
else if (singletarget && targetresult.Players.Count > 1)
|
else if (singletarget && targetresult.Players.Count > 1)
|
||||||
{
|
{
|
||||||
if (command.CallingPlayer != null)
|
if (command.CallingPlayer != null)
|
||||||
command.ReplyToCommand(command.CallingPlayer.GetTranslation("duplicate_player"));
|
command.ReplyToCommand(command.CallingPlayer.GetTranslationWithoutIlliterate("duplicate_player"));
|
||||||
return (new List<CCSPlayerController>(), string.Empty);
|
return (new List<CCSPlayerController>(), string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ namespace src.utils
|
||||||
}
|
}
|
||||||
|
|
||||||
var value = Math.Round((double)(chance ?? 1), 2);
|
var value = Math.Round((double)(chance ?? 1), 2);
|
||||||
var skillNameText = GetTranslation(SkillKey(skill), langCode, player, value);
|
var skillNameText = GetTranslation(SkillKey(skill), langCode, player, true, value);
|
||||||
if (skillNameText.Contains('%')) skillNameText = skillNameText.Replace(value.ToString(), Math.Round(value * 100, 0).ToString());
|
if (skillNameText.Contains('%')) skillNameText = skillNameText.Replace(value.ToString(), Math.Round(value * 100, 0).ToString());
|
||||||
return skillNameText;
|
return skillNameText;
|
||||||
}
|
}
|
||||||
|
|
@ -173,7 +173,7 @@ namespace src.utils
|
||||||
|
|
||||||
var skillName = SkillDesc2Key(skill);
|
var skillName = SkillDesc2Key(skill);
|
||||||
var value = Math.Round((double)(chance ?? 1), 2);
|
var value = Math.Round((double)(chance ?? 1), 2);
|
||||||
var desc2 = GetTranslation(skillName, langCode, player, value);
|
var desc2 = GetTranslation(skillName, langCode, player, true, value);
|
||||||
|
|
||||||
var skilLDescription = desc2 == skillName
|
var skilLDescription = desc2 == skillName
|
||||||
? player.GetTranslation(SkillDescKey(skill))
|
? player.GetTranslation(SkillDescKey(skill))
|
||||||
|
|
@ -181,7 +181,7 @@ namespace src.utils
|
||||||
return skilLDescription;
|
return skilLDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PrintTranslationToChatAll(string message, string[]? key, params object[][]? args)
|
public static void PrintTranslationToChatAll(string message, string[]? key, bool useIlliterate = true, params object[][]? args)
|
||||||
{
|
{
|
||||||
foreach (var player in Utilities.GetPlayers().Where(p => !p.IsBot))
|
foreach (var player in Utilities.GetPlayers().Where(p => !p.IsBot))
|
||||||
{
|
{
|
||||||
|
|
@ -196,7 +196,7 @@ namespace src.utils
|
||||||
for (int i = 0; i < key.Length; i++)
|
for (int i = 0; i < key.Length; i++)
|
||||||
{
|
{
|
||||||
object[] currentArgs = args != null && i < args.Length ? args[i] : [];
|
object[] currentArgs = args != null && i < args.Length ? args[i] : [];
|
||||||
string translation = GetTranslation(key[i], langCode, null, currentArgs);
|
string translation = GetTranslation(key[i], langCode, null, useIlliterate, currentArgs);
|
||||||
translations.Add(translation);
|
translations.Add(translation);
|
||||||
}
|
}
|
||||||
player.PrintToChat(string.Format(message, [.. translations]));
|
player.PrintToChat(string.Format(message, [.. translations]));
|
||||||
|
|
@ -206,10 +206,21 @@ namespace src.utils
|
||||||
public static string GetTranslation(this CCSPlayerController player, string key, params object[] args)
|
public static string GetTranslation(this CCSPlayerController player, string key, params object[] args)
|
||||||
{
|
{
|
||||||
string langCode = GetLangCode(player);
|
string langCode = GetLangCode(player);
|
||||||
return GetTranslation(key, langCode, player, args);
|
return GetTranslation(key, langCode, player, true, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetTranslation(string key, string? langCode = null, CCSPlayerController? player = null, params object[] args)
|
public static string GetTranslationWithoutIlliterate(this CCSPlayerController player, string key, params object[] args)
|
||||||
|
{
|
||||||
|
string langCode = GetLangCode(player);
|
||||||
|
return GetTranslation(key, langCode, player, false, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetTranslationWithoutIlliterate(string key)
|
||||||
|
{
|
||||||
|
return GetTranslation(key, null, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetTranslation(string key, string? langCode = null, CCSPlayerController? player = null, bool useIlliterate = true, params object[] args)
|
||||||
{
|
{
|
||||||
langCode ??= defaultLangCode;
|
langCode ??= defaultLangCode;
|
||||||
if (_translations.TryGetValue(langCode, out var langDict) && langDict.TryGetValue(key, out var translation))
|
if (_translations.TryGetValue(langCode, out var langDict) && langDict.TryGetValue(key, out var translation))
|
||||||
|
|
@ -219,13 +230,13 @@ namespace src.utils
|
||||||
{
|
{
|
||||||
string output = args.Length == 0 ? translation : string.Format(translation, args);
|
string output = args.Length == 0 ? translation : string.Format(translation, args);
|
||||||
|
|
||||||
if (Illiterate.CheckIlliterateSkill(player))
|
if (useIlliterate && Illiterate.CheckIlliterateSkill(player))
|
||||||
return Illiterate.GetRandomText(output)!;
|
return Illiterate.GetRandomText(output)!;
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (langCode != defaultLangCode)
|
if (langCode != defaultLangCode)
|
||||||
return GetTranslation(key, null, player, args);
|
return GetTranslation(key, null, player, useIlliterate, args);
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -878,7 +878,7 @@ namespace src.utils
|
||||||
if (manager == null) return;
|
if (manager == null) return;
|
||||||
|
|
||||||
var config = Config.LoadedConfig.HtmlHudCustomisation;
|
var config = Config.LoadedConfig.HtmlHudCustomisation;
|
||||||
var your_skill = player.GetTranslation("your_skill");
|
var your_skill = player.GetTranslationWithoutIlliterate("your_skill");
|
||||||
var emptySymbol = $"<font class='fontSize-{(string.IsNullOrEmpty(your_skill) ? "l" : "ml")}'> </font>";
|
var emptySymbol = $"<font class='fontSize-{(string.IsNullOrEmpty(your_skill) ? "l" : "ml")}'> </font>";
|
||||||
|
|
||||||
string infoLine = string.IsNullOrEmpty(your_skill)
|
string infoLine = string.IsNullOrEmpty(your_skill)
|
||||||
|
|
@ -897,9 +897,9 @@ namespace src.utils
|
||||||
var hudContent = infoLine + skillLine + remainingLine;
|
var hudContent = infoLine + skillLine + remainingLine;
|
||||||
|
|
||||||
string controllsLine =
|
string controllsLine =
|
||||||
$"{emptySymbol}<font class='fontSize-{config.WSADMenuControllsLineSize}' color='{config.WSADMenuControllsLineColor1}'>{player.GetTranslation($"menu_controlls_scroll")}</font>"
|
$"{emptySymbol}<font class='fontSize-{config.WSADMenuControllsLineSize}' color='{config.WSADMenuControllsLineColor1}'>{player.GetTranslationWithoutIlliterate($"menu_controlls_scroll")}</font>"
|
||||||
+ $"<font class='fontSize-{config.WSADMenuControllsLineSize}' color='{config.WSADMenuControllsLineColor2}'>{player.GetTranslation($"menu_controlls_padding")}</font>"
|
+ $"<font class='fontSize-{config.WSADMenuControllsLineSize}' color='{config.WSADMenuControllsLineColor2}'>{player.GetTranslationWithoutIlliterate($"menu_controlls_padding")}</font>"
|
||||||
+ $"<font class='fontSize-{config.WSADMenuControllsLineSize}' color='{config.WSADMenuControllsLineColor3}'>{player.GetTranslation($"menu_controlls_select")}</font>{emptySymbol}";
|
+ $"<font class='fontSize-{config.WSADMenuControllsLineSize}' color='{config.WSADMenuControllsLineColor3}'>{player.GetTranslationWithoutIlliterate($"menu_controlls_select")}</font>{emptySymbol}";
|
||||||
|
|
||||||
string itemText = $"<font class='fontSize-{config.WSADMenuItemLineSize}' color='{config.WSADMenuItemLineColor}'>{{0}}</font><br>";
|
string itemText = $"<font class='fontSize-{config.WSADMenuItemLineSize}' color='{config.WSADMenuItemLineColor}'>{{0}}</font><br>";
|
||||||
string itemHoverText = $"<font class='fontSize-{config.WSADMenuItemLineSize}'><font color='purple'>[ </font><font color='{config.WSADMenuItemHoverLineColor}'>{{0}}</font><font color='purple'> ]</font></font><br>";
|
string itemHoverText = $"<font class='fontSize-{config.WSADMenuItemLineSize}'><font color='purple'>[ </font><font color='{config.WSADMenuItemHoverLineColor}'>{{0}}</font><font color='purple'> ]</font></font><br>";
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -248,6 +248,7 @@
|
||||||
|
|
||||||
"illiterate": "Analphabet",
|
"illiterate": "Analphabet",
|
||||||
"illiterate_desc": "Solange du am Leben bist, können deine Feinde nichts lesen",
|
"illiterate_desc": "Solange du am Leben bist, können deine Feinde nichts lesen",
|
||||||
|
"illiterate_alert": "Analphabet ist aktiv! Du kannst keine Nachrichten lesen, bis der Besitzer dieser Fähigkeit eliminiert ist",
|
||||||
|
|
||||||
"illusionist": "Illusionist",
|
"illusionist": "Illusionist",
|
||||||
"illusionist_desc": "Klicke [css_useSkill], um ein Abbild zu schicken, das geradeaus läuft",
|
"illusionist_desc": "Klicke [css_useSkill], um ein Abbild zu schicken, das geradeaus läuft",
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,7 @@
|
||||||
|
|
||||||
"illiterate": "Illiterate",
|
"illiterate": "Illiterate",
|
||||||
"illiterate_desc": "As long as you are alive, your enemies cannot read",
|
"illiterate_desc": "As long as you are alive, your enemies cannot read",
|
||||||
|
"illiterate_alert": "Illiterate is active! You cannot read messages until the owner of this skill is eliminated",
|
||||||
|
|
||||||
"illusionist": "Illusionist",
|
"illusionist": "Illusionist",
|
||||||
"illusionist_desc": "Click [css_useSkill] to deploy a replica that walks straight ahead",
|
"illusionist_desc": "Click [css_useSkill] to deploy a replica that walks straight ahead",
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,8 @@
|
||||||
"iana_desc": "Cliquez sur [css_useSkill] pour contrôler votre hologramme pendant quelques secondes",
|
"iana_desc": "Cliquez sur [css_useSkill] pour contrôler votre hologramme pendant quelques secondes",
|
||||||
|
|
||||||
"illiterate": "Illettré",
|
"illiterate": "Illettré",
|
||||||
"illiterate_desc": "Tant que vous êtes en vie, vos ennemis ne mogą pas lire",
|
"illiterate_desc": "Tant que vous êtes en vie, vos ennemis ne peuvent pas lire",
|
||||||
|
"illiterate_alert": "Illettré est actif ! Vous ne pouvez pas lire les messages tant que le propriétaire de cette compétence n'est pas éliminé",
|
||||||
|
|
||||||
"illusionist": "Illusionniste",
|
"illusionist": "Illusionniste",
|
||||||
"illusionist_desc": "Cliquez sur [css_useSkill] pour déployer une réplique qui marche droit devant",
|
"illusionist_desc": "Cliquez sur [css_useSkill] pour déployer une réplique qui marche droit devant",
|
||||||
|
|
|
||||||
|
|
@ -248,6 +248,7 @@
|
||||||
|
|
||||||
"illiterate": "Analfabeta",
|
"illiterate": "Analfabeta",
|
||||||
"illiterate_desc": "Dopóki żyjesz, Twoi wrogowie nie potrafią czytać",
|
"illiterate_desc": "Dopóki żyjesz, Twoi wrogowie nie potrafią czytać",
|
||||||
|
"illiterate_alert": "Analfabeta jest aktywny! Nie możesz czytać wiadomości, dopóki właściciel tej umiejętności nie zostanie wyeliminowany",
|
||||||
|
|
||||||
"illusionist": "Iluzjonista",
|
"illusionist": "Iluzjonista",
|
||||||
"illusionist_desc": "Naciśnij [css_useSkill], aby wypuścić replikę idącą prosto przed siebie",
|
"illusionist_desc": "Naciśnij [css_useSkill], aby wypuścić replikę idącą prosto przed siebie",
|
||||||
|
|
|
||||||
|
|
@ -248,6 +248,7 @@
|
||||||
|
|
||||||
"illiterate": "Analfabeto",
|
"illiterate": "Analfabeto",
|
||||||
"illiterate_desc": "Enquanto você estiver vivo, seus inimigos não conseguem ler",
|
"illiterate_desc": "Enquanto você estiver vivo, seus inimigos não conseguem ler",
|
||||||
|
"illiterate_alert": "Analfabeto está ativo! Você não pode ler mensagens até que o proprietário desta habilidade seja eliminado",
|
||||||
|
|
||||||
"illusionist": "Ilusionista",
|
"illusionist": "Ilusionista",
|
||||||
"illusionist_desc": "Clique em [css_useSkill] para enviar uma réplica que caminha em frente",
|
"illusionist_desc": "Clique em [css_useSkill] para enviar uma réplica que caminha em frente",
|
||||||
|
|
|
||||||
|
|
@ -248,6 +248,7 @@
|
||||||
|
|
||||||
"illiterate": "Неграмотный",
|
"illiterate": "Неграмотный",
|
||||||
"illiterate_desc": "Пока вы живы, ваши враги не могут читать (чат)",
|
"illiterate_desc": "Пока вы живы, ваши враги не могут читать (чат)",
|
||||||
|
"illiterate_alert": "Неграмотный активен! Вы не можете читать сообщения, пока владелец этой способности не будет устранён",
|
||||||
|
|
||||||
"illusionist": "Иллюзионист",
|
"illusionist": "Иллюзионист",
|
||||||
"illusionist_desc": "Нажмите [css_useSkill], чтобы создать копию, идущую вперёд",
|
"illusionist_desc": "Нажмите [css_useSkill], чтобы создать копию, идущую вперёд",
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,7 @@
|
||||||
|
|
||||||
"illiterate": "Cahiliye",
|
"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 rakibin sohbeti (chat) veya oyun yazılarını okuyamaz",
|
||||||
|
"illiterate_alert": "Cahiliye aktif! Bu yeteneğin sahibi ortadan kalkana kadar mesajları okuyamazsınız.",
|
||||||
|
|
||||||
"illusionist": "İllüzyonist",
|
"illusionist": "İllüzyonist",
|
||||||
"illusionist_desc": "[css_useSkill] tuşuna basarak düz ilerleyen illüzyon oluştur",
|
"illusionist_desc": "[css_useSkill] tuşuna basarak düz ilerleyen illüzyon oluştur",
|
||||||
|
|
|
||||||
|
|
@ -226,6 +226,7 @@
|
||||||
|
|
||||||
"illiterate": "文盲",
|
"illiterate": "文盲",
|
||||||
"illiterate_desc": "只要你还活着,你的敌人就无法阅读",
|
"illiterate_desc": "只要你还活着,你的敌人就无法阅读",
|
||||||
|
"illiterate_alert": "文盲已激活!在该技能的拥有者被消灭之前,你无法阅读消息。",
|
||||||
|
|
||||||
"illusionist": "幻术师",
|
"illusionist": "幻术师",
|
||||||
"illusionist_desc": "点击 [css_useSkill] 部署一个直线行走的幻象",
|
"illusionist_desc": "点击 [css_useSkill] 部署一个直线行走的幻象",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue